require 'rubygems'
require 'gosu'
WIDTH = 1366
HEIGHT = 768
class Point
attr_accessor :x, :y, :dx, :dy
def initialize(x, y, vx, vy, win)
@x = x
@y = y
@ox = x - vx
@oy = y - vy
end
def update
@dx = @x - @ox
@dy = @y - @oy + 0.1
@ox = @x
@oy = @y
@x = @x + @dx
@y = @y + @dy
if @y > HEIGHT - 10
@y = HEIGHT - 10
@dx = @x-@ox
@dx *= 0.5
@ox = @ox + @dx
end
if @y < 10
@y = 10
@dx = @x-@ox
@dx *= 0.5
@ox = @ox + @dx
end
if @x > WIDTH - 10
@x = WIDTH - 10
@dy = @y-@oy
@dy *= 0.5
@oy = @oy + @dy
end
if @x < 10
@x = 10
@dy = @y-@oy
@dy *= 0.5
@oy = @oy + @dy
end
end
end
class Contact
def initialize(p1, p2,win)
@p1 = p1
@p2 = p2
@win = win
@length = Math.sqrt((@p1.x-@p2.x)**2 + (@p1.y-@p2.y)**2)
end
def update
3.times{
dist = Math.sqrt((@p1.x-@p2.x)**2 + (@p1.y-@p2.y)**2)
diff = dist - @length
dx = @p1.x-@p2.x
dy = @p1.y-@p2.y
if @length > 0
diff = diff / @length
else
diff = 0
end
dx *= 0.15
dy *= 0.15
@p1.x -= diff*dx
@p1.y -= diff*dy
@p2.x += diff*dx
@p2.y += diff*dy
}
end
def draw
@win.draw_line(@p1.x,@p1.y,Gosu::white,@p2.x,@p2.y,Gosu::white)
end
end
class GameWindow < Gosu::Window
def initialize
super(1366, 768, true)
self.caption = "Physics"
game = 'snake'
if game == 'snake'
@points, @contacts = [] ,[]
10.times{|i|
@points.push(Point.new(200 - 14*i,50,0,0,self))
@contacts.push(Contact.new(@points[i-1],@points[i],self))
}
elsif game == 'man'
@points = [
Point.new(200,80,0,0,self),
Point.new(180,100,0,0,self),
Point.new(220,100,0,0,self),
Point.new(200,120,0,0,self),
Point.new(200,140,0,0,self),
Point.new(165,170,0,0,self),
Point.new(235,170,0,0,self),
Point.new(165,240,0,0,self),
Point.new(230,240,0,0,self),
Point.new(165,285,0,0,self),
Point.new(165,320,0,0,self),
Point.new(230,285,0,0,self),
Point.new(230,320,0,0,self),
Point.new(140,180,0,0,self),
Point.new(120,210,0,0,self),
Point.new(260,180,0,0,self),
Point.new(280,210,0,0,self)
]
@contacts = [
Contact.new(@points[0],@points[1],self),
Contact.new(@points[2],@points[1],self),
Contact.new(@points[0],@points[3],self),
Contact.new(@points[0],@points[2],self),
Contact.new(@points[3],@points[1],self),
Contact.new(@points[3],@points[2],self),
Contact.new(@points[4],@points[3],self),
Contact.new(@points[5],@points[4],self),
Contact.new(@points[5],@points[6],self),
Contact.new(@points[6],@points[4],self),
Contact.new(@points[5],@points[7],self),
Contact.new(@points[7],@points[8],self),
Contact.new(@points[8],@points[6],self),
Contact.new(@points[6],@points[7],self),
Contact.new(@points[5],@points[8],self),
Contact.new(@points[4],@points[7],self),
Contact.new(@points[4],@points[8],self),
Contact.new(@points[9],@points[7],self),
Contact.new(@points[10],@points[9],self),
Contact.new(@points[11],@points[8],self),
Contact.new(@points[12],@points[11],self),
Contact.new(@points[13],@points[5],self),
Contact.new(@points[14],@points[13],self),
Contact.new(@points[15],@points[6],self),
Contact.new(@points[16],@points[15],self)
]
end
end
def update
@points.each{|p| p.update}
@contacts.each{|c| c.update}
if button_down? Gosu::Button::KbUp then
@points[0].y -= 1.4
end
if button_down? Gosu::Button::KbLeft then
@points[0].x -= 0.4
end
if button_down? Gosu::Button::KbRight then
@points[0].x += 0.4
end
end
def draw
@contacts.each { |c|
c.draw
}
end
end
window = GameWindow.new
window.show