Hohmann Miner, a sandbox physics game where you mine stuff.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hohmann-miner/physobj.rb

109 lines
2.1 KiB

3 years ago
require "matrix"
3 years ago
load "gosu_plugin.rb"
3 years ago
3 years ago
GRAV_CONSTANT = 1e+1
3 years ago
3 years ago
class PhysObj
3 years ago
attr_accessor :world, :saved_pos, :pos, :vel, :accel, :x, :y
3 years ago
attr_reader :name
def initialize(name, world)
@name = name
3 years ago
@world = world
@pos = Vector.zero(2)
@vel = Vector.zero(2)
@accel = Vector.zero(2)
@x, @y = 0, 0
3 years ago
@saved_pos = []
3 years ago
end
def tick
if( @accel.magnitude != 0 ) then
@vel += @accel
end
if( @vel.magnitude != 0 ) then
@pos += @vel
end
@x, @y = @pos[0], @pos[1]
3 years ago
@saved_pos << @pos
end
def render_path
@saved_pos.each do |pos|
3 years ago
Gosu.draw_rect(pos[0], pos[1], 2, 2, Gosu::Color.argb(0x44_ccccff))
3 years ago
end
3 years ago
end
end
class PhysCube < PhysObj
attr_reader :width, :height
3 years ago
def initialize(name, world, width, height, color=0xff_ffffff, ela=-0.8)
super name, world
3 years ago
@width, @height = width, height
@color = Gosu::Color.argb(color)
@ela = ela
end
def render
x, y = self.pos[0], self.pos[1]
Gosu.draw_quad(x, y, @color, x + self.width, y, @color, x, y + self.height, @color, x + self.width, y + self.height, @color)
end
def physics
self.tick
end
3 years ago
3 years ago
def draw_vector(vec, scale=2, color=0xaf_ffaaaa)
if( vec.magnitude != 0 ) then
clr = Gosu::Color.argb(color)
scaled_vec = vec*scale
pos1 = self.pos + Vector[self.width/2, self.height/2]
pos2 = pos1 + scaled_vec
x1 = pos1[0]
y1 = pos1[1]
x2 = pos2[0]
y2 = pos2[1]
Gosu.draw_line(x1, y1, clr, x2, y2, clr)
end
3 years ago
end
3 years ago
end
3 years ago
class Planet < PhysCube
3 years ago
attr_reader :mass
def initialize(name, world, color, mass=1e+2)
super name, world, 40, 40, color
@mass = mass
end
3 years ago
3 years ago
private def calculate_gravity_scalar(obj, dir_vec)
grav = GRAV_CONSTANT * (self.mass/(dir_vec.magnitude**2))
return grav
3 years ago
end
private def calculate_gravity_vector(obj)
3 years ago
dir_vec = self.pos - obj.pos + Vector[self.width/2, self.height/2]
3 years ago
return (dir_vec/dir_vec.magnitude) * calculate_gravity_scalar(obj, dir_vec)
3 years ago
end
def orbit(physobjs)
physobjs.each do |obj|
grav_vec = self.calculate_gravity_vector(obj)
obj.accel = grav_vec
end
end
3 years ago
def render
Gosu.draw_circle(self.pos[0], self.pos[1], 20, @color)
end
3 years ago
end