Onychophora

This is the first game that I tried to port to the arduboy before getting distracted by developing Lagunita and then creating Ardubrain for the Game Jam 4.
Finally I have a functional port of Onychophora which offers almost the same challenge as the original game.
Source code is in GitHub. If you want to help developing or add a new level, send me a Pull Request and I’ll gladly add your contribution.

onychophora.hex

  • 2019-12-14: added levels 15 and 16
  • 2019-12-12: added another level
  • 2019-12-01: added a new level, fixed the start position in previous levels and added a logo.
  • 2019-11-29: bug fix where the length of the worm was increased before checking the early out conditions.
  • 2019-11-27: first feature complete version with 11 levels and a basic UI, but no music.
13 Likes

This is awesome! reminds me a bit of Snake Pass for xbox, but in 2d :smiley:

1 Like

Yes, the game is very similar to snakebird and snake pass, but it also has some mining elements since the main character is a worm :smiley:
I’ll try to add more levels, but I’ll be busy helping a friend porting a synthesizer from linux to android in the near future, so any help is welcome :slight_smile:

@bateske is like Oprah, he should give that synthesizer friend an arduboy and make him help with the game instead :stuck_out_tongue:

image

3 Likes

This is pretty cool and I cannot wait to see what contributions people make to the levels.

4 Likes

Super cool! I can’t figure out how to beat the poop level lol

1 Like

This might not be a bug but are you ment to fall when not supported but are contacting a powerup?
Edit:
image
image

1 Like

More Arduboy memes I love it

1 Like

I wasn’t expecting people to enjoy this game that much, but since there is so much demand, I guess that now I have no choice but to make it more presentable and come out with some new levels :slight_smile:

@eried, I gave up on porting that linux synthetizer to Android after I got myself up to date and found out about Android switching to AAudio and AMidi: the rewrite is so big that I can as well start a new hobby project.

@Dreamer2345, the decision about whether or not a food/poop are supposed to support the worm is something I’m morally struggling with the port. For the color version it was clear if the worm was in front of a powerup, but with a black and with it’s not that easy, so I declared food and poop as solid in Level.cpp
However your screenshot shows that the tail is in front of the head, which is definitively a bug :smiley:
Would you be able to please record a gif of how you reached that situation? Or maybe just give me a sequence of arrows press, like RURLD (right, up, right, left, down).

2 Likes

Its R to record gifs right?

ArduboyRecording%20(2)

@renato-grottesi
its to do with level resets when dying to spikes I think

1 Like

thank! I managed to reproduce it with a similar sequence, but it doesn’t happen all the time. I bet it’s some uninitialized variables. I’ll take a look :slight_smile:

1 Like

Looking at the bitmaps you could compile them into one variable but idk if that would increase the memory size by much

@Dreamer2345, I think that I found the problem and fixed it: I was increasing the length of the worm before the early out conditions. Can you refresh the page and try the latest version?
About the bitmaps (and the levels), I prefer to keep them in 0b form to edit them inside vim :slight_smile:

1 Like
const unsigned char PROGMEM bmpRock[] = {
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
};

const unsigned char PROGMEM bmpSoil[] = {
    0b01010101, /**/
    0b10101010, /**/
    0b01010101, /**/
    0b10101010, /**/
    0b01010101, /**/
    0b10101010, /**/
    0b01010101, /**/
    0b10101010, /**/
};

const unsigned char PROGMEM bmpFood[] = {
    0b00011000, /**/
    0b00111100, /**/
    0b01111110, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b01111110, /**/
    0b00111100, /**/
    0b00011000, /**/
};

const unsigned char PROGMEM bmpGoal[] = {
    0b00000000, /**/
    0b11111000, /**/
    0b00000100, /**/
    0b00000010, /**/
    0b00000010, /**/
    0b00000100, /**/
    0b11111000, /**/
    0b00000000, /**/
};

const unsigned char PROGMEM bmpPoop[] = {
    0b10000000, /**/
    0b11000000, /**/
    0b11110000, /**/
    0b11111100, /**/
    0b11111110, /**/
    0b11101000, /**/
    0b11100000, /**/
    0b10000000, /**/
};

