c++ 打飞机游戏开发日志

时间:2023-03-09 07:41:02
c++ 打飞机游戏开发日志

c++ 打飞机游戏开发日志

设计思路:
控制台模式
  初始化:
  建立画面,初始化数据
  游戏过程:
    1.获取操作
    2.修改数据
    3.更新画面
  结束:
    关闭画面,delete动态分配数据

4.29日

  创建游戏背景,实现飞机移动操作,实现子弹飞行

4.30日

  实现游戏数据管理,飞机击落动画,随机出现敌机

代码:

见最终版

5.1日

  感觉类的编写处理不好,导致有很多重复的代码。决定重构一下。

  编写了 FlyingObject Plane Bullet类

  实现了hero移动 发射子弹的操作。实现了所有Hero子弹的移动

设计思路(修改版):

1.使用类进行数据的管理和封装

FlyingObject

—Plane(敌机)

—Hero(玩家飞机)

—Bullet(玩家子弹)

SEM(friend Hero,Bullet,Plane)  : 屏幕特效展示(坠毁动画,激光)

2.使用控制台完成指令交互

5.2日

  实现了随机间隔出现敌机,敌机的飞行

6.1 日

  基本完成第一关的实现,个人感觉重复代码较少。

FlyingObject类:

#pragma once
#ifndef FLYINGOBJECT_H
#define FLYINGOBJECT_H
#include<easyx.h>
#include<graphics.h>
#include<queue>
#include<vector>
#include<time.h>
#include<list>
using namespace std;
double direction[][] = { { ,- },{ , } ,{ -, },{ , },{0.5,0.5},{-0.5,0.5} };//上下左右
struct pos
{
double x, y;
};
class FlyingObject
{
public:
FlyingObject() = default;
FlyingObject(double x, double y)
{
p.x = x; p.y = y; speed = ;
Setspeed();
Setdir();
}
FlyingObject(pos p)
{
FlyingObject(p.x, p.y);
}
pos Getpos()
{
return p;
}
//virtual void Add() const = 0;
double Getspeed()
{
return speed;
}
void Setspeed(double _s)
{
speed = _s;
}
void Setpos(double x, double y)
{
p.x = x; p.y = y;
}
int Getdir()
{
return dir;
}
void Setdir(int _d)
{
dir = _d;
}
virtual void Move(int)
{
p.x += direction[dir][] * speed;
p.y += direction[dir][] * speed;
if (p.x >= )
p.x = ;
else if (p.x < )
p.x = ;
if (p.y < )
p.y = ;
else if (p.y > )
p.y = ;
}
void Draw()
{
putimage(p.x, p.y, &img);
}
IMAGE img;
bool operator==(const FlyingObject& t)
{
if (((int)t.p.x == (int)p.x) && ((int)t.p.y == (int)p.y))
return true;
return false;
}
private:
pos p;
double speed;
int dir;
};
#endif

Plane 类

这个类表示广义敌机(与自己操控的飞机相撞会导致游戏结束的飞机),为了便于管理把敌机发射的子弹也归类于敌机

#pragma once
#ifndef PLANE_H
#define PLANE_H
#include"Bullet.h"
using namespace std;
class SEM;
class Plane : public FlyingObject
{
public:
friend SEM;
friend bool Check();
friend void MoveallPlane(int dir);
friend void DrawallPlane();
friend class Bullet;
using FlyingObject::FlyingObject;
void Add()
{
Plane::L.insert(L.begin(), *this);
}
virtual void Move(int) override
{
pos p = Getpos();
int dir = Getdir();
double speed = Getspeed();
p.x += direction[dir][] * speed;
p.y += direction[dir][] * speed;
if (p.x >= || p.x < || p.y < || p.y > )
{ }
else
Setpos(p.x, p.y);
}
virtual void shoot();
private:
static list<Plane> L;
};
list<Plane> Plane::L;
void Plane::shoot()
{
pos tmp = Plane::Getpos();
Bullet b(tmp.x + , tmp.y);
loadimage(&b.img, _T("D:\\bullet1.ico"));
b.Bullet::Add();
b.Draw();
}
class Hero :public Plane
{
public:
Hero(double _x, double _y)
{
Setpos(_x, _y);
Setspeed();
loadimage(&img, _T("D:\\hero1.ico"));
}
void Shootlaser()//发射激光
{ }
virtual void Move(int dir) override
{
//int dir = Getdir();
pos p = Getpos();
double speed = Getspeed();
p.x += direction[dir][] * speed;
p.y += direction[dir][] * speed;
if (p.x >= )
p.x = ;
else if (p.x < )
p.x = ;
if (p.y < )
p.y = ;
else if (p.y > )
p.y = ;
Setpos(p.x, p.y);
}
private: };
void MoveallPlane(int dir);
class Boss :public FlyingObject
{
friend class Plane;
public:
Boss(double x,double y)
{
Setpos(x, y);
Setspeed(0.0);
loadimage(&img, __T("D:\\Boss.jpg"));
}
void Shoot()
{
Plane P(Getpos().x,Getpos().y);
loadimage(&P.img, _T("D:\\Bullet3.ico"));
P.Setspeed();
P.Setdir(rand() % + );
P.Add();
}
};
#endif

