Week 1 - Parts 0 and 1


Part 0 - Setting Up

Project Setup

  • Acquire a licensed copy of DragonRuby GTK
  • Extract to a standard location for development work
    • Downloaded dragonruby-pro-linux-amd64.zip
    • Opened archive and copied contents to /home/kehvarl/DragonRuby/RLD_Tutorial_2024
    • Deleted mygame folder
    • At a terminal in the newply created RLD_Tutorial_2024 folder:
      • git clone git@github.com:Kehvarl/roguelikedev-2024-drgtk.git ./mygame
  • Install the editor of your choice
    • In this instance I am using Pulsar Edit (a fork of Atom)
  • Open mygame folder as a project in your editor

Part 1 - Drawing the '@' Symbol and Moving it around

Assuming you've followed Part 0 or otherwise set up your DragonRuby development environment, begin by opening the main.rb file in your mygame folder in the editor of your choice.

Opening an Empty Window

Replace the contents so what you have looks like this

def tick args   args.outputs.primitives << {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid! end

You can run the program like any other DragonRuby program. If you're new to DragonRuby, just run the dragonruby or dragonruby.exeexecutable in the parent directory above mygame.

You should now see a relatively plain window with a solid black background, and a title that tells you to update a different file to change it.

Open that new file mygame\metadata\game_metadata.txt in your editor, and replace the top section with something like this:

# devid=myname # devtitle=My Name # gameid=mygame gametitle=RoguLikeDev Tutorial 2024 # version=0.1 # icon=metadata/icon.png 

Lines that start with a 'sharp' (#) symbol are comments, and will be ignored in favor of their defaults. In the above example the gametitle line has been uncommented and a new title added. Save the file and re-run dragonruby to view the window with the new title. Part 1.0

Drawing to the screen

Before we proceed, what's going on in our current main.rb?

def tick args   args.outputs.primitives << {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid! end

tick

The line def tick args creates a function named tick that expects a single parameter names args. The tick function is special in DragonRuby, and is the main entrypoint for the engine into your game code. In the background, the engine will try to run everything in the tick function 60 times per second, performing any drawing every time. This means that as long as your game code can run in 1/60 of a second, you can maintain 60FPS by just letting DragonRuby run.

args

The only line in our tick function references the args parameter. If tick is how DragonRuby runs your code, args is how your code interacts with DragonRuby. It lets you save and recover game-state information, it provides you with information about what inputs are being provided by your player, it includes some tools for layout, and interaction of on-screen objects, and it lets you output information to the screen. The line args.outputs.primitives << ... uses the << command to append a definition to the outputs.primitives collection for DragonRuby to draw on screen this tick.

Hashes

The definition in question: {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid! is a hash (the ruby word for a dictionary or map) with a few parameters:

  • x: the x position defining the left side of our rectangle (Nearly everything in DragonRuby is rects at this level)
  • y: the y position defining the bottom of our rectangle
  • w: The width of our rectangle
  • h: The height of our rectangle
  • r: , g: , b: the red, green, and blue parameters for the color to use (in this case 0,0,0 or Black)
  • .solid! the primitive marker that tells DragonRuby this specific rectangle is to be filled in with the defined color

As you can see we are defining a solid black rectangle starting at the lower-left corner (0,0) that is the size of our window (1280x720), filling it completely. This gives us a black background to draw the rest of our game on top of.

Sprite hashes

In additions to "solid" rectangles, DragonRuby can render an image known as a sprite. For example, we can use the built-in blue square sprite found in the folder mygame/sprites/square/ it's named blue.png.

A minimal sprite hash definition looks like

{x: x_value, y: y_value, w: draw_width, h: draw_height, path: sprite_path}.sprite!

As with the solid, it expects an x and y position for the lower left corner, then a width and height. Instead of a color, it looks for a path to the image to use. There are several other properties we can work with, but they all have sensible defaults. For more details, refer to the DragonRuby Documentation: API: Outputs: Sprites: Rendering a Sprite Using a Hash

Update the tick method of your main.rb file to look like this:

def tick args   args.outputs.primitives << {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid!   args.outputs.primitives << {x:640, y:360, w:40, h:40, path:'sprites/square/blue.png'}.sprite! end

If you now run your game, you'll see a screen like this: Part 1.1

Working with Sprite Sheets

Instead of drawing an entire image onto the screen, DragonRuby is capable of drawing just part of a larger image. This allows you to store several sprites in a single image file, for example all the animation frames for a specific action, or all the different animation frames for a specific character.

In this case we're going to use the included font-file sprites/mist/simple-mood-16x16.png. This sprite sheet is a 16x16 grid of 16x16-pixel sprites that make up the simple-mood font. Using this we can easily draw ASCII characters to the screen. Part 1.2-font

To draw a single item from a sprite sheet, we need to add 4 more properties to our hash:

{x: x_value, y: y_value, w: draw_width, h: draw_height,  source_x: sprite-sheet_x_position, source_y:sprite-sheet_y_position,  tile_w:width_of_sprite_in_sheet, tileh:height_of_sprite,  path: sprite_path}.sprite!

For example, if we adjust our tick method like so:

def tick args   args.outputs.primitives << {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid!   args.outputs.primitives << {x:640, y:360, w:40, h:40,                               tile_x:0, tile_y:64,                               tile_w:16, tile_h:16,                               path:'sprites/misc/simple-mood-16x16.png'}.sprite! end

We've replaced our blue square with the "@" symbol from the sprite sheet. Part 1.2

Remembering State

To turn the new "@" sprite into our player representation, we need some way to make it respond to our inputs. Which means we need some way to track the sprite's state, specifically its position on the screen.

In args there's a collection named state. Any value stored into this collection will be available to be accessed on any future tick. We will use this to store our entire player hash like so:

def tick args   args.state.player ||= {x:640, y:360, w:16, h:16,                               tile_x:0, tile_y:64,                               tile_w:16, tile_h:16,                               path:'sprites/misc/simple-mood-16x16.png'}.sprite!   args.outputs.primitives << {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid!   args.outputs.primitives << args.state.player end

Every time DragonRuby runs our tick function, it checks args.state for a variable named player. If that variable is not set, then DragonRuby populates it with our player hash. If it was already set in a prior tick, then this line does nothing.

We also updated out output to draw the contents of our player variable onto the screen. Meaning any update we make will be reflected in our output

Moving a Sprite

Now that we have our player sprite stored in our game state, we can change it and render our changes each tick

Getting Keyboard Input

To get inputs we will use args again. In this case args.inputs holds any supported input states, whether from controllers, a mouse, a touchscreen, or a keyboard.

To check for a pressed key we can look at args.inputs.keyboard.<key>, but this will return true whether the key was just pressed, or if it's currently held down. At 60 ticks per second, that might cause the player to take several turns when they only intend to take one. Instead we'll use args.inputs.keyboard.key_down.<key> to only move when the key is pressed, then stop and wait for a new keypress.

If we add keypress checking to the tick method, the result might look like this:

def tick args   args.state.player ||= {x:640, y:360, w:16, h:16,                               tile_x:0, tile_y:64,                               tile_w:16, tile_h:16,                               path:'sprites/misc/simple-mood-16x16.png'}.sprite!   args.outputs.primitives << {x:0, y:0, w:1280, h:720, r:0, g:0, b:0}.solid!   args.outputs.primitives << args.state.player    if args.inputs.keyboard.key_down.up     args.state.player.y += 16   elsif args.inputs.keyboard.key_down.down     args.state.player.y -= 16   elsif args.inputs.keyboard.key_down.left     args.state.player.x -= 16   elsif args.inputs.keyboard.key_down.right     args.state.player.x += 16   end end

If you now run the game, you can move the player around the screen with the arrow keys Part 1.3

Files

rld-2024-macos.zip 5.2 MB
Version 0.1 83 days ago
rld-2024-windows-amd64.zip 3.8 MB
Version 0.1 83 days ago
rld-2024-linux-raspberrypi.zip 3.7 MB
Version 0.1 83 days ago
rld-2024-linux-amd64.zip 3.9 MB
Version 0.1 83 days ago
rld-2024-html5.zip Play in browser
Version 0.1 83 days ago
rld-2024-macos.zip 5.2 MB
Version 0.1 83 days ago
rld-2024-windows-amd64.zip 3.8 MB
Version 0.1 83 days ago
rld-2024-linux-raspberrypi.zip 3.7 MB
Version 0.1 83 days ago
rld-2024-linux-amd64.zip 3.9 MB
Version 0.1 83 days ago
rld-2024-html5.zip Play in browser
Version 0.1 83 days ago

Get RLD2024

Leave a comment

Log in with itch.io to leave a comment.