【C语言】实现天天酷跑游戏

天天酷跑游戏开发日志及源码

**

纯c语言开发的游戏项目,与天天酷跑玩法与贴图类似,日志中有着详细的开发过程,从零开始手把手带你,解决游戏开发的问题;体验开发的乐趣!!!

ps:源码在文章最下面,有详细的注释内容。

**请添加图片描述

1.创建项目
2.导入素材
3.创建游戏界面
基于C语言和Easyx图形库
1)创建游戏窗口
2)设计游戏背景
a)三重背景以不同的速度同时移动
b)循环滚动背景的实现
3)实现游戏背景
a)加载背景资源
b)打印背景图片(背景知识:坐标)

​ 遇到问题:背景图片的png格式图片出现黑色

​ 解决方案:导入tools.h和tools.cpp,包含到头文件并引用putimagePNG2

c)滚动效果加循环fly

​ 遇到问题:背景闪烁抖动(不断打印与渲染)

​ 解决方案:双缓冲机制(一次性准备好后一起渲染)

​ BeginBatchDraw();EndBatchDraw();

4.实现角色奔跑效果
1)加载角色奔跑的图片素材
2)设置角色的初始位置
a) 定义并取值角色X坐标,Y坐标,图片帧序号
3)实现角色跑动效果
a) 图片帧序号数组+1取余实现

​ heroIndex = (heroIndex + 1) % 12;

5.实现角色跳跃效果
1)处理用户输入的按键
a)如果有按键按下,kbhit()返回 ture
b)_getch不需要按回车即可直接读取,如果是 ‘ ’ 引用jump
2)实现跳跃
a)定义跳跃开关:跳跃Y坐标最大高度,偏移量(值为负)
b)打开跳跃开关

​ 1> 角色Y坐标 > 最大高度,则向上偏移

​ 2> 角色Y坐标 < 最大高度,将偏移量改为正,则向下偏移

c)关闭跳跃开关:当角色Y坐标 > 角色自身高度(最小高度),偏移量还原默认值
3)优化帧等待效果
a)sleep缺点:会导致程序休眠失去响应,在30s内无法触发按键响应
b)getDelay优化:返回距离上一次调用间隔的时间,第一次调用时返回。在30s内可以触发按键响应
c)update开关:用来实时刷新画面
6.实现敌人和障碍物
1)实现小乌龟的随机出现
a)加载小乌龟素材
b)出现小乌龟:(每3s刷新一个小乌龟)同时保证窗口只存在一个乌龟
c)渲染小乌龟

​ 1> 定义并取值小乌龟X坐标,Y坐标,图片帧序号

​ 2> 图片帧序号数组+1取余实现小乌龟旋转效果

​ 3>实现小乌龟水平移动,当小乌龟移出窗口后消失

​ 4>定义小乌龟的出现频率,使小乌龟随2s~5s随机出现、

2)使用结构体封装障碍物
a)定义结构体obstacle_t
b)用枚举存放障碍物类型,并定义为obstacle_type
c)使用c++中vector定义动态数组用来存储各障碍物图片(相当于c中:IMAGE obstacleImgs【3】【12】)
3)封装后障碍物的初始化
a)用结构体加载小乌龟素材
b)用结构体加载狮子素材
C)定义并初始化障碍物池
4)显示多个障碍物
a)出现障碍物:每隔一段时间刷新一个障碍物
b)创建障碍物的各个参数

​ 1>定义exist,imgIndex,type,x,y

​ 2>乌龟的数值,狮子的数值

c)更新所有障碍物的坐标
d)实现障碍物动态效果
7.实现玩家下蹲技能
1)加载下蹲素材
2)下蹲按键实现
3)定义下蹲开关和更新下蹲
a)用updateHero封装更新跳跃和下蹲
b)如果不下蹲则实现跳跃,否则实现下蹲
c)在滚动效果中实现下蹲

​ 遇到问题:下蹲速度太快

​ 解决方案:使用count增加帧数让图片变慢,增加delay延时

8.添加柱子障碍物
1)加载柱子障碍物素材
2)创建柱子障碍物的各个参数
3)优化障碍物的出现频率
a)对3取余降低柱子出现概率
9.实现碰撞检测
1)计算角色和障碍物的矩形大小(在tool.h中)
2)角色的矩形计算
a)奔跑与跳跃状态(通过偏移量来计算)
b)下蹲状态
2)障碍物的矩形计算
3)检测玩家与障碍物是否相交
a)相交:玩家掉血+碰撞声音

​ 遇到问题:角色碰撞后持续掉血

​ 解决方案:新定义hited,控制其开关来解决持续掉血

