Implement vertical collision (#2)

master
rexim 2017-12-01 00:47:11 +07:00
parent 679f825960
commit b7c9a5957f
8 changed files with 102 additions and 8 deletions

View File

@ -1,4 +1,4 @@
OBJS = src/main.o src/player.o src/platforms.o
OBJS = src/main.o src/player.o src/platforms.o src/rect.o
LIBS=$(shell pkg-config gl sdl2 --libs)
CFLAGS=-Wall -Werror -std=c11 $(shell pkg-config gl sdl2 --cflags)

View File

@ -39,7 +39,7 @@ int main(int argc, char *argv[])
goto sdl_create_renderer_fail;
}
struct player *player = create_player(0.0f, GROUND_LEVEL);
struct player *player = create_player(100.0f, 0.0f);
if (player == NULL) {
perror("Could not create player");
exit_code = -1;
@ -49,7 +49,27 @@ int main(int argc, char *argv[])
const struct rect_t platforms_rects[] = {
{ .x = 0.0f,
.y = GROUND_LEVEL + 50.0f,
.w = SCREEN_WIDTH,
.w = 50.0f,
.h = 50.0f },
{ .x = 150.0f,
.y = GROUND_LEVEL + 50.0f,
.w = SCREEN_WIDTH - 150.0f,
.h = 50.0f },
{ .x = 0.0f,
.y = GROUND_LEVEL + 100.0f,
.w = 50.0f,
.h = 50.0f },
{ .x = 150.0f,
.y = GROUND_LEVEL + 100.0f,
.w = 50.0f,
.h = 50.0f },
{ .x = 0.0f,
.y = GROUND_LEVEL + 150.0f,
.w = 50.0f,
.h = 50.0f },
{ .x = 150.0f,
.y = GROUND_LEVEL + 150.0f,
.w = 50.0f,
.h = 50.0f }
};
struct platforms_t *platforms = create_platforms(
@ -72,6 +92,13 @@ int main(int argc, char *argv[])
case SDL_QUIT:
quit = 1;
break;
case SDL_KEYDOWN:
switch (e.key.keysym.sym) {
case SDLK_SPACE:
player_jump(player);
break;
}
}
}
@ -84,7 +111,7 @@ int main(int argc, char *argv[])
player_stop(player);
}
update_player(player, delay_ms);
update_player(player, platforms, delay_ms);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);

View File

@ -69,3 +69,18 @@ int render_platforms(const struct platforms_t *platforms,
return 0;
}
int platforms_rect_object_collide(const struct platforms_t *platforms,
const struct rect_t *object)
{
assert(platforms);
assert(object);
for (size_t i = 0; i < platforms->rects_size; ++i) {
if (rects_intersect(object, &platforms->rects[i])) {
return 1;
}
}
return 0;
}

View File

@ -12,4 +12,7 @@ void destroy_platforms(struct platforms_t *platforms);
int render_platforms(const struct platforms_t *platforms,
SDL_Renderer *renderer);
int platforms_rect_object_collide(const struct platforms_t *platforms,
const struct rect_t *object);
#endif // PLATFORMS_H_

View File

@ -3,10 +3,12 @@
#include <SDL2/SDL.h>
#include "./player.h"
#include "./platforms.h"
#define PLAYER_WIDTH 50.0f
#define PLAYER_HEIGHT 50.0f
#define PLAYER_SPEED 500.0f
#define PLAYER_GRAVITY 1500.0f
struct player {
float x, y;
@ -54,12 +56,36 @@ int render_player(const struct player * player,
return 0;
}
void update_player(struct player * player, int delta_time)
void update_player(struct player * player,
const struct platforms_t *platforms,
int delta_time)
{
float d = delta_time / 1000.0;
player->x += player->dx * d;
player->y += player->dy * d;
float dx = player->dx;
float dy = player->dy + PLAYER_GRAVITY * d;
float x = player->x + dx * d;
float y = fmod(player->y + dy * d, 600.0f);
struct rect_t player_object = {
.x = x,
.y = y,
.w = PLAYER_WIDTH,
.h = PLAYER_HEIGHT
};
/* TODO: Implement collision for the left/right sides */
if (platforms_rect_object_collide(platforms, &player_object)) {
dy = -player->dy * 0.75;
x = player->x + dx * d;
y = fmod(player->y + dy * d, 600.0f);
}
player->dx = dx;
player->dy = dy;
player->x = x;
player->y = y;
}
void player_move_left(struct player *player)
@ -76,3 +102,8 @@ void player_stop(struct player *player)
{
player->dx = 0.0f;
}
void player_jump(struct player *player)
{
player->dy = -500.0f;
}

View File

@ -2,6 +2,7 @@
#define PLAYER_H_
struct player;
struct platforms_t;
struct SDL_Renderer;
struct player *create_player(float x, float y);
@ -9,10 +10,13 @@ void destroy_player(struct player * player);
int render_player(const struct player * player,
SDL_Renderer *renderer);
void update_player(struct player * player, int delta_time);
void update_player(struct player * player,
const struct platforms_t *platforms,
int delta_time);
void player_move_left(struct player *player);
void player_move_right(struct player *player);
void player_stop(struct player *player);
void player_jump(struct player *player);
#endif // PLAYER_H_

12
src/rect.c Normal file
View File

@ -0,0 +1,12 @@
#include <math.h>
#include "./rect.h"
int rects_intersect(const struct rect_t *rect1,
const struct rect_t *rect2)
{
float x1 = fmax(rect1->x, rect2->x);
float y1 = fmax(rect1->y, rect2->y);
float x2 = fmin(rect1->x + rect1->w, rect2->x + rect2->w);
float y2 = fmin(rect1->y + rect1->h, rect2->y + rect2->h);
return x1 <= x2 && y1 <= y2;
}

View File

@ -5,5 +5,7 @@ struct rect_t {
float x, y, w, h;
};
int rects_intersect(const struct rect_t *rect1,
const struct rect_t *rect2);
#endif // RECT_H_