-
Notifications
You must be signed in to change notification settings - Fork 0
/
map.rb
85 lines (70 loc) · 2.95 KB
/
map.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require 'rubygame'
require_relative './cell.rb'
require_relative './custom_events.rb'
include Rubygame
# This class will contain our map, which is made up of an array of Cell instances
class Map
include EventHandler::HasEventHandler
attr_reader :cells, :cells_at
def initialize
@cells = [] # store all cells for easy loop access
@cells_at = [] # store all cells for easy coord access
@updated_cells = [] # store cells that should be redrawn during the next step
# Populate the array of cells based on defined map size
(0..MAP_SIZE - 1).each do |x|
@cells_at[x] = []
(0..MAP_SIZE - 1).each do |y|
@cells << @cells_at[x][y] = Cell.new([x,y])
end
end
# This line just "forwards" events to the appropriate method
make_magic_hooks(CellDugEvent => :cell_dug, PlayerMovedEvent => :player_moved)
# Build a 2 cell high "above ground" area at the top of the map.
# Note: The player may not build ladders up here. Also, this is where the shops will be. :)
make_above_ground
# Populate the map with some scattered boulders, which cannot be dug through or anything.
# TODO: give rocks gravity, so they smash a players head if he tunnels directly underneath one.
make_some_random_rocks
end
# I'm just setting @sky to true on the cells I deem to be worthy of above-ground-ness
def make_above_ground
(0..MAP_SIZE - 1).each do |x|
(0..1).each do |y|
@cells_at[x][y].sky = true
end
end
end
# Method to make random rocks
def make_some_random_rocks
count = 5 + rand(10) # somewhere from 5-15 rocks will do, i guess
count.times do
x = rand(MAP_SIZE - 1)
y = rand(MAP_SIZE - 3) + 2 # being careful not to put rocks above ground!
puts "making rock at: #{x}, #{y}"
@cells_at[x][y].rock = true
end
end
# If Map receives a CellDug event, it marks the appropriate cell as dug.
def cell_dug(event)
target_cell = @cells_at[event.cell_coords[0]][event.cell_coords[1]]
puts "Digging cell: " + target_cell.to_s
target_cell.dug = true
end
# If it gets a PlayerMoved event, it puts the vacated cell into the @updated_cells list,
# so that the cell will be redrawn (to erase the player) on the next loop.
# TODO: see if it would be smarter to do something like Player#undraw instead
def player_moved(event)
vacated_cell = @cells_at[event.cell_coords[0]][event.cell_coords[1]]
@updated_cells << vacated_cell
end
# Note that Map doesn't include Sprite, so it doesn't have it's own #draw method.
# Instead I delegate all of the drawing to the cells, which can draw themselves where they belong
def draw(screen)
@cells.each { |cell| cell.draw(screen) }
end
# Sometimes I only want to draw the cells that have changed in some way, to save precious screen-drawing-overhead-time-stuff
def draw_changes(screen)
@updated_cells.each { |cell| cell.draw(screen) }
@updated_cells.clear
end
end