Bullet类 :

这个类管理玩家自己发射的子弹(与敌人飞机相撞后会导致敌机坠毁的飞行物)

#pragma once
#ifndef BULLET_H
#define BULLET_H
#include"FlyingObject.h"
using namespace std;
class Bullet : public FlyingObject
{
public:
friend bool Check();
friend void MoveallBullet(int dir);
Bullet() = default;
Bullet(double x, double y)
{
Setpos(x, y);
Setspeed();
Setdir();
}
Bullet(pos p)
{
Bullet(p.x, p.y);
}
void Add()
{
this->L.insert(L.begin(), *this);
}
void DrawAll()
{
for (auto it = Bullet::L.begin(); it != Bullet::L.end(); it++)
{
it->Draw();
}
}
private:
static list<Bullet> L;
};
list<Bullet> Bullet::L;
void Moveall(int dir); #endif

为了便于管理飞机坠毁,激光特效(由于发射子弹是基于FlyingObject类,而激光不属于飞行物品,所以需要特殊管理)

加入SEM类(special effect manager)

#pragma once
#ifndef SEM_H
#define SEM_H
#include"Plane.h"
struct node
{
double x, y;
time_t t;
};
class SEM
{
public:
friend class Hero;
friend bool Check();
void Drawlaser(Hero &h)
{
putimage(h.Getpos().x+, h.Getpos().y-, &Laser);
}
void Show(Hero &h)
{
Gettime();
if (Getflag())
{
if (Nowt - Lasertime > )
SetLaserflag(false);
else
{
Drawlaser(h);
}
}
for (auto it = Crash.begin(); it != Crash.end(); )
{
if (it->t <= Nowt)
{
it = Crash.erase(it);
}
else it++;
}
for (auto it = Crash.begin(); it != Crash.end(); it++)
{
putimage(it->x, it->y, &Crasheffect);
}
}
void Add(double _x, double _y)
{
node tmp;
tmp.x = _x, tmp.y = _y;
tmp.t = time(NULL)+;
Crash.push_back(tmp);
}
void Init()
{
Begt = time(NULL);
Nowt = time(NULL);
loadimage(&Crasheffect, _T("D:\\ashes.ico"));
loadimage(&Laser, _T("D:\\Laser.bmp"));
}
IMAGE Crasheffect,Laser;
time_t Gettime()//获得游戏开始了多长时间
{
Nowt = time(NULL);
return Nowt-Begt;
}
bool Getflag()
{
return Laserflag;
}
void SetLaserflag(bool f)
{
Laserflag = f;
}
void SetLasertime()
{
Lasertime = time(NULL);
}
private:
time_t Begt;
time_t Nowt;
time_t Lasertime;
vector<node> Crash;
bool Laserflag;
};
#endif

main

