From 73d1206edbb3ec8d78df60cfd24b49196acb223b Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Thu, 1 Nov 2018 21:29:41 +0900 Subject: [PATCH] Initial commit. --- shard.yml | 22 ++++++++ src/main.cr | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 shard.yml create mode 100644 src/main.cr diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..151c43f --- /dev/null +++ b/shard.yml @@ -0,0 +1,22 @@ +name: naka +version: 0.0.1 + +authors: + - Lukc + +description: | + Experimental Löve-like APIs for game programming. +# Future description’s gonna be like “Game Programming no Aidoru!”. + +# Currently, game and libraries are merged, because everything’s still a WIP. +# It’ll change, though. Soon. Probably. +targets: + main: + main: src/main.cr + +dependencies: + sdl: + github: ysbaddaden/sdl.cr + branch: master # No upstream tag or branches provided. :( + +license: EUPLv1.2 diff --git a/src/main.cr b/src/main.cr new file mode 100644 index 0000000..119a5b3 --- /dev/null +++ b/src/main.cr @@ -0,0 +1,153 @@ + +require "sdl" +require "sdl/image" + +## Helper code comes here + +class Naka + def self.init + SDL.init SDL::Init::VIDEO + SDL::IMG.init SDL::IMG::Init::PNG + + at_exit { SDL.quit } + end +end + +class Naka::Renderer < SDL::Renderer +end + +class Naka::Window + alias Flags = LibSDL::WindowFlags + alias Position = LibSDL::WindowPosition + + getter renderer + + def initialize(title, width, height, + x : Position = Position::UNDEFINED, + y : Position = Position::UNDEFINED, + flags : Flags = Flags::SHOWN) + + @window = SDL::Window.new(title, width, height, x, y, flags) + @renderer = Naka::Renderer.new @window + end + + def newImage(file_path) : SDL::Texture + SDL::IMG.load file_path, @renderer + end + + # FIXME: We’ll probably want options for scaling, rotations, and so on. + def draw(texture : SDL::Texture, x : Int32, y : Int32) + @renderer.copy texture, + dstrect: SDL::Rect[x, y, texture.width, texture.height] + end +end + +class Naka::Timer + getter start + getter last_update + + def initialize + @start = Time.now + @last_update = @start + end + + def step + now = Time.now + + dt = now.epoch_ms - @last_update.epoch_ms + + @last_update = now + + dt + end +end + +class Naka::Event + class Quit + end + + class Draw + getter window : Naka::Window + + def initialize(@window) + end + end + + class Update + getter dt : Int64 + + def initialize(@dt) + end + end + + # FIXME: THIS MAIN LOOP IS **NOT** READY FOR PRODUCTION + # Update events are still missing, and both Draw and Update should + # be time-based. + # Why having a `window` parameter instead of making a Window#loop method? + # Because we may want to have a `windows` parameter in the future, although + # unlikely. But still possible. + def self.loop(window, &block) + max_fps = 60 + max_dt = 1000. / 60 + + timer = Naka::Timer.new + + renderer = window.renderer + + ::loop do + exit_requested = false + + while event = SDL::Event.poll + r_value = yield case event + when SDL::Event::Quit + Naka::Event::Quit.new + else # FIXME: Most event types may need proper Naka:: classes. + event + end + + if r_value == Naka::Event::Quit + exit_requested = true + break + end + end + + break if exit_requested + + dt = timer.step + + r_value = yield Naka::Event::Update.new dt + + break if r_value == Naka::Event::Quit + + renderer.draw_color = SDL::Color[255, 255, 255, 255] + renderer.clear + + yield Naka::Event::Draw.new window + + renderer.present + + sleep 0.001 + end + end +end + +## Actual application code comes here + +Naka.init + +window = Naka::Window.new "Test", 640, 480 + +naka = window.newImage "naka.png" + +Naka::Event.loop window do |event| + case event + when Naka::Event::Quit + next Naka::Event::Quit + when Naka::Event::Update + p "Update(#{event.dt})" + when Naka::Event::Draw + p "Draw" + event.window.draw naka, 20, 20 + end +end +