Eaglev0.1.0

2D sandbox

Scene tree, tile map, following camera with shake, tweens and a HUD layer.

WASD moves the player

Source: examples/sandbox2d/main.cr

examples/sandbox2d/main.cr

require "../../src/eagle"
include Eagle

# Scene-tree sandbox: a player sprite you move with WASD/arrows/gamepad,
# a following camera, a tile map, timers, tweens and a HUD on a CanvasLayer.

class Player < Sprite2D
  SPEED = 220

  def initialize
    super("Player")
    img = Image.new(24, 24, Color::TRANSPARENT)
    img.blit(Image.circle(24, Color.hex("#ffcc00")), 0, 0)
    img.fill_rect(15, 8, 4, 4, Color::BLACK)
    self.texture = Texture.new(img)
  end

  def ready
    Input.map "left", Key::A, Key::Left, Input.axis(GamepadAxis::LeftX, -1)
    Input.map "right", Key::D, Key::Right, Input.axis(GamepadAxis::LeftX, 1)
    Input.map "up", Key::W, Key::Up, Input.axis(GamepadAxis::LeftY, -1)
    Input.map "down", Key::S, Key::Down, Input.axis(GamepadAxis::LeftY, 1)
  end

  def process(dt : Float32)
    v = Input.vector("left", "right", "up", "down")
    self.position += v * SPEED * dt
    self.rotation = v.angle if !v.zero?
  end
end

class Sandbox < App
  @cam = Camera2D.new(zoom: 2)
  @player = Player.new
  @hud = Label.new("", v2(8, 8))
  @spin = Polygon2D.regular(6, 20, Color.hex("#66ccff"))

  def load
    Texture.default_filter = GPU::Filter::Nearest
    root = SceneTree.root
    # Tileset: 2 tiles, 16px, grass and stone
    ts = Image.new(32, 16)
    ts.fill_rect(0, 0, 16, 16, Color.hex("#3a7d44"))
    ts.fill_rect(16, 0, 16, 16, Color.hex("#6b6b6b"))
    4.times { |i| ts[2 + i * 3, 3 + (i % 2) * 5] = Color.hex("#5cb85c") }
    map = TileMap.new(Texture.new(ts), 16, 16)
    24.times { |y| 32.times { |x| map[x, y] = (x == 0 || y == 0 || x == 31 || y == 23 || (x * y) % 17 == 0) ? 1 : 0 } }
    map.position = v2(-256, -192)
    root.add(map)

    @spin.position = v2(80, -40)
    root.add(@spin)
    Tween.to(2.0, ease: :sine_in_out) { |t| @spin.rotation = t * Math::PI * 2 }.loop = true

    @player.position = v2(0, 0)
    root.add(@player)
    root.add(@cam)
    @cam.follow(@player)
    @cam.limits = Rect.new(-256, -192, 512, 384)

    hud_layer = CanvasLayer.new
    hud_layer.add(@hud)
    root.add(hud_layer)

    t = Timer.new(1.0) { @cam.shake(3, 0.2) }
    t.start
    root.add(t)
  end

  def update(dt : Float32)
    @hud.text = "WASD to move  fps #{Clock.fps.round}  pos #{@player.position.round}  nodes #{SceneTree.node_count}"
    Eagle.quit if Input.pressed?(Key::Escape)
  end

  def draw(g : Graphics)
    g.print("draw calls #{g.draw_calls}", 8, Window.height - 24, Color::GRAY)
  end
end

Eagle.run(Sandbox, title: "Eagle sandbox 2D", width: 800, height: 600)