Class: Core::Game::Map
Instance Attribute Summary collapse
-
#layers ⇒ Object
readonly
Returns the value of attribute layers.
-
#module ⇒ Object
readonly
Returns the value of attribute module.
-
#objects ⇒ Object
Returns the value of attribute objects.
-
#properties ⇒ Object
readonly
Returns the value of attribute properties.
-
#xoff ⇒ Object
Returns the value of attribute xoff.
-
#yoff ⇒ Object
Returns the value of attribute yoff.
Instance Method Summary collapse
- #astar(node_start, node_goal) ⇒ Object
- #create_static_collision ⇒ Object
-
#draw(xoff, yoff) ⇒ Object
parameters are scrolling, instance variables are world positions.
- #generate_costmap ⇒ Object
- #generate_successor_nodes(anode, costmap) ⇒ Object
- #height ⇒ Object
-
#initialize(props, layers, objects, mod) ⇒ Map
constructor
A new instance of Map.
- #left ⇒ Object
- #lower ⇒ Object
- #passable?(x, y, player = false) ⇒ Boolean
- #right ⇒ Object
- #show_path(anode) ⇒ Object
- #upper ⇒ Object
- #width ⇒ Object
Constructor Details
#initialize(props, layers, objects, mod) ⇒ Map
Returns a new instance of Map.
10 11 12 13 14 15 16 17 |
# File 'lib/game/map/map.rb', line 10 def initialize(props, layers, objects, mod) @properties = props @layers = layers @objects = objects @xoff = @yoff = 0 @module = mod create_static_collision end |
Instance Attribute Details
#layers ⇒ Object (readonly)
Returns the value of attribute layers.
8 9 10 |
# File 'lib/game/map/map.rb', line 8 def layers @layers end |
#module ⇒ Object (readonly)
Returns the value of attribute module.
8 9 10 |
# File 'lib/game/map/map.rb', line 8 def module @module end |
#objects ⇒ Object
Returns the value of attribute objects.
9 10 11 |
# File 'lib/game/map/map.rb', line 9 def objects @objects end |
#properties ⇒ Object (readonly)
Returns the value of attribute properties.
8 9 10 |
# File 'lib/game/map/map.rb', line 8 def properties @properties end |
#xoff ⇒ Object
Returns the value of attribute xoff.
9 10 11 |
# File 'lib/game/map/map.rb', line 9 def xoff @xoff end |
#yoff ⇒ Object
Returns the value of attribute yoff.
9 10 11 |
# File 'lib/game/map/map.rb', line 9 def yoff @yoff end |
Instance Method Details
#astar(node_start, node_goal) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/game/map/map.rb', line 171 def astar(node_start, node_goal) iterations = 0 open = AStar::PriorityQueue.new() closed = AStar::PriorityQueue.new() node_start.calc_h(node_goal) open.push(node_start) costmap = generate_costmap while !open.empty? do iterations += 1 #keep track of how many times this itersates node_current = open.find_best if node_current == node_goal #puts("Iterations: #{iterations}") #show_path(node_current) return node_current end generate_successor_nodes(node_current, costmap) { |node_successor| #now doing for each successor node of node_current node_successor.calc_g(node_current) #skip to next node_successor if better one already on open or closed list if open_successor=open.find(node_successor) then if open_successor<=node_successor then next end #need to account for nil result end if closed_successor=closed.find(node_successor) then if closed_successor<=node_successor then next end end #still here, then there's no better node yet, so remove any copies of this node on open/closed lists open.remove(node_successor) closed.remove(node_successor) # set the parent node of node_successor to node_current node_successor.parent=node_current # set h to be the estimated distance to node_goal using the heuristic node_successor.calc_h(node_goal) # so now we know this is the best copy of the node so far, so put it onto the open list open.push(node_successor) } #now we've gone through all the successors, so the current node can be closed closed.push(node_current) end end |
#create_static_collision ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/game/map/map.rb', line 27 def create_static_collision return if @layers.empty? tiles = [] @layers.each { |l| i = 0 l.filled.each { |row| row.each { |tile| if !tile if tiles[i] == false i += 1 next else tiles[i] = true i += 1 next end end tiles[i] = tile.passable? i += 1 } } } @collision = Core::CollisionLayer.new(@layers.first.filled.first.size, @layers.first.filled.size, tiles) end |
#draw(xoff, yoff) ⇒ Object
parameters are scrolling, instance variables are world positions
53 54 55 56 57 58 59 60 61 |
# File 'lib/game/map/map.rb', line 53 def draw(xoff, yoff) @layers.each { |l| l.filled.each { |ary| ary.each { |tile| tile.draw(xoff+@xoff, yoff+@yoff) if tile } } } end |
#generate_costmap ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/game/map/map.rb', line 116 def generate_costmap map = [] x = 0 @collision.tiles.each { |ary| cary = [] y = 0 ary.each { |tile| if tile obj = Core.window.state.find_object(y*32, x*32) if obj and !obj.through cary.push(0) y += 1 next end cary.push(1) else cary.push(0) end y += 1 } map.push(cary) x += 1 } return map end |
#generate_successor_nodes(anode, costmap) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/game/map/map.rb', line 142 def generate_successor_nodes(anode, costmap) height = costmap.size width = costmap.first.size # determine nodes bordering this one - only N,S,E,W for now # no boundary condition check, eg if anode.x==-4 # considers a wall to be a 0 so therefore not allow that to be a neighbour north = costmap[anode.y-1][anode.x] unless (anode.y-1) < 0 #boundary check for -1 south = costmap[anode.y+1][anode.x] unless (anode.y+1) > (height - 1) east = costmap[anode.y][anode.x+1] unless (anode.x+1) > (width - 1) west = costmap[anode.y][anode.x-1] unless (anode.x-1) < 0 #boundary check for -1 if (west && west > 0) # not on left edge, so provide a left-bordering node newnode = AStar::Node.new((anode.x-1),anode.y,costmap[anode.y][(anode.x-1)]) yield newnode end if (east && east > 0) # not on right edge, so provide a right-bordering node newnode = AStar::Node.new((anode.x+1),anode.y,costmap[anode.y][(anode.x+1)]) yield newnode end if (north && north > 0) # not on left edge, so provide a left-bordering node newnode = AStar::Node.new(anode.x,(anode.y-1),costmap[(anode.y-1)][anode.x]) yield newnode end if (south && south > 0) # not on right edge, so provide a right-bordering node newnode = AStar::Node.new(anode.x,(anode.y+1),costmap[(anode.y+1)][anode.x]) yield newnode end end |
#height ⇒ Object
23 24 25 |
# File 'lib/game/map/map.rb', line 23 def height return @properties[:height] end |
#left ⇒ Object
238 239 240 |
# File 'lib/game/map/map.rb', line 238 def left return @properties[:left] end |
#lower ⇒ Object
234 235 236 |
# File 'lib/game/map/map.rb', line 234 def lower return @properties[:lower] end |
#passable?(x, y, player = false) ⇒ Boolean
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/game/map/map.rb', line 63 def passable?(x, y, player=false) if !player && ((x/32) < 0 or (x/32) >= width or (y/32) < 0 or (y/32) >= height) return false elsif player if (x/32).to_i >= width if Core.window.state.map.right.passable?(0, y, true) Core.window.state.map.load(Core.window.state.map.right.properties[:file]) Core.window.state.map.player.teleport(0, y / 32) return true else return false end elsif (x/32).to_i < 0 if Core.window.state.map.left.passable?((Core.window.state.map.left.width - 1) * 32, y, true) Core.window.state.map.load(Core.window.state.map.left.properties[:file]) Core.window.state.map.player.teleport(Core.window.state.map.current.width, y / 32) return true else return false end elsif (y/32).to_i >= height if Core.window.state.map.left.passable?(x, 0, true) Core.window.state.map.load(Core.window.state.map.lower.properties[:file]) Core.window.state.map.player.teleport(x / 32, 0) return true else return false end elsif (y/32).to_i < 0 if Core.window.state.map.left.passable?(x, (Core.window.state.map.upper.height - 1) * 32, true) Core.window.state.map.load(Core.window.state.map.upper.properties[:file]) Core.window.state.map.player.teleport(x / 32, Core.window.state.map.current.height) return true else return false end end end begin p = @collision.tiles[y/32][x/32] rescue puts("Collision out of bounds: #{x/32}|#{y/32}") end if p obj = Core.window.state.find_object(x, y) if !obj return true end p = obj.through end return p end |
#right ⇒ Object
242 243 244 |
# File 'lib/game/map/map.rb', line 242 def right return @properties[:right] end |
#show_path(anode) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/game/map/map.rb', line 211 def show_path(anode) #shows the path back from node 'anode' by following the parent pointer curr = anode pathmap = generate_costmap while curr.parent do pathmap[curr.y][curr.x] = '*' curr = curr.parent end pathmap[curr.y][curr.x] = '*' pathstr="" pathmap.each_index do |row| pathmap[row].each_index do |col| pathstr<<"|#{pathmap[row][col]}" end pathstr<<"|\n" end puts(pathstr) end |
#upper ⇒ Object
230 231 232 |
# File 'lib/game/map/map.rb', line 230 def upper return @properties[:upper] end |
#width ⇒ Object
19 20 21 |
# File 'lib/game/map/map.rb', line 19 def width return @properties[:width] end |