Skip to main content

Placing the Fruit

A freely moving snake is nice. But it get's a bit dull if that's all there is. To make it a bit more of a challenge, you'd need to add something to change the snake. The classic approach is to let the snake "eat" fruits. That's a good place to start.

To place (and eat) a fruit, you first need to make a variable for this. Since it's simply a point on the grid, `Point` will do.
require "wasm4"local Snake = require "snake"local Point, Snake = Snake.Point, Snake.Snake
local snake = Snake.init()local fruit: Pointlocal frame_count = 0local prev_state = 0

Random Numbers#

Nelua provides us a math library with a random function, which when called with two integers m and n it returns a pseudo-random integer with uniform distribution in the range [m, n]. This allows you to call math.random(0, 19) to get a number between 0 and 19. Now you can change the fruit declaration:

local math = require 'math'
local snake = Snake.init()local fruit: Point = { x = math.random(0, 19), y = math.random(0,19) }local frame_count = 0local prev_state = 0

Importing PNG Files#

Importing images in WASM-4 works a bit different compared to other game engines and Fantasy Consoles. Images have to meet certain criteria:

  • PNG only
  • Index only
  • 4 colors max

Indexed PNG files can be created by several image apps like Aseprite or GIMP.

The image we import is a 8x8 PNG file with exactly 4 colors:

Zoomed Fruit This image is zoomed by 800%.

Zoomed Fruit This is the original image. You can download it to proceed.

Now you need to import the image. For this, the WASM-4 CLI tool w4 comes with another tool: png2src. You can use it like this:

w4 png2src --nelua fruit.png

This will output the following content in the terminal:

-- fruitlocal fruit_width <comptime> = 8local fruit_height <comptime> = 8local fruit_flags <comptime> = 1 -- BLIT_2BPPlocal fruit: [16]uint8 = { 0x00,0xa0,0x02,0x00,0x0e,0xf0,0x36,0x5c,0xd6,0x57,0xd5,0x57,0x35,0x5c,0x0f,0xf0 }

To get it into a an existing file, use the >> operator. Like this:

w4 png2src --nelua fruit.png >> main.nelua

This will add the previous lines to your main.nelua and it will shadow the previous fruit variable. Just rename the new fruit to fruit_sprite and move it somewhere else. Also: You can remove the other stuff added, you won't need it for this project:

local snake = Snake.init()local fruit: Point = { x = math.random(0, 19), y = math.random(0,19) }local frame_count = 0local prev_state = 0local fruit_sprite: [16]uint8 = { 0x00,0xa0,0x02,0x00,0x0e,0xf0,0x36,0x5c,0xd6,0x57,0xd5,0x57,0x35,0x5c,0x0f,0xf0 }

With that out of the way, it's time to actually render the newly imported sprite.

Rendering a PNG File#

Rendering the sprite is rather simple. Just call the blit function of w4:

// Blit draws a sprite at position `x`, `y` and uses DRAW_COLORS accordinglyglobal function blit(data: *[0]uint8, x: int32, y: int32, width: uint32, height: uint32, flags: uint32)

In practice it looks like this:

local function update()  frame_count = frame_count + 1
  input()
  if frame_count % 15 == 0 then    snake:update()  end
  snake:draw()
  blit(fruit_sprite, fruit.x * 8, fruit.y * 8, 8, 8, BLIT_2BPP)end

But since you set the drawing colors, you need to change the drawing colors too:

  snake:draw()
  $DRAW_COLORS = 0x4320  blit(fruit_sprite, fruit.x * 8, fruit.y * 8, 8, 8, BLIT_2BPP)

This way, w4 uses the color palette in its default configuration. Except for one thing: The background will be transparent.