Refactor props handling and inventory logic; add ghost prop preview
This commit is contained in:
+30
-14
@@ -8,11 +8,26 @@ class Prop
|
||||
# A prop is one that is placed at the center of a tile (radar, torch & chest)
|
||||
attr_reader :x, :y
|
||||
|
||||
def self.setup_sprites(path, frames)
|
||||
@frames_count = frames
|
||||
@spritesheet = Gosu::Image.load_tiles(path, 20, 20, retro: true)
|
||||
end
|
||||
|
||||
def self.spritesheet
|
||||
@spritesheet
|
||||
end
|
||||
|
||||
def self.frames_count
|
||||
@frames_count
|
||||
end
|
||||
|
||||
def self.ghost
|
||||
@spritesheet&.first
|
||||
end
|
||||
|
||||
def initialize(x, y)
|
||||
@x = x
|
||||
@y = y
|
||||
@frames_count = 0
|
||||
@spritesheet = nil
|
||||
@health = 100
|
||||
end
|
||||
|
||||
@@ -34,20 +49,21 @@ class Prop
|
||||
end
|
||||
|
||||
def update(dt)
|
||||
return unless Gosu.button_down?(Gosu::MS_LEFT)
|
||||
|
||||
return unless Gosu.button_down?(Gosu::MS_LEFT) || Gosu.button_down?(Gosu::KB_X)
|
||||
|
||||
player_x, player_y = $bus.get(:player_position) || [0, 0]
|
||||
|
||||
tile_x, tile_y = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round)
|
||||
|
||||
return unless tile_x == @x && tile_y == @y
|
||||
|
||||
mouse_x, mouse_y = $bus.get(:mouse_pos)
|
||||
cam_x, cam_y = $bus.get(:camera_pos)
|
||||
world_mouse_x = mouse_x + cam_x
|
||||
world_mouse_y = mouse_y + cam_y
|
||||
|
||||
return unless intersects?([world_mouse_x, world_mouse_y, 1, 1], self.rect)
|
||||
if Gosu.button_down?(Gosu::MS_LEFT)
|
||||
mouse_x, mouse_y = $bus.get(:mouse_pos)
|
||||
cam_x, cam_y = $bus.get(:camera_pos)
|
||||
world_mouse_x = mouse_x + cam_x
|
||||
world_mouse_y = mouse_y + cam_y
|
||||
return unless intersects?([world_mouse_x, world_mouse_y, 1, 1], self.rect)
|
||||
end
|
||||
|
||||
@health -= DESTRUCTION_SPEED * dt
|
||||
if @health <= 0
|
||||
@@ -60,16 +76,16 @@ class Prop
|
||||
end
|
||||
|
||||
def draw
|
||||
return unless @spritesheet
|
||||
return unless self.class.spritesheet
|
||||
|
||||
cam_x, cam_y = $bus.get(:camera_pos) || [0, 0]
|
||||
screen_x = @x * 120 + 90 - cam_x
|
||||
screen_y = @y * 120 + 90 - cam_y
|
||||
|
||||
elapsed = Gosu.milliseconds / 1000.0
|
||||
frame_index = ((elapsed * @frames_count).floor) % @frames_count
|
||||
frame_index = ((elapsed * self.class.frames_count).floor) % self.class.frames_count
|
||||
|
||||
@spritesheet[frame_index].draw(screen_x - 20, screen_y - 20, screen_y, 2, 2)
|
||||
self.class.spritesheet[frame_index].draw(screen_x - 20, screen_y - 20, screen_y, 2, 2)
|
||||
|
||||
if @health < 100
|
||||
percent = 1.0 - @health / 100.0
|
||||
@@ -81,7 +97,7 @@ class Prop
|
||||
bar_x = screen_x - w / 2
|
||||
bar_y = screen_y + h + 5
|
||||
|
||||
Gosu.draw_rect(bar_x, bar_y, bar_width, bar_height, Gosu::Color::RED, screen_y + 1)
|
||||
Gosu.draw_rect(bar_x, bar_y, bar_width, bar_height, Gosu::Color::RED, screen_y - 19)
|
||||
end
|
||||
|
||||
return unless DEBUG
|
||||
|
||||
+1
-5
@@ -1,11 +1,7 @@
|
||||
require_relative "base"
|
||||
|
||||
class Chest < Prop
|
||||
def initialize(x, y)
|
||||
super(x, y)
|
||||
@frames_count = 1
|
||||
@spritesheet = Gosu::Image.load_tiles("assets/images/chest.png", 20, 20, retro: true)
|
||||
end
|
||||
setup_sprites("assets/images/chest.png", 1)
|
||||
|
||||
def resources
|
||||
{ wood: rand(0..64), metal: rand(0..16), science: rand(0..4) }
|
||||
|
||||
+51
-5
@@ -58,8 +58,7 @@ class PropsHandler
|
||||
[start_room_x + 2, start_room_y + 2]
|
||||
].sample
|
||||
chest = Chest.new(x, y)
|
||||
@props << chest
|
||||
@grid[[x, y]] = chest
|
||||
add(chest)
|
||||
end
|
||||
|
||||
def nearby_props(rect)
|
||||
@@ -84,9 +83,7 @@ class PropsHandler
|
||||
|
||||
def add(prop)
|
||||
@props << prop
|
||||
|
||||
key = [prop.x, prop.y]
|
||||
@grid[key] = prop
|
||||
@grid[[prop.x, prop.y]] = prop
|
||||
end
|
||||
|
||||
def update(dt)
|
||||
@@ -97,10 +94,59 @@ class PropsHandler
|
||||
@grid.delete([prop.x, prop.y])
|
||||
end
|
||||
end
|
||||
if Gosu.button_down?(Gosu::KB_P) # place selected if it is a placeable item
|
||||
selected_item = $bus.get(:selected_item)
|
||||
if selected_item == :torch
|
||||
player_x, player_y = $bus.get(:player_position) || [0, 0]
|
||||
tile = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round)
|
||||
torch = Torch.new(*tile)
|
||||
return if @grid[[tile[0], tile[1]]] # can't place if something is already there
|
||||
return if $bus.get_all(:collides?, torch.rect).include?(:character) # can't place if colliding with player
|
||||
return unless $bus.get(:consume, :torch, 1)
|
||||
add(torch)
|
||||
elsif selected_item == :radar
|
||||
player_x, player_y = $bus.get(:player_position) || [0, 0]
|
||||
tile = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round)
|
||||
radar = Radar.new(*tile)
|
||||
return if @grid[[tile[0], tile[1]]]
|
||||
return if $bus.get_all(:collides?, radar.rect).include?(:character)
|
||||
return unless $bus.get(:consume, :radar, 1)
|
||||
add(radar)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def button_down(id, pos)
|
||||
#
|
||||
end
|
||||
|
||||
def draw
|
||||
cam = $bus.get(:camera_pos) || [0, 0]
|
||||
nearby_props([*cam, *SCREEN_SIZE]).each(&:draw)
|
||||
draw_ghost_prop!
|
||||
end
|
||||
|
||||
def draw_ghost_prop!
|
||||
# draw a ghost of the prop that would be placed if the player presses the place button,
|
||||
# to give them a preview of where it would go, also tint it red if it can't be placed there for any reason
|
||||
# or green if it can
|
||||
selected_item = $bus.get(:selected_item)
|
||||
return unless [:torch, :radar].include?(selected_item)
|
||||
cam_x, cam_y = $bus.get(:camera_pos) || [0, 0]
|
||||
player_x, player_y = $bus.get(:player_position) || [0, 0]
|
||||
x, y = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round)
|
||||
return if @grid[[x, y]]
|
||||
return if $bus.get(:count, selected_item) < 1
|
||||
world_x = x * 120 + 90
|
||||
world_y = y * 120 + 90
|
||||
screen_x = world_x - cam_x
|
||||
screen_y = world_y - cam_y
|
||||
possible = !$bus.get_all(:collides?, [world_x - 20, world_y - 20, 40, 40]).include?(:character)
|
||||
color = possible ? Gosu::Color.new(255 * 0.7, 128, 239, 128) : Gosu::Color.new(255 * 0.7, 255, 116, 108)
|
||||
if selected_item == :torch
|
||||
Torch.ghost.draw(screen_x - 20, screen_y - 20, screen_y, 2, 2, color)
|
||||
elsif selected_item == :radar
|
||||
Radar.ghost.draw(screen_x - 20, screen_y - 20, screen_y, 2, 2, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
+1
-5
@@ -1,11 +1,7 @@
|
||||
require_relative "base"
|
||||
|
||||
class Radar < Prop
|
||||
def initialize(x, y)
|
||||
super(x, y)
|
||||
@frames_count = 4
|
||||
@spritesheet = Gosu::Image.load_tiles("assets/images/radar.png", 20, 20, retro: true)
|
||||
end
|
||||
setup_sprites("assets/images/radar.png", 4)
|
||||
|
||||
def resources
|
||||
{ wood: rand(0..2), metal: rand(0..8), science: rand(0..2) }
|
||||
|
||||
+1
-5
@@ -1,11 +1,7 @@
|
||||
require_relative "base"
|
||||
|
||||
class Torch < Prop
|
||||
def initialize(x, y)
|
||||
super(x, y)
|
||||
@frames_count = 4
|
||||
@spritesheet = Gosu::Image.load_tiles("assets/images/torch.png", 20, 20, retro: true)
|
||||
end
|
||||
setup_sprites("assets/images/torch.png", 4)
|
||||
|
||||
def resources
|
||||
{ wood: rand(0..8) }
|
||||
|
||||
Reference in New Issue
Block a user