package space_invaders import "core:c" import "core:log" import glm "core:math/linalg/glsl" import rl "vendor:raylib" GLOBAL_SPRITE_SCALE :: 2 ALIEN_ROWS :: 5 ALIENS_PER_ROW :: 11 ALIENS :: ALIEN_ROWS * ALIENS_PER_ROW ALIEN_SIDE_STEP :: 20 * GLOBAL_SPRITE_SCALE ALIEN_RECT :: glm.ivec2{16 * GLOBAL_SPRITE_SCALE, 16 * GLOBAL_SPRITE_SCALE} MAX_BULLETS :: 100 BULLET_SPEED :: 240 BULLET_RECT :: glm.ivec2{16 * GLOBAL_SPRITE_SCALE, 16 * GLOBAL_SPRITE_SCALE} MAX_PLAYER_HEALTH :: 3 PLAYER_SPEED :: 40 PLAYER_RECT :: glm.ivec2{16 * GLOBAL_SPRITE_SCALE, 16 * GLOBAL_SPRITE_SCALE} Alien :: struct { alive: bool, position: glm.vec2, id: int, } Bullet :: struct { alive: bool, position: glm.vec2, } setup_game :: proc(state: ^GameState) { using state player_pos = glm.vec2{f32(screen_width / 2), f32(screen_height - PLAYER_RECT.x)} // setup the initial positions of the aliens for row in 0 ..< ALIEN_ROWS { for alien in 0 ..< ALIENS_PER_ROW { aliens[(row * ALIENS_PER_ROW) + alien].position = glm.vec2 { f32((alien + 1) * int(ALIEN_RECT.x + 10)), f32((row + 1) * int(ALIEN_RECT.x + 10)), } } } } update_game :: proc(state: ^GameState) { using state // If we're entering the game screen then we need to setup initial state of the game variables if last_frame_screen != .GAMEPLAY { setup_game(state) log.info("Done setting up game") } // Press enter to change to ENDING screen if (rl.IsKeyPressed(rl.KeyboardKey.ENTER)) { state.screen = .ENDING log.info("Updated screen enum", state.screen) } // Press space to change to fire if (rl.IsKeyPressed(rl.KeyboardKey.SPACE)) { log.info("FIRE!") bullet := &bullets[bullet_index] bullet.alive = true bullet.position = player_pos bullet.position.y = bullet.position.y - f32((PLAYER_RECT.y / 2) + BULLET_RECT.y / 2) } if (rl.IsKeyDown(rl.KeyboardKey.RIGHT)) { player_pos.x = player_pos.x + f32(PLAYER_SPEED * delta_time) } if (rl.IsKeyDown(rl.KeyboardKey.LEFT)) { player_pos.x = player_pos.x - f32(PLAYER_SPEED * delta_time) } // movement update { for &bullet in bullets { if bullet.alive { bullet.position.y = bullet.position.y - f32(BULLET_SPEED * delta_time) } } } } draw_game :: proc(state: ^GameState) { using state rl.DrawRectangle(0, 0, state.screen_width, state.screen_height, rl.BLACK) // rl.DrawText("GAMEPLAY SCREEN", 20, 20, 40, rl.MAROON) // rl.DrawText("PRESS ENTER or TAP to JUMP to ENDING SCREEN", 130, 220, 20, rl.MAROON) rl.DrawCircle(c.int(player_pos.x), c.int(player_pos.y), f32(PLAYER_RECT.x / 2), rl.RED) for row in 0 ..< ALIEN_ROWS { for alien in 0 ..< ALIENS_PER_ROW { alien := &aliens[(row * ALIENS_PER_ROW) + alien] rl.DrawCircle( c.int(alien.position.x), c.int(alien.position.y), f32(ALIEN_RECT.x / 2), rl.YELLOW, ) } } for &bullet in bullets { if !bullet.alive { continue } rl.DrawCircle(c.int(bullet.position.x), c.int(bullet.position.y), f32(BULLET_RECT.x / 2), rl.WHITE) } // rl.DrawText("GAMEPLAY SCREEN", 20, 20, 40, rl.MAROON) }