2021-12-18 22:47:12 +01:00
|
|
|
require "../src/game"
|
|
|
|
require "../src/controller"
|
|
|
|
require "../src/sprite"
|
|
|
|
require "../src/sprite/vector_sprite"
|
|
|
|
require "../src/pixel"
|
|
|
|
require "../src/point"
|
|
|
|
|
|
|
|
require "../src/3d/*"
|
|
|
|
|
|
|
|
class Model
|
2021-12-20 05:17:51 +01:00
|
|
|
property mesh : PF::Mesh
|
|
|
|
property position = PF::Vec3d(Float64).new(0.0, 0.0, 0.0)
|
|
|
|
property rotation = PF::Vec3d(Float64).new(0.0, 0.0, 0.0)
|
2021-12-18 22:47:12 +01:00
|
|
|
|
2021-12-20 05:17:51 +01:00
|
|
|
def initialize(obj_path : String)
|
|
|
|
@mesh = PF::Mesh.load_obj(obj_path)
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def update(dt : Float64)
|
2021-12-20 05:17:51 +01:00
|
|
|
@rotation.x += 0.33 * dt
|
|
|
|
@rotation.y += 0.66 * dt
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
2021-12-20 05:17:51 +01:00
|
|
|
def draw(engine : PF::Game, projector : PF::Projector)
|
|
|
|
projector.project(@mesh.tris, rotation: @rotation, position: @position).each do |tri|
|
|
|
|
# Rasterize all triangles
|
2021-12-18 22:47:12 +01:00
|
|
|
engine.fill_triangle(
|
|
|
|
PF::Point.new(tri.p1.x.to_i, tri.p1.y.to_i),
|
|
|
|
PF::Point.new(tri.p2.x.to_i, tri.p2.y.to_i),
|
|
|
|
PF::Point.new(tri.p3.x.to_i, tri.p3.y.to_i),
|
|
|
|
pixel: tri.color
|
|
|
|
)
|
|
|
|
|
|
|
|
engine.draw_triangle(
|
|
|
|
PF::Point.new(tri.p1.x.to_i, tri.p1.y.to_i),
|
|
|
|
PF::Point.new(tri.p2.x.to_i, tri.p2.y.to_i),
|
|
|
|
PF::Point.new(tri.p3.x.to_i, tri.p3.y.to_i),
|
|
|
|
pixel: PF::Pixel.green
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class CubeGame < PF::Game
|
2021-12-20 05:17:51 +01:00
|
|
|
@projector : PF::Projector
|
2021-12-18 22:47:12 +01:00
|
|
|
@paused = false
|
2021-12-20 05:17:51 +01:00
|
|
|
@light : PF::Vec3d(Float64) = PF::Vec3d.new(0.0, 0.0, -1.0).normalized
|
2021-12-18 22:47:12 +01:00
|
|
|
@speed = 5.0
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera : PF::Camera
|
2021-12-18 22:47:12 +01:00
|
|
|
|
|
|
|
def initialize(@width, @height, @scale)
|
|
|
|
super(@width, @height, @scale)
|
|
|
|
|
2021-12-20 05:17:51 +01:00
|
|
|
@projector = PF::Projector.new(@width, @height)
|
|
|
|
@camera = @projector.camera
|
2021-12-18 22:47:12 +01:00
|
|
|
@cube = Model.new("examples/cube.obj")
|
|
|
|
@cube.position.z = @cube.position.z + 3.0
|
|
|
|
|
|
|
|
@controller = PF::Controller(LibSDL::Keycode).new({
|
|
|
|
LibSDL::Keycode::RIGHT => "Rotate Right",
|
|
|
|
LibSDL::Keycode::LEFT => "Rotate Left",
|
|
|
|
LibSDL::Keycode::UP => "Up",
|
|
|
|
LibSDL::Keycode::DOWN => "Down",
|
|
|
|
LibSDL::Keycode::A => "Left",
|
|
|
|
LibSDL::Keycode::E => "Right",
|
|
|
|
LibSDL::Keycode::COMMA => "Forward",
|
|
|
|
LibSDL::Keycode::O => "Backward",
|
|
|
|
LibSDL::Keycode::SPACE => "Pause",
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
def update(dt)
|
|
|
|
@paused = !@paused if @controller.pressed?("Pause")
|
|
|
|
|
2021-12-20 05:17:51 +01:00
|
|
|
forward = @camera.forward_vector
|
|
|
|
strafe = @camera.strafe_vector
|
2021-12-18 22:47:12 +01:00
|
|
|
|
|
|
|
if @controller.action?("Right")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.position = @camera.position - (strafe * @speed * dt)
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Left")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.position = @camera.position + (strafe * @speed * dt)
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Up")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.position.y = @camera.position.y + @speed * dt
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Down")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.position.y = @camera.position.y - @speed * dt
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Rotate Left")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.yaw = @camera.yaw + (@speed / 2) * dt
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Rotate Right")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.yaw = @camera.yaw - (@speed / 2) * dt
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Forward")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.position = @camera.position + (forward * @speed * dt)
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if @controller.action?("Backward")
|
2021-12-20 05:17:51 +01:00
|
|
|
@camera.position = @camera.position - (forward * @speed * dt)
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
@cube.update(dt)
|
|
|
|
end
|
|
|
|
|
|
|
|
def draw
|
|
|
|
clear(0, 0, 100)
|
2021-12-20 05:17:51 +01:00
|
|
|
@cube.draw(self, @projector)
|
2021-12-18 22:47:12 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-12-20 05:17:51 +01:00
|
|
|
engine = CubeGame.new(400, 300, 2)
|
2021-12-18 22:47:12 +01:00
|
|
|
engine.run!
|