参考

  1. 《C和C++游戏趣味编程》 童晶

火柴人跑酷

游戏的思路是,玩家通过键盘控制火柴人的奔跑和跳跃,躲避蝙蝠到达终点。游戏地图随机生成,随着关卡数增加,游戏难度越来越大

定义Player类

class Player
{public:IMAGE im_show;                               // 当前时刻要显示的图像float x_left, y_bottom;                      // 左下角位置float vx, vy;                                // 速度float width, height;                         // 图片的宽度、高度void draw(){putimagePng(x_left, y_bottom - height, &im_show);}void initialize(){loadimage(&im_show, _T("standright.png"));width = im_show.getwidth();height = im_show.getheight();updateXY(WIDTH / 2, HEIGHT / 2);vx = 10;vy = 10;}void updateXY(float mx, float my){x_left = mx;y_bottom = my;}
};

定义全局变量,初始化并显示:

IMAGE im_land;
IMAGE im_bk;
Player player;void startup()
{player.initialize();loadimage(&im_land, _T("land.png"));loadimage(&im_bk, _T("landscape1.png"));initgraph(WIDTH, HEIGHT);BeginBatchDraw();
}void show()
{putimage(-100, -100, &im_bk);putimage(WIDTH / 2, HEIGHT / 2, &im_land);player.draw();FlushBatchDraw();
}

通过按键控制角色移动:

void updateWithInput()
{if (_kbhit()){char input = getch();if (input == 'A'){player.x_left -= player.vx;}if (input == 'D'){player.x_left += player.vx;}if (input == 'W'){player.y_bottom -= player.vy;}if (input == 'S'){player.y_bottom += player.vy;}}
}

异步输入

利用异步输入函数GetAsyncKeyState(),可以同时识别两个按键被按下的情况,玩家可以用A、S、D、W或左、右、上、下方向键控制火柴人移动:

void updateWithInput()
{if (_kbhit()){if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A')){player.x_left -= player.vx;}if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D')){player.x_left += player.vx;}if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W')){player.y_bottom -= player.vy;}if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S')){player.y_bottom += player.vy;}}
}

枚举类型状态切换

火柴人会有向左站立、向右站立、向左奔跑、向右奔跑、向左跳跃、向右跳跃、死亡这7种状态:

在Player类中新增成员变量存储向右站立图像、向左站立图像和角色状态:

IMAGE im_standright;
IMAGE im_standleft;
PlayerStatus playerStatus;                   // 当前状态

在initialize()中对新增成员变量初始化:

loadimage(&im_standright, _T("standright.png"));
loadimage(&im_standleft, _T("standleft.png"));playerStatus = standright;
im_show = im_standright;

在updateWithInput()中,当键盘控制角色移动时,角色站立方向也应变化:

if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A'))
{player.x_left -= player.vx;player.playerStatus = standleft;
}
if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
{player.x_left += player.vx;player.playerStatus = standright;
}

添加奔跑动画

在Player类中添加成员变量ims_runright存储向右奔跑的8张图片,并初始化:

vector<IMAGE> ims_runright;
int animId;void initialize()
{loadimage(&im_standright, _T("standright.png"));loadimage(&im_standleft, _T("standleft.png"));playerStatus = standright;im_show = im_standright;width = im_standright.getwidth();height = im_standright.getheight();TCHAR filename[80];for (int i = 0; i <= 7; i++){swprintf_s(filename, _T("runright%d.png"), i);IMAGE im;loadimage(&im, filename);ims_runright.push_back(im);}animId = 0;updateXY(WIDTH / 2, HEIGHT / 2);vx = 10;vy = 10;
}

新增成员函数runRight(),把角色向右奔跑涉及的坐标更新,状态切换和动画效果实现:

void runRight()
{x_left += vx;if (playerStatus != runright){playerStatus = runright;animId = 0;}else{animId++;if (animId >= ims_runright.size()){animId = 0;}}im_show = ims_runright[animId];
}

实现跳跃

在Player类中添加成员变量存储向右、向左跳跃的图片和重力加速度,并初始化:

IMAGE im_jumpright;
IMAGE im_jumpleft;
float gravity;void initialize()
{loadimage(&im_jumpright, _T("jumpright.png"));loadimage(&im_jumpleft, _T("jumpleft.png"));vx = 10;vy = 0;gravity = 3;
}

