Actual gravity

pull/1/head
E. Almqvist 3 years ago
parent 883af17673
commit 8dfaad1cfe
  1. 46
      app.rb
  2. 43
      gosu_plugin.rb
  3. 24
      physobj.rb

@ -3,7 +3,7 @@ require "gosu"
load "physobj.rb"
class Window < Gosu::Window
attr_accessor :caption, :physobjs, :planets
attr_accessor :freeze, :caption, :physobjs, :planets
attr_reader :width, :height
def initialize(title, width, height, physobjs = [], planets = [])
@ -13,24 +13,48 @@ class Window < Gosu::Window
@physobjs = physobjs
@planets = planets
@font = Gosu::Font.new(self, Gosu::default_font_name, 12)
@font2 = Gosu::Font.new(self, Gosu::default_font_name, 32)
@freeze = false
end
def update
@physobjs.each do |obj|
obj.physics
def button_up(id)
super id
if( id == Gosu::KbEscape ) then
@freeze = !@freeze
end
end
@planets.each do |planet|
planet.orbit(@physobjs)
def update
if( !@freeze ) then
@physobjs.each do |obj|
obj.physics
end
@planets.each do |planet|
planet.orbit(@physobjs)
end
end
end
private def generate_debug_string(obj)
return "\n#{obj.name}\nVel: #{obj.vel.round(4)} (#{obj.vel.magnitude.round(1)})\nAccel: #{obj.accel.round(4)} (#{obj.accel.magnitude.round(4)})\nPos: #{obj.pos.round(4)}\n"
end
def draw
if( @freeze ) then
@font2.draw("FROZEN", 0, 0, 1, 1.0, 1.0, Gosu::Color::WHITE)
end
@physobjs.each do |obj|
obj.render
obj.draw_vector(obj.vel, 10)
obj.draw_vector(obj.accel, 500, 0xff_aaffaa)
obj.render_path
@font.draw(self.generate_debug_string(obj), obj.pos[0], obj.pos[1], 1, 1.0, 1.0, Gosu::Color.argb(0xee_aaaaff))
end
@planets.each do |planet|
@ -42,16 +66,16 @@ end
window = Window.new("Physics!", 1600, 900)
planet = Planet.new("Earth", window, 0xff_aaffaa, 0.0001)
planet = Planet.new("Earth", window, 0xff_aaffaa)
planet.pos = Vector[800, 450]
cube = PhysCube.new("Cube", window, 8, 8)
cube.pos = Vector[800, 450 + 100]
cube.vel = Vector[4, 0]
cube.pos = Vector[800, 450 + 200]
cube.vel = Vector[2.5, 0]
cube2 = PhysCube.new("Cube2", window, 8, 8)
cube2.pos = Vector[800, 450 + 500]
cube2.vel = Vector[5, 0]
cube2.pos = Vector[800, 450 + 400]
cube2.vel = Vector[1.25, 0]
planet.orbit([cube, cube2])
window.planets << planet

@ -0,0 +1,43 @@
require "gosu"
module Gosu
def self.draw_circle(x, y, r, c, z = 0, thickness = 1, sides = nil, mode = :default)
# Unless specified, calculate a nice-looking "minimum" number of sides
# sides = (r + Math::sqrt(r * 0.1) * 4).floor if sides.nil?
sides = (2.0 * r * Math::PI).floor if sides.nil?
# Calculate the inner and outer offsets from the "true" circle
offs = thickness * 0.5
r_in = r - offs
r_out = r + offs
# Calculate the angular increment
ai = 360.0 / sides.to_f
translate(x, y) {
ang = 0
while ang <= 359.9 do
draw_quad(
Gosu.offset_x(ang, r_in), Gosu.offset_y(ang, r_in), c,
Gosu.offset_x(ang, r_out), Gosu.offset_y(ang, r_out), c,
Gosu.offset_x(ang + ai, r_in), Gosu.offset_y(ang + ai, r_in), c,
Gosu.offset_x(ang + ai, r_out), Gosu.offset_y(ang + ai, r_out), c,
z, mode
)
ang += ai
end
}
end
class Window
def draw_circle(x, y, r, c, z = 0, thickness = 1, sides = nil, mode = :default)
Gosu::draw_circle(x, y, r, c, z, thickness, sides, mode)
end
end # Window class
end # Gosu module

@ -1,6 +1,7 @@
require "matrix"
load "gosu_plugin.rb"
GRAV_CONSTANT = 1e+2
GRAV_CONSTANT = 1e+1
class PhysObj
attr_accessor :world, :saved_pos, :pos, :vel, :accel, :x, :y
@ -29,7 +30,7 @@ class PhysObj
def render_path
@saved_pos.each do |pos|
Gosu.draw_rect(pos[0], pos[1], 2, 2, Gosu::Color.argb(0xaa_ccccff))
Gosu.draw_rect(pos[0], pos[1], 2, 2, Gosu::Color.argb(0x44_ccccff))
end
end
@ -78,17 +79,20 @@ end
class Planet < PhysCube
attr_reader :gravity
def initialize(name, world, color, gravity=0.05)
super name, world, 10, 10, color
attr_reader :mass
def initialize(name, world, color, mass=1e+2)
super name, world, 40, 40, color
@mass = mass
end
@gravity = gravity
private def calculate_gravity_scalar(obj, dir_vec)
grav = GRAV_CONSTANT * (self.mass/(dir_vec.magnitude**2))
return grav
end
private def calculate_gravity_vector(obj)
dir_vec = self.pos - obj.pos + Vector[self.width/2, self.height/2]
return dir_vec * self.gravity
# return (self.gravity * dir_vec)/(dir_vec.magnitude)
return (dir_vec/dir_vec.magnitude) * calculate_gravity_scalar(obj, dir_vec)
end
def orbit(physobjs)
@ -97,4 +101,8 @@ class Planet < PhysCube
obj.accel = grav_vec
end
end
def render
Gosu.draw_circle(self.pos[0], self.pos[1], 20, @color)
end
end

Loading…
Cancel
Save