01: Add animation switching

This commit is contained in:
0xdeadbeer 2023-11-12 19:43:14 +01:00
parent e0ef71674c
commit ee7626159e
11 changed files with 82 additions and 39 deletions

BIN
.imgs/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,9 @@
<p align="center">
<img src=".imgs/showcase.png" width="300" />
</p>
# Introduction
First code I ever wrote for SDL. It contains some basic functionality for importing textures, player movement, and animations/animation switching

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -3,15 +3,16 @@
#include <SDL2/SDL_image.h>
#include "structs.h"
const int SCREEN_WIDTH = 640;
const int SCREEN_WIDTH = 1000;
const int SCREEN_HEIGHT = 480;
const Uint32 WINDOW_FLAGS = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS;
const Uint32 WINDOW_FLAGS = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
const Uint32 RENDERER_FLAGS = SDL_RENDERER_ACCELERATED;
int GAME_RUNNING = 1;
struct game game;
int movement_speed = 5;
int animation_frames = 100;
int frames = 0;
int movement_speed = 10;
int gravity = 8;
double delta_time;
double last_frame;
void prepare_scene(void) {
SDL_SetRenderDrawColor(game.renderer, 96, 128, 255, 255);
@ -22,10 +23,6 @@ void key(SDL_KeyboardEvent *event) {
if (event->repeat != 0)
return;
if (event->keysym.scancode == SDL_SCANCODE_W)
game.up = !game.up;
if (event->keysym.scancode == SDL_SCANCODE_S)
game.down = !game.down;
if (event->keysym.scancode == SDL_SCANCODE_A)
game.left = !game.left;
if (event->keysym.scancode == SDL_SCANCODE_D)
@ -63,7 +60,7 @@ SDL_Texture *load_texture(const char *path) {
return texture;
}
struct object *create_object(const char *texture_path, int x, int y, int scale, int resolution) {
struct object *create_object(SDL_Texture *texture, int x, int y, int scale, int resolution) {
struct object *object = (struct object *) calloc(1, sizeof(struct object));
if (object == NULL) {
@ -71,26 +68,22 @@ struct object *create_object(const char *texture_path, int x, int y, int scale,
return NULL;
}
object->texture = load_texture(texture_path);
if (object->texture == NULL) {
fprintf(stderr, "Error: loading texture into new object\n");
return NULL;
}
object->texture = texture;
object->resolution = resolution;
object->animation_speed = 15;
object->scale = scale;
object->x = x;
object->y = y;
object->scale = scale;
object->resolution = resolution;
return object;
}
void draw_object(struct object *object) {
int texture_width;
SDL_Rect src;
SDL_Rect dest;
src.x = object->state * object->resolution;
src.x = object->animation_slide * object->resolution;
src.y = 0;
src.w = object->resolution;
@ -101,7 +94,17 @@ void draw_object(struct object *object) {
dest.w = object->resolution * object->scale;
dest.h = object->resolution * object->scale;
SDL_RenderCopy(game.renderer, object->texture, &src, &dest);
SDL_RenderCopyEx(game.renderer, object->texture, &src, &dest, 0, NULL, object->flip);
// update animation slide
SDL_QueryTexture(object->texture, NULL, NULL, &texture_width, NULL);
object->animation_clock += object->animation_speed*(delta_time/1000);
if (object->animation_clock >= 1) {
object->animation_clock = 0;
object->animation_slide = (object->animation_slide+1) % (texture_width / object->resolution); // clock arithmetic: jump back to first animation slide
}
}
void present_scene(void) {
@ -128,24 +131,40 @@ int main(int argc, char *argv[]) {
return -1;
}
struct object *player = create_object("assets/player.png", SCREEN_WIDTH/2, SCREEN_HEIGHT/2, 3, 48);
// load player animations
SDL_Texture *idle_animation = load_texture("assets/player/idle.png");
SDL_Texture *run_animation = load_texture("assets/player/run.png");
struct object *player = create_object(idle_animation, SCREEN_WIDTH/2, 0, 4, 48);
// game loop
while (GAME_RUNNING) {
frames++;
double current_frame = SDL_GetTicks();
delta_time = current_frame - last_frame;
last_frame = current_frame;
prepare_scene();
handle_input();
if (game.up)
player->y -= movement_speed;
if (game.down)
player->y += movement_speed;
if (game.left)
if (game.left) {
player->x -= movement_speed;
if (game.right)
player->flip = SDL_FLIP_HORIZONTAL;
player->texture = run_animation;
}
if (game.right) {
player->x += movement_speed;
player->flip = SDL_FLIP_NONE;
player->texture = run_animation;
}
if (!game.right && !game.left) {
player->texture = idle_animation;
}
player->state = ((frames % animation_frames)/5) % 10;
player->y += gravity;
if (player->y > SCREEN_HEIGHT-(player->resolution*player->scale)) {
player->y = SCREEN_HEIGHT-(player->resolution*player->scale);
}
draw_object(player);

Binary file not shown.

View File

@ -7,22 +7,30 @@ struct game {
SDL_Window *window;
SDL_Renderer *renderer;
int up;
int down;
int left;
int right;
};
struct animation {
SDL_Texture *tilemap;
int resolution;
int skippable;
};
struct object {
SDL_Texture *texture;
int resolution; // of the texture/each tiles
SDL_Texture *texture;
int resolution; // of the texture/every tile
int x;
int y;
int scale;
Uint32 flip;
// animation
int state;
double animation_clock; // everytime it reaches 1, the texture switches to the next slide
double animation_speed; // how fast will the clock reach 1 with respect to delta_time
int animation_slide; // the current slide of the animation
};
#endif

4
README
View File

@ -1,4 +0,0 @@
SDL Playground
==============
My little playground for SDL.

11
README.md Normal file
View File

@ -0,0 +1,11 @@
<p align="center">
<img src=".imgs/icon.png" width="200"/>
</p>
# SDL Playground
My little playground for SDL.
## License
The code is licensed under the GPL-3.0 license. See the `LICENSE` file for more information