112 lines
4.1 KiB
Crystal
112 lines
4.1 KiB
Crystal
require "spec"
|
|
require "../../src/engine/physics"
|
|
|
|
describe Physics do
|
|
it "test basic tick usage" do
|
|
time = Time.utc
|
|
one_second = Time::Span.new(seconds: 1)
|
|
t1 = Physics::Tick.new(n: 0, time: time, last: nil)
|
|
t2 = Physics::Tick.new(n: 1, time: time + one_second, last: t1)
|
|
|
|
t2.timelaps.should eq(one_second)
|
|
end
|
|
|
|
it "test basic timer" do
|
|
timer = Physics::Tick::Timer.new
|
|
start_time = timer.tick.time
|
|
timer.tick.n.should eq(0)
|
|
12.times { timer.timeskip!(seconds: 1) }
|
|
timer.tick.n.should eq(12)
|
|
timer.tick.time.should eq(start_time + Time::Span.new(seconds: 12))
|
|
end
|
|
|
|
it "accelerate an object" do
|
|
a_ball_movement = Vector[0.0, 0.0, 0.0]
|
|
a_engine_accelerate = Vector[20.0, 0.0, 0.0]
|
|
timer = Physics::Tick::Timer.new
|
|
|
|
timer.timeskip!(seconds: 1)
|
|
Physics.accelerate_by_one_tick!(timer.tick, a_ball_movement, a_engine_accelerate)
|
|
a_ball_movement[0].should eq(20.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
timer.timeskip!(milliseconds: 500)
|
|
Physics.accelerate_by_one_tick!(timer.tick, a_ball_movement, a_engine_accelerate)
|
|
a_ball_movement[0].should eq(30.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
timer.timeskip!(milliseconds: 500)
|
|
Physics.accelerate_by_one_tick!(timer.tick, a_ball_movement, a_engine_accelerate)
|
|
a_ball_movement[0].should eq(40.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
a_engine_stopped = Vector[0.0, 0.0, 0.0]
|
|
timer.timeskip!(milliseconds: 500)
|
|
Physics.accelerate_by_one_tick!(timer.tick, a_ball_movement, a_engine_stopped)
|
|
a_ball_movement[0].should eq(40.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
a_retro_pulse = Vector[0.0, 0.1, 0.0]
|
|
timer.timeskip!(milliseconds: 500)
|
|
Physics.accelerate_by_one_tick!(timer.tick, a_ball_movement, a_retro_pulse)
|
|
a_ball_movement[0].should eq(40.0)
|
|
a_ball_movement[1].should eq(0.05)
|
|
end
|
|
|
|
it "move and accelerate an object" do
|
|
a_ball_position = Vector[0.0, 0.0, 0.0]
|
|
a_ball_movement = Vector[0.0, 0.0, 0.0]
|
|
a_engine_accelerate = Vector[20.0, 0.0, 0.0]
|
|
timer = Physics::Tick::Timer.new
|
|
|
|
timer.timeskip!(seconds: 1)
|
|
Physics.move_by_one_tick!(timer.tick, a_ball_position, a_ball_movement, a_engine_accelerate)
|
|
a_ball_position[0].should eq(10.0)
|
|
a_ball_position[1].should eq(0.0)
|
|
a_ball_movement[0].should eq(20.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
timer.timeskip!(seconds: 1)
|
|
Physics.move_by_one_tick!(timer.tick, a_ball_position, a_ball_movement, a_engine_accelerate)
|
|
a_ball_position[0].should eq(40.0)
|
|
a_ball_position[1].should eq(0.0)
|
|
a_ball_movement[0].should eq(40.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
# cut a second in 2 computations gives the same result as one second
|
|
timer.timeskip!(milliseconds: 500)
|
|
Physics.move_by_one_tick!(timer.tick, a_ball_position, a_ball_movement, a_engine_accelerate)
|
|
a_ball_position[0].should eq(62.5)
|
|
a_ball_position[1].should eq(0.0)
|
|
a_ball_movement[0].should eq(50.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
timer.timeskip!(milliseconds: 500)
|
|
Physics.move_by_one_tick!(timer.tick, a_ball_position, a_ball_movement, a_engine_accelerate)
|
|
a_ball_position[0].should eq(90.0)
|
|
a_ball_position[1].should eq(0.0)
|
|
a_ball_movement[0].should eq(60.0)
|
|
a_ball_movement[1].should eq(0.0)
|
|
|
|
a_gravity_generator = Vector[0.0, 0.0, 0.0]
|
|
a_retro_pulse = Vector[0.0, 0.1, 0.0]
|
|
star_gravity = Vector[-0.01, 0.02, 0.01]
|
|
total_forces = a_gravity_generator + a_retro_pulse + star_gravity
|
|
timer.timeskip!(seconds: 1)
|
|
Physics.move_by_one_tick!(timer.tick, a_ball_position, a_ball_movement, total_forces)
|
|
a_ball_position[0].round(3).should eq(149.995)
|
|
a_ball_position[1].round(3).should eq(0.06)
|
|
a_ball_position[2].round(3).should eq(0.005)
|
|
a_ball_movement[0].round(3).should eq(59.99)
|
|
a_ball_movement[1].round(3).should eq(0.12)
|
|
a_ball_movement[2].round(3).should eq(0.01)
|
|
end
|
|
end
|
|
|
|
# v0 = 40 m/s
|
|
# a = 20 m/s²
|
|
# t1 = 0.5 s
|
|
# v1 = v0 + a * t1 = 40 + 20 * 0.6 = 50 m/s (m/s + m/s^2*s = m/s)
|
|
# [v] = (v0 + v1) / 2 = (40 + 50) / 2 = 45 (m/s + m/s)
|
|
# d = [v] * (t1 - t0) = 45 * 0.5 = 22.5 (m/s * s)
|