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

 

반응형