10.解决音效BUG–优化下蹲–增加血条
1)预加载音效,解决音效BUG
2)优化下蹲
3)使用封装好的血条
11.实现游戏结束,增加初始界面
1)播放背景音乐
2)判断游戏结束

a)血量<= 0,加载结束图片,0表示加载到界面;关闭背景音乐;游戏暂停

b)暂停以后,直接开始下一局;血量回复;播放背景音乐

3)增加初始界面
12.解决死亡障碍(柱子与狮子同时出现)
1)记录上一次障碍物,如果上一次障碍物时柱子&&下一次出现狮子&&上一个障碍物没走远
则将下一次障碍物替换成乌龟
13.通过障碍物后自动加分机制
1)比较x坐标:障碍物x坐标 + 障碍物第一章图片的宽度 < 玩家坐标
2)障碍物通过玩家加一分
14.实现界面界面显示分数
1)加载得分数字图片
2)显示分数
a)实现方法:50 =>‘50’ ‘5’ ‘5’-‘0’=5
15.判断游戏胜利
1)当分数 > 100分,播放胜利音效及图片
2)回复玩家血条,清零分数
3)注意:胜利前最后一分不显示就胜利,用”手动“刷新解决
注意:错误 C4996 'sprintf’要改为sprintf_s
右键文件名->属性->C/C++中常规->SDL检查关闭

源码如下:

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <vector>
#include "tools.h"

using namespace std;	//声明命名空间

#define WIN_SCORE  3

#define WIN_WIDTH 1012
#define WIN_HEIGHT 396	//宏定义,便于维护和更改
#define OBSTACLE_COUNT 10	//宏定义障碍物池数量

IMAGE imgBgs[3];	//(全局数组)存放背景图片
int bgX[3];		//背景图片的x坐标
int bgSpeed[3] = {
   2, 3, 5};		//三张图不同的速度

IMAGE imgHeros[12];		//存放角色奔跑图片
int heroX;	//角色的x坐标
int heroY;	//角色的y坐标
int heroIndex;	//角色奔跑的图片帧序号

bool heroJump;	//表示角色正在跳跃开关
int jumpHeighetMax;	//跳跃的最大值
int heroJumpOff;	//表示偏移量
int update;	//表示是否马上刷新画面

//	IMAGE imgTortoise[7];	//小乌龟
//	int torToiseX;	//小乌龟的水平坐标
//	int torToiseY;	//小乌龟的垂直坐标
//	bool torToiseExist;	//当前窗口是否存在小乌龟
//	int tortoiseIndex;//小乌龟旋转的图片帧序号

int heroBlood;	//玩家血量
int score;	//得分

//枚举封装障碍物的类型
typedef enum {
   
	TORTOISE,	//乌龟 0
	LION,	//狮子 1
	HOOK1,	//四个柱子障碍物
	HOOK2,
	HOOK3,
	HOOK4,
	OBSTACLE_TYPE_CONST // 6 便于查看枚举数
}obstacle_type; 

vector<vector<IMAGE>>obstacleImgs;//c++存放所用障碍物的各个图片
//相当于c中:IMAGE obstacleImgs[3][12]

//结构体封装障碍物
typedef struct obstacle {
   
	int type;	//障碍物的类型
	int imgIndex;	//当前显示图片的序号
	int x, y;	//障碍物坐标
	int speed;	//障碍物速度
	int power;	//障碍物杀伤力
	bool exist;	//障碍物存在
	bool hited;	//表示是否已经发生碰撞
	bool passed;//表示是否被通过

}obstacle_t;

obstacle_t obstacles[OBSTACLE_COUNT];	//定义障碍物池
int lastObsIndex;	//记录上一次障碍物

IMAGE imgHeroDown[2];	//角色下蹲
bool heroDown;	//表示玩家正在下蹲开关

IMAGE imgSZ[10];//得分数字图片

//游戏初始化
void init()	

{
   
	initgraph(WIN_WIDTH, WIN_HEIGHT, EW_SHOWCONSOLE);	//创建游戏窗口

	//加载背景资源
	char name[64];
	for (int i = 0; i < 3; i++) {
   
		//"res/bg001.png"   "res/bg002.png"   "res/bg003.png"   
		sprintf(name, "res/bg%03d.png", i + 1);
		loadimage(&imgBgs[i],name);	
		bgX[i] = 0;
	}

	//加载Hero奔跑的图片素材
	for (int i = 0; i < 12; i++) {
   
		//	"res/hero1.png"	...	"res/hero12.png"
		sprintf(name, "res/hero%d.png", i+1);
		loadimage(&imgHeros[i], name)
  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eugeooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值