const unsigned char PROGMEM bmpNail[] = {
    0b00000000, /**/
    0b00000000, /**/
    0b10000000, /**/
    0b11100000, /**/
    0b11111110, /**/
    0b11100000, /**/
    0b10000000, /**/
    0b00000000, /**/
};

const unsigned char PROGMEM bmpWormHead[] = {
    /* 0 degrees */
    0b01111110, /**/
    0b01111110, /**/
    0b01011110, /**/
    0b01010010, /**/
    0b01010010, /**/
    0b01011110, /**/
    0b00011100, /**/
    0b00000000, /**/
    /* 90 degrees */
    0b00000000, /**/
    0b11111100, /**/
    0b11100110, /**/
    0b11100110, /**/
    0b11111110, /**/
    0b11000000, /**/
    0b11111100, /**/
    0b00000000, /**/
    /* 180 degrees */
    0b00000000, /**/
    0b00011100, /**/
    0b01011110, /**/
    0b01010010, /**/
    0b01010010, /**/
    0b01011110, /**/
    0b01111110, /**/
    0b01111110, /**/
    /* 270 degrees */
    0b00000000, /**/
    0b00111111, /**/
    0b01100111, /**/
    0b01100111, /**/
    0b01111111, /**/
    0b00000011, /**/
    0b00111111, /**/
    0b00000000, /**/
};

const unsigned char PROGMEM bmpWormBody[] = {
    /* 0 degrees */
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    /* 90 degrees */
    0b00000000, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b00000000, /**/
};

const unsigned char PROGMEM bmpWormTail[] = {
    /* 0 degrees */
    0b00000000, /**/
    0b00111000, /**/
    0b01111000, /**/
    0b01111000, /**/
    0b01111100, /**/
    0b01111100, /**/
    0b01111110, /**/
    0b01111110, /**/
    /* 90 degrees */
    0b00000000, /**/
    0b00000011, /**/
    0b00001111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b00111111, /**/
    0b00000000, /**/
    /* 180 degrees */
    0b01111110, /**/
    0b01111110, /**/
    0b01111100, /**/
    0b01111100, /**/
    0b01111000, /**/
    0b01111000, /**/
    0b00111000, /**/
    0b00000000, /**/
    /* 270 degrees */
    0b00000000, /**/
    0b11000000, /**/
    0b11110000, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111100, /**/
    0b00000000, /**/
};

const unsigned char PROGMEM bmpWormJoin[] = {
    /* 0 degrees */
    0b01111110, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b00111111, /**/
    0b00011111, /**/
    0b00000000, /**/
    /* 90 degrees */
    0b01111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111100, /**/
    0b11111000, /**/
    0b00000000, /**/
    /* 180 degrees */
    0b00000000, /**/
    0b11111000, /**/
    0b11111100, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b01111110, /**/
    /* 270 degrees */
    0b00000000, /**/
    0b00011111, /**/
    0b00111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111110, /**/
};

const unsigned char PROGMEM bmpArrow[] = {
    0b00000000, /**/
    0b00011100, /**/
    0b00011100, /**/
    0b00011100, /**/
    0b01111111, /**/
    0b00111110, /**/
    0b00011100, /**/
    0b00001000, /**/
};

This can be turned into this