添加beginJump(),控制动画切换并给角色一个向上初速度:

void beginJump()
{if (playerStatus != jumpleft && playerStatus != jumpright)           // 已在空中不能起跳{if (playerStatus == runleft || playerStatus == standleft){im_show = im_jumpleft;playerStatus = jumpleft;}else if (playerStatus == runright || playerStatus == standright){im_show = im_jumpright;playerStatus = jumpright;}vy = -30;}
}

新增成员函数updateYcoordinate(),自动完成自由落体运动:

void updateYcoordinate()
{if (playerStatus == jumpleft || playerStatus == jumpright){vy += gravity;y_bottom += vy;if (y_bottom > HEIGHT / 2){y_bottom = HEIGHT / 2;                     // 保证正好落在地面上if (playerStatus == jumpleft){playerStatus = standleft;}if (playerStatus == jumpright){playerStatus = standright;}}}
}

地面类

class Land
{public:IMAGE im_land;float left_x, right_x, top_y;float land_width, land_height;void initialize(){loadimage(&im_land, _T("land.png"));land_width = im_land.getwidth();land_height = im_land.getheight();left_x = WIDTH / 2;right_x = left_x + land_width;top_y = HEIGHT / 2;}void draw(){putimage(left_x, top_y, &im_land);}
};

场景类

场景类包括背景图片和多个地面对象

class Scene
{public:IMAGE im_bk;vector<Land> lands;void draw(){putimage(-100, -100, &im_bk);for (int i = 0; i < lands.size(); i++){lands[i].draw();}}void initialize(){loadimage(&im_bk, _T("landscape1.png"));for (int i = 1; i <= 6; i++){Land land;land.initialize();land.left_x = i * land.land_width;land.top_y = (i - 1) / 6.0 * HEIGHT;lands.push_back(land);}}
};

碰撞检测

产生一些随机地面:

void initialize()
{loadimage(&im_bk, _T("landscape1.png"));lands.clear();for (int i = 1; i < 10; i++){Land land;land.initialize();land.left_x = i * land.land_width;land.right_x = land.left_x + land.land_width;land.top_y = HEIGHT / 2 + rand() % 2 * HEIGHT / 10;lands.push_back(land);}
}

为Player类添加成员函数isOnLand(),判断角色是否在地面上:

int isOnLand(Land& land, float ySpeed)
{float x_right = x_left + width;if (ySpeed <= 0){ySpeed = 0;}if (land.left_x - x_left <= width * 0.6 && x_right - land.right_x <= width * 0.6 && abs(y_bottom - land.top_y) <= 5 + ySpeed){return 1;}else{return 0;}
}

添加成员函数isNotAllLands(),判断角色是否不在所有地面上:

int isNotOnAllLands(vector<Land>& lands, float speed)
{for (int i = 0; i < lands.size(); i++){if (isOnLand(lands[i], speed)){return 0;}}return 1;
}

修改runRight()和runLeft(),如果角色不在任何地面上,进入跳跃状态:

void runRight(Scene& scene)
{x_left += vx;if (isNotOnAllLands(scene.lands, vy)){im_show = im_jumpright;playerStatus = jumpright;return;}
}void runLeft(Scene& scene)
{x_left -= vx;if (isNotOnAllLands(scene.lands, vy)){im_show = im_jumpleft;playerStatus = jumpright;return;}
}

修改updateYcoordinate(),使角色碰到地面再停止下落:

void updateYcoordinate(Scene& scene)
{if (playerStatus == jumpleft || playerStatus == jumpright){vy += gravity;y_bottom += vy;for (int i = 0; i < scene.lands.size(); i++){if (isOnLand(scene.lands[i], vy)){y_bottom = scene.lands[i].top_y;if (playerStatus == jumpleft){playerStatus = standleft;}if (playerStatus == jumpright){playerStatus = standright;}break;}}}
}

实现相对运动

让角色位置不变,而背景、地面做相对运动:

class Land
{void draw(float px, float py){putimage(left_x - px, top_y - py, &im_land);      // 绘制地面有一个偏移量}
};class Scene
{void draw(float px, float py){putimage(-px / 20, -100 - py / 20, &im_bk);       // 绘制背景有一个偏移量,实现前后景for (int i = 0; i < lands.size(); i++){lands[i].draw(px, py);}}
}class Player
{void draw(){putimagePng(WIDTH / 2, HEIGHT / 2 - height, &im_show);  // 角色位置不动}
}

无尽关卡与胜负判断

在updateWithoutInput()中,角色跑到最后一个地面上,这一关游戏胜利,level加1,进入下一关;角色掉落画面底部,游戏失败,重新开始这一关:

void updateWithoutInput()
{player.updateYcoordinate(scene);int landSize = scene.lands.size();if (player.x_left > scene.lands[landSize - 1].left_x && abs(player.y_bottom - scene.lands[landSize - 1].top_y) <= 2) // 游戏胜利{scene.lastlevel = scene.level;scene.level++;scene.initialize();player.initialize();}else if (player.y_bottom > 1.5 * HEIGHT)                   // 角色落到画面底部,游戏失败{scene.lastlevel = scene.level;scene.initialize();player.initialize();}
}

随着level增加,生成的地图更大、地面之间更不连续:

void initialize()
{loadimage(&im_bk, _T("landscape1.png"));if (lands.size() == 0)                             // 默认从第一关开始{level = 1;lastlevel = 1;}if (lands.size() == 0 || level > lastlevel)        // 如果不升级,则不重新生成场景{lands.clear();Land land1;                                    // 第一关land要在游戏角色下方land1.initialize();lands.push_back(land1);for (int i = 1; i < 10 + level * 2; i++){Land land2;land2.initialize();int r1 = randBetweenMinMax(1, 30);if (r1 > level){land2.left_x = land1.left_x + land2.land_width;}else{land2.left_x = land1.left_x + 2 * land2.land_width;}int r3 = randBetweenMinMax(1, 20);if (r1 > level){land2.top_y = land1.top_y;}else{int r3 = randBetweenMinMax(-1, 1);land2.top_y = WIDTH / 2 + HEIGHT / 10 * r3;}land2.right_x = land2.left_x + land2.land_width;lands.push_back(land2);land1 = land2;}}
}

敌人类

class Enemy
{public:IMAGE im_enemy;float x, y;float enemy_width, enemy_height;float x_min, x_max;                                   // 敌人移动的x坐标最大值、最小值float vx;                                             // x方向速度void initialize(){loadimage(&im_enemy, _T("bat.png"));enemy_width = im_enemy.getwidth();enemy_height = im_enemy.getheight();}void draw(float px, float py){putimagePng(x - enemy_width / 2 - px, y - enemy_height / 2 - py, &im_enemy);}void update(){x += vx;if (x > x_max || x < x_min){vx = -vx;}}
};

在场景中添加Enemy变量,并初始化:

vector<Enemy> enemies;void draw(float px, float py)
{putimage(-px / 20, -100 - py / 20, &im_bk);       // 绘制背景有一个偏移量,实现前后景for (int i = 0; i < lands.size(); i++){lands[i].draw(px, py);}for (int i = 0; i < enemies.size(); i++){enemies[i].draw(px, py);}
}void initialize()
{if (lands.size() == 0 || level > lastlevel)        // 如果不升级,则不重新生成场景{enemies.clear();int numEnemy = (level + 3) / 5;int idStep = lands.size() / (numEnemy + 1);       // 敌人在scene中均匀分布for (int j = 1; j <= numEnemy; j++){Enemy enemy;enemy.initialize();int landId = j * idStep;enemy.x = lands[landId].left_x + lands[landId].land_width / 2;enemy.y = lands[landId].top_y - enemy.enemy_height;float movingRange = enemy.enemy_width * (3 + level / 15.0);enemy.x_min = enemy.x - movingRange;enemy.x_max = enemy.x + movingRange;enemy.vx = 2 + level / 10.0;enemies.push_back(enemy);}}
}

在Player类中,添加成员函数isCollideEnemy()判断角色是否和蝙蝠发生碰撞:

int isCollideEnemy(Enemy& enemy)
{float x_center = x_left + width / 2;float y_center = y_bottom - height / 2;if (abs(enemy.x - x_center) <= enemy.enemy_width * 0.5 && abs(enemy.y - y_center) <= enemy.enemy_height * 0.5){return 1;}else{return 0;}
}

在updateWithoutInput()中,让所有敌人水平移动,如果与角色碰撞,游戏失败:

for (int i = 0; i < scene.enemies.size(); i++)
{scene.enemies[i].update();                              // 敌人自动更新位置if (player.isCollideEnemy(scene.enemies[i])){scene.lastlevel = scene.level;scene.initialize();player.initialize();}
}

添加音效

在startup()中添加背景音乐:

mciSendString(_T("open game_music.mp3 alias bkmusic"), NULL, 0, NULL);
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL);

添加胜利音效:

PlayMusicOnce(_T("success.mp3"));

添加失败音效:

PlayMusicOnce(_T("warning.mp3"));

添加五角星

在每一关的终点处放置五角星:

IMAGE im_star;
void draw(float px, float py)
{// 在最后一个地面上方,放置五角星putimagePng(lands[lands.size() - 1].left_x + im_star.getwidth() - px, lands[lands.size() - 1].top_y - im_star.getheight() - py, &im_star);
}

完整代码

#include <graphics.h>
#include <conio.h>
#include <time.h>
#include "EasyXPng.h"
#include "Timer.h"
#include <vector>
using namespace std;
#pragma comment(lib,"Winmm.lib")#define WIDTH 800
#define HEIGHT 600enum PlayerStatus
{standleft, standright, runleft, runright, jumpleft, jumpright, die
};int randBetweenMinMax(int min, int max)
{int r = rand() % (max - min + 1) + min;return r;
}void PlayMusicOnce(TCHAR fileName[80]) // 播放一次音乐函数
{TCHAR cmdString1[50];swprintf_s(cmdString1, _T("open %s alias tmpmusic"), fileName); // 生成命令字符串mciSendString(_T("close tmpmusic"), NULL, 0, NULL); // 先把前面一次的音乐关闭mciSendString(cmdString1, NULL, 0, NULL); // 打开音乐mciSendString(_T("play tmpmusic"), NULL, 0, NULL); // 仅播放一次
}class Land
{public:IMAGE im_land;float left_x, right_x, top_y;float land_width, land_height;void initialize(){loadimage(&im_land, _T("land.png"));land_width = im_land.getwidth();land_height = im_land.getheight();left_x = WIDTH / 2;right_x = left_x + land_width;top_y = HEIGHT / 2;}void draw(float px, float py){putimage(left_x - px, top_y - py, &im_land);      // 绘制地面有一个偏移量}
};class Enemy
{public:IMAGE im_enemy;float x, y;float enemy_width, enemy_height;float x_min, x_max;                                   // 敌人移动的x坐标最大值、最小值float vx;                                             // x方向速度void initialize(){loadimage(&im_enemy, _T("bat.png"));enemy_width = im_enemy.getwidth();enemy_height = im_enemy.getheight();}void draw(float px, float py){putimagePng(x - enemy_width / 2 - px, y - enemy_height / 2 - py, &im_enemy);}void update(){x += vx;if (x > x_max || x < x_min){vx = -vx;}}
};class Scene
{public:IMAGE im_bk;IMAGE im_star;vector<Land> lands;vector<Enemy> enemies;int level;int lastlevel;void draw(float px, float py){putimage(-px / 20, -100 - py / 20, &im_bk);       // 绘制背景有一个偏移量,实现前后景for (int i = 0; i < lands.size(); i++){lands[i].draw(px, py);}for (int i = 0; i < enemies.size(); i++){enemies[i].draw(px, py);}// 在最后一个地面上方,放置五角星putimagePng(lands[lands.size() - 1].left_x + im_star.getwidth() - px, lands[lands.size() - 1].top_y - im_star.getheight() - py, &im_star);// 显示这是第几关TCHAR s[20]; // 字符串setbkmode(TRANSPARENT); // 文字透明显示swprintf_s(s, _T("第 %d 关"), level); // 生成文字字符串settextcolor(RGB(0, 50, 200));  // 设置文字颜色settextstyle(30, 0, _T("黑体")); // 设置文字大小、字体outtextxy(WIDTH * 0.45, 30, s); // 输出文字}void initialize(){TCHAR filename[80];int i = level % 9 + 1;swprintf_s(filename, _T("landscape%d.png"), i);loadimage(&im_bk, filename);loadimage(&im_star, _T("star.png"));if (lands.size() == 0)                             // 默认从第一关开始{level = 1;lastlevel = 1;}if (lands.size() == 0 || level > lastlevel)        // 如果不升级,则不重新生成场景{lands.clear();Land land1;                                    // 第一关land要在游戏角色下方land1.initialize();lands.push_back(land1);for (int i = 1; i < 10 + level * 2; i++){Land land2;land2.initialize();int r1 = randBetweenMinMax(1, 30);if (r1 > level){land2.left_x = land1.left_x + land2.land_width;}else{land2.left_x = land1.left_x + 2 * land2.land_width;}int r3 = randBetweenMinMax(1, 20);if (r1 > level){land2.top_y = land1.top_y;}else{int r3 = randBetweenMinMax(-1, 1);land2.top_y = WIDTH / 2 + HEIGHT / 10 * r3;}land2.right_x = land2.left_x + land2.land_width;lands.push_back(land2);land1 = land2;}enemies.clear();int numEnemy = (level + 3) / 5;int idStep = lands.size() / (numEnemy + 1);       // 敌人在scene中均匀分布for (int j = 1; j <= numEnemy; j++){Enemy enemy;enemy.initialize();int landId = j * idStep;enemy.x = lands[landId].left_x + lands[landId].land_width / 2;enemy.y = lands[landId].top_y - enemy.enemy_height;float movingRange = enemy.enemy_width * (3 + level / 15.0);enemy.x_min = enemy.x - movingRange;enemy.x_max = enemy.x + movingRange;enemy.vx = 2 + level / 10.0;enemies.push_back(enemy);}}}
};class Player
{public:IMAGE im_show;                               // 当前时刻要显示的图像IMAGE im_standright;IMAGE im_standleft;IMAGE im_jumpright;IMAGE im_jumpleft;vector<IMAGE> ims_runright;vector<IMAGE> ims_runleft;int animId;PlayerStatus playerStatus;                   // 当前状态float x_left, y_bottom;                      // 左下角位置float vx, vy;                                // 速度float gravity;float width, height;                         // 图片的宽度、高度void draw(){putimagePng(WIDTH / 2, HEIGHT / 2 - height, &im_show);  // 角色位置不动}void initialize(){ims_runleft.clear();ims_runright.clear();loadimage(&im_standright, _T("standright.png"));loadimage(&im_standleft, _T("standleft.png"));loadimage(&im_jumpright, _T("jumpright.png"));loadimage(&im_jumpleft, _T("jumpleft.png"));playerStatus = standright;im_show = im_standright;width = im_standright.getwidth();height = im_standright.getheight();TCHAR filename[80];for (int i = 0; i <= 7; i++){swprintf_s(filename, _T("runright%d.png"), i);IMAGE im;loadimage(&im, filename);ims_runright.push_back(im);}for (int i = 0; i <= 7; i++){swprintf_s(filename, _T("runleft%d.png"), i);IMAGE im;loadimage(&im, filename);ims_runleft.push_back(im);}animId = 0;updateXY(WIDTH / 2, HEIGHT / 2);vx = 10;vy = 0;gravity = 3;}void updateXY(float mx, float my){x_left = mx;y_bottom = my;}void runRight(Scene& scene){x_left += vx;if (isNotOnAllLands(scene.lands, vy)){im_show = im_jumpright;playerStatus = jumpright;return;}if (playerStatus == jumpleft || playerStatus == jumpright)    // 如果是起跳状态{im_show = im_jumpright;}else{if (playerStatus != runright){playerStatus = runright;animId = 0;}else{animId++;if (animId >= ims_runright.size()){animId = 0;}}im_show = ims_runright[animId];}}void runLeft(Scene& scene){x_left -= vx;if (isNotOnAllLands(scene.lands, vy)){im_show = im_jumpleft;playerStatus = jumpright;return;}if (playerStatus == jumpleft || playerStatus == jumpright)      // 如果是起跳状态{im_show = im_jumpleft;}else{if (playerStatus != runleft){playerStatus = runleft;animId = 0;}else{animId++;if (animId >= ims_runleft.size()){animId = 0;}}im_show = ims_runleft[animId];}}void standStill(){if (playerStatus == runleft || playerStatus == standleft){im_show = im_standleft;}else if (playerStatus == runright || playerStatus == standright){im_show = im_standright;}}void beginJump(){if (playerStatus != jumpleft && playerStatus != jumpright)           // 已在空中不能起跳{if (playerStatus == runleft || playerStatus == standleft){im_show = im_jumpleft;playerStatus = jumpleft;}else if (playerStatus == runright || playerStatus == standright){im_show = im_jumpright;playerStatus = jumpright;}vy = -30;}}int isCollideEnemy(Enemy& enemy){float x_center = x_left + width / 2;float y_center = y_bottom - height / 2;if (abs(enemy.x - x_center) <= enemy.enemy_width * 0.5 && abs(enemy.y - y_center) <= enemy.enemy_height * 0.5){return 1;}else{return 0;}}int isOnLand(Land& land, float ySpeed){float x_right = x_left + width;if (ySpeed <= 0){ySpeed = 0;}if (land.left_x - x_left <= width * 0.6 && x_right - land.right_x <= width * 0.6 && abs(y_bottom - land.top_y) <= 5 + ySpeed){return 1;}else{return 0;}}int isNotOnAllLands(vector<Land>& lands, float speed){for (int i = 0; i < lands.size(); i++){if (isOnLand(lands[i], speed)){return 0;}}return 1;}void updateYcoordinate(Scene& scene){if (playerStatus == jumpleft || playerStatus == jumpright){vy += gravity;y_bottom += vy;for (int i = 0; i < scene.lands.size(); i++){if (isOnLand(scene.lands[i], vy)){y_bottom = scene.lands[i].top_y;if (playerStatus == jumpleft){playerStatus = standleft;}if (playerStatus == jumpright){playerStatus = standright;}break;}}}}
};Player player;
Scene scene;
Timer timer;void startup()
{mciSendString(_T("open game_music.mp3 alias bkmusic"), NULL, 0, NULL);mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL);srand(time(0));scene.initialize();player.initialize();initgraph(WIDTH, HEIGHT);BeginBatchDraw();
}void show()
{scene.draw(player.x_left - WIDTH / 2, player.y_bottom - HEIGHT / 2);player.draw();FlushBatchDraw();timer.Sleep(50);
}void updateWithoutInput()
{player.updateYcoordinate(scene);int landSize = scene.lands.size();if (player.x_left > scene.lands[landSize - 1].left_x && abs(player.y_bottom - scene.lands[landSize - 1].top_y) <= 2) // 游戏胜利{PlayMusicOnce((TCHAR*)_T("success.mp3"));scene.lastlevel = scene.level;scene.level++;scene.initialize();player.initialize();}else if (player.y_bottom > 1.5 * HEIGHT)                   // 角色落到画面底部,游戏失败{PlayMusicOnce((TCHAR*)_T("warning.mp3"));scene.lastlevel = scene.level;scene.initialize();player.initialize();}for (int i = 0; i < scene.enemies.size(); i++){scene.enemies[i].update();                              // 敌人自动更新位置if (player.isCollideEnemy(scene.enemies[i])){PlayMusicOnce((TCHAR*)_T("warning.mp3"));scene.lastlevel = scene.level;scene.initialize();player.initialize();}}
}void updateWithInput()
{player.standStill(); // 游戏角色默认为向左或向右静止站立if (_kbhit()){if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D')){player.runRight(scene);}else if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A')){player.runLeft(scene);}if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W')){player.beginJump();}}
}int main()
{startup();while (1){show();updateWithoutInput();updateWithInput();}return 0;
}

C++入门——实现“火柴人跑酷”游戏相关推荐

  1. DEVC++实现火柴人跑酷游戏

    C++可以做很多游戏,今天带给大家一个跑酷游戏 直接上代码(只能用DEVC++运行): #include<bits/stdc++.h> #include<windows.h> ...

  2. Dev-C++5.11游戏创作之火柴人跑酷

    大家好!我是你们的编程小王子! 今天我们来一起制作一个火柴人跑酷的小游戏! 还在等什么,准备好编译器,放下你们手里的小心心吧,谢谢啦Thanks♪(・ω・)ノ 这个代码比较难,我一段一段解释吧 //首 ...

  3. java编写火柴人小游戏,摧毁火柴人

    摧毁火柴人无敌版是一款有趣的休闲小游戏,玩家在这里需要快速的攻击火柴人,这款游戏就是希望玩家不断的进行攻击火柴人,游戏的目标就是攻击火柴人,游戏里面拥有海量丰富的道具,还拥有各种的关卡,这些关卡的难度 ...

  4. java动画火柴人_基于html的火柴人羽毛球游戏

    一.游戏简介 火柴人羽毛球灵感来自于flash小游戏 游戏中,玩家可操作画面中的火柴人来进行羽毛球比赛 通过键盘上的左右键控制火柴人的左右移动,按上键跳跃,按下键挥拍击球 当某一方分数达到7分即判定取 ...

  5. 基于html的火柴人羽毛球游戏

    一.游戏简介 火柴人羽毛球灵感来自于flash小游戏 游戏中,玩家可操作画面中的火柴人来进行羽毛球比赛 通过键盘上的左右键控制火柴人的左右移动,按上键跳跃,按下键挥拍击球 当某一方分数达到7分即判定取 ...

  6. 【180929】趣味火柴人奔跑游戏源码

    (WPF帧动画效果)火柴人在画板上前进的效果,演示了MainWindow.xaml 的交互逻辑,调用系统默认的帧进行动画, 开启一个后台线程,用来控制帧频率的刷新速度,找到系统图片存放的位置,并添加图 ...

  7. 火柴人跑酷c++(附源码)

    注:(代码转载于其他作者,不喜勿喷) #include<bits/stdc++.h> #include<windows.h> #include<stdio.h> # ...

  8. python编程火柴人格斗_格斗火柴人_JAVA游戏免费版下载_7723手机游戏[www.7723.cn]

    快速搜索机型: 诺基亚 N73系列(240×320) N73 5320 5320XM 5320di_XM 5630XM 5700 5700XM 5710XM 5730XM 6110 6110N 612 ...

  9. c++奔跑的火柴人游戏

    C++是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由本贾尼▪斯特劳斯特卢普在 AT&T贝尔工作室研发. C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据 ...

最新文章

  1. 从JoinBatchGroup 代码细节 来看Rocksdb的相比于leveldb的写入优势
  2. 代码质量第4层——健壮的代码!
  3. 推荐11个第2职业挣大钱的公众号!第5名一年涨8万粉丝!
  4. 对C语言 结构指针变量做函数的参数 结构作为函数的参数
  5. 谈谈java面向对象思想_对于Java面向对象思想的理解
  6. python和javascript哪个好_JavaScript与Python:主要区别
  7. 黄聪:电子商务关键数字优化(线上部分,上)
  8. 多校#5-1005-Instring-HDU5785-manacher+维护
  9. 程序员究竟还需要读书么?
  10. JavaScript:数组、函数和对象
  11. 谁说财务软件不能上纯公有云?
  12. ArcGIS Server中各种服务详解
  13. UtIL DBUtil
  14. 【python】微信朋友圈分析
  15. 用Keras和直方图均衡化进行深度学习的图像增强
  16. 服务器2颗cpu的性能,DIY从入门到放弃:两颗CPU性能更强吗?
  17. 局部边缘保留滤波器LEP算法原理及matlab代码实现
  18. 获取VM中win10虚拟机映像
  19. cscope精准查看linux函数调用,Cscope的使用(领略Vim + Cscope的强大魅力)
  20. Cannot retrieve metalink for repository: epel…错误解决办法

热门文章

  1. LaTeX技巧011:LaTtex中如何产生直立体希腊字母?
  2. Java多线程之线程同步
  3. Python钉钉打卡程序
  4. kubernetes学习:留言板(Guestbook)系统的搭建
  5. IE浏览器设置兼容模式不生效或者只是当次生效的解决办法
  6. 存储器空间或者桌面堆_手机桌面太杂乱?不知道如何管理自己的桌面,身为强迫症的我来教你!...
  7. Haar + AdaBoost
  8. java环境变量一键配置工具
  9. 求三个数的最大公约数和最小公倍数
  10. python代码优化无限营销软件工作室_批量群发,营销必备!Python代码实现自动发送邮件!...