diff options
Diffstat (limited to 'eepers.adb')
-rw-r--r-- | eepers.adb | 108 |
1 files changed, 67 insertions, 41 deletions
@@ -73,6 +73,11 @@ procedure Eepers is return Color_From_HSV(H, S, V); end; + procedure Increment(X: in out Integer) is + begin + X := X + 1; + end; + Palette_RGB: array (Palette) of Color := (others => (A => 255, others => 0)); Palette_HSV: array (Palette) of HSV := (others => (others => 0)); @@ -163,6 +168,7 @@ procedure Eepers is TUTORIAL_BOMB_WAIT_TIME_SECS : constant C_Float := 4.0; TUTORIAL_SPRINT_WAIT_TIME_SECS : constant C_Float := 15.0; POPUP_ANIMATION_DURATION : constant C_Float := 0.1; + RESTART_TIMEOUT_SECS : constant Double := 2.0; type IVector2 is record X, Y: Integer; @@ -220,7 +226,12 @@ procedure Eepers is return (A.X*S, A.Y*S); end; - type Item_Kind is (Item_None, Item_Key, Item_Bomb_Gen, Item_Checkpoint); + type Item_Kind is ( + Item_None, + Item_Key, + Item_Bomb_Refill, + Item_Checkpoint, + Item_Bomb_Slot); type Item is record Kind: Item_Kind := Item_None; Position: IVector2; @@ -278,6 +289,7 @@ procedure Eepers is Bombs: Integer := 0; Bomb_Slots: Integer := 1; Dead: Boolean := False; + Death_Time: Double; end record; type Eeper_Kind is (Eeper_Guard, Eeper_Mother, Eeper_Gnome, Eeper_Father); @@ -306,7 +318,7 @@ procedure Eepers is type Bomb_State_Array is array (1..10) of Bomb_State; - type Eeper_Index is range 1..15; + type Eeper_Index is range 1..30; type Eeper_Array is array (Eeper_Index) of Eeper_State; type Checkpoint_State is record @@ -645,25 +657,27 @@ procedure Eepers is Level_Wall, Level_Door, Level_Checkpoint, - Level_Bomb_Gen, + Level_Bomb_Refill, Level_Barricade, Level_Key, Level_Player, - Level_Father); + Level_Father, + Level_Bomb_Slot); Level_Cell_Color: constant array (Level_Cell) of Color := ( - Level_None => Get_Color(16#00000000#), - Level_Gnome => Get_Color(16#FF9600FF#), - Level_Mother => Get_Color(16#96FF00FF#), - Level_Guard => Get_Color(16#00FF00FF#), - Level_Floor => Get_Color(16#FFFFFFFF#), - Level_Wall => Get_Color(16#000000FF#), - Level_Door => Get_Color(16#00FFFFFF#), - Level_Checkpoint => Get_Color(16#FF00FFFF#), - Level_Bomb_Gen => Get_Color(16#FF0000FF#), - Level_Barricade => Get_Color(16#FF0096FF#), - Level_Key => Get_Color(16#FFFF00FF#), - Level_Player => Get_Color(16#0000FFFF#), - Level_Father => Get_Color(16#265FDAFF#)); + Level_None => Get_Color(16#00000000#), + Level_Gnome => Get_Color(16#FF9600FF#), + Level_Mother => Get_Color(16#96FF00FF#), + Level_Guard => Get_Color(16#00FF00FF#), + Level_Floor => Get_Color(16#FFFFFFFF#), + Level_Wall => Get_Color(16#000000FF#), + Level_Door => Get_Color(16#00FFFFFF#), + Level_Checkpoint => Get_Color(16#FF00FFFF#), + Level_Bomb_Refill => Get_Color(16#FF0000FF#), + Level_Barricade => Get_Color(16#FF0096FF#), + Level_Key => Get_Color(16#FFFF00FF#), + Level_Player => Get_Color(16#0000FFFF#), + Level_Father => Get_Color(16#265FDAFF#), + Level_Bomb_Slot => Get_Color(16#BC5353FF#)); function Cell_By_Color(Col: Color; Out_Cel: out Level_Cell) return Boolean is begin @@ -751,9 +765,12 @@ procedure Eepers is when Level_Checkpoint => Game.Map(Row, Column) := Cell_Floor; Allocate_Item(Game, (Column, Row), Item_Checkpoint); - when Level_Bomb_Gen => + when Level_Bomb_Refill => + Game.Map(Row, Column) := Cell_Floor; + Allocate_Item(Game, (Column, Row), Item_Bomb_Refill); + when Level_Bomb_Slot => Game.Map(Row, Column) := Cell_Floor; - Allocate_Item(Game, (Column, Row), Item_Bomb_Gen); + Allocate_Item(Game, (Column, Row), Item_Bomb_Slot); when Level_Barricade => Game.Map(Row, Column) := Cell_Barricade; when Level_Key => @@ -833,13 +850,15 @@ procedure Eepers is begin Draw_Rectangle_V(To_Vector2(Item.Position)*Cell_Size + Cell_Size*0.5 - Checkpoint_Item_Size*0.5, Checkpoint_Item_Size, Palette_RGB(COLOR_CHECKPOINT)); end; - when Item_Bomb_Gen => + when Item_Bomb_Refill => if Item.Cooldown > 0 then Draw_Bomb(Item.Position, Color_Brightness(Palette_RGB(COLOR_BOMB), -0.5)); Draw_Number(Item.Position, Item.Cooldown, Palette_RGB(COLOR_LABEL)); else Draw_Bomb(Item.Position, Palette_RGB(COLOR_BOMB)); end if; + when Item_Bomb_Slot => + Draw_Bomb(Item.Position, Palette_RGB(COLOR_DOORKEY)); end case; end loop; end; @@ -901,7 +920,7 @@ procedure Eepers is Game.Player.Keys := Game.Player.Keys + 1; Item.Kind := Item_None; Play_Sound(Key_Pickup_Sound); - when Item_Bomb_Gen => if + when Item_Bomb_Refill => if Game.Player.Bombs < Game.Player.Bomb_Slots and then Item.Cooldown <= 0 then @@ -909,6 +928,10 @@ procedure Eepers is Item.Cooldown := BOMB_GENERATOR_COOLDOWN; Play_Sound(Bomb_Pickup_Sound); end if; + when Item_Bomb_Slot => + Item.Kind := Item_None; + Increment(Game.Player.Bomb_Slots); + Game.Player.Bombs := Game.Player.Bomb_Slots; when Item_Checkpoint => Item.Kind := Item_None; Game.Player.Bombs := Game.Player.Bomb_Slots; @@ -930,6 +953,12 @@ procedure Eepers is end; end; + procedure Kill_Player(Game: in out Game_State) is + begin + Game.Player.Dead := True; + Game.Player.Death_Time := Get_Time; + end; + procedure Explode(Game: in out Game_State; Position: in IVector2) is procedure Explode_Line(Dir: Direction) is New_Position: IVector2 := Position; @@ -944,7 +973,7 @@ procedure Eepers is Game.Map(New_Position.Y, New_Position.X) := Cell_Explosion; if New_Position = Game.Player.Position then - Game.Player.Dead := True; + Kill_Player(Game); end if; for Eeper of Game.Eepers loop @@ -1037,13 +1066,11 @@ procedure Eepers is end; Command_Queue: Command_Queue_Record; - Any_Key_Pressed: Boolean := False; Holding_Shift: Boolean := False; procedure Swallow_Player_Input is begin Command_Queue.Size := 0; - Any_Key_Pressed := False; Holding_Shift := False; end; @@ -1134,7 +1161,7 @@ procedure Eepers is when Eeper_Guard | Eeper_Mother => Recompute_Path_For_Eeper(Game, Me, GUARD_STEPS_LIMIT, GUARD_STEP_LENGTH_LIMIT); if Eeper.Path(Eeper.Position.Y, Eeper.Position.X) = 0 then - Game.Player.Dead := True; + Kill_Player(Game); Eeper.Eyes := Eyes_Surprised; elsif Eeper.Path(Eeper.Position.Y, Eeper.Position.X) > 0 then if Eeper.Attack_Cooldown <= 0 then @@ -1175,7 +1202,7 @@ procedure Eepers is Eeper.Eyes_Target := Game.Player.Position; if Inside_Of_Rect(Eeper.Position, Eeper.Size, Game.Player.Position) then - Game.Player.Dead := True; + Kill_Player(Game); end if; else Eeper.Eyes := Eyes_Closed; @@ -1230,7 +1257,7 @@ procedure Eepers is procedure Game_Items_Turn(Game: in out Game_State) is begin for Item of Game.Items loop - if Item.Kind = Item_Bomb_Gen then + if Item.Kind = Item_Bomb_Refill then if Item.Cooldown > 0 then Item.Cooldown := Item.Cooldown - 1; end if; @@ -1354,7 +1381,7 @@ procedure Eepers is Draw_Eyes(Screen_Player_Position(Game), Cell_Size, Game.Player.Eyes_Angle, Game.Player.Prev_Eyes, Game.Player.Eyes, Game.Turn_Animation); end if; - if Any_Key_Pressed then + if (Get_Time - Game.Player.Death_Time) > RESTART_TIMEOUT_SECS then Game_Restore_Checkpoint(Game); Game.Player.Dead := False; end if; @@ -1463,11 +1490,16 @@ procedure Eepers is end; end loop; - for Index in 1..Game.Player.Bombs loop + for Index in 1..Game.Player.Bomb_Slots loop declare - Position: constant Vector2 := (100.0 + C_float(Index - 1)*Cell_Size.X, 200.0); + Padding: constant C_Float := Cell_Size.X*0.5; + Position: constant Vector2 := (100.0 + C_float(Index - 1)*(Cell_Size.X + Padding), 200.0); begin - Draw_Circle_V(Position, Cell_Size.X*0.5, Palette_RGB(COLOR_BOMB)); + if Index <= Game.Player.Bombs then + Draw_Circle_V(Position, Cell_Size.X*0.5, Palette_RGB(COLOR_BOMB)); + else + Draw_Circle_V(Position, Cell_Size.X*0.5, Color_Brightness(Palette_RGB(COLOR_BOMB), -0.5)); + end if; end; end loop; @@ -1546,7 +1578,7 @@ procedure Eepers is end; Game: Game_State; - Title: constant Char_Array := To_C("Eepers (v1.3)"); + Title: constant Char_Array := To_C("Eepers (v1.4)"); Palette_Editor: Boolean := False; Palette_Editor_Choice: Palette := Palette'First; @@ -1650,11 +1682,6 @@ begin end if; end if; - Any_Key_Pressed := False; - while not Any_Key_Pressed and then Get_Key_Pressed /= KEY_NULL loop - Any_Key_Pressed := True; - end loop; - if DEVELOPMENT then if Is_Key_Pressed(KEY_R) then Load_Game_From_Image("assets/map.png", Game, Update_Player => False, Update_Camera => False); @@ -1789,12 +1816,13 @@ begin Close_Window; end; --- TODO: Increase Bomb Slots item. -- TODO: Items in HUD may sometimes blend with the background --- TODO: Restart is annoying. It's easy to accidentally hit restart after death. +-- TODO: Different palettes on each NG+ +-- TODO: NG+ must make the Game harder while retaining the collected bomb slots -- TODO: The gnome blocking trick was never properly explained. -- We should introduce an extra room that entirely relies on that mechanic, -- so it does not feel out of place, when you discover it on Mother. +-- TODO: The puzzle with Gnome blocking Guard repeated twice (which sucks) -- TODO: Footstep variation for Mother/Guard bosses (depending on the distance traveled?) -- TODO: Footsteps for mother should be lower -- TODO: Restarting should be considered a turn @@ -1816,8 +1844,6 @@ end; -- times died etc. -- TODO: Animate key when you pick it up -- Smoothly move it into the HUD. --- TODO: Different palettes depending on the area --- Or maybe different palette for each NG+ -- TODO: Particles -- - Player Death animation -- - Eeper Death animation |