const unsigned char PROGMEM bmps[] = {
    8,8,
    /*Rock*/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    /*Soil*/
    0b01010101, /**/
    0b10101010, /**/
    0b01010101, /**/
    0b10101010, /**/
    0b01010101, /**/
    0b10101010, /**/
    0b01010101, /**/
    0b10101010, /**/
    /*Food*/
    0b00011000, /**/
    0b00111100, /**/
    0b01111110, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b01111110, /**/
    0b00111100, /**/
    0b00011000, /**/
    /*Goal*/
    0b00000000, /**/
    0b11111000, /**/
    0b00000100, /**/
    0b00000010, /**/
    0b00000010, /**/
    0b00000100, /**/
    0b11111000, /**/
    0b00000000, /**/
    /*Poop*/
    0b10000000, /**/
    0b11000000, /**/
    0b11110000, /**/
    0b11111100, /**/
    0b11111110, /**/
    0b11101000, /**/
    0b11100000, /**/
    0b10000000, /**/
    /*Nail*/
    0b00000000, /**/
    0b00000000, /**/
    0b10000000, /**/
    0b11100000, /**/
    0b11111110, /**/
    0b11100000, /**/
    0b10000000, /**/
    0b00000000, /**/
    /*Worm Head*/
    /* 0 degrees */
    0b01111110, /**/
    0b01111110, /**/
    0b01011110, /**/
    0b01010010, /**/
    0b01010010, /**/
    0b01011110, /**/
    0b00011100, /**/
    0b00000000, /**/
    /* 90 degrees */
    0b00000000, /**/
    0b11111100, /**/
    0b11100110, /**/
    0b11100110, /**/
    0b11111110, /**/
    0b11000000, /**/
    0b11111100, /**/
    0b00000000, /**/
    /* 180 degrees */
    0b00000000, /**/
    0b00011100, /**/
    0b01011110, /**/
    0b01010010, /**/
    0b01010010, /**/
    0b01011110, /**/
    0b01111110, /**/
    0b01111110, /**/
    /* 270 degrees */
    0b00000000, /**/
    0b00111111, /**/
    0b01100111, /**/
    0b01100111, /**/
    0b01111111, /**/
    0b00000011, /**/
    0b00111111, /**/
    0b00000000, /**/
    /*Worm Body*/
    /* 0 degrees */
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    0b01111110, /**/
    /* 90 degrees */
    0b00000000, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b11111111, /**/
    0b00000000, /**/
    /*Worm Tail*/
    /* 0 degrees */
    0b00000000, /**/
    0b00111000, /**/
    0b01111000, /**/
    0b01111000, /**/
    0b01111100, /**/
    0b01111100, /**/
    0b01111110, /**/
    0b01111110, /**/
    /* 90 degrees */
    0b00000000, /**/
    0b00000011, /**/
    0b00001111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b00111111, /**/
    0b00000000, /**/
    /* 180 degrees */
    0b01111110, /**/
    0b01111110, /**/
    0b01111100, /**/
    0b01111100, /**/
    0b01111000, /**/
    0b01111000, /**/
    0b00111000, /**/
    0b00000000, /**/
    /* 270 degrees */
    0b00000000, /**/
    0b11000000, /**/
    0b11110000, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111100, /**/
    0b00000000, /**/
    /*Worm Middle*/
    /* 0 degrees */
    0b01111110, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b00111111, /**/
    0b00011111, /**/
    0b00000000, /**/
    /* 90 degrees */
    0b01111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111100, /**/
    0b11111000, /**/
    0b00000000, /**/
    /* 180 degrees */
    0b00000000, /**/
    0b11111000, /**/
    0b11111100, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b11111110, /**/
    0b01111110, /**/
    /* 270 degrees */
    0b00000000, /**/
    0b00011111, /**/
    0b00111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111111, /**/
    0b01111110, /**/
    /*Arrow*/
    0b00000000, /**/
    0b00011100, /**/
    0b00011100, /**/
    0b00011100, /**/
    0b01111111, /**/
    0b00111110, /**/
    0b00011100, /**/
    0b00001000, /**/
};

Ah! I Misunderstood your suggestion. However I would still prefer to keep them named instead of putting them all inside a single array called bmps: names are easier to read, less prone to errors than integers and the compiler can do its work and translate them into memory pointers for me :slight_smile:

aw man this is wonderfully delightful. if this had been on my cellphone instead of snake, i probably would have died a long time ago losing sleep

2 Likes

Luckily (or unfortunately) for you, there is a very similar game called snakebird :slight_smile:
Thanks for playing the game :slight_smile:
Since people are still trying it, I just added one more level :smiley:

1 Like