前言
我终于决定还是把这个放出来。
介绍
具体信息主界面上都有写。
按空格暂停,建议暂停后再升级属性。
记录最高分的文件进行了加密。
有boss。
挺好玩的。
可能有bug,不想改了,整体体验不错就行了。
更多控制台操作可以看之前写的鼠标操作的文章,也可以直接在这个上面复制。
MinGW编译无错误,只有lld
输出的几个警告。
只有一个文件,没有任何其他的东西。
可以直接扒下来编译。
一开始写的时候打了很多注释,后来就不想打了。
大家凑合着看吧,不清楚的就评论,如果我还记得到就答一下哈。
对了,为了防止暂停作弊,暂停过后开始时鼠标会回到飞机的位置。
这个代码我一个人可能总共肝了20多个小时,希望不要随意转载。注明出处就好。
如果你能帮我改得更有趣,bug更少的话可以找我。
更多内容看代码。
我记不到这份代码是什么情况了,有可能是之前更新到一半的代码,反正我试着海星。
代码
#include<set>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<windows.h>
#include<algorithm>
#include<iostream>
#include<conio.h>
#include<fstream>
using namespace std;
#define fblack 0
#define fblue 1
#define fgreen 2
#define fcyan 3
#define fred 4
#define fpurple 5
#define fyellow 6
#define fwhite 7
#define fgray 8
#define flight 8
#define bblack 0
#define bblue 16
#define bgreen 32
#define bcyan 48
#define bfred 64
#define bpurple 80
#define byellow 96
#define bwhite 112
#define bgray 128
#define blight 128
#define dirkey -32
#define upkey 72
#define downkey 80
#define leftkey 75
#define rightkey 77
#define wclear system("cls")
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
#define LL long long
void flash(int times){
while(times--){
system("color 08");
Sleep(300);
system("color 80");
Sleep(300);
}
//Sleep(1000);
system("color 08");
}
void HindCursor(){
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle,&CursorInfo);
CursorInfo.bVisible=false;
SetConsoleCursorInfo(handle,&CursorInfo);
}
struct Button{
int x,y,color;
const char *name;
int len;
};
void GetPos(POINT &pt){
HWND hwnd=GetForegroundWindow();
GetCursorPos(&pt);
ScreenToClient(hwnd,&pt);
pt.y=pt.y/16,pt.x=pt.x/8;
swap(pt.x,pt.y);
}
void color(int a){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
void gto(int x,int y){
COORD pos;pos.X=y;pos.Y=x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
Button NewButton(int x,int y,int color,const char *name){
Button t;
t.x=x,t.y=y,t.name=name;
t.color=color;
t.len=strlen(name);
return t;
}
bool Preserve(Button A){
gto(A.x,A.y),color(A.color),printf("%s",A.name);
POINT pt;
GetPos(pt);
if(pt.x==A.x&&(pt.y>=A.y&&pt.y<=A.y+A.len)){
color(112),gto(A.x,A.y),printf("%s",A.name);
if(KEY_DOWN(MOUSE_MOVED)) return 1;
}
return 0;
}
pair<int,int> GetXY(){
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO pBuffer;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hStdout, &pBuffer);
return make_pair(pBuffer.dwCursorPosition.Y,pBuffer.dwCursorPosition.X);
}
template <typename T>void Tprint(int Nx,int Ny,int Color,T a){
int x=GetXY().first,y=GetXY().second;
gto(Nx,Ny),color(Color),cout<<a;
gto(x,y);
}
void ColorPrint(){
for(int i=0;i<256;i++)
color(i),printf("%d\n",i);
}
void SetWindow(const char *name,int c,int w){
char str[30];
sprintf(str,"title %s",name);
system(str);
sprintf(str,"mode con cols=%d lines=%d",w,c);
system(str);
}
void SetWindow(const char *name,int c,int w,int x,int y){
SetConsoleTitle(name);
HWND hwnd;
hwnd=GetForegroundWindow();
SetWindowPos(hwnd,HWND_TOP,y,x,w*8,c*16,SWP_SHOWWINDOW);
}
int read(){
color(fwhite+flight);
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){
x=x*10+c-'0';c=getchar();}
return x*f;
}
#define TP Tprint
#define WINDOWC 45
#define WINDOWW 55
#define INF 0x3f3f3f3f
#define OC fwhite+flight+bblack //original color
bool InRange(int x){
return x>=0&&x<=WINDOWC;
}
int BossFlag;
int OwnShotTimes,OwnLoseBlood,OwnShotOnTimes;
int MoneyFlash,ScoreFlash;
const int ConstNewDy[4]={
-1,0,1};
#define MAX_BULLET_TYPE_NUM 3
const int ConstBulletColor[MAX_BULLET_TYPE_NUM+5]={
0,fyellow,fred+flight,fred+flight,fblue+flight,fred+bwhite};
const char ConstBulletShape[MAX_BULLET_TYPE_NUM+5]={
0,'*','*','O','|','%'};
const int ConstBulletDamage[MAX_BULLET_TYPE_NUM+5]={
0,50,80,500,20,300};
/*Move 1 block every 100-Speed ms*/
const int ConstBulletSpeed[MAX_BULLET_TYPE_NUM+5]={
0,50,30,10,80,20};
/*The color of the full block in the blood line*/
const int ConstBloodColor[4]={
0,fred,fyellow,fgreen};
#define MAX_BOSS_NUM 10
const int ConstBossFullBlood[MAX_BOSS_NUM+5]={
0,1000,3000,5000,10000,30000,50000,100000,300000,500000,1000000};
const int ConstBossShotSpeed[MAX_BOSS_NUM+5][2]={
{
0,0},{
30,-3900},{
30,-3400},{
50,-2900},{
50,-2400},{
70,-1900},{
70,-1400},{
90,-900},{
90,-400},{
100,-400},{
100,-400}};
const int ConstBossStopCD[MAX_BOSS_NUM+5]={
0,3200,3400,3600,3800,4000,4200,4400,4600,4800,5000};
const int ConstBossStopTime[MAX_BOSS_NUM+5]={
0,3000,2800,2600,2400,2200,2000,1800,1600,1400,1200};
const int ConstBossMoveSpeed[MAX_BOSS_NUM+5]={
0,800,800,800,850,850,850,900,900,900,950};
const int ConstBossScore[MAX_BOSS_NUM+5]={
0,10000,20000,40000,80000,160000,320000,640000,1280000,2560000,5120000};
const int ConstBossMoney[MAX_BOSS_NUM+5]={
0,100,200,500,1000,2000,5000,8000,10000,20000,50000};
const int ConstBossNeedScore[MAX_BOSS_NUM+5]={
0,500,1000,1500,2000,2500,3000,3500,4000,4500,5000};
struct Bullet{
int isExist;
int x,y,Type;
int dx,dy,LastBulletRefreshTime;
Bullet(){
LastBulletRefreshTime=-INF;}
Bullet(int isExist_,int x_,int y_,int Type_,int dx_,int dy_):
isExist(isExist_),x(x_),y(y_),Type(Type_),dx(dx_),dy(dy_){
}
};
void MoveBullet(Bullet&);
/*We must use Bullet*, or we can't change the data(position of the bullet) in the set*/
set<Bullet*> Ammo;
void BulletsRefresh(){
vector<set<Bullet*>::iterator> Throw;
for(set<Bullet*>::iterator it=Ammo.begin();it!=Ammo.end();it++){
Bullet *New=*it;
MoveBullet(*New);
/*We can't erase it right away*/
if(!New->isExist)
Throw.push_back(it);
}
for(int i=0;i<int(Throw.size());i++)
Ammo.erase(Throw[i]);
}
int BEGINTIME;
int UFOAddBlood,UFOAddShotSpeed,UFOAddMoveSpeed,Added;
struct UFO{
/*
Shape of the UFO:
0000/0000
@@@
(OOO)
\-/
V
*/
int isExist;
int x,y;//position of the head
int dx,dy;
int Blood,FullBlood;
int ShotSpeed,LastShotTime;
int MoveSpeed;
int LastMoveTime;
int Score,Money;
UFO(){
if(BossFlag&&!Added)
UFOAddBlood+=100,UFOAddShotSpeed+=100,UFOAddMoveSpeed+=100,Added=1;
if(!BossFlag&&Added)
UFOAddBlood-=100,UFOAddShotSpeed-=100,UFOAddMoveSpeed-=100,Added=0;
isExist=1;
x=0,y=rand()%(WINDOWW-4)+4;//Must be in the screen
FullBlood=rand()%300+100+UFOAddBlood;
Blood=FullBlood;
ShotSpeed=rand()%1000+UFOAddShotSpeed;
/*Move 1 block every 1000-MoveSpeed ms*/
MoveSpeed=rand()%600+300+UFOAddMoveSpeed;
LastMoveTime=LastShotTime=-INF;
dx=1,dy=0;
Score=FullBlood/30+((clock()-BEGINTIME)/10000);
Money=MoveSpeed/100.0+FullBlood/100.0;
}
/*effects when being hit*/
void Flash(){
/*the head is sure to be in the screen so we needn't check*/
if(!isExist)
return;
if(x>0&&x<WINDOWC)
TP(x,y,fpurple+bwhite,'V');
if(x-1>0&&x-1<WINDOWC)
TP(x-1,y-1,fpurple+bwhite,"\\-/");
//Sleep(100);
if(x>0&&x<WINDOWC)
TP(x,y,fpurple+bblack,'V');
if(x-1>0&&x-1<WINDOWC)
TP(x-1,y-1,fpurple+bblack,"\\-/");
}
/*Check if hit only on the body*/
bool Hit(int tx,int ty){
return (tx==x&&ty==y)||
(tx==x-1&&ty>=y-1&&ty<=y+1);
}
/*To check if it will hit another UFO*/
void BloodRefresh(int NewX,int NewY){
/*To appear gradually, we should check the position*/
if(x-2>=0){
TP(x-2,y-1,OC," ");
if(isExist)
if(NewX-2<WINDOWC){
/*Round up*/
int FullBlock=(Blood*3+FullBlood-1)/FullBlood; //Number of "@"
int EmptyBlock=3-FullBlock; //Number of "O"
int BloodColor=ConstBloodColor[FullBlock];
/*Print the blood line*/
for(int i=1;i<=FullBlock;i++)
TP(NewX-2,NewY-2+i,BloodColor+bblack,'@');
for(int i=1;i<=EmptyBlock;i++)
TP(NewX-2,NewY-2+FullBlock+i,fgray+bblack,'O');
}
}
/*Print the blood/fullblood number*/
/*Due to %06d we can't use TP*/
if(x-3>=0){
TP(x-3,y-4,OC," ");
if(isExist){
if(NewX-3<WINDOWC){
gto(NewX-3,NewY-4),color(fcyan+bblack),printf("%04d",Blood);
TP(NewX-3,NewY,fcyan+bblack,'/');
gto(NewX-3,NewY+1),color(fcyan+bblack),printf("%04d",FullBlood);
}
}
}
if(x-3>=WINDOWC)
isExist=0;
}
/*Clear the shape after it died*/
void ClearPrint(){
BloodRefresh(x,y);
if(x-1>=0&&x-1<WINDOWC)
TP(x-1,y-1,OC," ");
if(x>=0&&x<WINDOWC)
TP(x,y