Use PF::Keys instead of LibSDL::Scancode, add fill_rect method

This commit is contained in:
Alex Clink 2022-02-02 00:33:53 -05:00
parent 3db76bcd44
commit c43dfbd90e
8 changed files with 95 additions and 66 deletions

View file

@ -13,7 +13,7 @@ class ThreeDee < PF::Game
@paused = false
@speed = 5.0
@text = PF::PixelText.new("./assets/pf-font.png")
@controller : PF::Controller(LibSDL::Scancode)
@controller : PF::Controller(PF::Keys)
def initialize(*args, **kwargs)
super
@ -23,16 +23,16 @@ class ThreeDee < PF::Game
@model = PF::Mesh.load_obj("./assets/pixelfaucet.obj")
@model.position.z = @model.position.z + 2.0
@controller = PF::Controller(LibSDL::Scancode).new({
LibSDL::Scancode::RIGHT => "Rotate Right",
LibSDL::Scancode::LEFT => "Rotate Left",
LibSDL::Scancode::UP => "Up",
LibSDL::Scancode::DOWN => "Down",
LibSDL::Scancode::A => "Left",
LibSDL::Scancode::D => "Right",
LibSDL::Scancode::W => "Forward",
LibSDL::Scancode::S => "Backward",
LibSDL::Scancode::SPACE => "Pause",
@controller = PF::Controller(PF::Keys).new({
PF::Keys::RIGHT => "Rotate Right",
PF::Keys::LEFT => "Rotate Left",
PF::Keys::UP => "Up",
PF::Keys::DOWN => "Down",
PF::Keys::A => "Left",
PF::Keys::D => "Right",
PF::Keys::W => "Forward",
PF::Keys::S => "Backward",
PF::Keys::SPACE => "Pause",
})
end
@ -48,45 +48,45 @@ class ThreeDee < PF::Game
forward = @camera.forward_vector
strafe = @camera.strafe_vector
if @controller.action?("Right")
if @controller.held?("Right")
@camera.position = @camera.position + (strafe * @speed * dt)
end
if @controller.action?("Left")
if @controller.held?("Left")
@camera.position = @camera.position - (strafe * @speed * dt)
end
if @controller.action?("Up")
if @controller.held?("Up")
@camera.position.y = @camera.position.y + @speed * dt
end
if @controller.action?("Down")
if @controller.held?("Down")
@camera.position.y = @camera.position.y - @speed * dt
end
# Controll the camera pitch instead of aft -
# if @controller.action?("Up")
# if @controller.held?("Up")
# @camera.pitch = @camera.pitch + (@speed / 2) * dt
# end
# if @controller.action?("Down")
# if @controller.held?("Down")
# @camera.pitch = @camera.pitch - (@speed / 2) * dt
# end
if @controller.action?("Rotate Left")
if @controller.held?("Rotate Left")
@camera.yaw = @camera.yaw - (@speed / 2) * dt
end
if @controller.action?("Rotate Right")
if @controller.held?("Rotate Right")
@camera.yaw = @camera.yaw + (@speed / 2) * dt
end
if @controller.action?("Forward")
if @controller.held?("Forward")
@camera.position = @camera.position + (forward * @speed * dt)
end
if @controller.action?("Backward")
if @controller.held?("Backward")
@camera.position = @camera.position - (forward * @speed * dt)
end

View file

@ -15,11 +15,11 @@ module PF
@noise_zoom = width / 4
@xpos = 0.0
@controller = PF::Controller(LibSDL::Scancode).new({
LibSDL::Scancode::UP => "scale up",
LibSDL::Scancode::DOWN => "scale down",
LibSDL::Scancode::RIGHT => "zoom up",
LibSDL::Scancode::LEFT => "zoom down",
@controller = PF::Controller(Keys).new({
Keys::UP => "scale up",
Keys::DOWN => "scale down",
Keys::RIGHT => "zoom up",
Keys::LEFT => "zoom down",
})
end

View file

@ -1,14 +1,13 @@
require "../src/game"
require "../src/lehmer32"
require "../src/pixel_text"
require "../src/controller"
module PF
class Proceedural < Game
@buffer_size : Int32
@buffer : Pointer(UInt32)
@text = PF::PixelText.new("assets/pf-font.png")
@pan : PF::Vector2(Float64) = PF::Vector[0.0, 0.0]
@text = PixelText.new("assets/pf-font.png")
@pan : Vector2(Float64) = PF::Vector[0.0, 0.0]
@seed : UInt32
def initialize(*args, **kwargs)
@ -17,13 +16,13 @@ module PF
@buffer = screen.pixel_pointer(0, 0)
@random = Lehmer32.new
@redraw = true
@text.color(PF::Pixel.new(255, 255, 255))
@text.color(Pixel.new(255, 255, 255))
@controller = PF::Controller(LibSDL::Scancode).new({
LibSDL::Scancode::LEFT => "left",
LibSDL::Scancode::RIGHT => "right",
LibSDL::Scancode::UP => "up",
LibSDL::Scancode::DOWN => "down",
@controller = Controller(Keys).new({
Keys::LEFT => "left",
Keys::RIGHT => "right",
Keys::UP => "up",
Keys::DOWN => "down",
})
@speed = 100.0
@ -36,7 +35,7 @@ module PF
def update(dt, event)
@controller.map_event(event)
@redraw = true if @controller.any_pressed?
@redraw = true if @controller.any_held?
@pan.x += @speed * dt if @controller.held?("right")
@pan.x -= @speed * dt if @controller.held?("left")
@pan.y -= @speed * dt if @controller.held?("up")

View file

@ -25,7 +25,7 @@ end
class TriangleThing < PF::Game
@tri : Triangle
@paused = false
@controller : PF::Controller(LibSDL::Scancode)
@controller : PF::Controller(PF::Keys)
def initialize(@width, @height, @scale)
super(@width, @height, @scale)
@ -34,10 +34,10 @@ class TriangleThing < PF::Game
@tri.position = viewport / 2
@tri.frame = PF::Shape.circle(3, size = @width / 3)
@controller = PF::Controller(LibSDL::Scancode).new({
LibSDL::Scancode::RIGHT => "Rotate Right",
LibSDL::Scancode::LEFT => "Rotate Left",
LibSDL::Scancode::SPACE => "Pause",
@controller = PF::Controller(PF::Keys).new({
PF::Keys::RIGHT => "Rotate Right",
PF::Keys::LEFT => "Rotate Left",
PF::Keys::SPACE => "Pause",
})
end
@ -50,8 +50,8 @@ class TriangleThing < PF::Game
@paused = !@paused if @controller.pressed?("Pause")
@tri.rotation = @tri.rotation + 0.5 * dt if @controller.action?("Rotate Right")
@tri.rotation = @tri.rotation - 0.5 * dt if @controller.action?("Rotate Left")
@tri.rotation = @tri.rotation + 0.5 * dt if @controller.held?("Rotate Right")
@tri.rotation = @tri.rotation - 0.5 * dt if @controller.held?("Rotate Left")
unless @paused
@tri.rotation = @tri.rotation + 1.0 * dt

View file

@ -1,10 +1,17 @@
require "./lib_sdl"
module PF
alias Keys = LibSDL::Scancode
# Handle button to action mapping in a dynamic way
class Controller(T)
PRESSED = 0b0000001_u8
READ = 0b0000010_u8
@[Flags]
enum State : UInt8
Unset = 0
Pressed
Released
Read
end
# Detect the current keyboard layout
def self.detect_layout
@ -31,10 +38,10 @@ module PF
end
def initialize(@mapping : Hash(T, String))
@keysdown = {} of String => UInt8
@keysdown = {} of String => State
@mapping.values.each do |key|
@keysdown[key] = 0
@keysdown[key] = State::Unset
end
end
@ -58,36 +65,45 @@ module PF
def press(button)
return nil unless registered?(button)
@keysdown[@mapping[button]] |= PRESSED
return nil if @keysdown[@mapping[button]] & State::Pressed == State::Pressed
@keysdown[@mapping[button]] = State::Pressed
end
def release(button)
return nil unless registered?(button)
@keysdown[@mapping[button]] = 0
return nil unless @keysdown[@mapping[button]] & State::Pressed == State::Pressed
@keysdown[@mapping[button]] = State::Released
end
# ===============
def any_pressed?
@keysdown.any? { |name, state| state & PRESSED > 0 }
def any_held?
@keysdown.any? { |name, state| state & State::Pressed == State::Pressed }
end
def none_held?
!any_held?
end
# Returns true the first time called if a button has been pressed
def pressed?(name)
return false if @keysdown[name] & READ != 0
return false unless @keysdown[name] & PRESSED != 0
@keysdown[name] |= READ
return false if @keysdown[name] & State::Read == State::Read
return false unless @keysdown[name] & State::Pressed == State::Pressed
@keysdown[name] |= State::Read
true
end
# Returns true if a registered button is being held
def held?(name)
@keysdown[name] & PRESSED > 0
@keysdown[name] & State::Pressed == State::Pressed
end
# ditto
def action?(name)
@keysdown[name] & PRESSED > 0
# Returns true the first time called after a button has been released
def released?(name)
return false unless @keysdown[name] & State::Released == State::Released
return false if @keysdown[name] & State::Read == State::Read
@keysdown[name] |= State::Read
true
end
end
end

View file

@ -1,22 +1,22 @@
require "./lib_sdl"
require "./pixel"
require "./sprite"
require "./controller"
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 title : String
getter width : Int32
getter height : Int32
getter scale : Int32
@viewport : Vector2(Int32)? = nil
property running = true
property screen : Sprite
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
@ -28,7 +28,7 @@ module PF
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)
SDL.init(SDL::Init::EVERYTHING)
@window = SDL::Window.new(@title, @width * @scale, @height * @scale, flags: window_flags)
@renderer = SDL::Renderer.new(@window, flags: flags)
@renderer.scale = {@scale, @scale}
@ -38,6 +38,10 @@ module PF
abstract def update(dt : Float64, event : SDL::Event)
abstract def draw
# To be overridden
def on_exit
end
def width=(value : Int32)
@viewport = nil
@width = value
@ -75,6 +79,7 @@ module PF
break unless @running
end
ensure
on_exit
SDL.quit
end

View file

@ -22,7 +22,7 @@ module PF
end
end
def draw_to(surface : SDL::Surface, text : String, x : Int32 = 0, y : Int32 = 0)
def draw_to(surface : SDL::Surface, text : String, x : Int = 0, y : Int = 0)
ix = 0
iy = 0
text.each_char do |char|
@ -59,5 +59,9 @@ module PF
end
draw_to(sprite.surface, text, x, y)
end
def draw_to(sprite : Sprite, text : String, pos : Vector2(Int))
draw_to(sprite.surface, text, pos.x, pos.y)
end
end
end

View file

@ -12,5 +12,10 @@ module PF
end
end
end
# ditto
def fill_rect(p1 : PF::Vector2(Int), p2 : PF::Vector2(Int), pixel : Pixel = Pixel.new)
fill_rect(p1.x, p1.y, p2.x, p2.y, pixel)
end
end
end