mirror of
https://github.com/SleepingInsomniac/pixelfaucet
synced 2024-11-17 07:48:20 +01:00
109 lines
2.7 KiB
Crystal
109 lines
2.7 KiB
Crystal
require "./lib_sdl"
|
|
require "./pixel"
|
|
require "./sprite"
|
|
|
|
module PF
|
|
abstract class Game
|
|
FPS_INTERVAL = 1.0
|
|
SHOW_FPS = true
|
|
|
|
property scale : Int32
|
|
property title : String
|
|
property running = true
|
|
property screen : Sprite
|
|
|
|
getter width : Int32
|
|
getter height : Int32
|
|
|
|
@viewport : Vector2(Int32)? = nil
|
|
|
|
delegate :draw_point, :draw_line, :scan_line, :draw_circle, :draw_triangle, :draw_rect, :draw_shape,
|
|
:fill_triangle, :fill_rect, :fill_circle, :fill_shape, to: @screen
|
|
|
|
@fps_lasttime : Float64 = Time.monotonic.total_milliseconds # the last recorded time.
|
|
@fps_current : UInt32 = 0 # the current FPS.
|
|
@fps_frames : UInt32 = 0 # frames passed since the last recorded fps.
|
|
@last_time : Float64 = Time.monotonic.total_milliseconds
|
|
|
|
def initialize(@width, @height, @scale = 1, @title = self.class.name,
|
|
flags = SDL::Renderer::Flags::ACCELERATED,
|
|
window_flags : SDL::Window::Flags = SDL::Window::Flags::SHOWN)
|
|
SDL.init(SDL::Init::VIDEO)
|
|
@window = SDL::Window.new(@title, @width * @scale, @height * @scale, flags: window_flags)
|
|
@renderer = SDL::Renderer.new(@window, flags: flags)
|
|
@renderer.scale = {@scale, @scale}
|
|
@screen = Sprite.new(@width, @height)
|
|
end
|
|
|
|
abstract def update(dt : Float64, event : SDL::Event)
|
|
abstract def draw
|
|
|
|
def width=(value : Int32)
|
|
@viewport = nil
|
|
@width = value
|
|
# TODO: Resize window
|
|
end
|
|
|
|
def height=(value : Int32)
|
|
@viewport = nil
|
|
@height = value
|
|
# TODO: Resize window
|
|
end
|
|
|
|
def viewport
|
|
@viewport ||= Vector[@width, @height]
|
|
end
|
|
|
|
def elapsed_time
|
|
Time.monotonic.total_milliseconds
|
|
end
|
|
|
|
def clear(r = 0, g = 0, b = 0)
|
|
@screen.fill(r, g, b)
|
|
end
|
|
|
|
def run!
|
|
loop do
|
|
case event = SDL::Event.poll
|
|
when SDL::Event::Quit
|
|
break
|
|
end
|
|
|
|
engine_update(event)
|
|
engine_draw
|
|
|
|
break unless @running
|
|
end
|
|
ensure
|
|
SDL.quit
|
|
end
|
|
|
|
private def engine_update(event)
|
|
et = elapsed_time
|
|
calculate_fps(et)
|
|
update((et - @last_time) / 1000.0, event)
|
|
@last_time = et
|
|
GC.collect
|
|
end
|
|
|
|
private def calculate_fps(et)
|
|
return unless SHOW_FPS
|
|
@fps_frames += 1
|
|
if @fps_lasttime < et - FPS_INTERVAL * 1000
|
|
@fps_lasttime = et
|
|
@fps_current = @fps_frames
|
|
@fps_frames = 0
|
|
@window.title = String.build { |io| io << @title << " - " << @fps_current << " fps" }
|
|
end
|
|
end
|
|
|
|
private def engine_draw
|
|
@screen.lock do
|
|
draw
|
|
end
|
|
|
|
@renderer.copy(@screen.surface)
|
|
@renderer.present
|
|
end
|
|
end
|
|
end
|