首页 > 编程语言 >C++ 游戏开发技术文档

C++ 游戏开发技术文档

时间:2024-12-31 16:28:03浏览次数:3  
标签:int void Game C++ Player 开发技术 文档 renderer SDL

项目概述

本技术文档将指导开发一个使用 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         # 构建脚本

2. 安装依赖

安装 SDL2

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

  • Ubuntu / Debian:

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

    brew install sdl2
    
  • 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;
}

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

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();
}

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

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);
}

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

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;
}

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)

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

make
./game

5. 项目总结

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

标签:int,void,Game,C++,Player,开发技术,文档,renderer,SDL
From: https://blog.csdn.net/wds326598/article/details/144852966

相关文章

  • yolov5单目测距与相机标定流程和c++单目测距RKNN部署
    相机模型、相机标定及基于YOLOv5的单目测距实现1.前言注意此方法不需要预先知道物体尺寸,不需要参照物体!!!!在摄像头成像的过程中,物体反射的光线通过摄像头的凸透镜聚焦到成像器件上,形成一张二维图像。这一过程将三维世界中的物体转换为二维图像,导致深度信息丢失,因此单目摄......
  • LeetCode算法题 (比较含退格的字符串)Day9!!!C/C++
    https://leetcode.cn/problems/backspace-string-compare/description/一、题目描述给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。注意:如果对空文本输入退格字符,文本继续为空。二、相关知识点了解   ......
  • 使用libtorch对光度立体算法(photometric stereo)进行加速(C++)
    光度立体法是一种三维重建方法,在一些表面产品的缺陷检测有较多的应用(具有深度的缺陷),但是光度立体法需要对每个像素点都求解一个线性方程组L(n*3)*N(3*1)=I(n*1)(n为光源数),在cpu中计算是非常耗时的。本文借助libtorch,在gpu中通过卷积的方式,实现方程组的求解,耗时大约为cpu......
  • C++背单词
    题目描述:最近小明在学习月份的英文单词一月January二月February三月March四月April五月May六月June七月July八月August九月September十月October十一月November十二月December小明爸爸想测试一下天佑到底有没有学会他说出每个月份的前3个字母,小明就写出月份的......
  • C++书籍推荐
    本人收藏的一些电子版:阅读顺序C++primer基础ProfessionalC++基础+新特性现代C++语言核心特性解析更多新特性,STL并发库介绍C++Templates更多的模板语法STLCookbook现代STL用法并发编程实战深入并发ProgrammingwithC++20Concepts,Coroutines,Ranges,andm......
  • 【c++编程基础】std::unique的理解
    前言项目中想要实现一个功能,对于一个自定义类,包含坐标和类别等属性,按照到某个中心点的角度从小到大排序,如果角度相同,只保留距离中心点更近的元素,过程中用到了0-360的角度计算,自定义函数排序,以及删除重复元素等内容,故记录之。具体内容1.计算到中心点的角度;//计算点到中心点......
  • C++项目链接C语言动态库
     有C++项目B,有C语言动态链接库A,需要在B程序中链接A库。 我们知道C++运行环境可以直接运行C语言程序,但因为C++编译时对方法名的解析不同,所以要在C++项目中运行C语言程序,关键问题是需要告诉C++编译器,按照C语言的规范来编译指定的C代码。上面所述的“指定的C代码”,包括C++项目中......
  • 在 VC++ 里最大化并且前置窗口
    在VC++里最大化并且前置窗口在Windows系统中,如果需要通过编程的方式,前置显示另一个进程的某个窗口,你会发现,你遇到了一个麻烦。至少你会发现,仅仅使用SetForegroundWindow或SetWindowPos是没有效果的。下面是解决方案,在VC++2022、VC++2019,Window10和Wind......
  • Deepseek V3 —— 6850亿参数混合专家(MoE)架构开源大模型!Deepseek V3全方位客观评测
    地址:https://www.youtube.com/watch?v=BnoMTeKxwBQ......
  • 在css中,请说说你对文档流的理解
    在前端开发中,文档流(DocumentFlow)是一个非常重要的概念,尤其在CSS布局中。它描述了元素在HTML文档中的排列方式,即元素如何定位以及它们之间的相对位置关系。理解文档流对于掌握CSS布局和页面渲染至关重要。1.普通文档流(NormalFlow)普通文档流,也称为标准流或常规流,是HTML元素的默......