summaryrefslogtreecommitdiff
path: root/in_practice/breakout/game.c
diff options
context:
space:
mode:
Diffstat (limited to 'in_practice/breakout/game.c')
-rw-r--r--in_practice/breakout/game.c117
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);
+ }
+}