Watchface: Nyan Cat (animated)

Hi Folks,

I've recreated one of my favourite Pebble watchfaces on CIQ, Nyan Cat;
https://apps.garmin.com/en-US/apps/c8f5e260-6a54-4f3a-a910-c10d7cc37778



I built this to explore sprite animation in Monkey C. My initial attempt was to use a number of bitmaps to represent the animation. However, I quickly hit the 64k memory limit with 12x bitmaps (4-bit colour).

I then explored the following;

- Using a series of Font Glyphs to represent the sprite animation.
- Manually draw sprites from colour integers in a series of arrays.
- Manually draw sprites using strings and a palette map.

Here's an example of the manual sprite routines:

[PHP]const nyan_data = "xxxxxxxxx00000000000000000xxxxxxxxxxxxxxxx0eeeeeeeeeeeeeeeee0xxxxxxxxxxxxxx0eeedddddddddddddeee0xxxxxxxxxxxxx0eeddddddaddadddddee0xxxxxxxxxxxxx0eddadddddddddddddde0xxxxxxxxxxxxx0edddddddddd00ddadde0x00xxxxxxxxxx0eddddddddd0bb0dddde00bb0xxx0000xx0eddddddadd0bbb0ddde0bbb0xxx0bb00x0eddddddddd0bbbb0000bbbb0xxx00bb000edddaddddd0bbbbbbbbbbbb0xxxx00bb00eddddddda0bbbbbbbbbbbbbb0xxxx00bb0edadddddd0bbbz0bbbbbz0bb0xxxxx0000edddddddd0bbb00bbb0b00bb0xxxxxxx00edddddadd0bccbbbbbbbbbcc0xxxxxxxx0eedaddddd0bccb0bb0bb0bcc0xxxxxxxx0eeeddddddd0bbb0000000bb0xxxxxxxx000eeeeeeeeee0bbbbbbbbbb0xxxxxxxx0bbb000000000000000000000xxxxxxxxx0bb00x0bb0xxxxx0bb0x0bb0xxxxxxxxxx0000xx000xxxxxxx000xx00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const palette = {"0" => 0, "a" => 11141120, "b" => 11184810, "c" => 16711680, "d" => 16711935, "e" => 16755200, "x" => Gfx.COLOR_TRANSPARENT, "z" => 16777215 };

// sprite_data = uses a char string + pallete to draw a sprite
function drawSpriteText( x, y, sprite_data, sprite_width, sprite_height, dc ) {
var old_x = x;

var size = sq_size;
var sprite_colour = 0;
var sprite_val = "";

for( var j = 0; j < sprite_height*sprite_width; j=j+sprite_width ) {

for( var i = 0; i < sprite_width ; i++ ){

sprite_val = sprite_data.substring(j+i,j+i+1);
sprite_colour = palette[sprite_val];

dc.setColor(sprite_colour, Gfx.COLOR_TRANSPARENT);
dc.fillRectangle(x, y, size, size);
x = x + size;
}

// on to the next sprite row
y = y + size;
x = old_x;

}

}

// draw the sprite
drawSpriteText(x_pos, y_pos, nyan_data, sprite_height, sprite_width, dc);
[/PHP]

All these options worked, and kept the watchface within memory limits - except they are slow.
Running hundreds of dc.fillRectangle fills are expensive, and the watchface could only update once a second.

My last option was to manually animate the sprite using a number of different bitmaps.

Here's the source code if anyones interested:
https://github.com/sunpazed/garmin-nyan-cat

I'd be keen if anyone has any other clever ideas on how to implement sprite animation.
  • Interesting! For testing, you could try turning you watch face into a watch-app, where you can set up your own timer and do the screen updates more often than every second (every 100ms for example), just to see how that runs. It will burn more battery. The 1hz update for watchfaces (when not in low power mode) is kind of a fixed thing with connect IQ, but there are cases where watch-apps that look like watchfaces are in the store.
  • Interesting! For testing, you could try turning you watch face into a watch-app, where you can set up your own timer and do the screen updates more often than every second (every 100ms for example), just to see how that runs. It will burn more battery.


    Sounds like a good idea, and I should get a larger memory footprint too.

    Here's a video of it in action... https://gfycat.com/PeskyUnnaturalArrowcrab
  • Due to popular demand, I've updated Nyan Cat to include 6 different date selections, and steps, steps remaining, step goal %, and battery!

    Oh, and I've updated the source code too... https://github.com/sunpazed/garmin-nyan-cat