帮我用c++实现一个面向对象的贪吃蛇游戏,带游戏窗口,可以使用键盘方向键控制
时间: 2024-02-06 16:09:18 浏览: 96
好的,以下是一个简单的面向对象贪吃蛇游戏的实现,基于Windows API的GDI绘图:
```c++
#include <windows.h>
#include <vector>
// 游戏窗口尺寸
const int kWindowWidth = 600;
const int kWindowHeight = 600;
// 贪吃蛇的节点
struct SnakeNode {
int x, y; // 坐标
SnakeNode(int _x, int _y) : x(_x), y(_y) {}
};
class Game {
public:
Game() { Init(); }
~Game() { End(); }
void Init() {
// 初始化游戏
srand(GetTickCount()); // 初始化随机数种子
score_ = 0;
direction_ = 0; // 初始方向向右
snake_.push_back(SnakeNode(5, 5)); // 初始蛇身为1个节点
GenerateFood(); // 随机生成食物
}
void End() {
// 结束游戏
// ...
}
void Update(HWND hWnd) {
// 更新游戏状态
MoveSnake(); // 移动蛇
if (IsCollideWithWall() || IsCollideWithSelf()) {
// 撞墙或者撞到自己,游戏结束
MessageBox(hWnd, TEXT("Game Over!"), TEXT("提示"), MB_OK);
Init(); // 重新开始游戏
}
if (IsCollideWithFood()) {
// 吃到食物
score_++;
snake_.push_back(SnakeNode(food_x_, food_y_)); // 蛇身增加1个节点
GenerateFood(); // 重新生成食物
}
}
void Draw(HDC hDC) {
// 绘制游戏画面
// 清空画面
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = kWindowWidth;
rect.bottom = kWindowHeight;
FillRect(hDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
// 绘制蛇
for (size_t i = 0; i < snake_.size(); i++) {
Rectangle(hDC, snake_[i].x * kNodeSize, snake_[i].y * kNodeSize, (snake_[i].x + 1) * kNodeSize, (snake_[i].y + 1) * kNodeSize);
}
// 绘制食物
Rectangle(hDC, food_x_ * kNodeSize, food_y_ * kNodeSize, (food_x_ + 1) * kNodeSize, (food_y_ + 1) * kNodeSize);
// 绘制得分
TCHAR score_str[128];
wsprintf(score_str, TEXT("Score: %d"), score_);
TextOut(hDC, 10, 10, score_str, lstrlen(score_str));
}
void OnKeyDown(int vkCode) {
// 处理键盘按键事件
switch (vkCode) {
case VK_LEFT: direction_ = 2; break;
case VK_UP: direction_ = 3; break;
case VK_RIGHT: direction_ = 0; break;
case VK_DOWN: direction_ = 1; break;
}
}
private:
// 游戏参数
const int kNodeSize = 20; // 节点大小
const int kNodeCountX = kWindowWidth / kNodeSize; // X方向节点数
const int kNodeCountY = kWindowHeight / kNodeSize; // Y方向节点数
int score_; // 得分
int direction_; // 方向,0-右,1-下,2-左,3-上
std::vector<SnakeNode> snake_; // 蛇身
int food_x_, food_y_; // 食物坐标
void MoveSnake() {
// 移动蛇
int dx = 0, dy = 0;
switch (direction_) {
case 0: dx = 1; break;
case 1: dy = 1; break;
case 2: dx = -1; break;
case 3: dy = -1; break;
}
for (size_t i = snake_.size() - 1; i > 0; i--) {
snake_[i].x = snake_[i - 1].x;
snake_[i].y = snake_[i - 1].y;
}
snake_[0].x += dx;
snake_[0].y += dy;
}
bool IsCollideWithWall() {
// 判断是否撞墙
if (snake_[0].x < 0 || snake_[0].x >= kNodeCountX || snake_[0].y < 0 || snake_[0].y >= kNodeCountY) {
return true;
}
return false;
}
bool IsCollideWithSelf() {
// 判断是否撞到自己
for (size_t i = 1; i < snake_.size(); i++) {
if (snake_[0].x == snake_[i].x && snake_[0].y == snake_[i].y) {
return true;
}
}
return false;
}
bool IsCollideWithFood() {
// 判断是否吃到食物
if (snake_[0].x == food_x_ && snake_[0].y == food_y_) {
return true;
}
return false;
}
void GenerateFood() {
// 随机生成食物
bool valid = false;
while (!valid) {
food_x_ = rand() % kNodeCountX;
food_y_ = rand() % kNodeCountY;
valid = true;
for (size_t i = 0; i < snake_.size(); i++) {
if (food_x_ == snake_[i].x && food_y_ == snake_[i].y) {
valid = false;
break;
}
}
}
}
};
// 全局变量
Game g_game;
// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
// 创建窗口时初始化游戏
g_game.Init();
break;
case WM_COMMAND:
break;
case WM_PAINT: {
// 绘制游戏画面
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
g_game.Draw(hdc);
EndPaint(hWnd, &ps);
break;
}
case WM_KEYDOWN:
// 处理键盘按键事件
g_game.OnKeyDown(wParam);
break;
case WM_TIMER:
// 定时器事件,更新游戏状态并刷新画面
g_game.Update(hWnd);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_DESTROY:
// 销毁窗口时结束游戏
g_game.End();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// WinMain函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
HWND hWnd;
MSG msg;
// 初始化窗口类
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = TEXT("SnakeGame");
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
// 创建窗口
hWnd = CreateWindow(TEXT("SnakeGame"), TEXT("Snake Game"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, kWindowWidth + 16, kWindowHeight + 39, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
// 显示窗口
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// 创建定时器,每100毫秒刷新一次画面
SetTimer(hWnd, 1, 100, NULL);
// 消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
```
上述代码仅为简单实现,还有很多可优化的地方,比如增加难度、增加音效、增加暂停等等。
阅读全文
相关推荐
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)