/****************************
天天酷跑开发日志
1.创建项目
2.导入素材
3.游戏界面
实际的开发流程
对于初学者.最好的方式,建议从用户界面入手
选择图形库或者其他引擎
天天酷跑,是基于"easyx"图形库的
1)创建游戏窗口
2)设计游戏背景
a.背景不同的速度同时移动
b.循环滚动
3)实现游戏背景
a.加载背景资源
b.渲染(背景知识:坐标)
遇到问题:背景图片的png格式图片出现黑色
4.实现玩家的奔跑
5.实现玩家的跳跃
6.实现随机小乌龟
7.创建障碍物结构体数据类型
8.使用障碍物结构体后重新初始化
9.封装后多个障碍物的显示
10.实现玩家的下蹲技能
11.实现"柱子"障碍物
*/
#include<stdio.h>
#include <graphics.h>
#include "tools.h"
#include<conio.h>
#include<vector>
using namespace std;
#define WIN_SCORE 20
#define WIN_WIDTH 1012
#define WIN_HEIGHT 396
#define OBSTACLE_COUNT 10
//背景图片
IMAGE imgBgs[3];
IMAGE imgHeros[12];
int heroX; // 玩家的x坐标
int heroY; //玩家的y坐标
int heroIndex;//玩家奔跑的图片帧序号
int bgX[3];
int bgSpeed[3] = { 1,2,4 };
bool heroJump;//表示玩家正在跳跃
int jumpHeighetMax;
int heroJumpOff;
int updata;
//IMAGE imgTortoise;//小乌龟
//int torToiseX; // 小乌龟的水平坐标
//int torToiseY;//小乌龟的垂直坐标
//bool torToiseExist;//当前窗口是否有小乌龟
int heroBlood;
int score;
typedef enum {
TPRTOISE,//乌龟
LION, // 狮子 1
HOOK1,
HOOK2,
HOOK3,
HOOK4,
OBSTACLE_TYPE_COUNT //2
}obstacle_type;
vector<vector<IMAGE>>obstacleImgs;//存放所有障碍物的图片 相当于 IMAGE obstacleImgs[3][12];
//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);
//加载背景资源
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);
}
//设置玩家的初始化位置
heroX = WIN_WIDTH * 0.5 - imgHeros[0].getwidth() * 0.5;
heroY = 345 - imgHeros[0].getheight();
heroIndex = 0;
heroJump = false;
jumpHeighetMax = 345 - imgHeros[0].getheight() - 120;
heroJumpOff = -4;
updata = true;
//加载小乌龟
/*loadimage(&imgTortoise, "res/t1.png");
torToiseExist = false;
torToiseY = 345 - imgTortoise.getheight() + 5;*/
IMAGE imgTort;
loadimage(&imgTort, "res/t1.png");
vector<IMAGE> imgTortArray;
imgTortArray.push_back(imgTort);
obstacleImgs.push_back(imgTortArray);
IMAGE imgLion[6];
vector<IMAGE>imgLionArray;
for (int i = 0; i < 6; i++) {
sprintf(name, "res/p%d.png", i + 1);
loadimage(&imgLion[i], name);
imgLionArray.push_back(imgLion[i]);
}
obstacleImgs.push_back(imgLionArray);
//初始化障碍物池
for (int i = 0; i < OBSTACLE_COUNT; i++) {
obstacles[i].exist = false;
}
//加载下蹲素材
loadimage(&imgHeroDown[0], "res/d1.png");
loadimage(&imgHeroDown[1], "res/d2.png");
heroDown = false;
IMAGE imgH;
for (int i = 0; i < 4; i++) {
vector<IMAGE>imgHookArry;
sprintf(name, "res/h%d.png", i + 1);
loadimage(&imgH, name, 63, 260, true);
imgHookArry.push_back(imgH);
obstacleImgs.push_back(imgHookArry);
}
heroBlood = 100;
//预加载音效
preLoadSound("res/hit.mp3");
mciSendString("play res/bg.mp3 repeat",0,0,0);
lastObsindex = -1;
score = 0;
//加载数字图片
for (int i = 0; i < 10; i++) {
sprintf(name, "res/sz/%d.png", i);
loadimage(&imgSZ[i], name);
}
}
void createObstaclr() {
int i;
for (i = 0; i < OBSTACLE_COUNT; i++) {
if (obstacles[i].exist == false) {
break;
}
}
if (i >= OBSTACLE_COUNT) {
return;
}
obstacles[i].exist = true;
obstacles[i].hited = false;
obstacles[i].passed = false;
obstacles[i].imgIndex = 0;
//obstacles[i].type = (obstacle_type)(rand() % OBSTACLE_TYPE_COUNT);
obstacles[i].type = (obstacle_type)(rand() % 3);
if(lastObsindex>=0&&
obstacles[lastObsindex].type >= HOOK1
&& obstacles[lastObsindex].type <= HOOK4
&& obstacles[i].type == LION
&& obstacles[lastObsindex].x > (WIN_WIDTH-500)){
obstacles[i].type = TPRTOISE;
}
lastObsindex = i;
if (obstacles[i].type == HOOK1) {
obstacles[i].type += rand() % 4;
}
obstacles[i].x = WIN_WIDTH;
obstacles[i].y = 345 + 5 - obstacleImgs[obstacles[i].type][0].getheight();
if (obstacles[i].type == TPRTOISE) {
obstacles[i].speed = 0;
obstacles[i].power = 5;
}
else if (obstacles[i].type == LION) {
obstacles[i].speed = 4;
obstacles[i].power = 20;
}
else if (obstacles[i].type >= HOOK1 && obstacles[i].type <= HOOK4) {
obstacles[i].speed = 0;
obstacles[i].power = 20;
obstacles[i].y = 0;
}
}
void checkHit() {
for (int i = 0; i < OBSTACLE_TYPE_COUNT; i++) {
if (obstacles[i].exist && obstacles[i].hited == false) {
int a1x, a1y, a2x, a2y;
int off = 30;
if (!heroDown) {//非下蹲(就是奔跑/跳跃)
a1x = heroX+ off;
a1y = heroY + off;
a2x = heroX + imgHeros[heroIndex].getwidth() - off;
a2y = heroY + imgHeros[heroIndex].getheight();
}
else {
a1x = heroX + off;
a1y = 345 - imgHeroDown[heroIndex].getheight();
a2x = heroX + imgHeroDown[heroIndex].getwidth();
a2y = 345;
}
IMAGE img = obstacleImgs[obstacles[i].type][obstacles[i].imgIndex];
int b1x = obstacles[i].x + off;
int b1y = obstacles[i].y + off;
int b2x = obstacles[i].x + img.getwidth()-off;
int b2y = obstacles[i].y+ img.getheight()-10;
if (rectIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)) {
heroBlood -= obstacles[i].power;
printf("血量剩余%d\n", heroBlood);
playSound("res/hit.mp3");
obstacles[i].hited = true;
}
}
}
}
void fly() {
for (int i = 0; i < 3; i++) {
bgX[i] -= bgSpeed[i];
if (bgX[i] < -WIN_WIDTH) {
bgX[i] = 0;
}
}
//实现跳跃
if (heroJump) {
if (heroY < jumpHeighetMax) {
heroJumpOff = 4;
}
heroY += heroJumpOff;
if (heroY > 345 - imgHeros[0].getheight()) {
heroJump = false;
heroJumpOff = -4;
}
}
else if (heroDown) {//不跳跃
static int count = 0;
static int delays[2] = { 8,35 };
count++;
if (count >= delays[heroIndex]) {
count = 0;
heroIndex++;
if (heroIndex >= 2) {
heroIndex = 0;
heroDown = false;
}
}
}
else {
heroIndex = (heroIndex + 1) % 12;
}
//创建障碍物
static int frameCount = 0;
static int enemyFre = 50;
frameCount++;
if (frameCount > enemyFre) {
frameCount = 0;
enemyFre = 50 + rand() % 50;
createObstaclr();
}
/*if (torToiseExist) {
torToiseX -= bgSpeed[2];
if (torToiseX < -imgTortoise.getwidth()) {
torToiseExist = false;
}
}*/
//更新障碍物的坐标
for (int i = 0; i < OBSTACLE_TYPE_COUNT; i++) {
if (obstacles[i].exist) {
obstacles[i].x -= obstacles[i].speed + bgSpeed[2];
if (obstacles[i].x < -obstacleImgs[obstacles[i].type][0].getheight() * 2) {
obstacles[i].exist = false;
}
int len = obstacleImgs[obstacles[i].type].size();
obstacles[i].imgIndex = (obstacles[i].imgIndex + 1) % len;
}
}
//玩家和障碍物的"碰撞检测"处理
checkHit();
}
//渲染"游戏背景"
void updateBg() {
putimagePNG2(bgX[0], 0, &imgBgs[0]);
putimagePNG2(bgX[1], 119, &imgBgs[1]);
putimagePNG2(bgX[2], 330, &imgBgs[2]);
}
void jump() {
heroJump = true;
updata = true;
}
void down() {
heroDown = true;
updata = true;
heroIndex = 0;
}
void keyEvent() {
if (_kbhit()) {//如果有按键按下,_kbhit()返回 true
char ch = _getch();//_getch()不需要按下回车即可直接读取
if (ch == ' ') {
jump();
}
else if (ch == 'a') {
down();
}
}
}
void updataEnemy() {
//渲染小乌龟
/*if (torToiseExist) {
putimagePNG2(torToiseX, torToiseY, WIN_WIDTH, &imgTortoise);
}*/
for (int i = 0; i < OBSTACLE_COUNT; i++) {
if (obstacles[i].exist) {
putimagePNG2(obstacles[i].x, obstacles[i].y, WIN_WIDTH, &obstacleImgs[obstacles[i].type][obstacles[i].imgIndex]);
}
}
}
void updataHero() {
if (heroDown == false) {
putimagePNG2(heroX, heroY, &imgHeros[heroIndex]);
}
else {
int y = 345 - imgHeroDown[heroIndex].getheight();
putimagePNG2(heroX, y, &imgHeroDown[heroIndex]);
}
}
void updateBloodBar() {
drawBloodBar(10, 10, 200, 10, 2, BLUE, DARKGRAY, RED, heroBlood / 100.0);
}
void checkOver() {
if (heroBlood <= 0) {
loadimage(0, "res/over.png");
FlushBatchDraw();
mciSendString("stop res/bg.mp3", 0, 0, 0);
system("pause");
//暂停之后,充币复活,或者开始下一局
heroBlood = 100;
score = 0;
mciSendString("play res/bg.mp3 repeat", 0, 0, 0);
}
}
void checkScore() {
for (int i = 0; i < OBSTACLE_TYPE_COUNT; i++) {
if (obstacles[i].exist &&
obstacles[i].hited == false &&
obstacles[i].passed == false &&
obstacles[i].x+obstacleImgs[obstacles[i].type][0].getwidth() < heroX
) {
score++;
obstacles[i].passed = true;
printf("score : %d\n", score);
}
}
}
void updateScroe() {
//50=>"50" '5' '5'-'0' = 5
char str[8];
int x = 20;
int y = 25;
sprintf(str, "%d", score);
for (int i = 0; str[i]; i++) {
int sz = str[i] - '0';
putimagePNG(x, y, &imgSZ[sz]);
x += imgSZ[sz].getwidth() + 5;
}
}
void cheakWin() {
if (score >= WIN_SCORE) {
FlushBatchDraw();
mciSendString("play res/win.mp3", 0, 0, 0);
Sleep(2000);
loadimage(0, "res/win.png", WIN_WIDTH, WIN_HEIGHT);
FlushBatchDraw();
mciSendString("stop res/bg.mp3", 0, 0, 0);
system("pause");
heroBlood = 100;
score = 0;
mciSendString("play res/bj.mp3 repeat", 0, 0, 0);
}
}
int main(void) {
init();
//显示初始画面
loadimage(0, "res/over.png");
system("pause");
int timer = 0;
while (1) {
keyEvent();
timer += getDelay();
if (timer > 30) {
timer = 0;
updata = true;
}
if (updata) {
updata = false;
BeginBatchDraw();
updateBg();
//putimagePNG2(heroX, heroY, &imgHeros[heroIndex]);
updataHero();
updataEnemy();
updateBloodBar();
updateScroe();
cheakWin();
EndBatchDraw();
checkOver();
checkScore();
fly();
}
//Sleep(30);
}
system("pause");
return 0;
}
python仿天天酷跑 天天酷跑代码大全
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
结算跑批返回结果超时扫雷排查
spring的async事务提交问题
线程池 数据库 数据 -
用Python写一个天天酷跑
用Python写一个天天酷跑
初始化 碰撞检测 跑酷游戏 -
天天酷跑java 天天酷跑交流平台
1.代码介绍 1.游戏背景的设计 2.实现玩家奔跑 3.实现玩家跳跃 4.优化帧等待 5.使用结构体封装障碍物 &nb
c语言 开发语言 #define ci