embSnake

Introduction

As part of our work at the Laboratory of Electronic and Information Systems, we traditionally produce a small inexpensive electronic device as gift for our partners and sponsors. This year, the device produced included a graphic LCD screen and two buttons to the side - an idea was born to embed a small game into the device as an additional “surprise” for the gift recipients. For this purpose, I have reimplemented the traditional snake game, commonly included in early mobile phones (e. g. Nokia 3310), as an optimized c program, which can be easily added to such small embedded projects.

The whole game consists of purely c source code, including the graphics, which are converted into raw c arrays from .png images using Python scripts. The whole embSnake code can be found at the embSnake GitHub repository. In its current form, it is directly targeted for use with display which support 16 bit colors (5b red, 6b green, 5b blue, e. g. ones using a HX8340-B driver).

Game code

The initial version of the embSnake game was developed as a standalone application, where the SDL2 library was used for graphics rendering. All function of the game itself were coded in a way to be suitable for later use with a microcontroller. The SDL2 library was the used to display the game state on the screen. The process was similar to the one used for the development of OsciWalker.

embSnake PC emulator

The embSnake game implements the following features:

  • A 20 x 16 grid on which the snake can move, with the border tiles having a custom graphics - the snake can move seamlessly through the border.
  • The snake, which can be controlled by using two buttons - to turn left or right.
  • Two randomly place apples, which the snake can eat to expand by 1 tile.
  • Random colors of apples and snake middle parts, which correspond to the apple colors eaten.

Implementation details

The primary design factor of the embSnake game was that it should run as fast as possible on a resource constrained microcontroller. For this purpose, the game is split into two parts, the first of which is an optimized draw part, which loops through all pixels of the LCD and returns the corresponding pixel data, a row of a tile at once.

The other part is the game logic part, which is stored in an 2D array of tile structs, which contain the current snake and apple data. Each frame tick, the snake is moved forward (or left or right, depending on user control) one tile, while the game parses the snake structure recursively, moving each tile forward by 1 step. If the snake eats an apple, an additional snake part is added. Then a new apple is randomly placed on the field.

This design allows a high frame-rate, especially when combined with a DMA to perform the actual transfer of data to the microcontroller - a frame-rate in the near of 20 fps was achieved with a STM32F071 microcontroller.

Related