v2
This commit is contained in:
93
src/assets.cpp
Normal file
93
src/assets.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "assets.hpp"
|
||||
|
||||
AssetManager::AssetManager() {
|
||||
}
|
||||
|
||||
AssetManager::~AssetManager() {
|
||||
clearAssets();
|
||||
}
|
||||
|
||||
void AssetManager::load(const std::string& name, const std::string& filePath) {
|
||||
SDL_Surface* surface = IMG_Load(filePath.c_str());
|
||||
if (!surface) {
|
||||
SDL_Log("Failed to load image %s: %s", filePath.c_str(), SDL_GetError());
|
||||
}
|
||||
assets[name] = surface;
|
||||
}
|
||||
|
||||
SDL_Surface* AssetManager::getAsset(const std::string& name) const {
|
||||
auto it = assets.find(name);
|
||||
if (it != assets.end()) {
|
||||
return it->second;
|
||||
}
|
||||
SDL_Log("Asset %s not found", name.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AssetManager::unloadAsset(const std::string& name) {
|
||||
auto it = assets.find(name);
|
||||
if (it != assets.end()) {
|
||||
SDL_DestroySurface(it->second);
|
||||
assets.erase(it);
|
||||
}
|
||||
SDL_Log("Asset %s not found", name.c_str());
|
||||
}
|
||||
|
||||
void AssetManager::clearAssets() {
|
||||
for (auto& pair : assets) {
|
||||
SDL_DestroySurface(pair.second);
|
||||
}
|
||||
assets.clear();
|
||||
}
|
||||
|
||||
TileMap::TileMap(AssetManager& assetManager)
|
||||
: assetManager(assetManager) {
|
||||
}
|
||||
|
||||
TileMap::~TileMap() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void TileMap::addTile(const std::string& name, const Tile& tile) {
|
||||
tiles[name] = tile;
|
||||
}
|
||||
|
||||
Tile TileMap::getTile(const std::string& name) const {
|
||||
auto it = tiles.find(name);
|
||||
if (it != tiles.end()) {
|
||||
return it->second;
|
||||
}
|
||||
SDL_Log("Tile %s not found", name.c_str());
|
||||
return Tile(); // Return an empty Tile
|
||||
}
|
||||
|
||||
SDL_Surface* TileMap::getTileAsset(const std::string& name) const {
|
||||
auto it = tiles.find(name);
|
||||
if (it != tiles.end()) {
|
||||
return assetManager.getAsset(it->second.assetName);
|
||||
}
|
||||
SDL_Log("Tile %s not found", name.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Rect TileMap::getTileRect(const std::string& name) const {
|
||||
auto it = tiles.find(name);
|
||||
if (it != tiles.end()) {
|
||||
return Rect(it->second.srcRect);
|
||||
}
|
||||
SDL_Log("Tile %s not found", name.c_str());
|
||||
return Rect(); // Return an empty Rect
|
||||
}
|
||||
|
||||
void TileMap::removeTile(const std::string& name) {
|
||||
auto it = tiles.find(name);
|
||||
if (it != tiles.end()) {
|
||||
tiles.erase(it);
|
||||
} else {
|
||||
SDL_Log("Tile %s not found", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void TileMap::clear() {
|
||||
tiles.clear();
|
||||
}
|
180
src/engine.cpp
180
src/engine.cpp
@@ -1,78 +1,138 @@
|
||||
#include "engine.h"
|
||||
#include "engine.hpp"
|
||||
|
||||
Engine::Engine(std::string title, int width, int height)
|
||||
{
|
||||
// convert title to char*
|
||||
ctitle = title.c_str();
|
||||
Engine::Engine(const char* windowTitle, int windowWidth, int windowHeight, int windowFlags) {
|
||||
// Initialize SDL
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
SDL_Log("SDL could not initialize! SDL_Error: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize SDL and TFF;
|
||||
TTF_Init();
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
// Create the window
|
||||
window = SDL_CreateWindow(windowTitle, windowWidth, windowHeight, windowFlags);
|
||||
if (!window) {
|
||||
SDL_Log("Window could not be created! SDL_Error: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Create window and renderer
|
||||
window = SDL_CreateWindow(
|
||||
ctitle,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
width,
|
||||
height,
|
||||
SDL_WINDOW_SHOWN
|
||||
);
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
// Create the renderer
|
||||
renderer = SDL_CreateRenderer(window, nullptr);
|
||||
if (!renderer) {
|
||||
SDL_Log("Renderer could not be created! SDL_Error: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::initSound()
|
||||
{
|
||||
// Initialize sound
|
||||
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
|
||||
soundInitialized = true;
|
||||
Engine::~Engine() {
|
||||
// Destroy the asset manager
|
||||
assets.clearAssets();
|
||||
|
||||
// Destroy the renderer
|
||||
if (renderer) {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
}
|
||||
|
||||
// Destroy the window
|
||||
if (window) {
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
||||
// Quit SDL subsystems
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void Engine::clear(SDL_Color color)
|
||||
{
|
||||
// Set color
|
||||
void Engine::clearScreen(const Color& color) {
|
||||
// Set the draw color
|
||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
|
||||
|
||||
// Clear screen
|
||||
|
||||
// Clear the screen
|
||||
SDL_RenderClear(renderer);
|
||||
}
|
||||
|
||||
void Engine::startFrame()
|
||||
{
|
||||
// Start frame
|
||||
frameStart = SDL_GetTicks();
|
||||
}
|
||||
|
||||
void Engine::render()
|
||||
{
|
||||
// Render screen
|
||||
void Engine::present() {
|
||||
// Present the renderer
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
if (1000 / targetFrameRate > SDL_GetTicks() - frameStart)
|
||||
{
|
||||
SDL_Delay(1000 / targetFrameRate - (SDL_GetTicks() - frameStart));
|
||||
|
||||
// Calculate frame duration
|
||||
frameEndTime = SDL_GetTicks();
|
||||
frameDuration = frameEndTime - frameStartTime;
|
||||
// Calculate delay to maintain target FPS
|
||||
if (targetFPSValue > 0) {
|
||||
Uint32 targetFrameTime = 1000 / targetFPSValue;
|
||||
if (frameDuration < targetFrameTime) {
|
||||
SDL_Delay(targetFrameTime - frameDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::update()
|
||||
{
|
||||
// Update input
|
||||
input.update();
|
||||
}
|
||||
|
||||
Engine::~Engine()
|
||||
{
|
||||
// Free renderer and window
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
// If sound is initialized, quit Mix
|
||||
if (soundInitialized)
|
||||
{
|
||||
Mix_Quit();
|
||||
void Engine::draw(SDL_Surface* surface, Rect destRect) {
|
||||
// Draw a surface to the renderer at the specified destination rectangle
|
||||
if (!surface) {
|
||||
SDL_Log("Cannot draw null surface");
|
||||
return;
|
||||
}
|
||||
|
||||
// Quit SDL and TTF
|
||||
SDL_Quit();
|
||||
TTF_Quit();
|
||||
SDL_FRect sdlDestRect = {
|
||||
static_cast<float>(destRect.x),
|
||||
static_cast<float>(destRect.y),
|
||||
static_cast<float>(destRect.width),
|
||||
static_cast<float>(destRect.height)
|
||||
};
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Failed to create texture from surface: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_RenderTexture(renderer, texture, nullptr, &sdlDestRect);
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
void Engine::draw(SDL_Surface* surface, Rect srcRect, Rect destRect) {
|
||||
// Draw a surface to the renderer with specified source and destination rectangles
|
||||
if (!surface) {
|
||||
SDL_Log("Cannot draw null surface");
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_FRect sdlSrcRect = {
|
||||
static_cast<float>(srcRect.x),
|
||||
static_cast<float>(srcRect.y),
|
||||
static_cast<float>(srcRect.width),
|
||||
static_cast<float>(srcRect.height)
|
||||
};
|
||||
SDL_FRect sdlDestRect = {
|
||||
static_cast<float>(destRect.x),
|
||||
static_cast<float>(destRect.y),
|
||||
static_cast<float>(destRect.width),
|
||||
static_cast<float>(destRect.height)
|
||||
};
|
||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
if (!texture) {
|
||||
SDL_Log("Failed to create texture from surface: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_RenderTexture(renderer, texture, &sdlSrcRect, &sdlDestRect);
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
void Engine::draw(Tile tile, Rect destRect) {
|
||||
// Draw a tile to the renderer at the specified destination rectangle
|
||||
SDL_Surface* surface = assets.getAsset(tile.assetName);
|
||||
if (!surface) {
|
||||
SDL_Log("Tile asset %s not found", tile.assetName.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
draw(surface, tile.srcRect, destRect);
|
||||
}
|
||||
|
||||
void Engine::startFrame() {
|
||||
// Start the frame timer
|
||||
frameStartTime = SDL_GetTicks();
|
||||
}
|
||||
|
||||
void Engine::targetFPS(int fps) {
|
||||
// Set the target frames per second
|
||||
targetFPSValue = fps;
|
||||
}
|
@@ -1,133 +0,0 @@
|
||||
// Includes
|
||||
#include "engine.h"
|
||||
|
||||
// Variables
|
||||
SDL_Surface* assets;
|
||||
Music* music;
|
||||
Engine *engine;
|
||||
|
||||
// Functions
|
||||
// Quit function
|
||||
void quit()
|
||||
{
|
||||
// Free assets
|
||||
SDL_FreeSurface(assets);
|
||||
delete engine;
|
||||
// Exit program
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Main function
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
engine = new Engine("Game", 800, 600);
|
||||
engine->initSound();
|
||||
engine->targetFrameRate = 60;
|
||||
|
||||
// Load assets
|
||||
assets = SDL_LoadBMP("example_assets/sprites.bmp");
|
||||
music = new Music("example_assets/crystal_zone.mp3");
|
||||
|
||||
// frame map
|
||||
std::map<std::string, SDL_Rect> idle = {
|
||||
{ "idle", { 76, 456, 68, 128 } },
|
||||
};
|
||||
|
||||
std::map<std::string, SDL_Rect> front = {
|
||||
{ "front", { 4, 456, 68, 125 } },
|
||||
{ "front2", { 76, 456, 68, 128 } },
|
||||
{ "front3", { 148, 456, 68, 125 } }
|
||||
};
|
||||
|
||||
std::map<std::string, SDL_Rect> back = {
|
||||
{ "back", { 662, 456, 68, 125 } },
|
||||
{ "back2", { 734, 456, 68, 128 } },
|
||||
{ "back3", { 806, 456, 68, 125 } }
|
||||
};
|
||||
|
||||
std::map<std::string, SDL_Rect> walk = {
|
||||
{ "walk", { 220, 456, 68, 124 } },
|
||||
{ "walk2", { 292, 456, 73, 127 } },
|
||||
{ "walk3", { 369, 456, 68, 124 } }
|
||||
};
|
||||
|
||||
std::map<std::string, SDL_Rect> test = {
|
||||
{ "test", { 4, 2095, 68, 59 } },
|
||||
{ "test2", { 76, 2095, 68, 59 } }
|
||||
};
|
||||
|
||||
// Create sprite and animation
|
||||
Sprite* sprite = new Sprite(engine->renderer, assets);
|
||||
AnimationManager* animations = new AnimationManager(sprite);
|
||||
animations->addAnimation("idle", idle, 10, false, true, false, false);
|
||||
animations->addAnimation("walk_left", walk, 10, false, true, true, false);
|
||||
animations->addAnimation("walk_right", walk, 10, true, true, true, false);
|
||||
animations->addAnimation("walk_back", back, 10, false, true, true, false);
|
||||
animations->addAnimation("walk_front", front, 10, false, true, true, true);
|
||||
animations->addAnimation("test", test, 20, false, true, false, false);
|
||||
animations->setAnimation("idle");
|
||||
|
||||
// Play music
|
||||
music->play();
|
||||
|
||||
// Main loop
|
||||
while (true)
|
||||
{
|
||||
// Start time
|
||||
engine->startFrame();
|
||||
|
||||
// Update input
|
||||
engine->update();
|
||||
|
||||
// Exit if window s closed
|
||||
if (engine->input.exit || engine->input.activeKeys[SDLK_ESCAPE])
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
if (engine->input.activeKeys[SDLK_d] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_RIGHT] || engine->input.controllers[0].leftStickX > 8000)
|
||||
{
|
||||
animations->setAnimation("walk_right");
|
||||
sprite->move({ 1, 0 });
|
||||
}
|
||||
if (engine->input.activeKeys[SDLK_a] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_LEFT] || engine->input.controllers[0].leftStickX < -8000)
|
||||
|
||||
{
|
||||
animations->setAnimation("walk_left");
|
||||
sprite->move({ -1, 0 });
|
||||
}
|
||||
if (engine->input.activeKeys[SDLK_w] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_UP] || engine->input.controllers[0].leftStickY < -8000)
|
||||
{
|
||||
animations->setAnimation("walk_back");
|
||||
sprite->move({ 0, -1 });
|
||||
}
|
||||
if (engine->input.activeKeys[SDLK_s] || engine->input.controllers[0].buttons[CBUTTONS::DPAD_DOWN] || engine->input.controllers[0].leftStickY > 8000)
|
||||
{
|
||||
animations->setAnimation("walk_front");
|
||||
sprite->move({ 0, 1 });
|
||||
}
|
||||
if (engine->input.activeKeys[SDLK_SPACE] || engine->input.controllers[0].buttons[CBUTTONS::A])
|
||||
{
|
||||
animations->playAnimation("test");
|
||||
}
|
||||
if (!engine->input.keysPressed({ SDLK_w, SDLK_a, SDLK_s, SDLK_d }) && engine->input.controllers[0].leftStickX < 8000 && engine->input.controllers[0].leftStickX > -8000 &&
|
||||
engine->input.controllers[0].leftStickY < 8000 && engine->input.controllers[0].leftStickY > -8000 &&
|
||||
!engine->input.controllerPressed({ CBUTTONS::DPAD_UP, CBUTTONS::DPAD_DOWN, CBUTTONS::DPAD_LEFT, CBUTTONS::DPAD_RIGHT }))
|
||||
{
|
||||
animations->setAnimation("idle");
|
||||
}
|
||||
|
||||
// Update animation
|
||||
animations->update();
|
||||
|
||||
// Clear screen
|
||||
engine->clear({ 100, 150, 255, 255 });
|
||||
|
||||
// Draw sprite
|
||||
animations->draw(engine->renderer);
|
||||
|
||||
// Update screen
|
||||
engine->render();
|
||||
}
|
||||
return 0;
|
||||
}
|
158
src/input.cpp
158
src/input.cpp
@@ -1,78 +1,112 @@
|
||||
#include "input.h"
|
||||
#include "input.hpp"
|
||||
|
||||
Input::Input() {
|
||||
|
||||
Input::Input()
|
||||
{
|
||||
SDL_Init(SDL_INIT_JOYSTICK);
|
||||
exit = false;
|
||||
}
|
||||
|
||||
void Input::update()
|
||||
{
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
controllers[event.cbutton.which].buttons[event.cbutton.button] = true;
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
controllers[event.cbutton.which].buttons[event.cbutton.button] = false;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
mouse.buttons[event.button.button] = true;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
mouse.buttons[event.button.button] = false;
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
activeKeys[event.key.keysym.sym] = true;
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
activeKeys.erase(event.key.keysym.sym);
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
controllers[SDL_NumJoysticks() - 1] = {
|
||||
SDL_GameControllerOpen(SDL_NumJoysticks() - 1),
|
||||
SDL_GameControllerName(SDL_GameControllerOpen(SDL_NumJoysticks() - 1))
|
||||
};
|
||||
printf("Controller added: %s\n", controllers[SDL_NumJoysticks() - 1].name.c_str());
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
exit = true;
|
||||
break;
|
||||
Input::~Input() {
|
||||
|
||||
}
|
||||
|
||||
void Input::handleEvents() {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
quitRequestedFlag = true;
|
||||
break;
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
if (keyStates[event.key.scancode] == false) {
|
||||
keyFallingEdgeStates[event.key.scancode] = true;
|
||||
}
|
||||
keyStates[event.key.scancode] = true;
|
||||
break;
|
||||
case SDL_EVENT_KEY_UP:
|
||||
keyStates[event.key.scancode] = false;
|
||||
keyFallingEdgeStates[event.key.scancode] = false;
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
if (mouseButtonStates[event.button.button] == false) {
|
||||
mouseButtonFallingEdgeStates[event.button.button] = true;
|
||||
}
|
||||
mouseButtonStates[event.button.button] = true;
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
mouseButtonStates[event.button.button] = false;
|
||||
mouseButtonFallingEdgeStates[event.button.button] = false;
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
mousePosition.x = static_cast<int>(event.motion.x);
|
||||
mousePosition.y = static_cast<int>(event.motion.y);
|
||||
break;
|
||||
}
|
||||
for (auto& controller : controllers)
|
||||
{
|
||||
controller.second.leftStickX = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_LEFTX);
|
||||
controller.second.leftStickY = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_LEFTY);
|
||||
controller.second.rightStickX = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_RIGHTX);
|
||||
controller.second.rightStickY = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_RIGHTY);
|
||||
controller.second.leftTrigger = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||
controller.second.rightTrigger = SDL_GameControllerGetAxis(controller.second.controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
||||
}
|
||||
SDL_GetMouseState(&mouse.x, &mouse.y);
|
||||
mouse.wheel = event.wheel.y;
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::keysPressed(std::vector<SDL_Keycode> keys)
|
||||
{
|
||||
for (auto key : keys)
|
||||
{
|
||||
if (activeKeys[key])
|
||||
{
|
||||
bool Input::quitRequested() const {
|
||||
return quitRequestedFlag;
|
||||
}
|
||||
|
||||
bool Input::isKeyPressed(SDL_Scancode key) {
|
||||
auto it = keyStates.find(key);
|
||||
return it != keyStates.end() && it->second;
|
||||
}
|
||||
|
||||
bool Input::isKeyPressed(std::vector<SDL_Scancode> keys) {
|
||||
for (const auto& key : keys) {
|
||||
if (isKeyPressed(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::controllerPressed(std::vector<Uint8> buttons, int controller)
|
||||
{
|
||||
for (auto button : buttons)
|
||||
{
|
||||
if (controllers[controller].buttons[button])
|
||||
{
|
||||
bool Input::isMouseButtonPressed(Uint8 button) {
|
||||
auto it = mouseButtonStates.find(button);
|
||||
return it != mouseButtonStates.end() && it->second;
|
||||
}
|
||||
|
||||
bool Input::isMouseButtonPressed(std::vector<Uint8> buttons) {
|
||||
for (const auto& button : buttons) {
|
||||
if (isMouseButtonPressed(button)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector2 Input::getMousePosition() const {
|
||||
return mousePosition;
|
||||
}
|
||||
|
||||
bool Input::hasKeyBeenPressed(SDL_Scancode key) {
|
||||
auto it = keyFallingEdgeStates.find(key);
|
||||
if (it != keyFallingEdgeStates.end() && it->second) {
|
||||
keyFallingEdgeStates[key] = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::hasKeyBeenPressed(std::vector<SDL_Scancode> keys) {
|
||||
for (const auto& key : keys) {
|
||||
if (hasKeyBeenPressed(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::hasMouseButtonBeenPressed(Uint8 button) {
|
||||
auto it = mouseButtonFallingEdgeStates.find(button);
|
||||
if (it != mouseButtonFallingEdgeStates.end() && it->second) {
|
||||
mouseButtonFallingEdgeStates[button] = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Input::hasMouseButtonBeenPressed(std::vector<Uint8> buttons) {
|
||||
for (const auto& button : buttons) {
|
||||
if (hasMouseButtonBeenPressed(button)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
57
src/main.cpp
Normal file
57
src/main.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "engine.hpp"
|
||||
|
||||
// Main function
|
||||
int main(int argc, char* argv[]) {
|
||||
// Create the engine with a window title and dimensions
|
||||
Engine engine("SDL3 Game Engine", 800, 600);
|
||||
TileMap tileMap(engine.assets);
|
||||
|
||||
// Load bird asset
|
||||
engine.assets.load("bird", "assets/bird.png");
|
||||
tileMap.addTile("bird0", Tile{{0, 0, 34, 24}, "bird"});
|
||||
tileMap.addTile("bird1", Tile{{34, 0, 34, 24}, "bird"});
|
||||
tileMap.addTile("bird2", Tile{{68, 0, 34, 24}, "bird"});
|
||||
|
||||
int currentBirdIndex = 0;
|
||||
|
||||
// bird position
|
||||
Vector2 birdPosition(0, 0);
|
||||
|
||||
while (!engine.input.quitRequested()) {
|
||||
// Start a new frame
|
||||
engine.startFrame();
|
||||
|
||||
// Handle input events
|
||||
engine.input.handleEvents();
|
||||
|
||||
// check for movement keys
|
||||
if (engine.input.isKeyPressed(SDL_SCANCODE_D)) {
|
||||
birdPosition.x += 1; // Move right
|
||||
}
|
||||
if (engine.input.isKeyPressed(SDL_SCANCODE_A)) {
|
||||
birdPosition.x -= 1; // Move left
|
||||
}
|
||||
if (engine.input.isKeyPressed(SDL_SCANCODE_W)) {
|
||||
birdPosition.y -= 1; // Move up
|
||||
}
|
||||
if (engine.input.isKeyPressed(SDL_SCANCODE_S)) {
|
||||
birdPosition.y += 1; // Move down
|
||||
}
|
||||
|
||||
// Change bird sprite on space key press
|
||||
if (engine.input.hasKeyBeenPressed(SDL_SCANCODE_SPACE)) {
|
||||
currentBirdIndex = (currentBirdIndex + 1) % 3; // Cycle through bird sprites
|
||||
}
|
||||
|
||||
// Clear the screen with a color
|
||||
engine.clearScreen({0, 0, 0}); // Black color
|
||||
|
||||
// Draw the bird asset at a specific position
|
||||
engine.draw(tileMap.getTile("bird" + std::to_string(currentBirdIndex)), birdPosition);
|
||||
|
||||
// Present the rendered frame
|
||||
engine.present();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
#include "sound.h"
|
||||
|
||||
Music::Music(const char* path)
|
||||
{
|
||||
music = Mix_LoadMUS(path);
|
||||
}
|
||||
|
||||
void Music::play(int loops)
|
||||
{
|
||||
Mix_PlayMusic(music, loops);
|
||||
}
|
||||
|
||||
void Music::pause()
|
||||
{
|
||||
Mix_PauseMusic();
|
||||
}
|
||||
|
||||
void Music::stop()
|
||||
{
|
||||
Mix_HaltMusic();
|
||||
}
|
||||
|
||||
void Music::resume()
|
||||
{
|
||||
Mix_ResumeMusic();
|
||||
}
|
||||
|
||||
void Music::setVolume(int volume)
|
||||
{
|
||||
Mix_VolumeMusic(volume);
|
||||
}
|
||||
|
||||
Music::~Music()
|
||||
{
|
||||
Mix_FreeMusic(music);
|
||||
}
|
||||
|
||||
Effect::Effect(const char* path)
|
||||
{
|
||||
effect = Mix_LoadWAV(path);
|
||||
}
|
||||
|
||||
void Effect::play(int loops, int channel)
|
||||
{
|
||||
Mix_PlayChannel(channel, effect, loops);
|
||||
}
|
||||
|
||||
void Effect::setVolume(int volume)
|
||||
{
|
||||
Mix_VolumeChunk(effect, volume);
|
||||
}
|
||||
|
||||
Effect::~Effect()
|
||||
{
|
||||
Mix_FreeChunk(effect);
|
||||
}
|
170
src/sprite.cpp
170
src/sprite.cpp
@@ -1,170 +0,0 @@
|
||||
#include "sprite.h"
|
||||
|
||||
Sprite::Sprite(SDL_Renderer *renderer, SDL_Surface *surface)
|
||||
{
|
||||
Texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
dstrect = { 0, 0, surface->w, surface->h };
|
||||
}
|
||||
|
||||
Sprite::~Sprite()
|
||||
{
|
||||
SDL_DestroyTexture(Texture);
|
||||
}
|
||||
|
||||
void Sprite::draw(SDL_Renderer* renderer, std::string frame, bool autoRect, bool flip)
|
||||
{
|
||||
if (frames.find(frame) == frames.end())
|
||||
{
|
||||
printf("Frame not found\n");
|
||||
return;
|
||||
}
|
||||
if (autoRect)
|
||||
{
|
||||
dstrect = { dstrect.x, dstrect.y, frames[frame].w, frames[frame].h };
|
||||
}
|
||||
SDL_SetTextureAlphaMod(Texture, 255);
|
||||
dstrect.w *= scale.x;
|
||||
dstrect.h *= scale.y;
|
||||
SDL_RenderCopyEx(renderer, Texture, &frames[frame], &dstrect, angle, NULL, flip ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE);
|
||||
}
|
||||
|
||||
void Sprite::addFrame(std::string name, SDL_Rect rect)
|
||||
{
|
||||
frames[name] = rect;
|
||||
}
|
||||
|
||||
void Sprite::setPos(int_vec2 position)
|
||||
{
|
||||
dstrect.x = position.x;
|
||||
dstrect.y = position.y;
|
||||
}
|
||||
|
||||
void Sprite::move(int_vec2 position)
|
||||
{
|
||||
dstrect.x += position.x;
|
||||
dstrect.y += position.y;
|
||||
}
|
||||
|
||||
int_vec2 Sprite::getSize(std::string frame)
|
||||
{
|
||||
size = { frames[frame].w, frames[frame].h };
|
||||
return size;
|
||||
}
|
||||
|
||||
void Sprite::autorect(std::string frame)
|
||||
{
|
||||
dstrect = { dstrect.x, dstrect.y, frames[frame].w, frames[frame].h };
|
||||
}
|
||||
|
||||
|
||||
Animation::Animation(std::map<std::string, SDL_Rect> frames, Sprite* sprite, int frameDuration)
|
||||
{
|
||||
this->sprite = sprite;
|
||||
this->frameDuration = frameDuration;
|
||||
|
||||
for (auto const& x : frames)
|
||||
{
|
||||
this->frames.push_back(x.first);
|
||||
this->sprite->addFrame(x.first, x.second);
|
||||
}
|
||||
currentFrameName = this->frames[0];
|
||||
}
|
||||
|
||||
void Animation::reset()
|
||||
{
|
||||
frameIndex = 0;
|
||||
frameDirection = 1;
|
||||
currentFrameName = frames[0];
|
||||
end = false;
|
||||
}
|
||||
|
||||
void Animation::update()
|
||||
{
|
||||
frameCounter++;
|
||||
end = false;
|
||||
if (frameCounter >= frameDuration)
|
||||
{
|
||||
frameCounter = 0;
|
||||
if (pingpong)
|
||||
{
|
||||
frameIndex += frameDirection;
|
||||
if (frameIndex >= frames.size() - 1 || frameIndex <= 0)
|
||||
{
|
||||
if (!loop)
|
||||
{
|
||||
frameDirection = 0;
|
||||
end = true;
|
||||
} else {
|
||||
frameDirection *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
frameIndex++;
|
||||
if (frameIndex >= frames.size())
|
||||
{
|
||||
if (!loop)
|
||||
{
|
||||
frameIndex = frames.size() - 1;
|
||||
end = true;
|
||||
} else {
|
||||
frameIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
currentFrameName = frames[frameIndex];
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::draw(SDL_Renderer* renderer, bool autoRect, bool flip)
|
||||
{
|
||||
sprite->draw(renderer, currentFrameName, autoRect, flip);
|
||||
}
|
||||
|
||||
AnimationManager::AnimationManager(Sprite* sprite)
|
||||
{
|
||||
this->sprite = sprite;
|
||||
}
|
||||
|
||||
void AnimationManager::addAnimation(std::string name, std::map<std::string, SDL_Rect> frames, int frameDuration, bool flip, bool autoRect, bool loop, bool pingpong)
|
||||
{
|
||||
animations[name] = new Animation(frames, sprite, frameDuration);
|
||||
this->flip[name] = flip;
|
||||
this->autoRect[name] = autoRect;
|
||||
animations[name]->loop = loop;
|
||||
animations[name]->pingpong = pingpong;
|
||||
}
|
||||
|
||||
void AnimationManager::setAnimation(std::string name)
|
||||
{
|
||||
if (!playing) {
|
||||
currentAnimation = name;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationManager::update()
|
||||
{
|
||||
animations[currentAnimation]->update();
|
||||
if (playing && animations[currentAnimation]->end)
|
||||
{
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationManager::draw(SDL_Renderer* renderer)
|
||||
{
|
||||
animations[currentAnimation]->draw(renderer, autoRect[currentAnimation], flip[currentAnimation]);
|
||||
}
|
||||
|
||||
void AnimationManager::playAnimation(std::string name)
|
||||
{
|
||||
if (!playing) {
|
||||
animations[name]->loop = false;
|
||||
animations[name]->reset();
|
||||
setAnimation(name);
|
||||
playing = true;
|
||||
}
|
||||
}
|
17
src/text.cpp
17
src/text.cpp
@@ -1,17 +0,0 @@
|
||||
#include "text.h"
|
||||
|
||||
Text::Text(TTF_Font* font, SDL_Color color)
|
||||
{
|
||||
this->font = font;
|
||||
this->color = color;
|
||||
}
|
||||
|
||||
void Text::draw(SDL_Renderer* renderer, std::string text, int x, int y)
|
||||
{
|
||||
surface = TTF_RenderText_Solid(font, text.c_str(), color);
|
||||
texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
rect = { x, y, surface->w, surface->h };
|
||||
SDL_RenderCopy(renderer, texture, NULL, &rect);
|
||||
SDL_FreeSurface(surface);
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
Reference in New Issue
Block a user