aminmations
This commit is contained in:
parent
a756a4f68e
commit
8091651cc7
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.vscode
|
||||||
|
build
|
BIN
assets/C64.ttf
Normal file
BIN
assets/C64.ttf
Normal file
Binary file not shown.
BIN
assets/sprites.bmp
Normal file
BIN
assets/sprites.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 MiB |
14
include/input.h
Normal file
14
include/input.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Input
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool exit;
|
||||||
|
std::map<SDL_Keycode, bool> activeKeys;
|
||||||
|
void update();
|
||||||
|
};
|
64
include/sprite.h
Normal file
64
include/sprite.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "vector.h"
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Sprite
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<std::string, SDL_Rect> frames;
|
||||||
|
SDL_Surface* surface;
|
||||||
|
SDL_Texture* Texture;
|
||||||
|
int_vec2 size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SDL_Rect dstrect;
|
||||||
|
int_vec2 scale = { 1, 1 };
|
||||||
|
double angle = 0;
|
||||||
|
Sprite(SDL_Renderer* renderer, SDL_Surface* surface);
|
||||||
|
void draw(SDL_Renderer* renderer, std::string frame, bool autoRect = true, bool flip = false);
|
||||||
|
void addFrame(std::string name, SDL_Rect rect);
|
||||||
|
void move(int_vec2 position);
|
||||||
|
int_vec2 getSize(std::string frame);
|
||||||
|
void autorect(std::string frame);
|
||||||
|
~Sprite();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Animation
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<std::string> frames;
|
||||||
|
Sprite* sprite;
|
||||||
|
int currentFrame = 0;
|
||||||
|
int frameDuration = 0;
|
||||||
|
int frameCounter = 0;
|
||||||
|
std::string currentFrameName;
|
||||||
|
int frameIndex = 0;
|
||||||
|
int frameDirection = 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool loop = true;
|
||||||
|
bool pingpong = false;
|
||||||
|
Animation(std::map<std::string, SDL_Rect> frames, Sprite* sprite, int frameDuration);
|
||||||
|
void update();
|
||||||
|
void draw(SDL_Renderer* renderer, bool autoRect = true, bool flip = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
class AnimationManager
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::map<std::string, Animation> *animations;
|
||||||
|
std::map<std::string, bool> flip;
|
||||||
|
std::map<std::string, bool> autoRect;
|
||||||
|
std::string currentAnimation;
|
||||||
|
Sprite* sprite;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AnimationManager(Sprite* sprite);
|
||||||
|
void addAnimation(std::string name, std::map<std::string, SDL_Rect> animation, int frameDuration = 10, bool flip = false, bool autoRect = true, bool loop = true, bool pingpong = false);
|
||||||
|
void setAnimation(std::string name);
|
||||||
|
void update();
|
||||||
|
void draw(SDL_Renderer* renderer);
|
||||||
|
};
|
17
include/text.h
Normal file
17
include/text.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_ttf.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Text
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SDL_Surface* surface;
|
||||||
|
SDL_Texture* texture;
|
||||||
|
TTF_Font* font;
|
||||||
|
SDL_Color color;
|
||||||
|
SDL_Rect rect;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Text(TTF_Font* font, SDL_Color color);
|
||||||
|
void draw(SDL_Renderer* renderer, std::string text, int x, int y);
|
||||||
|
};
|
49
include/vector.h
Normal file
49
include/vector.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class float_vec2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float x, y;
|
||||||
|
float_vec2 operator+(float_vec2 vec)
|
||||||
|
{
|
||||||
|
return { x + vec.x, y + vec.y };
|
||||||
|
}
|
||||||
|
float_vec2 operator*(float v)
|
||||||
|
{
|
||||||
|
return { x * v, y * v };
|
||||||
|
}
|
||||||
|
float_vec2 operator*(float_vec2 vec)
|
||||||
|
{
|
||||||
|
return { x * vec.x, y * vec.y };
|
||||||
|
}
|
||||||
|
float_vec2 operator-(float_vec2 vec)
|
||||||
|
{
|
||||||
|
return { x - vec.x, y - vec.y };
|
||||||
|
}
|
||||||
|
float_vec2 operator-(float v)
|
||||||
|
{
|
||||||
|
return { x - v, y - v };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class int_vec2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int x, y;
|
||||||
|
int_vec2 operator+(int_vec2 vec)
|
||||||
|
{
|
||||||
|
return { x + vec.x, y + vec.y };
|
||||||
|
}
|
||||||
|
int_vec2 operator*(int v)
|
||||||
|
{
|
||||||
|
return { x * v, y * v };
|
||||||
|
}
|
||||||
|
int_vec2 operator*(int_vec2 vec)
|
||||||
|
{
|
||||||
|
return { x * vec.x, y * vec.y };
|
||||||
|
}
|
||||||
|
int_vec2 operator-(int_vec2 vec)
|
||||||
|
{
|
||||||
|
return { x - vec.x, y - vec.y };
|
||||||
|
}
|
||||||
|
};
|
17
makefile
Normal file
17
makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
CXX = g++
|
||||||
|
LDFLAGS = `sdl2-config --libs` -l SDL2_ttf
|
||||||
|
CXXFLAGS = `sdl2-config --cflags` -pedantic -O2 -std=c++17 -lX11 -lstdc++fs -I include
|
||||||
|
SRC = $(wildcard src/*.cpp)
|
||||||
|
OBJ = $(addprefix build/, $(notdir $(SRC:.cpp=.o)))
|
||||||
|
TARGET = build/x86_64/main.x86_64
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
@$(CXX) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
build/%.o: src/%.cpp
|
||||||
|
@$(CXX) -c -o $@ $< $(CXXFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f $(OBJ) $(TARGET)
|
20
src/input.cpp
Normal file
20
src/input.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void Input::update()
|
||||||
|
{
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
if (event.type == SDL_KEYDOWN)
|
||||||
|
{
|
||||||
|
activeKeys[event.key.keysym.sym] = true;
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_KEYUP)
|
||||||
|
{
|
||||||
|
activeKeys.erase(event.key.keysym.sym);
|
||||||
|
}
|
||||||
|
else if (event.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
exit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
95
src/main.cpp
Normal file
95
src/main.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Inludes
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "input.h"
|
||||||
|
#include "text.h"
|
||||||
|
#include "sprite.h"
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
SDL_Surface* assets;
|
||||||
|
int startTime = 0;
|
||||||
|
Input input;
|
||||||
|
TTF_Font *font;
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_Renderer *renderer;
|
||||||
|
const int targetFps = 60;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
// Quit function
|
||||||
|
void quit()
|
||||||
|
{
|
||||||
|
// Free assets
|
||||||
|
TTF_CloseFont(font);
|
||||||
|
SDL_FreeSurface(assets);
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
TTF_Quit();
|
||||||
|
// Exit program
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Initialize SDL and TFF;
|
||||||
|
TTF_Init();
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
|
// Create window and renderer
|
||||||
|
window = SDL_CreateWindow("test game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);
|
||||||
|
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||||
|
|
||||||
|
// Load assets
|
||||||
|
assets = SDL_LoadBMP("assets/sprites.bmp");
|
||||||
|
|
||||||
|
// frame map
|
||||||
|
std::map<std::string, SDL_Rect> frames = {
|
||||||
|
{ "idle", { 4, 456, 68, 125 } },
|
||||||
|
{ "idle2", { 76, 456, 68, 128 } },
|
||||||
|
{ "idle3", { 148, 456, 68, 125 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create sprite and animation
|
||||||
|
Sprite* sprite = new Sprite(renderer, assets);
|
||||||
|
AnimationManager* animations = new AnimationManager(sprite);
|
||||||
|
animations->addAnimation("idle", frames);
|
||||||
|
animations->setAnimation("idle");
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// Start time
|
||||||
|
startTime = SDL_GetTicks();
|
||||||
|
|
||||||
|
// Update input
|
||||||
|
input.update();
|
||||||
|
|
||||||
|
// Exit if window is closed
|
||||||
|
if (input.exit)
|
||||||
|
{
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update animation
|
||||||
|
animations->update();
|
||||||
|
|
||||||
|
// Clear screen
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
// Draw sprite
|
||||||
|
animations->draw(renderer);
|
||||||
|
|
||||||
|
// Update screen
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
|
||||||
|
// if frame is faster than target fps, delay
|
||||||
|
if (1000 / targetFps > SDL_GetTicks() - startTime)
|
||||||
|
{
|
||||||
|
SDL_Delay(1000 / targetFps - (SDL_GetTicks() - startTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
126
src/sprite.cpp
Normal file
126
src/sprite.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#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::move(int_vec2 position)
|
||||||
|
{
|
||||||
|
dstrect = { position.x, position.y, dstrect.w, dstrect.h };
|
||||||
|
}
|
||||||
|
|
||||||
|
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::update()
|
||||||
|
{
|
||||||
|
frameCounter++;
|
||||||
|
if (frameCounter >= frameDuration)
|
||||||
|
{
|
||||||
|
frameCounter = 0;
|
||||||
|
if (pingpong)
|
||||||
|
{
|
||||||
|
frameIndex += frameDirection;
|
||||||
|
if (frameIndex >= frames.size() - 1 || frameIndex <= 0)
|
||||||
|
{
|
||||||
|
frameDirection *= -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frameIndex++;
|
||||||
|
if (frameIndex >= frames.size())
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
currentAnimation = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationManager::update()
|
||||||
|
{
|
||||||
|
animations[currentAnimation].update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationManager::draw(SDL_Renderer* renderer)
|
||||||
|
{
|
||||||
|
animations[currentAnimation].draw(renderer, autoRect[currentAnimation], flip[currentAnimation]);
|
||||||
|
}
|
17
src/text.cpp
Normal file
17
src/text.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user