C++控制台打飞机小游戏

文章目录

前言

我终于决定还是把这个放出来。

介绍

运行图
具体信息主界面上都有写。

按空格暂停,建议暂停后再升级属性。

记录最高分的文件进行了加密。

有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
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值