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: Render Targets

Next up in my notes onDragonRuby: render targets!

Weirdly, thedocumentation on DragonRuby's render targets is limited to example code. Personally, I prefer prose when I am trying to learn... so here we are!

In DragonRuby, a render target is like an infinite canvas you can render as many regular sprites onto as you want, then manipulate the whole thing as if it is one sprite.

This is especially good for things like tiled backgrounds that are built once and do not change.

Let's take an example.

Clouds!

Let's start off very simple and build up.

First, here's all the code to render a single 250x250 pixel image to the screen:

deftickargsclouds={x:0,y:0,h:250,w:250,path:'sprites/cloud.png'}args.outputs.sprites<<cloudsend
Enter fullscreen modeExit fullscreen mode

Single cloud tile

More Clouds

Cool, but I'd like to fill the whole window with clouds, so I'm going to tile them.

The code below makes a 6x3 grid of the cloud image.

(In DragonRuby, the screen is always 1280x720. Our grid is 1500x750 but I'm not trying to be too precise with the numbers here.)

deftickargsclouds=[]6.timesdo|x|3.timesdo|y|clouds<<{x:x*250,y:y*250,h:250,w:250,path:'sprites/cloud.png'}endendargs.outputs.sprites<<cloudsend
Enter fullscreen modeExit fullscreen mode

Screen full of blue clouds

Ah... blue clouds. Nice.

On every tick, the code builds up an array of 18 sprites (images) and renders it out to the screen.

(There are a number of ways to make this more efficient - check out theprevious posts in this series for different ways to "cache" the sprite information.)

Render Targets

But in this post we are talking about render targets - which is a way of rendering a bunch of sprites (or any other renderable thing) just once, and then treating the whole group of sprites as a single sprite. This isfaster, simpler, and enables some neat effects.

The code only needs minor changes to switch the cloud grid to using a render target instead:

# Move cloud grid creation into a helper methoddefmake_clouds(args)clouds=[]6.timesdo|x|3.timesdo|y|clouds<<{x:x*250,y:y*250,h:250,w:250,path:'sprites/cloud.png'}endend# Similar to `args.outputs`,# render targets have `.sprites`, `.solids`, etc.# The argument will be used as the path belowargs.render_target(:clouds).sprites<<cloudsenddeftick(args)# Set up the render target on the first tickifargs.tick_count==0make_clouds(args)end# Output a single sprite# located at 0,0 and the size of the whole grid# created in `make_clouds`args.outputs.sprites<<{x:0,y:0,w:250*6,h:250*3,path: :clouds# Name of the render target!}end
Enter fullscreen modeExit fullscreen mode

For convenience, the code above moves the creation of the cloud grid and the render target into a helper method which gets called on the first tick of the game.

args.render_target(:clouds) automatically creates a new render target named:clouds if it does not already exist. Then we can render things to it just as if it wereargs.outputs.

Interestingly, render targets do not seem to have an innate width or height. In order to avoid unintentional scaling, you will need to "know" how big the render target is. In this case, we know it is a 6x3 grid of 250x250 images, so the size is fairly straightforward. I left the math in to make it clearer.

Finally, we reference the render target similarly to an image file, but pass in the name of the render target as the:path instead of an actual file path.

Static Sprites, Too!

As explored in a different post, we can usestatic_sprites to "render" the spriteonce.

# No changes heredefmake_clouds(args)clouds=[]6.timesdo|x|3.timesdo|y|clouds<<{x:x*250,y:y*250,h:250,w:250,path:'sprites/cloud.png'}endendargs.render_target(:clouds).sprites<<cloudsenddeftick(args)ifargs.tick_count==0make_clouds(args)# Create the clouds sprite once# and keep it in `args.state`.args.state.clouds={x:0,y:0,w:250*6,h:250*3,path: :clouds}# Add the clouds sprite just once# as a "static" spriteargs.outputs.static_sprites<<args.state.cloudsendend
Enter fullscreen modeExit fullscreen mode

And now we can move the clouds around just by changing the attributes on the render target.

Adding a little bit of code at the end oftick:

args.state.clouds.x=(Math.sin(args.tick_count/20)*100)-100
Enter fullscreen modeExit fullscreen mode

(The calculation and numbers aren't really important here, I just fiddled around until something looked decent.)

Clouds moving back and forth

Oh hey! Those extra pixels on the sides of the cloud grid actually came in handy.

What Else?

Remember, the entire render target is like one sprite now. That means all the regular sprite attributes (e.g. color, size, blending, flipping, rotation) can be applied to the entire thing at once.

Wait, did you say rotation?

Sure, let's make ourselves dizzy.

args.state.clouds.angle=(Math.sin(args.tick_count/120)*180)
Enter fullscreen modeExit fullscreen mode

Spinning clouds

Okay, that's as deep as we'll go on render targets in this post!

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