一个简单的2D游戏,使用C++和SDL库实现,主要包含游戏循环、精灵、碰撞检测、基本控制等功能。
首先安装SDL库并设置开发环境,然后在代码中添加以下头文件:
cpp复制插入
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#include <vector>
复制插入
接着定义一些全局变量:
cpp复制插入
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SPRITE_SIZE = 32;
SDL_Window* gWindow = nullptr;
SDL_Renderer* gRenderer = nullptr;
bool gQuitGame = false;
bool gKeyDown[SDL_NUM_SCANCODES] = { false };
struct Sprite
{
SDL_Texture* texture;
SDL_Rect rect;
};
std::vector<Sprite> gSprites;
Sprite gPlayerSprite;
复制插入
定义一个初始化函数用于加载图像及创建精灵:
cpp复制插入
bool Init()
{
// 初始化SDL库
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cout << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
return false;
}
// 创建窗口
gWindow = SDL_CreateWindow("2D Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == nullptr)
{
std::cout << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
return false;
}
// 创建渲染器
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
if (gRenderer == nullptr)
{
std::cout << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl;
return false;
}
// 初始化SDL_image库
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
std::cout << "SDL_image could not initialize! SDL_Image Error: " << IMG_GetError() << std::endl;
return false;
}
// 创建纹理
SDL_Surface* surface = IMG_Load("player.png");
if (surface == nullptr)
{
std::cout << "Could not load player.png! SDL_Error: " << SDL_GetError() << std::endl;
return false;
}
gPlayerSprite.texture = SDL_CreateTextureFromSurface(gRenderer, surface);
if (gPlayerSprite.texture == nullptr)
{
std::cout << "Could not create player texture! SDL_Error: " << SDL_GetError() << std::endl;
return false;
}
SDL_FreeSurface(surface);
gPlayerSprite.rect.x = SCREEN_WIDTH / 2;
gPlayerSprite.rect.y = SCREEN_HEIGHT / 2;
gPlayerSprite.rect.w = SPRITE_SIZE;
gPlayerSprite.rect.h = SPRITE_SIZE;
return true;
}
复制插入
接着定义一个碰撞检测函数:
cpp复制插入
bool Collides(SDL_Rect a, SDL_Rect b)
{
if ((a.x + a.w) > b.x && a.x < (b.x + b.w) && (a.y + a.h) > b.y && a.y < (b.y + b.h))
{
return true;
}
return false;
}
复制插入
定义一个精灵渲染函数:
cpp复制插入
void RenderSprite(SDL_Texture* texture, SDL_Rect rect)
{
SDL_RenderCopy(gRenderer, texture, nullptr, &rect);
}
复制插入
定义一个游戏循环:
cpp复制插入
void GameLoop()
{
while (!gQuitGame)
{
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
gQuitGame = true;
}
else if (e.type == SDL_KEYDOWN)
{
gKeyDown[e.key.keysym.scancode] = true;
}
else if (e.type == SDL_KEYUP)
{
gKeyDown[e.key.keysym.scancode] = false;
}
}
// 移动玩家精灵
if (gKeyDown[SDL_SCANCODE_LEFT])
{
gPlayerSprite.rect.x -= 5;
}
else if (gKeyDown[SDL_SCANCODE_RIGHT])
{
gPlayerSprite.rect.x += 5;
}
else if (gKeyDown[SDL_SCANCODE_UP])
{
gPlayerSprite.rect.y -= 5;
}
else if (gKeyDown[SDL_SCANCODE_DOWN])
{
gPlayerSprite.rect.y += 5;
}
// 碰撞检测
for (int i = 0; i < gSprites.size(); i++)
{
if (Collides(gPlayerSprite.rect, gSprites[i].rect))
{
std::cout << "Collision detected with sprite " << i << std::endl;
}
}
// 渲染游戏场景
SDL_SetRenderDrawColor(gRenderer, 255, 255, 255, 255);
SDL_RenderClear(gRenderer);
for (int i = 0; i < gSprites.size(); i++)
{
RenderSprite(gSprites[i].texture, gSprites[i].rect);
}
RenderSprite(gPlayerSprite.texture, gPlayerSprite.rect);
SDL_RenderPresent(gRenderer);
}
}
复制插入
最后在main函数中调用这些函数即可:
cpp复制插入
int main(int argc, char* args[])
{
if (!Init())
{
return -1;
}
GameLoop();
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow);
IMG_Quit();
SDL_Quit();
return 0;
}