游戏截图:
游戏介绍
我的职务:程序、美术、策划
此游戏为我与两名同班同学合作制作,为刚刚接触C++的第一款Win32面向对象游戏作品。我在项目中担任程序与美术,Yuuki担任音乐,GH担任测试与推广。
玩法简介
按空格起跳,躲避障碍
美术风格
因为框架优化奇差的问题,我必须选择像素风格。
但既然已经选用了像素,那就将像素简约的优点发扬光大。所以我选择舍弃了颜色,使用黑白风格。而且完全使用了不带任何渐变的边缘,防止产生模糊的感觉。
既然是我们自己做着玩r的游戏,我们在其中夹带了许多私货。但是既然夹带了私货那就得让别人能看出来。所以我在本来只有黑白两色的画面中添加了很亮眼的色彩,每个色彩都高度概括了我们夹带的私货。
音乐设计
既然选择了像素风格,那音乐必然得选用8bit。
Yukki将5首我们耳熟能详的8bit音乐缝合在了一起,写出了背景循环音乐
技术路线
通过枚举值储存游戏阶段,在Update函数中根据不同枚举值做出不同的反应
1 2 3 4 5 6 7 8
| enum EGameState { eGS_Menu, eGS_Help, eGS_About, eGS_Play, eGS_Gameover, };
|
类设计
- 玩家
- 初始化时添加事件监听器,加载指定bmp贴图,并设置坐标以及碰撞箱大小;
- 更新时重绘贴图以及碰撞箱,以及重力响应;
- 空格按下时跳跃,给垂直方向初速度;
- 障碍物
- 初始化时随机生成石头或者鸟,石头则初始坐标在地面,鸟则在天空。加载对应bmp贴图;
- 刷新时每帧向左移动
- 当玩家跳过去后加分
- 当玩家撞到后游戏结束
- 当自己出屏幕后销毁
按位读取BMP文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| if (m_bpp == 32) {
for (uint32 i = 0; i < m_width * m_height; ++i) { m_data[i] = (colorStart[i * 4 + 0] << 0) | (colorStart[i * 4 + 1] << 8) | (colorStart[i * 4 + 2] << 16) | (colorStart[i * 4 + 3] << 24); }
} else if (m_bpp == 24) { for (uint32 i = 0; i < m_width * m_height; ++i) { m_data[i] = 0xff << 24 | (colorStart[i * 3 + 0] << 0) | (colorStart[i * 3 + 1] << 8) | (colorStart[i * 3 + 2] << 16); } }
|
背景滚动
通过图片大小归一化处理制作,也就是UV的方法进行循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void GtGameDemo::BeiJingGunDong(GtBitmap* bg, float2 pos1, float2 pos2, float speed, float* t, float fElapsedTime)
{ int2 k(0, 0); for (uint32 iy = (pos1.y * g_context.height); iy < (pos2.y * g_context.height); ++iy) { k.y++; for (uint32 ix = (pos1.x * g_context.width); ix < (pos2.x * g_context.width); ++ix) { k.x++; uint32 address = (iy * g_context.width + ix); if (address > 0 && address < g_context.width * g_context.height) { texX = k.x / ((float)bg->GetWidth() * mult.x); texY = k.y / ((float)bg->GetHeight() * mult.y); g_context.buffer[address] = bg->getColor(float2(texX + *t, texY)); } } } *t += speed * fElapsedTime; }
|
计分系统
我自己绘制了数字0-9的bmp图像,导入之后通过对分数求余计算分数的十位以及个位是什么数字,然后显示。
1 2 3 4
| g_context.painter->DrawBitmap(number[(score % 100) / 10], pos.x, pos.y, size, size, 5, eBm_Direct, int2(1, 1));
g_context.painter->DrawBitmap(number[score % 10], pos.x + size, pos.y, size, size, 5, eBm_Direct, int2(1, 1));
|
音频系统
考虑了PlaySound函数无法进行音频混响,所以选用了MCI音频系统
使用方法如下:
1 2 3 4 5 6 7 8 9
| #include <windows.h> #include <Mmsystem.h> #pragma comment(lib, "winmm.lib")
int main() { mciSendString(TEXT("open Fail.wav alias fail"), NULL, 0, NULL); return 0; }
|
其中text部分为(操作 音频源 别称 循环/开始位置/结束位置)
比如
1 2 3 4 5 6
| mciSendString(TEXT("open Fail.wav alias fail"), NULL, 0, NULL);
mciSendString(TEXT("play click from 0"), NULL, 0, NULL);
mciSendString(TEXT("play bgm from 0 repeat"), NULL, 0, NULL);
|
Github链接
如果可以的话随手点开star一下岂不美哉#滑稽
Github链接