diff options
Diffstat (limited to 'in_practice/breakout/game.c')
-rw-r--r-- | in_practice/breakout/game.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/in_practice/breakout/game.c b/in_practice/breakout/game.c new file mode 100644 index 0000000..cf3c0a2 --- /dev/null +++ b/in_practice/breakout/game.c @@ -0,0 +1,117 @@ +#include "game.h" +#include "sys.h" +#include "shader.h" +#include "texture.h" +#include "sprite.h" + +#include <GL/glew.h> +#include "gl_utils.h" + +#include <stdio.h> +#include <math.h> + +static void init_gl(game_t game) +{ + i32 flags; + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) { + info("debug context initialized successfully"); + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(gl_debug_output, 0); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); + } + glViewport(0, 0, game.width, game.height); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(0.16f, 0.16f, 0.16f, 1.0f); +} + +game_t init_game(i32 width, i32 height) +{ + game_t game = {0}; + game.state = game_active; + game.running = 1; + game.width = width; + game.height = height; + game.input = init_input(); + init_gl(game); + game.bindir = get_bin_dir(); + char dir[512] = {0}; + snprintf(dir, 512, "%s/%s", game.bindir, "shaders"); + u32 shader = load_shader(dir, "shader.vert", "shader.frag", 0, "shader"); + glUseProgram(shader); + mat projection = ortho(0.0f, game.width, game.height, 0.0f, -1.0f, 1.0f); + uniform_mat(shader, "projection", projection); + glUseProgram(0); + snprintf(dir, 512, "%s/%s", game.bindir, "textures"); + load_texture(dir, "gentleman.jpg", "gentleman", 0); + load_texture(dir, "block.png", "block", 0); + load_texture(dir, "solid.png", "solid", 0); + load_texture(dir, "paddle.png", "paddle", 1); + load_texture(dir, "ball.png", "ball", 1); + game.renderer = init_renderer(shader); + snprintf(dir, 512, "%s/%s", game.bindir, "levels"); + game.level = load_level(0, "first.txt", game.width, game.height / 2.0f); + game.player = (object_t)default_object; + v2 size = get_texture_size("paddle"); + game.player.size = scale_v2(size, 0.4f); + game.player.pos = (v2){width / 2.0f - game.player.size.x / 2.0f, height - game.player.size.y}; + game.player.vel = v2a(500.0f); + game.player.texture = get_texture_id("paddle"); + game.ball.o = (object_t)default_object; + game.ball.radius = 12.5f; + game.ball.o.size = v2a(2.0f * game.ball.radius); + game.ball.o.pos = (v2){game.player.pos.x + game.player.size.x / 2.0f - game.ball.o.size.x / 2.0f, game.player.pos.y - game.ball.o.size.y}; + game.ball.o.vel = (v2){100.0f, -350.0f}; + game.ball.o.texture = get_texture_id("ball"); + game.ball.stuck = 1; + return game; +} + +void process_input(game_t *game) +{ + if (key_first_press(game->input.escape)) + game->running = 0; +} + +void update_game(game_t *game, f32 dt) +{ + f32 vel = game->player.vel.x * dt; + if (game->state == game_active) { + if (key_is_pressed(game->input.right)) { + if (game->player.pos.x + game->player.size.x <= game->width) { + game->player.pos.x += vel; + if (game->ball.stuck) + game->ball.o.pos.x += vel; + } + } + if (key_is_pressed(game->input.left)) { + if (game->player.pos.x >= 0.0f) { + game->player.pos.x -= vel; + if (game->ball.stuck) + game->ball.o.pos.x -= vel; + } + } + if (key_first_press(game->input.space)) + game->ball.stuck = 0; + } + move_ball(&game->ball, dt, game->width); + /* collisions */ + for (i32 i = 0; i < game->level.count; i++) { + object_t *tile = game->level.tiles + i; + if (!tile->destroyed && check_collision(game->ball.o, *tile) && (!tile->solid)) { + tile->destroyed = 1; + } + } +} + +void render_game(game_t game) +{ + glClear(GL_COLOR_BUFFER_BIT); + if (game.state == game_active) { + render_level(game.renderer, game.level); + render_object(game.renderer, game.player); + render_object(game.renderer, game.ball.o); + } +} |