Skip to main content

Drawing the Snake

Drawing the Body#

To draw the snake, you can take advantage of nelua's for syntax. To make it a little easier, it's a good idea to use the rect function of WASM-4:

// rect draws a rectangle. It uses color 1 to fill and color 2 for the outlineglobal function rect(x: int32, y: int32, width: uint32, height: uint32)

With that out the way, let's see what a first draft could look like.

function Snake:draw()  for i = 1, #self.body do    rect(self.body[i].x * 8, self.body[i].y * 8, 8, 8)  endend

Simply loop through the body and draw it at x * 8 and y * 8. 8 is the width and the height of a single part. On a 160x160 screen, it's big enough to fit snake that is 20*20=400 parts long.

That's all fine, but since we haven't initialized the snake, nothing can be drawn. To fix this, simply create a new variable in main and call its draw function:

require "wasm4"local Snake = require "snake"local Point, Snake = Snake.Point, Snake.Snake
local snake = Snake.init()
$PALETTE = {  0xfbf7f3,  0xe5b083,  0x426e5d,  0x20283d}
local function update()  snake:draw()end
## setup_wasm4_callbacks(update)

Creating a global variable of a snake with some default values.

After that, simply call the draw function of the snake.

You should see some green blocks at the top.

Snake Body

Drawing the Head#

But where is the head? You can pick a side. Either position [1] or position [#self.body].

I think it's easier to pick [1].

Since the body is drawn, head is not much of a problem. Simply use the rect function again. But use a specific part instead:

  rect(self.body[1].x * 8, self.body[1].y * 8, 8, 8)

The draw function should now look like this:

function Snake:draw()  for i = 1, #self.body do    rect(self.body[i].x * 8, self.body[i].y * 8, 8, 8)  end
  rect(self.body[1].x * 8, self.body[1].y * 8, 8, 8)end

Notice the difference? Me neither.

The head should stand out a little. For this, you can use a different color:

$DRAW_COLORS = 0x0004;

You can set the colors with this variable. You can look at this variable like a table that is read from right to left.

The value for each digit can be 0 up to 4:

  • 0 = Use transparency
  • 1 = Use the 1st color from the color palette
  • 2 = Use the 2nd color from the color palette
  • 3 = Use the 3rd color from the color palette
  • 4 = Use the 4th color from the color palette

The snippet above reads like this: "Color 1 uses Color 4 of the color palette, Color 2 to Color 4 don't use any color." The basic drawing functions use "Color 1" to fill the shape and "Color 2" for the border.

If you change the source to

function Snake:draw()  for i = 1, #self.body do    rect(self.body[i].x * 8, self.body[i].y * 8, 8, 8)  end
  $DRAW_COLORS = 0x0004;  rect(self.body[1].x * 8, self.body[1].y * 8, 8, 8)end

Result:

Changing Color

You'll see a change. The snake changed color. Not only the head, but the complete snake! Once you've set a color, it stays that way. So if you want to change only the head, you have to change Color 1 again. Right before you draw the body.

function Snake:draw()  $DRAW_COLORS = 0x0043;  for i = 1, #self.body do    rect(self.body[i].x * 8, self.body[i].y * 8, 8, 8)  end
  $DRAW_COLORS = 0x0004;  rect(self.body[1].x * 8, self.body[1].y * 8, 8, 8)end

This changes the color back and adds the darker green as its outline.

Snake with outline