Skip to content

Instantly share code, notes, and snippets.

@marcheiligers
Created July 2, 2022 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcheiligers/dec73c0a64c03b834543a62b70721005 to your computer and use it in GitHub Desktop.
Save marcheiligers/dec73c0a64c03b834543a62b70721005 to your computer and use it in GitHub Desktop.
DRGTK Layer Hack
LAYERS = %w[
solids
sprites
primitives
labels
lines
borders
].freeze
class Player
attr_sprite
attr_accessor :zindex
def initialize
@w = 100
@h = 80
@x = (1280 - @w) / 2
@y = (720 - @h) / 2
@zindex = 3
LAYERS.each do |layer|
$args.outputs.send("static_#{layer}") << self
end
end
def update
@cur_index = 0
@frame = $args.tick_count.idiv(3) % 5
end
def draw_override(ffi)
return unless (@cur_index += 1) == @zindex
ffi.draw_sprite @x, @y, @w, @h, "sprites/misc/dragon-#{@frame}.png"
end
end
class Cloud
attr_sprite
SPRITE_PATH = 'sprites/misc/explosion-1.png'.freeze
def initialize(zindex)
@w = 32
@h = 32
@x = rand(1280)
@y = rand(720)
@sat = zindex * 35
$args.outputs.send("static_#{LAYERS[zindex]}") << self
end
def draw_override(ffi)
ffi.draw_sprite_3 @x, @y, @w, @h,
SPRITE_PATH,
0,
255, @sat, @sat, @sat,
0, 0, -1, -1,
false, false,
0, 0,
nil, nil, nil, nil
end
end
def boot(args)
LAYERS.length.times do |z|
300.times do
Cloud.new(z)
end
end
$player = Player.new
end
def tick(args)
$player.zindex -= 1 if args.keyboard.key_down.comma && $player.zindex > 1
$player.zindex += 1 if args.keyboard.key_down.period && $player.zindex < LAYERS.length
$player.x += args.keyboard.left_right * 3
$player.y += args.keyboard.up_down * 3
$player.update
args.outputs.debug << { x: 20, y: 697, text: $player.zindex.to_s, size_enum: 3, r: 180, g: 0, b: 0 }
end
@marcheiligers
Copy link
Author

marcheiligers commented Jul 7, 2022

A recent discussion on z-index spawned an interesting thought and I wanted to write it down before the Scotch washed it away … so I did … and the next day I built this sample to illustrate it.

In my most optimised code I stick everything into static_* outputs and use draw_override.

Now draw_override doesn't care what you draw: you can draw Sprites in the static_labels collection or really anything anywhere. That means you can treat the different static_* outputs like layers: they are rendered in a specific order, so that gives you a z-index, and you can render different things at different levels -- but statically.

Here’s the trick: for something that needs to move between layers, like a player that needs to be in front of (some) clouds sometimes and behind them at others, you put it in all the static_* outputs, and only render it when being asked to render in the right layer.

But you don't know which static_* output (layer) is being rendered at the time of the draw_override call. Well, since the calls are always in a defined order, if you keep a count of how many times you've been asked to render, you have your z-index.

So this gives you about six layers to play with, and an way to move players and enemies between layers. Additionally, ephemeral objects, like bullets, can go into non-static outputs since they are interleaved with the static ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment