提示:该项目需要使用EasyX 图形库
文章目录
前言
提示:本文主要作为自己之前学习C++的总结,顺便做一个游戏小项目,加深数组、循环、结构体的一些的理解
〇、效果展示
一、准备工作
- 下载 Easyx ,这个比较简单,直接跳过
- 准备素材资源,飞机,敌机,子弹,背景
二、具体步骤
1.包含头文件
2.枚举变量
提示:这个步骤也可以使用宏替换
3.飞机属性
三、问题剖析
问题1:战机怎么创建?战机怎么移动?
Easyx 有 loadimage 加载图片,注意这只是把图片加载到内存中,还没并没有画出来
至于移动的处理,可以采用事件监听
问题2:战机如何发子弹,子弹的移动?
战机的子弹,首先绘制子弹和战机一样,发送子弹可以监听空格键
提示:子弹我用一个数组保存起来,这个数组大小N,N的意思就是在屏幕中最多能出现N个子弹,因为我们绘制子弹的时候,首先去判断子弹是否存在,如果只用一个变量保存,那么屏幕中永远只有一颗子弹,这不符合常理
子弹这个逻辑比较难,如果不懂,可以看看下面的图
我们再来看看这个图,就应该明白了
这样子弹就被节能的利用起来了,而不是一直向内存索要资源去创建
子弹的移动就很简单了,先去判断它是否存在,如果存在则 y-=1
问题3:敌机创建和移动?
敌机也不可能只有一辆,所以用数组保存起来,其原理和子弹一样
敌机移动和子弹一样,比较简单,只要一直 y+=1 就行了
问题4:碰撞处理方式?
这个碰撞方式也比较简单,看图就明白了
当然如果想更加严格的话,就需要细心去处理,当然这个碰撞比较简单粗暴
问题5:整个游戏的逻辑是什么样的?
问题6:什么是定时器?
来了,定时器是啥?
通俗来讲,就是某一个周期去执行一个任务,或者到某一个时间去执行任务
为什么要使用定时器,在创建敌机的时候,如果不用定时器,那么所有的战机会被一起创建出来,这是不合理的,所以我们给一个周期,比如每 500ms 去创建一个,这样游戏体验比较好,敌人是源源不断的来,而不是一股脑的倾巢而出
封装定时器
以上就是本章全部问题了
四、奉上源码
头文件 flane.h
#pragma once
#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <time.h>
#pragma comment (lib, "Winmm.lib")//导入Winmm.lib库
enum my{
WIDTH = 591, // 窗口宽度
HEIGHT = 664, // 窗口高度
BULLLET_NUM = 1, // 子弹数量
ENEMY_NUM = 15, // 敌机数量
BIG, // 敌机类型大
SMALL, // 敌机类型小
};
// 飞机、子弹状态
struct Plance{
int x; // x 坐标
int y; // y 坐标
bool live; // 是否存活
int width; // 飞机宽度
int height; // 飞机高度
int hp; // 血量值
int type; // 敌机类型
};
void loadImg(); //加载资源
bool Timer(size_t ms, int id); //定时器
void enemyHp(int i); //敌机生命值
void gameInit(); //游戏初始化
void createBullet(); //创建子弹
void createEnemy(); //创建敌机
void enemyMove(); //敌机移动
void bulletMove(); //子弹移动
void gameDraw(); //游戏图片绘制
void playerMove(int speed); //监听角色移动
void playPlance(); //碰撞检测
void startGame(); //启动游戏
功能文件function.cpp
#include "flane.h"
IMAGE bk; //背景资源
IMAGE img_role[2]; //战机图片
IMAGE img_bull[2]; //子弹图片
IMAGE img_enemy[2][2]; //敌机图片
struct Plance player, bull[BULLLET_NUM], enemy[ENEMY_NUM];
void loadImg(){
loadimage