游戏编程入门(9):开发 Henway(小鸡过马路) 游戏
应用前面学到的子画面知识,开发一个小鸡过马路游戏。
接上文 游戏编程入门(8):管理子画面
Henway 游戏的玩法
Henway 游戏的主角是一只小鸡,它急需从一条繁忙的高速公路的一边到达另一边。Henway 的游戏方向是水平的,这意味着小鸡要从屏幕的左边到右边。
Henway 游戏,小鸡的数量是有限的3只。当所有小鸡都死掉时,游戏就结束了。当小鸡成功的穿越了高速公路或者玩家失去了一只小鸡,都会计入积分系统中,最后显示玩家所得的分数。
Henway 游戏,以键盘的上下左右键,控制小鸡。
设计Henway 游戏
Henway 游戏有5个子画面:一个小鸡子画面和4辆汽车子画面,有7个位图图像:1个背景高速公路图像,1个小鸡图像,4个汽车图像,很小的鸡头图像。
很小的鸡头图像显示在右下角,提示玩家还剩下多少只小鸡。在高速公路上损失小鸡时,鸡头就会消失,直到没有剩下任何鸡头位置,这时游戏就结束了。
现在,读者已经对游戏中涉及的图像对象有了一定的了解,下面考虑游戏必须维护的其他数据。首先,很显然需要记录剩余多少个小鸡,还需要维护一个连续的积分,在每次小鸡安全穿过高速公路时都加分,还需要一个布尔变量,用来记录游戏是否结束了。
还有最后一个变量,如果读者没有真正开发这个程序并彻底测试它,那么很难预见到这个变量。我是指一个输入延迟变量,它有助于改变键盘的输入响应,以便改进游戏的可玩性。
如果在每一个游戏循环里都直接响应键盘,那么小鸡在游戏屏幕上的移动就会太快了,这就产生了太多的游戏周期,过多的注意了输入设备。为了稍微放慢输入,可以使用一个延迟变量,每三个游戏循环才检查一次键盘输入。确定合适的延迟是一个不断尝试的过程,因此可以随意修改它并查看最合适的延迟。
总结一下,Henway 游戏的设计使我们了解到游戏必须管理以下信息:
- 剩下的小鸡数量
- 得分
- 确定游戏是否结束的布尔变量
- 输入延迟变量
开发Henway 游戏
注意:若出现编译错误,请在项目设置->连接->对象/库模块中 加入 msimg32.lib winmm.lib
Henway 目录结构与效果图
Henway 目录结构:
Henway 效果图:
Henway 游戏源代码
Henway.h 源代码
#pragma once//-----------------------------------------------------------------
// 包含的文件
//-----------------------------------------------------------------
#include <windows.h>
#include "Resource.h"
#include "GameEngine.h"
#include "Bitmap.h"
#include "Sprite.h"//-----------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------
HINSTANCE g_hInstance; //程序实例句柄
GameEngine* g_pGame; //游戏引擎指针
HDC g_hOffscreenDC; //屏幕外设备
HBITMAP g_hOffscreenBitmap; //屏幕外缓冲区的位图
Bitmap* g_pHighwayBitmap; //背景高速公路位图
Bitmap* g_pChickenBitmap; //小鸡位图
Bitmap* g_pCarBitmaps[4]; //4个汽车位图
Bitmap* g_pChickenHeadBitmap;//鸡头位图
Sprite* g_pChickenSprite; //小鸡子画面
int g_iInputDelay; //输入延迟
int g_iNumLives; //剩下的小鸡
int g_iScore; //得分
BOOL g_bGameOver; //游戏是否结束//-----------------------------------------------------------------
// 根据用户输入事件移动小鸡子画面
//-----------------------------------------------------------------
void MoveChicken(int iXDistance, int iYDistance);
Henway.cpp 源代码
//-----------------------------------------------------------------
// 包含的文件
//-----------------------------------------------------------------
#include "Henway.h"//-----------------------------------------------------------------
// 游戏事件函数
//-----------------------------------------------------------------// 初始化游戏
BOOL GameInitialize(HINSTANCE hInstance)
{// Create the game engineg_pGame = new GameEngine(hInstance, TEXT("Henway"),TEXT("Henway"), IDI_HENWAY, IDI_HENWAY_SM, 465, 400);if (g_pGame == NULL)return FALSE;// Set the frame rateg_pGame->SetFrameRate(30);// Store the instance handleg_hInstance = hInstance;return TRUE;
}// 开始游戏
void GameStart(HWND hWindow)
{// 生成随机数种子srand(GetTickCount());// 创建屏幕外的设备环境,然后使用它创建一个屏幕外位图g_hOffscreenDC = CreateCompatibleDC(GetDC(hWindow));g_hOffscreenBitmap = CreateCompatibleBitmap(GetDC(hWindow),g_pGame->GetWidth(), g_pGame->GetHeight());SelectObject(g_hOffscreenDC, g_hOffscreenBitmap);// 创建并加载位图HDC hDC = GetDC(hWindow);g_pHighwayBitmap = new Bitmap(hDC, IDB_HIGHWAY, g_hInstance);g_pChickenBitmap = new Bitmap(hDC, IDB_CHICKEN, g_hInstance);g_pCarBitmaps[0] = new Bitmap(hDC, IDB_CAR1, g_hInstance);g_pCarBitmaps[1] = new Bitmap(hDC, IDB_CAR2, g_hInstance);g_pCarBitmaps[2] = new Bitmap(hDC, IDB_CAR3, g_hInstance);g_pCarBitmaps[3] = new Bitmap(hDC, IDB_CAR4, g_hInstance);g_pChickenHeadBitmap = new Bitmap(hDC, IDB_CHICKENHEAD, g_hInstance);// 创建小鸡和汽车的子画面(汽车的z顺序比小鸡高,这样小鸡被汽车压的时候,小鸡显示在车下面)Sprite* pSprite;RECT rcBounds = { 0, 0, 465, 400 };g_pChickenSprite = new Sprite(g_pChickenBitmap, rcBounds, BA_STOP);g_pChickenSprite->SetPosition(4, 175);g_pChickenSprite->SetVelocity(0, 0);g_pChickenSprite->SetZOrder(1);g_pGame->AddSprite(g_pChickenSprite);pSprite = new Sprite(g_pCarBitmaps[0], rcBounds, BA_WRAP);pSprite->SetPosition(70, 0);pSprite->SetVelocity(0, 7);pSprite->SetZOrder(2);g_pGame->AddSprite(pSprite);pSprite = new Sprite(g_pCarBitmaps[1], rcBounds, BA_WRAP);pSprite->SetPosition(160, 0);pSprite->SetVelocity(0, 3);pSprite->SetZOrder(2);g_pGame->AddSprite(pSprite);pSprite = new Sprite(g_pCarBitmaps[2], rcBounds, BA_WRAP);pSprite->SetPosition(239, 400);pSprite->SetVelocity(0, -5);pSprite->SetZOrder(2);g_pGame->AddSprite(pSprite);pSprite = new Sprite(g_pCarBitmaps[3], rcBounds, BA_WRAP);pSprite->SetPosition(329, 400);pSprite->SetVelocity(0, -10);pSprite->SetZOrder(2);g_pGame->AddSprite(pSprite);// 初始化其余全局变量g_iInputDelay = 0;g_iNumLives = 3;g_iScore = 0;g_bGameOver = FALSE;
}// 结束游戏
void GameEnd()
{// 清除屏幕外设备环境和位图DeleteObject(g_hOffscreenBitmap);DeleteDC(g_hOffscreenDC); // 清除位图delete g_pHighwayBitmap;delete g_pChickenBitmap;for (int i = 0; i < 4; i++)delete g_pCarBitmaps[i];delete g_pChickenHeadBitmap;// 清除子画面g_pGame->CleanupSprites();// 清除游戏引擎delete g_pGame;
}void GameActivate(HWND hWindow)
{}void GameDeactivate(HWND hWindow)
{}// 绘制游戏
void GamePaint(HDC hDC)
{// 绘制高速公路背景g_pHighwayBitmap->Draw(hDC, 0, 0);// 绘制游戏子画面g_pGame->DrawSprites(hDC);// 绘制剩余小鸡生命的数量for (int i = 0; i < g_iNumLives; i++)g_pChickenHeadBitmap->Draw(hDC,406 + (g_pChickenHeadBitmap->GetWidth() * i), 382, TRUE);
}// 游戏循环
void GameCycle()
{if (!g_bGameOver){// 更新子画面g_pGame->UpdateSprites();// 获得用来绘制游戏的设备环境HWND hWindow = g_pGame->GetWindow();HDC hDC = GetDC(hWindow);// 在屏幕外设备环境上绘制游戏GamePaint(g_hOffscreenDC);// 将屏幕外位图位块传送到游戏屏幕BitBlt(hDC, 0, 0, g_pGame->GetWidth(), g_pGame->GetHeight(),g_hOffscreenDC, 0, 0, SRCCOPY);// 清理ReleaseDC(hWindow, hDC);}
}// 键盘响应事件
void HandleKeys()
{if (!g_bGameOver && (++g_iInputDelay > 2)){// 根据按键移动小鸡if (GetAsyncKeyState(VK_LEFT) < 0)MoveChicken(-20, 0);else if (GetAsyncKeyState(VK_RIGHT) < 0)MoveChicken(20, 0);if (GetAsyncKeyState(VK_UP) < 0)MoveChicken(0, -20);else if (GetAsyncKeyState(VK_DOWN) < 0)MoveChicken(0, 20);// 重置输入延迟g_iInputDelay = 0;}
}// 按下鼠标
void MouseButtonDown(int x, int y, BOOL bLeft)
{// 开始一个新游戏if (g_bGameOver){g_iNumLives = 3;g_iScore = 0;g_bGameOver = FALSE;}
}void MouseButtonUp(int x, int y, BOOL bLeft)
{
}void MouseMove(int x, int y)
{
}// 碰撞检测
BOOL SpriteCollision(Sprite* pSpriteHitter, Sprite* pSpriteHittee)
{// 查看是否撞上了小鸡if (pSpriteHittee == g_pChickenSprite){// 将小鸡移回开始位置,给人一种新小鸡开始的错觉g_pChickenSprite->SetPosition(4, 175);// 查看游戏是否结束if (--g_iNumLives > 0)MessageBox(g_pGame->GetWindow(), TEXT("Ouch!"), TEXT("Henway"), MB_OK);else{// 显示游戏结束消息TCHAR szText[64];wsprintf(szText, "Game Over! You scored %d points.", g_iScore);MessageBox(g_pGame->GetWindow(), szText, TEXT("Henway"), MB_OK);g_bGameOver = TRUE;}return FALSE;}return TRUE;
}//-----------------------------------------------------------------
// 移动小鸡子画面
//-----------------------------------------------------------------
void MoveChicken(int iXDistance, int iYDistance)
{// 将小鸡移动到新位置g_pChickenSprite->OffsetPosition(iXDistance, iYDistance);// 查看小鸡是否成功通过if (g_pChickenSprite->GetPosition().left > 400){// 将小鸡移回开始位置并增加得分g_pChickenSprite->SetPosition(4, 175);g_iScore += 150;MessageBox(g_pGame->GetWindow(), TEXT("You made it!"), TEXT("Henway"),MB_OK);}
}
源代码 下载
http://pan.baidu.com/s/1ge2Vzr1
游戏编程入门(9):开发 Henway(小鸡过马路) 游戏相关推荐
- 游戏编程入门(3):绘制基本 GDI 图形
接上文 游戏编程入门(2):创建游戏引擎和使用该引擎制作小游戏 本篇内容包括: 使用Windows图形设备接口绘制图形的基础知识 设备环境是什么以及它为什么对GDI图形如此重要 如何在Windows中 ...
- 游戏编程入门(6):开发 Brainiac(记忆对对碰) 游戏
接上文 游戏编程入门(5):使用键盘和鼠标控制游戏 这个游戏是记忆游戏,将隐藏的方块配对.即点击一下方块,就会翻转出图片页,然后记忆几秒,回归成方块,要将相同图片的方块进行配对. 本章内容包括: 如果 ...
- 游戏编程入门(完):开发 Stunt Jumper(摩托车跳跃)游戏
Stunt Jumper 是一个横向滚动的摩托车跳跃游戏,玩家必须仔细控制摩托车手的速度,以便帮助它越过一排汽车. 本章内容包括: Stunt Jumper 的基本思路 如何设计 Stunt Jump ...
- 如何根据自己的需要培养游戏开发技能?又一篇游戏编程入门指南
对游戏编程感兴趣或是想自己做游戏的人可以参考一下~ 我是一个独立游戏开发者,在一个主机独立游戏开发团队里做主程.大学毕业 10 年,毕业以后就一直在做游戏编程,从一开始的"端游", ...
- 游戏编程入门(10):播放数字声音效果
本章内容包括: 如何使用 Win32 API 播放波形声音 如何将波形声音合并到现有的游戏中 接上文 游戏编程入门(9):开发 Henway(小鸡过马路) 游戏 播放波形声音 Win32 API 提供 ...
- 游戏编程入门(11):播放MIDI 音乐
MIDI音乐是将音乐结合到游戏的最佳方式之一,本章就将介绍究竟如何使用相对较少的代码播放MIDI音乐. 本章内容包括: 如何使用MCI播放MIDI音乐 如何向游戏添加MIDI音乐 接上文 游戏编程入门 ...
- python游戏编程入门 免费-python游戏编程入门 python游戏编程入门课
python游戏编程入门 python游戏编程入门课 什么是python游戏编程入门?首先我们需要认识什么是Python Python既是一个软件工具包,也是一种语言.Python软件包包含了一个名为 ...
- 《Python游戏编程入门》——1.2 初识Python
本节书摘来自异步社区<Python游戏编程入门>一书中的第1章,第1.2节,作者[美]Jonathan S. Harbour ,李强 译,更多章节内容可以访问云栖社区"异步社区& ...
- .netframework游戏编程入门——模拟魔兽学院永远的羁绊
相信有很多和我一样摸索着编游戏的自学者,自学是辛苦的,一没明确的引导,二没正确的工具,我就谈一下自己的经验,也许可以让你少走一点弯路.3D 的先不谈,2D作为基础还是有必要研究,然后把地图模型一换(换 ...
最新文章
- java怎么来用urlrewrite伪静态化和urlrewrite的配置
- h5调微信支付 unkonw url_聚合支付系统设计(一)
- 风控策略和模型的区别_智能风控平台核心之风控决策引擎(二)
- 深入理解 KVC\KVO 实现机制 — KVC
- leetcode266. 回文排列
- 成就优秀程序员的很多因素你知道多少?
- bugku——普通的二维码(进制转换)
- docker1.13.1的安装与卸载及mysql5.5安装实例
- 剑指offer——面试题26:复杂链表的复制
- 27. 二叉搜索树与双向链表(C++版本)
- docker学习记录 docker 脚本----redis,zookeeper,kafka(三)
- cetnos6.4 基础版安装
- LENET-5卷积神经网络的深度学习技术
- Flutter 桌面应用调研
- ReadHub android版
- AtCoder abc256全题解(区间合并模板、矩阵快速幂优化dp、线段树……)
- UNITY 5.2.1 发行说明 中文版
- SQLyog 试用期过的解决办法
- 从头到尾创建自己的仿真编译flow
- 六、Oracle 同义词