#include<iostream>
#include<list>
#include<time.h>
#include<easyx.h>
#include<graphics.h>
#include"stdio.h"
#include"math.h"
#include "dos.h"
#include<windows.h>
#include<mmsystem.h>
#include<cstdlib>
#include"FlyingObject.h"
#include"Plane.h"
#include"Bullet.h"
#include"SEM.h"
#define KEY_DOWN(vk_c) (GetAsyncKeyState(vk_c)&0x8000)
using namespace std;
Hero hero(, );
IMAGE background, ash,Enemy[];
SEM S;
Boss boss(, );
void MoveallBullet(int dir)
{
for (auto it = Bullet::L.begin(); it != Bullet::L.end();)
{
it->Move(dir);
if (it->Getpos().y <= )
it = Bullet::L.erase(it);
else
it++;
}
}
bool Check()
{
int d = ;
for (auto it = Plane::L.begin(); it != Plane::L.end(); it++)
{
auto tbullet = it->Getpos();
auto tpos = hero.Getpos();
if ((tbullet.x - tpos.x<d&&tbullet.x - tpos.x>-d) && (tbullet.y - tpos.y<d&&tbullet.y - tpos.y>-d))
{
return false;
}
}
if (S.Getflag())
{
for (auto it = Plane::L.begin(); it != Plane::L.end(); )
{
pos tp = it->Getpos(), hp = hero.Getpos();
if (abs(tp.x - hp.x) < )
{
S.Add(tp.x, tp.y);
it = Plane::L.erase(it);
}
else
it++;
}
}
for (auto it = Bullet::L.begin(); it != Bullet::L.end();)
{
auto tbullet = it->Getpos();
bool f = false;
for (auto k = Plane::L.begin(); k != Plane::L.end();)
{
auto tpos = k->Getpos();
tpos.x += ;
tpos.y += ;
if ((tbullet.x - tpos.x<d&&tbullet.x - tpos.x>-d) && (tbullet.y - tpos.y<d&&tbullet.y - tpos.y>-d))
{
f = true;
S.Add(tpos.x, tpos.y);
k = Plane::L.erase(k);
break;
}
else k++;
}
if (!f)
it++;
else
it = Bullet::L.erase(it);
}
return true;
}
void DrawallPlane()
{
for (auto it = Plane::L.begin(); it != Plane::L.end(); it++)
{
it->Draw();
} }
void MoveallPlane(int dir)
{
for (auto it = Plane::L.begin(); it != Plane::L.end();)
{
it->Move(dir);
if (it->Getpos().y >=)
it = Plane::L.erase(it);
else
it++;
}
}
void init()//初始化窗口
{
S.Init();
loadimage(&Enemy[], _T("D:\\plane1.ico"));
loadimage(&Enemy[], _T("D:\\plane2.ico"));
loadimage(&Enemy[], _T("D:\\plane3.ico"));
loadimage(&Enemy[], _T("D:\\plane4.ico"));
srand((unsigned)time(NULL));
initgraph(, );
loadimage(&background, _T("D:\\background.jpg"));
loadimage(&ash, _T("D:\\ashes.ico"));
putimage(, , &background);
BeginBatchDraw();
}
void Show()//更新画面
{
putimage(, , &background);
hero.Draw();
boss.Draw();
Bullet tmp;
tmp.DrawAll();
DrawallPlane();
S.Show(hero);
FlushBatchDraw();
}
void Key_scan()//扫描键盘
{
if (KEY_DOWN(VK_UP))
{
hero.Move();
}
else if (KEY_DOWN(VK_LEFT))
{
hero.Move();
}
else if (KEY_DOWN(VK_RIGHT))
{
hero.Move();
}
else if (KEY_DOWN(VK_DOWN))
{
hero.Move();
}
else if (KEY_DOWN(VK_RETURN) || KEY_DOWN(VK_SPACE))
{
while (KEY_DOWN(VK_RETURN) || KEY_DOWN(VK_SPACE))
{
}
hero.shoot();
}
else if (KEY_DOWN(VK_SHIFT))
{
S.SetLaserflag(true);
S.SetLasertime();
hero.Shootlaser();
}
}
bool Update()//更新游戏数据
{
MoveallPlane();
MoveallBullet();
if (!Check())
return false;
if (rand() % == )
{
Plane tmp(rand() % , );
tmp.img = Enemy[rand() % ];
tmp.Setspeed(0.2);
tmp.Add();
}
if (rand() % == )
{
boss.Shoot();
}
return true;
}
void Gameover()
{ }
int main()
{
init();
while ()
{
Show();
Key_scan();
if (!Update())
{
closegraph();
printf("Game Over\n");
break;
}
}
}