diff --git a/01-introduction/src/main.c b/01-introduction/src/main.c index 1ed90aa..05194c8 100644 --- a/01-introduction/src/main.c +++ b/01-introduction/src/main.c @@ -60,6 +60,14 @@ SDL_Texture *load_texture(const char *path) { return texture; } +void switch_animation(struct object *object, SDL_Texture *animation) { + if (object->texture == animation) + return; + + object->animation_slide = 0; + object->texture = animation; +} + 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)); @@ -70,7 +78,7 @@ struct object *create_object(SDL_Texture *texture, int x, int y, int scale, int object->texture = texture; object->resolution = resolution; - object->animation_speed = 15; + object->animation_speed = 13; object->scale = scale; object->x = x; object->y = y; @@ -149,15 +157,15 @@ int main(int argc, char *argv[]) { if (game.left) { player->x -= movement_speed; player->flip = SDL_FLIP_HORIZONTAL; - player->texture = run_animation; + switch_animation(player, run_animation); } if (game.right) { player->x += movement_speed; player->flip = SDL_FLIP_NONE; - player->texture = run_animation; + switch_animation(player, run_animation); } if (!game.right && !game.left) { - player->texture = idle_animation; + switch_animation(player, idle_animation); } player->y += gravity; diff --git a/01-introduction/src/main.o b/01-introduction/src/main.o index 243fdc0..8e6797f 100644 Binary files a/01-introduction/src/main.o and b/01-introduction/src/main.o differ diff --git a/02-jumping/.imgs/showcase.png b/02-jumping/.imgs/showcase.png new file mode 100644 index 0000000..5e08d16 Binary files /dev/null and b/02-jumping/.imgs/showcase.png differ diff --git a/02-jumping/Makefile b/02-jumping/Makefile new file mode 100644 index 0000000..8433341 --- /dev/null +++ b/02-jumping/Makefile @@ -0,0 +1,28 @@ +CC=gcc +CFLAGS=`pkg-config --cflags sdl2 SDL2_image` +LDFLAGS=`pkg-config --libs sdl2 SDL2_image` +TARGET=jumping +SDIR=src +ADIR=assets +ODIR=build + +SRC=$(shell find $(SDIR) -type f -name *.c) +OBJ=$(SRC:.c=.o) + +all: $(TARGET) + +.PHONY: default +$(TARGET): $(OBJ) + mkdir -p build + cp -rf $(ADIR) $(ODIR)/$(ADIR) + $(CC) -o $(ODIR)/$@ $^ $(LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +run: + $(ODIR)/$(TARGET) + +.PHONY: clean +clean: + rm -f $(ODIR)/$(TARGET) $(OBJ) diff --git a/02-jumping/README.md b/02-jumping/README.md new file mode 100644 index 0000000..5b04361 --- /dev/null +++ b/02-jumping/README.md @@ -0,0 +1,3 @@ +# Jumping + +Code added to 01-introduction for jumping around. diff --git a/02-jumping/assets/player/idle.png b/02-jumping/assets/player/idle.png new file mode 100644 index 0000000..4cf0c43 Binary files /dev/null and b/02-jumping/assets/player/idle.png differ diff --git a/02-jumping/assets/player/jump.png b/02-jumping/assets/player/jump.png new file mode 100644 index 0000000..dff105c Binary files /dev/null and b/02-jumping/assets/player/jump.png differ diff --git a/02-jumping/assets/player/land.png b/02-jumping/assets/player/land.png new file mode 100644 index 0000000..2c24d6f Binary files /dev/null and b/02-jumping/assets/player/land.png differ diff --git a/02-jumping/assets/player/run.png b/02-jumping/assets/player/run.png new file mode 100644 index 0000000..615b222 Binary files /dev/null and b/02-jumping/assets/player/run.png differ diff --git a/02-jumping/src/main.c b/02-jumping/src/main.c new file mode 100644 index 0000000..1c5aaef --- /dev/null +++ b/02-jumping/src/main.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include "structs.h" + +const int SCREEN_WIDTH = 1000; +const int SCREEN_HEIGHT = 480; +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 = 10; +int gravity = 8; +double delta_time; +double last_frame; + +void prepare_scene(void) { + SDL_SetRenderDrawColor(game.renderer, 96, 128, 255, 255); + SDL_RenderClear(game.renderer); +} + +void key(SDL_KeyboardEvent *event) { + if (event->repeat != 0) + return; + + if (event->keysym.scancode == SDL_SCANCODE_A) + game.left = !game.left; + if (event->keysym.scancode == SDL_SCANCODE_D) + game.right = !game.right; + if (event->keysym.scancode == SDL_SCANCODE_SPACE) + game.jump = !game.jump; +} + +void handle_input(void) { + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + GAME_RUNNING = 0; + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + key(&event.key); + break; + default: + break; + } + if (event.type == SDL_QUIT) { + GAME_RUNNING = 0; + } + } +} + +SDL_Texture *load_texture(const char *path) { + SDL_Texture *texture; + + SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading %s", path); + + texture = IMG_LoadTexture(game.renderer, path); + + return texture; +} + +void switch_animation(struct object *object, SDL_Texture *animation) { + if (object->texture == animation) + return; + + object->animation_slide = 0; + object->texture = animation; +} + +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) { + fprintf(stderr, "Error: failed allocating memory for new object\n"); + return NULL; + } + + object->texture = texture; + object->resolution = resolution; + object->animation_speed = 13; + object->scale = scale; + object->x = x; + object->y = y; + + return object; +} + +void draw_object(struct object *object) { + int texture_width; + SDL_Rect src; + SDL_Rect dest; + + src.x = object->animation_slide * object->resolution; + src.y = 0; + + src.w = object->resolution; + src.h = object->resolution; + + dest.x = object->x; + dest.y = object->y; + dest.w = object->resolution * object->scale; + dest.h = object->resolution * object->scale; + + 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) { + SDL_RenderPresent(game.renderer); +} + +int main(int argc, char *argv[]) { + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + fprintf(stderr, "Error: could not initialize SDL\n%s\n", SDL_GetError()); + return -1; + } + + game.window = SDL_CreateWindow("02-jumping", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_FLAGS); + + if (game.window == NULL) { + fprintf(stderr, "Error: could not create window\n%s\n", SDL_GetError()); + return -1; + } + + game.renderer = SDL_CreateRenderer(game.window, -1, RENDERER_FLAGS); + + if (game.renderer == NULL) { + fprintf(stderr, "Error: could not create renderer\n%s\n", SDL_GetError()); + return -1; + } + + // load player animations + SDL_Texture *idle_animation = load_texture("assets/player/idle.png"); + SDL_Texture *run_animation = load_texture("assets/player/run.png"); + SDL_Texture *jump_animation = load_texture("assets/player/jump.png"); + + struct object *player = create_object(idle_animation, SCREEN_WIDTH/2, 0, 4, 48); + + // game loop + while (GAME_RUNNING) { + double current_frame = SDL_GetTicks(); + delta_time = current_frame - last_frame; + last_frame = current_frame; + + prepare_scene(); + handle_input(); + + // The reason why I don't do + // that much game development + // in my free time. Damn youuu ifs + if (player->colliding) { + if (game.left) + switch_animation(player, run_animation); + if (game.right) + switch_animation(player, run_animation); + if (!game.left && !game.right) + switch_animation(player, idle_animation); + if (game.jump) { + switch_animation(player, jump_animation); + player->force -= movement_speed * 3; + player->y += player->force; + player->colliding = 0; + } + } + + if (game.left) { + player->x -= movement_speed; + player->flip = SDL_FLIP_HORIZONTAL; + } + if (game.right) { + player->x += movement_speed; + player->flip = SDL_FLIP_NONE; + } + + if (player->y < 200) { + player->force += 2; + } else { + player->colliding = 1; + player->force = 0; + } + + player->y += player->force; + + draw_object(player); + + present_scene(); + + SDL_Delay(16); + } + + SDL_DestroyWindow(game.window); + SDL_Quit(); + + return 0; +} diff --git a/02-jumping/src/main.o b/02-jumping/src/main.o new file mode 100644 index 0000000..de82e66 Binary files /dev/null and b/02-jumping/src/main.o differ diff --git a/02-jumping/src/structs.h b/02-jumping/src/structs.h new file mode 100644 index 0000000..dc0af64 --- /dev/null +++ b/02-jumping/src/structs.h @@ -0,0 +1,40 @@ +#ifndef STRUCTS_H +#define STRUCTS_H + +#include + +struct game { + SDL_Window *window; + SDL_Renderer *renderer; + + int left; + int right; + int jump; +}; + +struct animation { + SDL_Texture *tilemap; + int resolution; + + int skippable; +}; + +struct object { + SDL_Texture *texture; + int resolution; // of the texture/every tile + + int x; + int y; + int scale; + Uint32 flip; + + // animation + 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 + + int colliding; + int force; +}; + +#endif