Game Programming in C++
Game Programming in C++ Chapter2 - BGSpriteComponent
skyho
2025. 9. 6. 21:51
반응형

책의 소스 코드를 직접 작성해보면서 정리한 글입니다. (실습환경: windows)
책 소스 코드: GitHub - gameprogcpp/code: Game Programming in C++ Code
1. BGSpriteComponent 역할(기능)
Sprite Component를 상속받아서 구현한다.
| 기능 | 설명 |
| 배경 스크롤 | Sprite Component에 스크롤 기능을 더한다 |
2. BGSpriteComponent 생성 동작
Sprite를 상속받았기 때문에, 기본적으로 동작이 유사하다.
- Step 1
부모인 Sprite 생성자를 통해서 Game Manager에 등록된다.
SpriteComponent::SpriteComponent(Actor* owner, int draw_order) : Component(owner), _draw_order(draw_order), _texture(nullptr),
_texture_width(0), _texture_height(0)
{
_owner->getGameManager()->addSprite(this);
}
- Step 2
Sprite 부모의 Component를 통해서 Actor에게 등록된다.
Component::Component(Actor* owner) : _owner(owner)
{
_owner->addComponent(this);
}
3. BGSpriteComponent.hpp
#pragma once
#include <vector>
#include "SpriteComponent.hpp"
struct BGTexture
{
SDL_Texture* texture;
float x, y;
};
class BGSpriteComponent : public SpriteComponent
{
public:
BGSpriteComponent(class Actor* owner, int draw_order = 10);
~BGSpriteComponent();
void setBGTextures(std::vector<SDL_Texture*>& textures);
void setScrollSpeed(float speed);
void virtual update(float delta_time) override;
void virtual draw(SDL_Renderer* renderer) override;
private:
std::vector<BGTexture> _bg_textures;
int _window_width;
int _window_height;
float _scroll_speed;
};
4. BGSpriteComponent.cpp
스크롤을 위해서 Sprite의 draw()를 사용하지 않고, override 했다.
update() 역시 override 했다. (Component와 Sprite에는 update 미구현)
#include "Actor.hpp"
#include "GameManager.hpp"
#include "BGSpriteComponent.hpp"
BGSpriteComponent::BGSpriteComponent(Actor* actor, int draw_order) : SpriteComponent(actor, draw_order), _scroll_speed(-1.0f)
{
_window_width = actor->getGameManager()->getWindowWidth();
_window_height = actor->getGameManager()->getWindowheight();
}
BGSpriteComponent::~BGSpriteComponent()
{
}
void BGSpriteComponent::update(float delta_time)
{
for (auto& bg : _bg_textures)
{
bg.x += _scroll_speed * delta_time;
if (bg.x < -_window_width)
{
bg.x = static_cast<float>((_bg_textures.size() - 1) * (_window_width - 1));
}
}
}
void BGSpriteComponent::setBGTextures(std::vector<SDL_Texture*>& textures)
{
for (int i = 0; i < textures.size(); i++)
{
BGTexture bg;
bg.texture = textures[i];
bg.x = i * _window_width;
bg.y = 0;
_bg_textures.emplace_back(bg);
}
}
void BGSpriteComponent::setScrollSpeed(float speed)
{
_scroll_speed = speed;
}
void BGSpriteComponent::draw(SDL_Renderer* renderer)
{
for (auto& bg_texture : _bg_textures)
{
SDL_FRect r;
r.w = static_cast<float>(_window_width);
r.h = static_cast<float>(_window_height);
r.x = bg_texture.x;
r.y = bg_texture.y;
// Draw this background
SDL_RenderTexture(
renderer,
bg_texture.texture,
nullptr,
&r
);
}
}
반응형