Skip to content

Instantly share code, notes, and snippets.

@poemdexter
Created April 9, 2012 21:17
Show Gist options
  • Save poemdexter/2346603 to your computer and use it in GitHub Desktop.
Save poemdexter/2346603 to your computer and use it in GitHub Desktop.
# this is also what the player.rb looks like
class Enemy
def initialize(window)
@skeleton_sprite = Gosu::Image.new(window, "skeleton.bmp", false)
@x = @y = 19
end
def draw
@skeleton_sprite.draw(24*@x, 24*@y, 1)
end
def reposition(x, y)
@x = (x/24).floor
@y = (y/24).floor
end
def position
return [@x,@y]
end
end
class Pathfinder
def get_path(start, finish, world)
@open_list = []
@closed_list = []
@finish = finish
@world = world
# moving to ANY square costs 1, even diagonals
@movement_cost = 1
found_path = false
###
### Nodes are:
### [heuristic, open list count, position, parent, moved cost]
###
#add starting point to open list
starting_point = [-1, 0, start, start, 0]
@open_list << starting_point
#while open_list isn't empty or fail to find square
while !@open_list.empty?
# pick lowest heuristic (thanks sort!) and get more path options
next_node = @open_list[0]
@open_list.delete(next_node)
@closed_list << next_node
if found_finish_in_closed
found_path = true
break
end # finish condition
get_adjacent_squares(next_node)
@open_list.sort!
end
if found_path
# work backwards from finish node, go to parent's node until get to start.
return nil
else
return nil
end
end
def get_adjacent_squares(node)
moved_cost = node[4]
point = node[2]
#N
new_point = [point[0],point[1]-1]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#NE
new_point = [point[0]+1,point[1]-1]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#E
new_point = [point[0]+1,point[1]]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#SE
new_point = [point[0]+1,point[1]+1]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#S
new_point = [point[0],point[1]+1]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#SW
new_point = [point[0]-1,point[1]+1]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#W
new_point = [point[0]-1,point[1]]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
#NW
new_point = [point[0]-1,point[1]-1]
if is_new_point_in_open(new_point)
is_better_path(new_point,node)
elsif can_add_to_open(new_point)
@open_list << [calc_heuristic(new_point,moved_cost),@open_list.count,new_point,point,moved_cost+@movement_cost]
end
end
def is_new_point_in_open(point)
@open_list.any?{|x| x[2] == point}
end
def found_finish_in_closed
@closed_list.any?{|x| x[2] == @finish}
end
# check to see if path to node from new_point is better
# if node's move cost (G) is lower if we use new_point to get there, then yes
def is_better_path(new_point, node)
new_node = @open_list.find{|x| x[2] == new_point}
if new_node[4] + @movement_cost < node[4]
node[3] = new_point # set parent to new_point
node[0] = calc_heuristic(node[2], new_node[4]) # recalculate heuristic for node
end
end
# ignore squares on closed_list and check bounds of world
def can_add_to_open(p)
!@closed_list.include?(p) && is_within_bounds(p)
end
def is_within_bounds(point)
x = point[0]
y = point[1]
x.between?(0,@world.width-1) && y.between?(0,@world.height-1)
end
# = path score (heuristic or F) = manhattan distance (H) + movement cost (G)
def calc_heuristic(point, move)
return ((point[0] - @finish[0]).abs + (point[1] - @finish[1]).abs) + move + @movement_cost
end
end
require 'gosu'
require_relative 'player'
require_relative 'world'
require_relative 'enemy'
require_relative 'pathfinder'
class GameWindow < Gosu::Window
def initialize
super 480, 480, false
self.caption = "Dan's Shit Game For Idiots: Dubstep Protocol"
@world = World.new(self)
@player = Player.new(self)
@enemy = Enemy.new(self)
@pathfinder = Pathfinder.new
end
def needs_cursor?
true
end
def update
end
def draw
@world.draw
@player.draw
@enemy.draw
if !@path.nil?
# draw path
end
end
def button_down(id)
case id
when Gosu::MsLeft
if (0 < mouse_x && mouse_x < 480 && 0 < mouse_y && mouse_y < 480)
@player.reposition(mouse_x, mouse_y)
end
when Gosu::MsRight
if (0 < mouse_x && mouse_x < 480 && 0 < mouse_y && mouse_y < 480)
@enemy.reposition(mouse_x, mouse_y)
end
when Gosu::KbSpace
@path = @pathfinder.get_path(@player.position, @enemy.position, @world)
end
end
end
window = GameWindow.new
window.show
class World
attr_reader :grid, :width, :height
def initialize(window)
@width = 20
@height = 20
@grid = Array.new(width,[])
@grid = @grid.map {Array.new(height,0)}
@target_sprite = Gosu::Image.new(window, "target.bmp", true)
end
def draw
@grid.each_with_index do |inner, x|
inner.each_index do |y|
@target_sprite.draw(x*24,y*24,0)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment