1.44mb-gamejam

submission for the 1.44mb game jam - https://2pgarcade.com/contest-144mb.html
git clone git://brookjeynes.dev/bjeynes/1.44mb-gamejam.git
Log | Files | Refs

main.zig (7785B)


      1 const raylib = @import("raylib");
      2 const raymath = @import("raymath");
      3 
      4 const Bullet = @import("./bullet.zig");
      5 const constants = @import("./constants.zig");
      6 const Grunt = @import("./enemy_types/grunt.zig");
      7 const Player = @import("./player.zig");
      8 const GameState = @import("./state.zig").GameState;
      9 const Timer = @import("./timer.zig");
     10 const Button = @import("./ui.zig").Button;
     11 const UpgradeId = @import("./upgrade.zig").UpgradeId;
     12 const upgrade_meta = @import("./upgrade.zig").meta;
     13 const upgrade_fields = @typeInfo(UpgradeId).@"enum".fields;
     14 
     15 const start_button = Button.new(
     16     .{ .x = 100, .y = 70 },
     17     .{
     18         .x = (constants.screen_width / 2) - 50,
     19         .y = (constants.screen_height / 2) - 35,
     20     },
     21 );
     22 
     23 pub fn main() !void {
     24     var game_state: GameState = .init();
     25 
     26     raylib.InitWindow(
     27         constants.screen_width,
     28         constants.screen_height,
     29         constants.screen_title,
     30     );
     31     defer raylib.CloseWindow();
     32 
     33     raylib.SetTargetFPS(constants.fps);
     34     while (!raylib.WindowShouldClose()) {
     35         switch (game_state.screen) {
     36             .title => {
     37                 raylib.BeginDrawing();
     38                 defer raylib.EndDrawing();
     39 
     40                 raylib.ClearBackground(raylib.RAYWHITE);
     41 
     42                 raylib.DrawRectangleV(
     43                     start_button.position,
     44                     start_button.size,
     45                     raylib.BLACK,
     46                 );
     47 
     48                 const start_button_text = "start";
     49                 const start_button_font_size: f32 = 18.0;
     50                 const start_button_text_width = raylib.MeasureText(start_button_text, start_button_font_size);
     51                 raylib.DrawText(
     52                     start_button_text,
     53                     @intFromFloat(start_button.position.x + (start_button.size.x - @as(f32, @floatFromInt(start_button_text_width))) / 2),
     54                     @intFromFloat(start_button.position.y + (start_button.size.y - start_button_font_size) / 2),
     55                     start_button_font_size,
     56                     raylib.WHITE,
     57                 );
     58 
     59                 if (start_button.clicked(raylib.GetMousePosition())) {
     60                     game_state.reset();
     61                 }
     62             },
     63             .upgrade => {
     64                 raylib.BeginDrawing();
     65                 defer raylib.EndDrawing();
     66 
     67                 raylib.ClearBackground(raylib.RAYWHITE);
     68 
     69                 raylib.DrawText("upgrades", 20, 40, 30, raylib.BLACK);
     70                 raylib.DrawText(
     71                     raylib.TextFormat("points: %d", game_state.enemies_killed),
     72                     20,
     73                     90,
     74                     20,
     75                     raylib.BLACK,
     76                 );
     77                 raylib.DrawText(
     78                     raylib.TextFormat("last run: %0.1fs", game_state.time),
     79                     20,
     80                     120,
     81                     18,
     82                     raylib.GRAY,
     83                 );
     84 
     85                 const row_size: raylib.Vector2 = .{ .x = 700, .y = 60 };
     86                 const row_spacing: f32 = 80;
     87                 var row_position: raylib.Vector2 = .{ .x = 50, .y = 200 };
     88 
     89                 inline for (upgrade_fields) |field| {
     90                     const id: UpgradeId = @enumFromInt(field.value);
     91                     const meta = upgrade_meta[@intFromEnum(id)];
     92 
     93                     const level = game_state.upgrades.level(id);
     94                     const cost = game_state.upgrades.cost(id);
     95                     const buyable = !game_state.upgrades.maxed(id) and game_state.enemies_killed >= cost;
     96 
     97                     const row = Button.new(row_size, row_position);
     98                     raylib.DrawRectangleV(
     99                         row.position,
    100                         row.size,
    101                         if (buyable) raylib.BLACK else raylib.GRAY,
    102                     );
    103                     raylib.DrawText(
    104                         meta.name.ptr,
    105                         @intFromFloat(row.position.x + 20),
    106                         @intFromFloat(row.position.y + row.size.y / 2 - 10),
    107                         20,
    108                         raylib.WHITE,
    109                     );
    110 
    111                     if (game_state.upgrades.maxed(id)) {
    112                         raylib.DrawText(
    113                             "MAX",
    114                             @intFromFloat(row.position.x + row.size.x - 120),
    115                             @intFromFloat(row.position.y + row.size.y / 2 - 10),
    116                             18,
    117                             raylib.WHITE,
    118                         );
    119                     } else {
    120                         raylib.DrawText(
    121                             raylib.TextFormat("lvl %d/%d  cost %d", level, meta.max_level, cost),
    122                             @intFromFloat(row.position.x + row.size.x - 300),
    123                             @intFromFloat(row.position.y + row.size.y / 2 - 10),
    124                             18,
    125                             raylib.WHITE,
    126                         );
    127                     }
    128 
    129                     if (buyable and row.clicked(raylib.GetMousePosition())) {
    130                         game_state.enemies_killed -= cost;
    131                         _ = game_state.upgrades.upgrade(id);
    132                     }
    133 
    134                     row_position.y += row_spacing;
    135                 }
    136 
    137                 const continue_button = Button.new(
    138                     .{ .x = 300, .y = 60 },
    139                     .{
    140                         .x = (constants.screen_width / 2) - 150,
    141                         .y = row_position.y + 60,
    142                     },
    143                 );
    144                 raylib.DrawRectangleV(
    145                     continue_button.position,
    146                     continue_button.size,
    147                     raylib.BLACK,
    148                 );
    149                 raylib.DrawText(
    150                     "continue",
    151                     @intFromFloat(continue_button.position.x + continue_button.size.x / 2 - 30),
    152                     @intFromFloat(continue_button.position.y + continue_button.size.y / 2 - 10),
    153                     20,
    154                     raylib.WHITE,
    155                 );
    156 
    157                 if (continue_button.clicked(raylib.GetMousePosition())) {
    158                     game_state.reset();
    159                 }
    160             },
    161             .gameplay => {
    162                 // -- tick
    163                 for (0..game_state.enemy_count) |idx| {
    164                     game_state.enemies[idx].move(game_state.player.position);
    165                 }
    166                 game_state.player.handleMovement();
    167                 game_state.tick();
    168 
    169                 // -- render
    170                 raylib.BeginDrawing();
    171                 defer raylib.EndDrawing();
    172 
    173                 raylib.ClearBackground(raylib.RAYWHITE);
    174 
    175                 // Render entities
    176                 game_state.player.render();
    177                 for (0..game_state.enemy_count) |idx| {
    178                     game_state.enemies[idx].render();
    179                 }
    180 
    181                 game_state.orphaned_bullet_pool.render(.{ .x = constants.screen_width, .y = constants.screen_height });
    182 
    183                 // Health overlay
    184                 const health_percent: f32 = @max(
    185                     0,
    186                     @min(1, game_state.player.health / game_state.player.max_health),
    187                 );
    188                 const damage_percent = 1 - health_percent;
    189                 raylib.DrawRectangle(
    190                     0,
    191                     0,
    192                     constants.screen_width,
    193                     constants.screen_height,
    194                     raylib.ColorAlpha(raylib.RED, damage_percent),
    195                 );
    196 
    197                 // Score
    198                 raylib.DrawText(
    199                     raylib.TextFormat("score: %0.0f", game_state.time),
    200                     10,
    201                     10,
    202                     18,
    203                     raylib.BLACK,
    204                 );
    205             },
    206         }
    207     }
    208 }