Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Justin
Justin

Posted on • Edited on • Originally published atblog.presidentbeef.com

     

DragonRuby: Static Outputs

In aprevious post we looked at different ways to render outputs (sprites, rectangles, lines, etc.) in theDragonRuby Game Toolkit.

The post ended by hinting at a more efficient way to render outputs instead of adding them to e.g.args.outputs.solids orargs.outputs.sprites each tick.

This post explores the world of "static outputs"!

Static What?

First of all, we should address the most confusing part of all this.

"Static" does not mean the images don't move or change. Instead, it means that render "queue" is not cleared after every tick.

Normally, one would load up the queue each tick, like this:

deftickargs# Render a black rectangleargs.outputs.solids<<{x:100,y:200,w:300,# widthh:400# height}end
Enter fullscreen modeExit fullscreen mode

But this is kind of wasteful. We are creating a new hash table each tick (60 ticks/second) and then throwing it away. Also each tick we are filling up theargs.outputs.solids queue and then emptying it.

Instead, why not create the hash table once, load up the queue once, and then re-use them?

That's the idea of static outputs!

There are static versions for each rendered type:

  • args.outputs.static_borders
  • args.outputs.static_labels
  • args.outputs.static_primitives
  • args.outputs.static_solids
  • args.outputs.static_sprites

Going Static

Starting Out

Here's an example with comments explaining what the code is doing. This "game" simply moves a square back and forth across the screen. This is the entire program!

deftickargs# Initialize the x location of the squareargs.state.x||=0# Initialize the direction/velocityargs.state.direction||=10# If we hit the sides, change directionifargs.state.x>args.grid.rightorargs.state.x<args.grid.leftargs.state.direction=-args.state.directionend# Update the x locationargs.state.x+=args.state.direction# Build the squaresquare={x:args.state.x,y:400,w:40,h:40,}# Add the square to the render queueargs.outputs.solids<<squareend
Enter fullscreen modeExit fullscreen mode

The resulting output looks like:

Image description

This example introducesargs.state. This is basically a persistent bag you can throw anything into. (For Rubyists - this is likeOpenStruct.)

x anddirection are not special, they are just variables we are defining. We use||= to initialize them because we only want to set the values on the first tick.

This example illustrates the point from above - every tick it creates a new square and adds it to the queue. The queue is emptied out and then the code starts all over again.

Seems wasteful, right?

Caching the Objects

First thing I think of is - "why not create the square once, then just update the object each tick? Does that work?" Yes! It does.

deftickargsargs.state.direction||=10args.state.square||={x:0,y:400,w:40,h:40,}ifargs.state.square[:x]>args.grid.rightorargs.state.square[:x]<args.grid.leftargs.state.direction=-args.state.directionendargs.state.square[:x]+=args.state.directionargs.outputs.solids<<args.state.squareend
Enter fullscreen modeExit fullscreen mode

In this code, we create thesquare only once and then store it inargs.state.square.

Instead of having a separatex variable, the code updates thex property on the square directly.

This isbetter, but we are still updatingargs.outputs.solids each tick.

Full Static

deftickargsargs.state.direction||=10args.state.square||={x:0,y:400,w:40,h:40,}# On the first tick, add the square to the render queueifargs.tick_count==0args.outputs.static_solids<<args.state.squareendifargs.state.square[:x]>args.grid.rightorargs.state.square[:x]<args.grid.leftargs.state.direction=-args.state.directionendargs.state.square[:x]+=args.state.directionend
Enter fullscreen modeExit fullscreen mode

In this code, we use the fact that the firstargs.tick_count is0 to add thesquare toargs.outputs.static_solids justonce. It will continue to be rendered on each tick.

Performance

Intuitively, since the code is doing less, it should be faster. But does it really make a difference?

It depends on your game, how much it's doing per tick, how many sprites you are rendering, and what platform/hardware it's running on.

The examples above? Not going to see any difference usingstatic_solids.

But DragonRuby contains two examples that directly compareargs.outputs.sprites vs.args.outputs.static_sprites (here andhere).

In these examples, you can play with the number of "stars" rendered to see different performance. On my ancient laptop, I do not see a performance difference until around 3,000 stars.

Your mileage may vary, though!

Should I Always Use the Static Versions?

It depends! Probably not?

If your code mainly manipulates the same objects around the screenand always renders them in the same order, then using thestatic_ approach might be simpler and faster.

But in many cases it might be easier to simply set up the render queues each tick, especially if the objects rendered or their ordering change regularly. Otherwise, managing the state of the rendering queues can become cumbersome. (We haven't even talked about clearing the static queues, for example.)

Some of this comes down to personal preference and how you would like to structure your code. But hopefully this post has helped explain how to use theargs.outputs.static_* methods in your game!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I work on Brakeman (security tool for Ruby on Rails) and do other stuff too.
  • Location
    San Francisco Bay Area
  • Education
    UCLA, Seattle University
  • Joined

More fromJustin

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp