add miniaudio; add tilesheet; add audio test
This commit is contained in:
parent
d683587d58
commit
d1fbdb1898
|
@ -11,8 +11,10 @@ set(ENGINE_NAME tinyengine)
|
||||||
|
|
||||||
aux_source_directory(src/tinyengine ENGINE_SRC)
|
aux_source_directory(src/tinyengine ENGINE_SRC)
|
||||||
aux_source_directory(src/component ENGINE_SRC)
|
aux_source_directory(src/component ENGINE_SRC)
|
||||||
|
aux_source_directory(src/tinyengine/ecs ENGINE_SRC)
|
||||||
aux_source_directory(libs/glad/src ENGINE_SRC)
|
aux_source_directory(libs/glad/src ENGINE_SRC)
|
||||||
aux_source_directory(libs/stb_image ENGINE_SRC)
|
aux_source_directory(libs/stb_image ENGINE_SRC)
|
||||||
|
aux_source_directory(libs/miniaudio/ ENGINE_SRC)
|
||||||
|
|
||||||
add_library(${ENGINE_NAME} STATIC ${ENGINE_SRC})
|
add_library(${ENGINE_NAME} STATIC ${ENGINE_SRC})
|
||||||
|
|
||||||
|
@ -24,7 +26,7 @@ add_subdirectory(libs/glfw)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
${ENGINE_NAME}
|
${ENGINE_NAME}
|
||||||
PRIVATE include/tinyengine
|
PRIVATE include/tinyengine
|
||||||
PUBLIC libs/glad/include libs/stb_image # /usr/local/Cellar/glm/0.9.9.8/include
|
PUBLIC libs/glad/include libs/stb_image libs/miniaudio # /usr/local/Cellar/glm/0.9.9.8/include
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
|
@ -51,6 +53,7 @@ target_compile_options(
|
||||||
# space sector
|
# space sector
|
||||||
################
|
################
|
||||||
aux_source_directory(src/game GAME_SRC)
|
aux_source_directory(src/game GAME_SRC)
|
||||||
|
aux_source_directory(src/game/stages GAME_SRC)
|
||||||
add_executable(${PROJECT_NAME} ${GAME_SRC})
|
add_executable(${PROJECT_NAME} ${GAME_SRC})
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 481 B |
Binary file not shown.
After Width: | Height: | Size: 889 B |
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
|
||||||
|
class GameLogoScence final: public Scence {
|
||||||
|
public:
|
||||||
|
void OnInit() override;
|
||||||
|
void OnRender() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Camera camera;
|
||||||
|
float initTime_;
|
||||||
|
Unique<Sound> sound_;
|
||||||
|
bool soundPlayed_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "pch.hpp"
|
||||||
|
#include "tool.hpp"
|
||||||
|
#include "log.hpp"
|
||||||
|
#include "libmath.hpp"
|
||||||
|
|
||||||
|
class Audio final {
|
||||||
|
public:
|
||||||
|
static void Init();
|
||||||
|
static void Shutdown();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Sound final {
|
||||||
|
public:
|
||||||
|
Sound(const std::string& filename);
|
||||||
|
~Sound();
|
||||||
|
|
||||||
|
void Play();
|
||||||
|
void Pause();
|
||||||
|
void Stop();
|
||||||
|
void SetVolume(float volume);
|
||||||
|
void EnableLoop();
|
||||||
|
void DisableLoop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ma_sound sound_;
|
||||||
|
};
|
|
@ -13,7 +13,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mat44 viewMat_;
|
Mat44 viewMat_;
|
||||||
Point position_;
|
Point position_ = {0, 0};
|
||||||
Point scale_;
|
Point scale_ = {1, 1};
|
||||||
bool dirty_ = false;
|
bool dirty_ = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
_Pragma("once")
|
||||||
|
|
||||||
|
#include "pch.hpp"
|
||||||
|
#include "pool.hpp"
|
||||||
|
|
||||||
|
using ComponentId = unsigned int;
|
||||||
|
|
||||||
|
class Component {
|
||||||
|
public:
|
||||||
|
friend class Pool<Component>;
|
||||||
|
|
||||||
|
virtual ~Component() = default;
|
||||||
|
inline bool IsAlive() const { return alive_; }
|
||||||
|
virtual void Release() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool alive_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ComponentIdx final {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
static ComponentId Get() {
|
||||||
|
static_assert(std::is_base_of_v<Component, T> && !std::is_same_v<Component, T>);
|
||||||
|
static ComponentId id = count_ ++;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static ComponentId GetCount() { return count_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ComponentId count_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ComponentPool{
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::unordered_map<ComponentId, Pool<Component>> gComponentPool;
|
|
@ -0,0 +1,46 @@
|
||||||
|
_Pragma("once")
|
||||||
|
|
||||||
|
#include "pool.hpp"
|
||||||
|
#include "component.hpp"
|
||||||
|
|
||||||
|
class Entity;
|
||||||
|
|
||||||
|
class Context final {
|
||||||
|
public:
|
||||||
|
friend class Entity;
|
||||||
|
Entity* CreateEntity();
|
||||||
|
|
||||||
|
bool HasEntity(Entity* entity);
|
||||||
|
Pool<Entity>::ElemContainer& GetEntities();
|
||||||
|
void DestroyEntity(Entity* entity);
|
||||||
|
int GetEntityNum() const;
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
T* CreateComponent(Args... args) {
|
||||||
|
ComponentId id = ComponentIdx::Get<T>();
|
||||||
|
auto it = gComponentPool.find(id);
|
||||||
|
if (it != gComponentPool.end()) {
|
||||||
|
return it->second.Create<T>(args...);
|
||||||
|
} else {
|
||||||
|
gComponentPool[id] = Pool<Component>();
|
||||||
|
return gComponentPool[id].Create<T>(args...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void DestroyComponent(T* elem) {
|
||||||
|
DestroyComponentById(elem, ComponentIdx::Get<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void DestroyComponentById(Component* elem, int id) {
|
||||||
|
auto it = gComponentPool.find(id);
|
||||||
|
if (it != gComponentPool.end()) {
|
||||||
|
gComponentPool[id].Destroy(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Pool<Entity> entities_;
|
||||||
|
|
||||||
|
void onComponentUpdate(Entity*, ComponentId, Component*);
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
_Pragma("once")
|
||||||
|
|
||||||
|
#include "entity.hpp"
|
||||||
|
#include "component.hpp"
|
||||||
|
#include "context.hpp"
|
|
@ -0,0 +1,135 @@
|
||||||
|
_Pragma("once")
|
||||||
|
|
||||||
|
#include "pch.hpp"
|
||||||
|
#include "pool.hpp"
|
||||||
|
#include "component.hpp"
|
||||||
|
#include "context.hpp"
|
||||||
|
|
||||||
|
class Entity final {
|
||||||
|
public:
|
||||||
|
friend class Pool<Entity>;
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
void Add(Args... args) {
|
||||||
|
if (!alive_) {
|
||||||
|
std::cout << "Entity::Add(): entity is die, can't add component." << std::endl;
|
||||||
|
} else {
|
||||||
|
T* comp = context_->CreateComponent<T>(args...);
|
||||||
|
components_[ComponentIdx::Get<T>()] = comp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Init(Context* context) {
|
||||||
|
context_ = context;
|
||||||
|
}
|
||||||
|
inline void Release() {
|
||||||
|
components_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const T* Get() const {
|
||||||
|
if constexpr (!std::is_base_of_v<Component, T>) {
|
||||||
|
std::cout << "Entity::Get() const: the type T is not inherit from Component" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
|
return (T*)Get(ComponentIdx::Get<T>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component* Get(ComponentId id) const {
|
||||||
|
if (!alive_) {
|
||||||
|
std::cout << "Entity::Get(id) const: entity is die, can't get anything from it." << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto it = components_.find(id);
|
||||||
|
if (it == components_.end()) {
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* Use() {
|
||||||
|
if (!alive_) {
|
||||||
|
std::cout << "Entity::Use() const: entity is die, can't get anything from it." << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto it = components_.find(ComponentIdx::Get<T>());
|
||||||
|
if (it == components_.end()) {
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
|
return (T*)it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
void Replace(Args... args) {
|
||||||
|
if (!alive_) {
|
||||||
|
std::cout << "Entity::Replace() const: entity is die, can't replace component." << std::endl;
|
||||||
|
} else {
|
||||||
|
auto it = components_.find(ComponentIdx::Get<T>());
|
||||||
|
if (it != components_.end()) {
|
||||||
|
T* c = (T*)it->second;
|
||||||
|
c->Init(args...);
|
||||||
|
} else {
|
||||||
|
Add<T>(args...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Remove() {
|
||||||
|
Remove(ComponentIdx::Get<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Remove(ComponentId id) {
|
||||||
|
if (!alive_) {
|
||||||
|
std::cout << "Entity::Remove() const: entity is die, can't remove anything from it." << std::endl;
|
||||||
|
} else {
|
||||||
|
auto it = components_.find(id);
|
||||||
|
if (it != components_.end()) {
|
||||||
|
context_->DestroyComponentById(it->second, id);
|
||||||
|
components_.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ... Types>
|
||||||
|
bool Has() const {
|
||||||
|
if (!alive_) {
|
||||||
|
std::cout << "Entity::Has() const: entity is die, can't query." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return hasIter<Types ...>();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Has(ComponentId id) const {
|
||||||
|
return components_.find(id) != components_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Reset() {
|
||||||
|
for (ComponentId i = 0; i < ComponentIdx::GetCount(); i++) {
|
||||||
|
auto it = components_.find(i);
|
||||||
|
if (it != components_.end()) {
|
||||||
|
components_.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsAlive() const { return alive_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<ComponentId, Component*> components_;
|
||||||
|
bool alive_;
|
||||||
|
Context* context_ = nullptr;
|
||||||
|
|
||||||
|
template <typename T, typename ... Types>
|
||||||
|
bool hasIter() const {
|
||||||
|
if constexpr (sizeof...(Types) == 0) {
|
||||||
|
return Get<T>();
|
||||||
|
} else {
|
||||||
|
return Get<T>() && hasIter<Types ...>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -6,6 +6,7 @@
|
||||||
#include "inner_bmpfont.hpp"
|
#include "inner_bmpfont.hpp"
|
||||||
#include "event.hpp"
|
#include "event.hpp"
|
||||||
#include "tool.hpp"
|
#include "tool.hpp"
|
||||||
|
#include "audio.hpp"
|
||||||
|
|
||||||
class Engine final {
|
class Engine final {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -143,3 +143,20 @@ inline Mat44 CreateOrthoMat(float left, float right,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Point GetCenterAlign(const Rect& parent, const Size& child) {
|
||||||
|
return Point{parent.x + (parent.w - child.w) / 2.0f,
|
||||||
|
parent.y + (parent.h - child.h) / 2.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Mat44 CreateSRT(const Point& pos, const Point& scale, float degree) {
|
||||||
|
float theta = Radians(degree);
|
||||||
|
float sinTheta = std::sin(theta),
|
||||||
|
cosTheta = std::cos(theta);
|
||||||
|
return Mat44({
|
||||||
|
scale.x * cosTheta, scale.y * sinTheta, 0, pos.x,
|
||||||
|
-scale.x * sinTheta, scale.y * cosTheta, 0, pos.y,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "miniaudio.h"
|
||||||
|
|
||||||
#ifdef USE_GLM
|
#ifdef USE_GLM
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
#include "glm/gtc/matrix_transform.hpp"
|
#include "glm/gtc/matrix_transform.hpp"
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
_Pragma("once")
|
||||||
|
|
||||||
|
#include "pch.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory Pool.
|
||||||
|
* To use this pool, your class must have:
|
||||||
|
* * `bool alive_` member
|
||||||
|
* * let Pool be it's friend class
|
||||||
|
* * `void Init(...)` function to init your object
|
||||||
|
* * `void Release()` function to release your object
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class Pool {
|
||||||
|
public:
|
||||||
|
using ElemContainer = std::vector<T*>;
|
||||||
|
|
||||||
|
Pool(size_t capacity = 20) {
|
||||||
|
datas_.reserve(capacity);
|
||||||
|
}
|
||||||
|
~Pool() {
|
||||||
|
for (size_t i = 0; i < datas_.size(); i++)
|
||||||
|
delete datas_[i];
|
||||||
|
while (!cache_.empty()) {
|
||||||
|
delete cache_.top();
|
||||||
|
cache_.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, typename... Args>
|
||||||
|
U* Create(Args... args) {
|
||||||
|
static_assert(std::is_base_of_v<T, U>);
|
||||||
|
if (GetReuseableNum() > 0) {
|
||||||
|
U* elem = (U*)cache_.top();
|
||||||
|
elem->Init(args ...);
|
||||||
|
elem->alive_ = true;
|
||||||
|
cache_.pop();
|
||||||
|
datas_.push_back(elem);
|
||||||
|
return elem;
|
||||||
|
} else {
|
||||||
|
U* elem = new U;
|
||||||
|
datas_.push_back(elem);
|
||||||
|
elem->Init(args ...);
|
||||||
|
elem->alive_ = true;
|
||||||
|
return (U*)datas_.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy(T* elem) {
|
||||||
|
auto it = std::find(datas_.begin(),
|
||||||
|
datas_.end(),
|
||||||
|
elem);
|
||||||
|
if (it != datas_.end()) {
|
||||||
|
(*it)->alive_ = false;
|
||||||
|
(*it)->Release();
|
||||||
|
cache_.push(*it);
|
||||||
|
datas_.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T*>& GetElems() { return datas_; }
|
||||||
|
|
||||||
|
int GetNum() const { return datas_.size(); }
|
||||||
|
int GetReuseableNum() const { return cache_.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ElemContainer datas_;
|
||||||
|
std::stack<T*> cache_;
|
||||||
|
};
|
|
@ -5,9 +5,22 @@
|
||||||
#include "glhelpfunc.hpp"
|
#include "glhelpfunc.hpp"
|
||||||
#include "shader.hpp"
|
#include "shader.hpp"
|
||||||
#include "camera.hpp"
|
#include "camera.hpp"
|
||||||
|
#include "tilesheet.hpp"
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
Point pos;
|
||||||
|
Point texcoord;
|
||||||
|
};
|
||||||
|
|
||||||
class Renderer final {
|
class Renderer final {
|
||||||
public:
|
public:
|
||||||
|
enum FlipFlag {
|
||||||
|
NoFlip = 0,
|
||||||
|
Vertical = 0x01,
|
||||||
|
Horizontal = 0x02,
|
||||||
|
Both = 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static void SetClearColor(const Color&);
|
static void SetClearColor(const Color&);
|
||||||
|
@ -16,7 +29,21 @@ public:
|
||||||
static void DrawLine(const Point& p1, const Point& p2);
|
static void DrawLine(const Point& p1, const Point& p2);
|
||||||
static void DrawRect(const Rect& rect);
|
static void DrawRect(const Rect& rect);
|
||||||
static void FillRect(const Rect& rect);
|
static void FillRect(const Rect& rect);
|
||||||
static void DrawTexture(const Texture& texture, const Mat44& transform, const Color& color = Color{1, 1, 1, 1});
|
static void DrawTile(const Tile& tile,
|
||||||
|
const Point& pos,
|
||||||
|
const Size& size = {0, 0},
|
||||||
|
float degree = 0,
|
||||||
|
FlipFlag flip = NoFlip);
|
||||||
|
static void DrawTexture(const Texture* texture,
|
||||||
|
const Rect* srcrect,
|
||||||
|
const Point& pos,
|
||||||
|
const Size& size = Size{0, 0},
|
||||||
|
float degree = 0,
|
||||||
|
FlipFlag flip = NoFlip);
|
||||||
|
static void DrawTexture(const Texture* texture,
|
||||||
|
const Rect* rect,
|
||||||
|
const Mat44& transform,
|
||||||
|
const Color& color = Color{1, 1, 1, 1});
|
||||||
static void SetViewport(int x, int y, int w, int h);
|
static void SetViewport(int x, int y, int w, int h);
|
||||||
static const Color& GetDrawColor();
|
static const Color& GetDrawColor();
|
||||||
static void SetCamera(Camera& camera);
|
static void SetCamera(Camera& camera);
|
||||||
|
@ -24,4 +51,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Color color_;
|
static Color color_;
|
||||||
|
|
||||||
|
static void drawRectFrag(const Texture* texture,
|
||||||
|
const std::array<Vertex, 6>& vertices,
|
||||||
|
const Mat44& transform,
|
||||||
|
const Color& color);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "texture.hpp"
|
||||||
|
|
||||||
|
struct Tile {
|
||||||
|
Texture* texture;
|
||||||
|
Rect rect;
|
||||||
|
Size size;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TileSheet final {
|
||||||
|
public:
|
||||||
|
TileSheet(const std::string& filename, int x, int y);
|
||||||
|
|
||||||
|
const Tile GetTile(int x, int y);
|
||||||
|
Texture* GetTexture() { return texture_.get(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Unique<Texture> texture_;
|
||||||
|
Size size_;
|
||||||
|
};
|
|
@ -9,3 +9,5 @@
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
#include "tool.hpp"
|
#include "tool.hpp"
|
||||||
#include "inner_bmpfont.hpp"
|
#include "inner_bmpfont.hpp"
|
||||||
|
#include "audio.hpp"
|
||||||
|
#include "tilesheet.hpp"
|
||||||
|
|
|
@ -13,3 +13,7 @@ using Ref = std::shared_ptr<T>;
|
||||||
#else
|
#else
|
||||||
#define FATAL_ERROR(msg)
|
#define FATAL_ERROR(msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inline float GetTime() {
|
||||||
|
return glfwGetTime();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef GAME_DEBUG
|
||||||
|
#define MA_DEBUG_OUTPUT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MA_ENABLE_ONLY_SPECIFIC_BACKENDS
|
||||||
|
#define MA_ENABLE_COREAUDIO
|
||||||
|
#define MA_NO_FLAC
|
||||||
|
#define MA_NO_MP3
|
||||||
|
#define MA_NO_ENCODING
|
||||||
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
|
#include "miniaudio.h"
|
File diff suppressed because it is too large
Load Diff
1
pack.sh
1
pack.sh
|
@ -7,3 +7,4 @@ fi
|
||||||
mkdir output
|
mkdir output
|
||||||
cp ./build/SpaceSector output
|
cp ./build/SpaceSector output
|
||||||
cp -r ./assets output
|
cp -r ./assets output
|
||||||
|
rm -rf ./output/assets/test
|
||||||
|
|
|
@ -1,24 +1,3 @@
|
||||||
#include "tinyengine/engine.hpp"
|
#include "game/stages/gamelogo.hpp"
|
||||||
#include "tinyengine/event.hpp"
|
|
||||||
#include "tinyengine/camera.hpp"
|
|
||||||
|
|
||||||
class WelcomeScene final: public Scence {
|
RUN_WINDOW("Space Sector", 1024, 720, GameLogoScence)
|
||||||
public:
|
|
||||||
void OnInit() override {
|
|
||||||
Log("init scence");
|
|
||||||
camera.Move(Point{0, 0});
|
|
||||||
camera.Scale(Point{1, 1});
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnUpdate(float dt) override {
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnQuit() override {
|
|
||||||
Log("quit scence");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Camera camera;
|
|
||||||
};
|
|
||||||
|
|
||||||
RUN_WINDOW("Space Sector", 1024, 720, WelcomeScene)
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "game/stages/gamelogo.hpp"
|
||||||
|
|
||||||
|
constexpr float TitlePixel = 40.0f;
|
||||||
|
constexpr float AuthorInfoPixel = 20.0f;
|
||||||
|
const char* Title = "1M GAMES DEV";
|
||||||
|
const char* AuthorInfo = "MADE BY VISUALGMQ";
|
||||||
|
|
||||||
|
void GameLogoScence::OnInit() {
|
||||||
|
Renderer::SetClearColor(Color{0, 0, 0, 255});
|
||||||
|
initTime_ = GetTime();
|
||||||
|
sound_.reset(new Sound("assets/1mgame_sound.wav"));
|
||||||
|
soundPlayed_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameLogoScence::OnRender() {
|
||||||
|
float duration = GetTime() - initTime_;
|
||||||
|
if (duration > 2 && !soundPlayed_) {
|
||||||
|
sound_->Play();
|
||||||
|
soundPlayed_ = true;
|
||||||
|
}
|
||||||
|
if (duration < 3) {
|
||||||
|
engine.GetInnerBmpFont().Render(Title,
|
||||||
|
TitlePixel,
|
||||||
|
Point{0, -25} +
|
||||||
|
GetCenterAlign(Rect{0, 0,
|
||||||
|
engine.GetWindowSize().w,
|
||||||
|
engine.GetWindowSize().h},
|
||||||
|
Size{TitlePixel * strlen(Title), TitlePixel}),
|
||||||
|
Color{1, 1, 1, 1});
|
||||||
|
engine.GetInnerBmpFont().Render(AuthorInfo,
|
||||||
|
AuthorInfoPixel,
|
||||||
|
Point{0, 25} +
|
||||||
|
GetCenterAlign(Rect{0, 0,
|
||||||
|
engine.GetWindowSize().w,
|
||||||
|
engine.GetWindowSize().h},
|
||||||
|
Size{AuthorInfoPixel * strlen(AuthorInfo), AuthorInfoPixel}),
|
||||||
|
Color{0.5, 0.5, 0.5, 1});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "audio.hpp"
|
||||||
|
|
||||||
|
ma_engine AudioEngine;
|
||||||
|
|
||||||
|
void Audio::Init() {
|
||||||
|
ma_result result;
|
||||||
|
result = ma_engine_init(NULL, &AudioEngine);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
FATAL_ERROR("sound system init failed");
|
||||||
|
}
|
||||||
|
ma_engine_start(&AudioEngine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audio::Shutdown() {
|
||||||
|
ma_engine_stop(&AudioEngine);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sound::Sound(const std::string& filename) {
|
||||||
|
ma_result result;
|
||||||
|
result = ma_sound_init_from_file(&AudioEngine,
|
||||||
|
filename.c_str(),
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
&sound_);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
Log("%s sound load failed!", filename.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound::Play() {
|
||||||
|
ma_sound_start(&sound_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound::Pause() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound::Stop() {
|
||||||
|
ma_sound_stop(&sound_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sound::~Sound() {
|
||||||
|
ma_sound_uninit(&sound_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound::SetVolume(float volume) {
|
||||||
|
ma_sound_set_volume(&sound_, Clamp(0.0f, 10.0f, volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound::EnableLoop() {
|
||||||
|
ma_sound_set_looping(&sound_, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sound::DisableLoop() {
|
||||||
|
ma_sound_set_looping(&sound_, false);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "ecs/component.hpp"
|
||||||
|
#include "ecs/context.hpp"
|
||||||
|
|
||||||
|
ComponentId ComponentIdx::count_ = 0;
|
||||||
|
|
||||||
|
std::unordered_map<ComponentId, Pool<Component>> gComponentPool;
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "ecs/context.hpp"
|
||||||
|
#include "ecs/entity.hpp"
|
||||||
|
|
||||||
|
Pool<Entity>::ElemContainer& Context::GetEntities() {
|
||||||
|
return entities_.GetElems();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::DestroyEntity(Entity* entity) {
|
||||||
|
for (size_t i = 0; i < ComponentIdx::GetCount(); i++) {
|
||||||
|
if (entity->Has(i)) {
|
||||||
|
DestroyComponentById(entity->Get(i), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entities_.Destroy(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Context::GetEntityNum() const {
|
||||||
|
return entities_.GetNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Context::HasEntity(Entity* entity) {
|
||||||
|
auto& entities = entities_.GetElems();
|
||||||
|
return std::find(entities.begin(), entities.end(), entity) !=
|
||||||
|
entities.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity* Context::CreateEntity() {
|
||||||
|
return entities_.Create(this);
|
||||||
|
}
|
|
@ -39,7 +39,11 @@ void Engine::Init(const std::string& title, const Size& size, Scence* scence) {
|
||||||
Renderer::SetViewport(0, 0, width, height);
|
Renderer::SetViewport(0, 0, width, height);
|
||||||
|
|
||||||
Renderer::Init();
|
Renderer::Init();
|
||||||
|
Log("render system init OK");
|
||||||
Renderer::SetClearColor(Color{0.1, 0.1, 0.1, 1});
|
Renderer::SetClearColor(Color{0.1, 0.1, 0.1, 1});
|
||||||
|
|
||||||
|
Audio::Init();
|
||||||
|
Log("sound system init OK");
|
||||||
|
|
||||||
scence_.reset(scence);
|
scence_.reset(scence);
|
||||||
scence_->OnInit();
|
scence_->OnInit();
|
||||||
|
@ -75,6 +79,7 @@ void Engine::PollEvent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::Shutdown() {
|
void Engine::Shutdown() {
|
||||||
|
Audio::Shutdown();
|
||||||
if (scence_)
|
if (scence_)
|
||||||
scence_->OnQuit();
|
scence_->OnQuit();
|
||||||
glfwDestroyWindow(window_);
|
glfwDestroyWindow(window_);
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "libmath.hpp"
|
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
Color Renderer::color_ = {255, 255, 255, 255};
|
Color Renderer::color_ = {255, 255, 255, 255};
|
||||||
|
|
||||||
struct Vertex {
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float texCoordX;
|
|
||||||
float texCoordY;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLuint vbo;
|
GLuint vbo;
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
|
@ -20,16 +12,15 @@ struct {
|
||||||
Unique<Texture> WhiteTexture;
|
Unique<Texture> WhiteTexture;
|
||||||
Camera* camera = nullptr;
|
Camera* camera = nullptr;
|
||||||
|
|
||||||
Vertex rectVertices[6] = {
|
const std::array<Vertex, 6> vertices = {
|
||||||
{0.0f, 1.0f, 0.0f, 1.0f},
|
Vertex{-0.5f, 0.5f, 0.0f, 1.0f},
|
||||||
{1.0f, 0.0f, 1.0f, 0.0f},
|
Vertex{ 0.5f,-0.5f, 1.0f, 0.0f},
|
||||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
Vertex{-0.5f,-0.5f, 0.0f, 0.0f},
|
||||||
|
|
||||||
{0.0f, 1.0f, 0.0f, 1.0f},
|
Vertex{-0.5f, 0.5f, 0.0f, 1.0f},
|
||||||
{1.0f, 1.0f, 1.0f, 1.0f},
|
Vertex{ 0.5f, 0.5f, 1.0f, 1.0f},
|
||||||
{1.0f, 0.0f, 1.0f, 0.0f}
|
Vertex{ 0.5f,-0.5f, 1.0f, 0.0f}
|
||||||
};
|
};
|
||||||
|
|
||||||
} Context;
|
} Context;
|
||||||
|
|
||||||
void createWhiteTexture() {
|
void createWhiteTexture() {
|
||||||
|
@ -86,6 +77,8 @@ void setShaderOrtho() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Init() {
|
void Renderer::Init() {
|
||||||
|
GL_CALL(glEnable(GL_BLEND));
|
||||||
|
GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
createWhiteTexture();
|
createWhiteTexture();
|
||||||
initRenderContext();
|
initRenderContext();
|
||||||
initShader("assets/shaders/vertex.shader",
|
initShader("assets/shaders/vertex.shader",
|
||||||
|
@ -128,41 +121,93 @@ void Renderer::DrawRect(const Rect& rect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::FillRect(const Rect& rect) {
|
void Renderer::FillRect(const Rect& rect) {
|
||||||
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, Context.vbo));
|
drawRectFrag(nullptr,
|
||||||
GL_CALL(glBindVertexArray(Context.vao));
|
Context.vertices,
|
||||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER,
|
CreateSRT(Point{rect.x + rect.w / 2, rect.y + rect.h / 2},
|
||||||
sizeof(Context.rectVertices),
|
Point{rect.w, rect.h},
|
||||||
Context.rectVertices,
|
0),
|
||||||
GL_STATIC_DRAW));
|
Renderer::color_);
|
||||||
Context.shader->Use();
|
|
||||||
Context.WhiteTexture->Bind();
|
|
||||||
Context.shader->SetMat4("model", Mat44({
|
|
||||||
rect.w, 0, 0, rect.x,
|
|
||||||
0, rect.h, 0, rect.y,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
0, 0, 0, 1,
|
|
||||||
}));
|
|
||||||
Context.shader->SetInt("Texture", 0);
|
|
||||||
GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawTexture(const Texture& texture,
|
void Renderer::DrawTile(const Tile& tile,
|
||||||
|
const Point& pos,
|
||||||
|
const Size& size,
|
||||||
|
float degree,
|
||||||
|
Renderer::FlipFlag flip) {
|
||||||
|
if (size.w == 0 && size.h == 0) {
|
||||||
|
DrawTexture(tile.texture, &tile.rect, pos, tile.size, degree, flip);
|
||||||
|
} else {
|
||||||
|
DrawTexture(tile.texture, &tile.rect, pos, size, degree, flip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::DrawTexture(const Texture* texture,
|
||||||
|
const Rect* srcrect,
|
||||||
|
const Point& pos,
|
||||||
|
const Size& size,
|
||||||
|
float degree,
|
||||||
|
FlipFlag flip) {
|
||||||
|
if (texture) {
|
||||||
|
auto scale = size;
|
||||||
|
if (size.w == 0 && size.h == 0) {
|
||||||
|
scale = texture->GetSize();
|
||||||
|
}
|
||||||
|
if (flip & Vertical) {
|
||||||
|
scale.h *= -1;
|
||||||
|
}
|
||||||
|
if (flip & Horizontal) {
|
||||||
|
scale.w *= -1;
|
||||||
|
}
|
||||||
|
DrawTexture(texture, srcrect, CreateSRT(pos, scale, degree));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::DrawTexture(const Texture* texture,
|
||||||
|
const Rect* rect,
|
||||||
const Mat44& transform,
|
const Mat44& transform,
|
||||||
const Color& color) {
|
const Color& color) {
|
||||||
|
if (!texture) return;
|
||||||
|
auto& size = texture->GetSize();
|
||||||
|
if (!rect) {
|
||||||
|
drawRectFrag(texture, Context.vertices, transform, color);
|
||||||
|
} else {
|
||||||
|
auto vertices = Context.vertices;
|
||||||
|
vertices[0].texcoord = Point{rect->x / size.w,
|
||||||
|
(rect->y + rect->h) / size.h};
|
||||||
|
vertices[1].texcoord = Point{(rect->x + rect->w) / size.w,
|
||||||
|
rect->y / size.h};
|
||||||
|
vertices[2].texcoord = Point{rect->x / size.w, rect->y / size.h};
|
||||||
|
vertices[3].texcoord = vertices[0].texcoord;
|
||||||
|
vertices[4].texcoord = Point{(rect->x + rect->w) / size.w,
|
||||||
|
(rect->y + rect->h) / size.h};
|
||||||
|
vertices[5].texcoord = vertices[1].texcoord;
|
||||||
|
drawRectFrag(texture, vertices, transform, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawRectFrag(const Texture* texture,
|
||||||
|
const std::array<Vertex, 6>& vertices,
|
||||||
|
const Mat44& transform,
|
||||||
|
const Color& color) {
|
||||||
Context.shader->Use();
|
Context.shader->Use();
|
||||||
Context.shader->SetInt("Texture", 0);
|
Context.shader->SetInt("Texture", 0);
|
||||||
texture.Bind(0);
|
if (texture) {
|
||||||
|
texture->Bind(0);
|
||||||
|
} else {
|
||||||
|
Context.WhiteTexture->Bind(0);
|
||||||
|
}
|
||||||
|
|
||||||
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, Context.vbo));
|
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, Context.vbo));
|
||||||
GL_CALL(glBindVertexArray(Context.vao));
|
GL_CALL(glBindVertexArray(Context.vao));
|
||||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER,
|
GL_CALL(glBufferData(GL_ARRAY_BUFFER,
|
||||||
sizeof(Context.rectVertices),
|
sizeof(Vertex) * vertices.size(),
|
||||||
Context.rectVertices,
|
vertices.data(),
|
||||||
GL_STATIC_DRAW));
|
GL_STATIC_DRAW));
|
||||||
|
|
||||||
Renderer::SetDrawColor(color);
|
Renderer::SetDrawColor(color);
|
||||||
Context.shader->SetMat4("model", transform);
|
Context.shader->SetMat4("model", transform);
|
||||||
GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
|
GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Clear() {
|
void Renderer::Clear() {
|
||||||
|
|
|
@ -3,17 +3,22 @@
|
||||||
Texture::Texture(const std::string& filename) {
|
Texture::Texture(const std::string& filename) {
|
||||||
int w, h, channels;
|
int w, h, channels;
|
||||||
unsigned char* data = stbi_load(filename.c_str(), &w, &h, &channels, 0);
|
unsigned char* data = stbi_load(filename.c_str(), &w, &h, &channels, 0);
|
||||||
if (channels == 4) {
|
if (!data) {
|
||||||
format_ = GL_RGBA;
|
Log("%s load failed!", filename.c_str());
|
||||||
}else if (channels == 3) {
|
texture_ = 0;
|
||||||
format_ = GL_RGB;
|
} else {
|
||||||
|
if (channels == 4) {
|
||||||
|
format_ = GL_RGBA;
|
||||||
|
}else if (channels == 3) {
|
||||||
|
format_ = GL_RGB;
|
||||||
|
}
|
||||||
|
size_.x = w;
|
||||||
|
size_.y = h;
|
||||||
|
|
||||||
|
createFromPixels(data, w, h, format_);
|
||||||
|
|
||||||
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
size_.x = w;
|
|
||||||
size_.y = h;
|
|
||||||
|
|
||||||
createFromPixels(data, w, h, format_);
|
|
||||||
|
|
||||||
stbi_image_free(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(const unsigned char* data, int w, int h, GLenum format) {
|
Texture::Texture(const unsigned char* data, int w, int h, GLenum format) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "tilesheet.hpp"
|
||||||
|
|
||||||
|
TileSheet::TileSheet(const std::string& filename, int x, int y) {
|
||||||
|
texture_.reset(new Texture(filename));
|
||||||
|
size_.x = x;
|
||||||
|
size_.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Tile TileSheet::GetTile(int x, int y) {
|
||||||
|
Size size = texture_->GetSize() / size_;
|
||||||
|
return {texture_.get(),
|
||||||
|
Rect{size.w * x, size.h * y, size.w, size.h},
|
||||||
|
size};
|
||||||
|
}
|
|
@ -9,3 +9,4 @@ endmacro()
|
||||||
AddTest(math math.cpp ${ENGINE_NAME})
|
AddTest(math math.cpp ${ENGINE_NAME})
|
||||||
AddTest(renderer renderer.cpp ${ENGINE_NAME})
|
AddTest(renderer renderer.cpp ${ENGINE_NAME})
|
||||||
AddTest(innerBmpFont innerBmpFont.cpp ${ENGINE_NAME})
|
AddTest(innerBmpFont innerBmpFont.cpp ${ENGINE_NAME})
|
||||||
|
AddTest(audio audio.cpp ${ENGINE_NAME})
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "tinyengine/tinyengine.hpp"
|
||||||
|
|
||||||
|
class TestAudio : public Scence {
|
||||||
|
public:
|
||||||
|
void OnInit() override {
|
||||||
|
sound_.reset(new Sound("assets/test/goodbyESAKA.wav"));
|
||||||
|
sound_->SetVolume(10);
|
||||||
|
sound_->Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRender() override {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnQuit() override {
|
||||||
|
sound_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Unique<Sound> sound_;
|
||||||
|
};
|
||||||
|
|
||||||
|
RUN_WINDOW("test renderer", 1024, 720, TestAudio)
|
|
@ -5,7 +5,16 @@ class TestRenderer: public Scence {
|
||||||
public:
|
public:
|
||||||
void OnInit() override {
|
void OnInit() override {
|
||||||
dirt_.reset(new Texture("assets/test/dirt.png"));
|
dirt_.reset(new Texture("assets/test/dirt.png"));
|
||||||
start_.reset(new Texture("assets/test/start.bmp"));
|
start_.reset(new Texture("assets/test/start.png"));
|
||||||
|
tilesheet_.reset(new TileSheet("assets/test/tilesheet.png", 8, 1));
|
||||||
|
degree_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUpdate(float second) override {
|
||||||
|
if (degree_ > 360) {
|
||||||
|
degree_ -= 360;
|
||||||
|
}
|
||||||
|
degree_ += 40 * second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnRender() override {
|
void OnRender() override {
|
||||||
|
@ -15,14 +24,26 @@ public:
|
||||||
|
|
||||||
Renderer::SetDrawColor(Color{0, 1, 0});
|
Renderer::SetDrawColor(Color{0, 1, 0});
|
||||||
Renderer::FillRect(Rect{100, 100, 50, 75});
|
Renderer::FillRect(Rect{100, 100, 50, 75});
|
||||||
|
|
||||||
Renderer::DrawTexture(*dirt_, CreateTextureTransform(dirt_->GetSize(), Point{50, 50}));
|
Renderer::DrawTexture(dirt_.get(), nullptr, CreateSRT(Point{50, 50}, dirt_->GetSize(), 0));
|
||||||
Renderer::DrawTexture(*start_, CreateTextureTransform(dirt_->GetSize(), Point{100, 50}));
|
Renderer::DrawTexture(start_.get(), nullptr, Point{100, 50}, Size{0, 0}, degree_);
|
||||||
|
|
||||||
|
Renderer::DrawTexture(tilesheet_->GetTexture(), nullptr, Point{100, 100});
|
||||||
|
Renderer::DrawTexture(tilesheet_->GetTexture(), nullptr, Point{100, 116}, Size{0, 0}, 0, Renderer::Horizontal);
|
||||||
|
Renderer::DrawTexture(tilesheet_->GetTexture(), nullptr, Point{100, 132}, Size{0, 0}, 0, Renderer::Vertical);
|
||||||
|
Renderer::DrawTexture(tilesheet_->GetTexture(), nullptr, Point{100, 148}, Size{0, 0}, 0, Renderer::Both);
|
||||||
|
Size tileSize = {16, 16};
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
Rect rect{i * 16.0f, 0, 16, 16};
|
||||||
|
Renderer::DrawTile(tilesheet_->GetTile(i, 0), Point{50 + 16.0f * i, 200}, Size{0, 0}, degree_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Unique<Texture> dirt_;
|
Unique<Texture> dirt_;
|
||||||
Unique<Texture> start_;
|
Unique<Texture> start_;
|
||||||
|
Unique<TileSheet> tilesheet_;
|
||||||
|
float degree_;
|
||||||
};
|
};
|
||||||
|
|
||||||
RUN_WINDOW("test renderer", 1024, 720, TestRenderer)
|
RUN_WINDOW("test renderer", 1024, 720, TestRenderer)
|
||||||
|
|
Reference in New Issue