讯飞AI开发者社区 C++ 游戏开发技术文档

C++ 游戏开发技术文档

项目概述本技术文档将指导开发一个使用 C++ 构建的简易 2D 游戏框架。该游戏是一个玩家控制角色收集随机生成的道具的小游戏,核心功能包括:游戏循环:支持帧率控制和逻辑更新。玩家控制:通过键盘控制角色上下左右移动。道具生成与收集:随机生成道具,玩家接触道具后得分。基本碰撞检测:检测角色与道具的碰撞。开发环境...

项目概述

本技术文档将指导开发一个使用 C++ 构建的简易 2D 游戏框架。该游戏是一个玩家控制角色收集随机生成的道具的小游戏,核心功能包括:

  1. 游戏循环:支持帧率控制和逻辑更新。
  2. 玩家控制:通过键盘控制角色上下左右移动。
  3. 道具生成与收集:随机生成道具,玩家接触道具后得分。
  4. 基本碰撞检测:检测角色与道具的碰撞。

开发环境:

  • 语言:C++
  • 工具库:使用 SDL2(Simple DirectMedia Layer)进行图形绘制和输入处理。

1. 项目结构

|-- Game/
    |-- main.cpp         # 程序入口
    |-- Game.h           # 游戏核心逻辑声明
    |-- Game.cpp         # 游戏核心逻辑实现
    |-- Player.h         # 玩家类声明
    |-- Player.cpp       # 玩家类实现
    |-- Item.h           # 道具类声明
    |-- Item.cpp         # 道具类实现
    |-- Makefile         # 构建脚本
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

2. 安装依赖

安装 SDL2

在使用该项目之前,需要确保安装了 SDL2 库。以下是在不同操作系统上安装 SDL2 的方法:

  • Ubuntu / Debian:

    sudo apt update
    sudo apt install libsdl2-dev
    
    • 1.
    • 2.
  • MacOS (使用 Homebrew):

    brewinstall sdl2
    
    • 1.
  • Windows:
    下载 SDL2 库并配置 Visual Studio 或 MinGW。


3. 代码实现

3.1 游戏主循环

main.cpp

#include "Game.h"

int main(int argc, char* argv[]) {
    Game game;
    if (game.init("2D Game", 800, 600)) {
        game.run();
    }
    game.cleanup();
    return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

3.2 核心游戏类

Game.h

#ifndef GAME_H
#define GAME_H

#include <SDL2/SDL.h>
#include "Player.h"
#include "Item.h"
#include <vector>

class Game {
public:
    bool init(const char* title, int width, int height);
    void run();
    void cleanup();

private:
    void handleEvents();
    void update();
    void render();

    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;
    bool isRunning = true;

    Player* player = nullptr;
    std::vector<Item*> items;
};

#endif // GAME_H
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

Game.cpp

#include "Game.h"
#include <cstdlib>
#include <ctime>

bool Game::init(const char* title, int width, int height) {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) return false;

    window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN);
    if (!window) return false;

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (!renderer) return false;

    player = new Player(width / 2, height / 2);
    srand(static_cast<unsigned>(time(0)));

    for (int i = 0; i < 5; ++i) {
        items.push_back(new Item(rand() % width, rand() % height));
    }

    return true;
}

void Game::run() {
    while (isRunning) {
        handleEvents();
        update();
        render();
        SDL_Delay(16); // 控制帧率
    }
}

void Game::handleEvents() {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            isRunning = false;
        }
    }
    player->handleInput();
}

void Game::update() {
    for (auto& item : items) {
        if (player->checkCollision(*item)) {
            item->resetPosition();
        }
    }
}

void Game::render() {
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    player->render(renderer);
    for (auto& item : items) {
        item->render(renderer);
    }

    SDL_RenderPresent(renderer);
}

void Game::cleanup() {
    delete player;
    for (auto& item : items) {
        delete item;
    }
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.

3.3 玩家类

Player.h

#ifndef PLAYER_H
#define PLAYER_H

#include <SDL2/SDL.h>

class Player {
public:
    Player(int x, int y);
    void handleInput();
    void render(SDL_Renderer* renderer);
    bool checkCollision(const SDL_Rect& other);

private:
    SDL_Rect rect;
    int speed = 5;
};

#endif // PLAYER_H
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

Player.cpp

#include "Player.h"

Player::Player(int x, int y) {
    rect = {x, y, 50, 50};
}

void Player::handleInput() {
    const Uint8* keystate = SDL_GetKeyboardState(nullptr);
    if (keystate[SDL_SCANCODE_UP]) rect.y -= speed;
    if (keystate[SDL_SCANCODE_DOWN]) rect.y += speed;
    if (keystate[SDL_SCANCODE_LEFT]) rect.x -= speed;
    if (keystate[SDL_SCANCODE_RIGHT]) rect.x += speed;
}

void Player::render(SDL_Renderer* renderer) {
    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
    SDL_RenderFillRect(renderer, &rect);
}

bool Player::checkCollision(const SDL_Rect& other) {
    return SDL_HasIntersection(&rect, &other);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

3.4 道具类

Item.h

#ifndef ITEM_H
#define ITEM_H

#include <SDL2/SDL.h>

class Item {
public:
    Item(int x, int y);
    void render(SDL_Renderer* renderer);
    void resetPosition();

    const SDL_Rect& getRect() const;

private:
    SDL_Rect rect;
};

#endif // ITEM_H
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

Item.cpp

#include "Item.h"
#include <cstdlib>

Item::Item(int x, int y) {
    rect = {x, y, 30, 30};
}

void Item::render(SDL_Renderer* renderer) {
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    SDL_RenderFillRect(renderer, &rect);
}

void Item::resetPosition() {
    rect.x = rand() % 800;
    rect.y = rand() % 600;
}

const SDL_Rect& Item::getRect() const {
    return rect;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

4. 编译与运行

Makefile

CXX= g++
CXXFLAGS = -std=c++17 -Wall -I/usr/include/SDL2
LDFLAGS = -lSDL2

SRC = main.cpp Game.cpp Player.cpp Item.cpp
OBJ = $(SRC:.cpp=.o)
TARGET = game

all: $(TARGET)

$(TARGET): $(OBJ)
	$(CXX) $(OBJ) -o $(TARGET) $(LDFLAGS)

clean:
	rm -f $(OBJ) $(TARGET)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

运行以下命令以编译并运行游戏:

make
./game
  • 1.
  • 2.

5. 项目总结

  • 学习了 SDL2 的基本使用,包括窗口创建、渲染、事件处理等。
  • 实现了一个简单的游戏循环以及核心的碰撞检测逻辑。
  • 可扩展方向:增加计分功能、时间限制、更多关卡等。
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐

  • 浏览量 849
  • 收藏 0
  • 0

所有评论(0)

查看更多评论 
已为社区贡献24条内容