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;
}
}
}
c++ 打飞机游戏开发日志的更多相关文章
- [游戏开发日志]Windows下Cocos2d-x 3.14环境搭建
总介绍 我们小组使用的是cocos2d-x的游戏开发引擎,因此在所有开发工作之前,我们需要对这个引擎进行环境的搭建. 搭建过程 VS2013的下载和安装 VS只是作为一个开发环境而已,简单来说就是敲代 ...
- Unity2D RPG游戏开发日志
一.游戏构建设计 场景设计:地面的每一层用unity的TiledMap来设计,首先第一层为地面层,也就是地形的大部分区域的图块:第二层为覆盖层,如图中蓝色线圈起来的柱子的上半部分,由于玩家可以在柱子背 ...
- unity独立游戏开发日志2018/09/22
f::很头痛之前rm做的游戏在新电脑工程打不开了...只能另起炉灶... 还不知道新游戏叫什么名...暂且叫方块世界.(素材已经授权) 首先是规划下场景和素材文件夹的建立. unity常用的文件夹有: ...
- unity独立游戏开发日志2018/09/26
最近太忙,今天吃饭的时候灵感一现...想到了随机地图生成的方法,不过可能实现的比较笨...还需要优化,大佬绕过. 注释没打,最后统一解释. using System.Collections; usin ...
- pygame开发PC端微信打飞机游戏
pygame开发PC端微信打飞机游戏 一.项目简介 1. 介绍 本项目类似曾经火爆的微信打飞机游戏.游戏将使用Python语言开发,主要用到pygame的API.游戏最终将会以python源文件gam ...
- [Unity3D]Unity3D游戏开发之飞机大战项目解说
大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目.这是一个比較综合的 ...
- 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)
在飞机大战游戏开发中遇到的问题和解决方法: 1.在添加菜单时,我要添加一个有背景的菜单,需要在菜单pMenu中添加一个图片精灵,结果编译过了但是运行出错,如下图: 查了很多资料,调试了很长时间,整个人 ...
- 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)
接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 bool PlaneWarGame::init() { bool bRet = fals ...
- Python之游戏开发-飞机大战
Python之游戏开发-飞机大战 想要代码文件,可以加我微信:nickchen121 #!/usr/bin/env python # coding: utf-8 import pygame impor ...
随机推荐
- git fetch批处理,遍历一个文件夹下的所有子目录,执行git fetch --all
echo off for /d %%i in (*) do ( echo %%i cd %%i git fetch --all cd .. ) 判断子目录是否有.git文件夹 echo off for ...
- Android内存解析(二)— 详解内存,内部存储和外部存储
总述 觉得十分有必要搞清楚内存,内部存储和外部存储的区别,还有我们在开发中真正将数据存在了手机的哪儿. 先提一个问题:手机设置的应用管理中,每个App下都有清除数据和清除缓存,清除的分别是哪里的数据? ...
- python3用list实现栈
工作中遇到的需求,****代表标签数据别的信息: D01 ******** 1 ******** D01 ******** 2 ******** D01 ******** 3 ******** D01 ...
- 91. ExtJS获取父子、兄弟容器元素方法
转自:https://blog.csdn.net/u014745818/article/details/44957341 1 1.当前对象的父对象(上级对象) this.ownerCt: 2.当前对象 ...
- Python入门 老司机带你上路
Phthon安装 https://www.python.org/download/releases/2.7.5/ 安装结束还没完,我们还差最后一步:设置环境变量.这是什么东西我暂时先不解释,大家照着做 ...
- java 格式化日期
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); simpleDat ...
- Win10,JDK8,tomact7.0.85配置
今天在win10上配置了jdk以及tomact先前使用jdk7+tomact7.0.56运行失败. 后经调整后正确配置注意事项如下: 1.下载并按照jdk-8u161-windows-x64,默认安装 ...
- Coursera公开课-Machine_learing:编程作业5
Regularized Linear Regression and Bias/Variance 大多数时候,我们使用机器学习方法得到的结果都不是特别理想,常见 欠拟合 和 过拟合 问题.通过一些变量画 ...
- Android 存储路径选择
Android能用来存储的地方有两个,一个是手机内置的存储空间,一个是外置的SD卡,内置的存储空间一般比较小,所以应用的缓存建议存储在外置的SD卡中. 在Android系统中如何获得存储的路径呢? p ...
- poj1328 Radar Installation 区间贪心
题目大意: 在X轴选择尽量少的点作为圆心,作半径为d的圆.使得这些圆能覆盖所有的点. 思路: 把每个点都转化到X轴上.也就是可以覆盖这个点的圆心的位置的范围[a,b].然后按照每个点对应的a从小到大排 ...