上一篇:Xcode与C++之游戏开发:2D图形
接下来在前两天游戏骨架的基础上实现一个经典的乒乓球(Pong)游戏。游戏是这样的,一个球在屏幕上移动,玩家控制球拍来击打球。可以说乒乓球游戏是游戏开发者的 “Hello World” 项目。
绘制游戏中的物体
乒乓球球拍我们使用矩形来表示。绘制填充矩形,SDL 有 SDL_RenderFillRect 函数,它接受一个 SDL_Rect 代表的填充矩形,而矩形颜色由当前的绘图颜色决定。换句说,现在我们不改变绘图颜色,它默认就会使用那个幸福浪漫的蒂芙尼蓝。当然,颜色一摸一样,我们是看不见的。为了看得出矩形,将它修改成蓝色。
在 Game::GenerateOutput() 交换缓冲区之前写入:
// 设置绘制颜色
SDL_SetRenderDrawColor(mRenderer, 0, 0, 255, 255);
要绘制矩形,需要指定一个 SDL_Rect 结构体。这个结构体有4个参数,左上角的点x/y坐标,还有矩形的高和宽度。在绝大多数的图形库中,包括 SDL,窗口左上角的点的坐标是(0, 0),x正半轴是向右,y正半轴是向下的(和数学上的相反)。
假设我们要在屏幕上方绘制矩形作为游戏的墙,可以使用下面的 SDL_Rect 的定义:
// 顶部墙的参数
SDL_Rect wall {
0, // 左上 x 坐标
0, // 左上 y 坐标
1024, // 宽度
kThickness // 高度
};
宽度被硬编码成1024,一般来说这需要根据窗口尺寸自动修正,后面会考虑修正这个问题。kThickness 是一个 const int 常量,被设置成15,这是为了方便调整墙的厚度。
C++ 不推荐使用
#define宏预定义,更推荐使用const
在头文件声明之后加入:
const int kThickness = 15;
最后,用 SDL_RenderFillRect 绘制矩形,传入 SDL_Rect 指针:
SDL_RenderFillRect(mRenderer, &wall);
这样游戏窗口上面多了一道墙,类似的,可以画出底部的墙和右边的墙,只需要通过改变 SDL_Rect 的参数。比如,下面那道墙左上角的 y 坐标就是 768 - kThickness(因为窗口初始化时高度被初始化为768)。
// 绘制底部墙
wall.y = 768 - kThickness;
SDL_RenderFillRect(mRenderer, &wall);
// 绘制右边的墙
wall = {
1024 - kThickness,
0,
kThickness,
1024
};
SDL_RenderFillRect(mRenderer, &wall);
左边的墙呢?留着给玩家打乒乓球。

墙硬编码可能问题不大,乒乓球球和球拍就不能硬编码了。随着游戏循环,球拍是要会动的。实际游戏编程中,球和球拍应该抽象成类,但是现在我们姑且先用变量代替一下硬编码。
首先,先定义一个 Vector2 结构体来存储 x 和 y 坐标。这个定义放到 Game.hpp 之中:
// Vector2 结构体仅存储 x 和 y 坐标
struct Vector2
{
float x;
float y;
};
接着添加两个 Vector2 的成员变量到 Game 类中,一个作为球拍 mPaddlePos,一个作为球 mBallPos。
// 球拍位置
Vector2 mPaddlePos;
// 球的位置
Vector2 mBallPos;
之后在初始化时 Game::Initialize() 赋予一个合理的初始值。
// 初始化球拍和球的坐标
mPaddlePos.x = 10.0f;
mPaddlePos.y = 768.0f<

本文介绍了如何使用Xcode和C++开发经典的Pong游戏,包括绘制游戏物体、更新游戏状态,以及处理球拍和球的动态。通过使用SDL库,创建了游戏的图形界面,并通过增量时间处理了不同帧率下的游戏速度,确保了游戏的稳定运行。
最低0.47元/天 解锁文章
2263

被折叠的 条评论
为什么被折叠?



