The Urinal Game

The title tells you just about everything you need to know.
theUrinalGame.hex

This is inspired, or a faithful copy of the old flash game I thought was pretty funny back in higschool (I am old):

I was playing this game IRL at the convention couldn’t stop thinking about it. chatGPT helped me immensely on this because I can’t actually “remember” how to program although I’m pretty good at reading it and knowing what I want it to do. Just writing syntax from scratch kills me so this was pretty cool experience.

I also went for it on the sound production too.

For anyone who takes any issue with the bathroom humor here, please understand it’s only a joke. If you have any feedback about the game, including the level design (you think you should be able to pee wherever you want) it’s suggested to comment!

Pretty proud of this as this is my first real “game” for the Arduboy with a complete play cycle, beyond New Blocks on the Kid which doesn’t really have any winning conditions and is more of a practical joke.

Thank you to @haloopdy I used the toolset on this to convert the images. Thank you for all of the community members for uploading code for chatgpt to digest and everyone to use! (sarcasm? I don’t know)

Make sure your shoelaces are tied before playing!


#include <Arduboy2.h>
#include <ArduboyPlaytune.h>

Arduboy2 arduboy;
ArduboyPlaytune tunes(arduboy.audio.enabled);

constexpr uint8_t Title[] PROGMEM
{
  0x00, 0x08, 0xFE, 0x88, 0x00, 0xFE, 0x08, 0x08, 0xF0, 0x00, 0x70, 0xA8, 0xA8, 0xB0, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x88, 0xD0, 0xE0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xE0, 0x10, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0C, 0x32, 0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xF8, 0xF0, 0x30, 0x08, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0xFC, 0xFB, 0x04, 0x7C, 0xC4, 0x20, 0x18, 0x0C, 0x08, 0x09, 0x0B, 0x0F, 0x7D, 0xE8, 0x00, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x0C, 0xF2, 0x01, 0x01, 0x01, 0x01, 0x02, 0x7C, 0xF8, 0x80, 0x60, 0x18, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x18, 0x70, 0xC0, 0x00, 0xF0, 0x08, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x07, 0x78, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xE0, 0x78, 0x3F, 0x1F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x40, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x0F, 0x04, 0x04, 0x04, 0x08, 0xF0, 0xE0,
  0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x60, 0x60, 0x40, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0x60, 0x70, 0x38, 0x1E, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x07, 0x1C, 0x60, 0x80, 0x80, 0x80, 0x82, 0x81, 0xC8, 0xF1, 0x62, 0x42, 0xC2, 0xC1, 0x81, 0x80, 0xC1, 0xC2, 0xC4, 0xF8, 0x70, 0x00, 0x00, 0x07, 0x18, 0x60, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0x60, 0x70, 0x38, 0x1F, 0x0F, 0x00, 0x01, 0x0E, 0x10, 0x20, 0x60, 0x60, 0x67, 0x68, 0x70, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x30, 0x38, 0x1F, 0x0F, 0x01, 0x03, 0x0C, 0x10, 0x20, 0x40, 0xC3, 0xC1, 0xC2, 0xE5, 0x78, 0x30, 0x20, 0x60, 0x60, 0x60, 0x60, 0x78, 0x1F, 0x0F, 0x00, 0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0x60, 0x60, 0x70, 0x38, 0x1F, 0x0F,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x10, 0x08, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x04, 0x18, 0x70, 0xC0, 0x01, 0x01, 0x00, 0x00, 0x80, 0x60, 0x10, 0x08, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x08, 0x30, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0xA0, 0x10, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x70, 0xC0, 0x00, 0x00, 0xC0, 0x60, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x30, 0xE0, 0x80,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0xD0, 0xD4, 0xDC, 0xD0, 0xD0, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0xF0, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0E, 0xF8, 0xE0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x7F,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x4F, 0x87, 0x97, 0x87, 0x4F, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x08, 0x08, 0x84, 0x44, 0x42, 0x02, 0x02, 0x02, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x08, 0xC8, 0x30, 0x98, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x7F, 0x07, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x84, 0x84, 0x44, 0xC4, 0xFE, 0x76, 0x07, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x70, 0x30, 0x30, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x01, 0x00, 0x00, 0x01, 0x06, 0x08, 0x10, 0x20, 0x60, 0x40, 0xC0, 0xC0, 0xE1, 0x7E, 0x38, 0x30, 0x20, 0x60, 0x60, 0x60, 0x60, 0x70, 0x3C, 0x1F, 0x07, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x20, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x30, 0x3B, 0x1C, 0x18, 0x10, 0x30, 0x30, 0x38, 0x1F, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x1C, 0x0E, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x60, 0x40, 0xC0, 0xC0, 0xC0, 0xC0, 0xC1, 0xE1, 0x60, 0x60, 0x60, 0x70, 0x3F, 0x1E, 0x00, 0x00, 0x00
};

constexpr uint8_t GameOver[] PROGMEM
{
  0x00, 0x00, 0xC0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x08, 0x30, 0xE0, 0x80, 0x00, 0x00, 0xC0, 0x20, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x08, 0x10, 0x20, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0xE0, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x20, 0xC0, 0x80, 0x00, 0xC0, 0x20, 0x10, 0x08, 0x04, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x04, 0x18, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0xE0, 0x7F, 0x3F, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1E, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x80, 0xC0, 0xF0, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x03, 0x0C, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x11, 0x08, 0x84, 0x84, 0xC0, 0xE0, 0x70, 0x3F, 0x1E, 0x03, 0x1C, 0x20, 0x40, 0x80, 0x00, 0x01, 0x07, 0x9A, 0xE4, 0xE0, 0xC0, 0x80, 0x80, 0x80, 0xC0, 0xE0, 0x7F, 0x3F, 0x0F, 0x30, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xF0, 0xC0, 0x80, 0x80, 0x80, 0xCC, 0xF0, 0x40, 0xC0, 0xC0, 0xC0, 0xE0, 0x78, 0x3F, 0x0F, 0x00, 0x00, 0x03, 0x0C, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x08, 0x84, 0x84, 0xC4, 0xFF, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x11, 0x0B, 0x0B, 0x07, 0x05, 0x04, 0x04, 0x04, 0x09, 0x09, 0x11, 0x20, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0x20, 0x11, 0x13, 0x0B, 0x0B, 0x0B, 0x0B, 0x13, 0xA1, 0x60, 0x10, 0x09, 0x09, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0xF8, 0xF0, 0xC0, 0x20, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x0B, 0x0B, 0x13, 0x23, 0xC3, 0x83, 0x83, 0x41, 0x41, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x20, 0xC0, 0x80,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x0F, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xFC, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0xE0, 0x60, 0x70, 0x3F, 0x1F, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xF0, 0x7F, 0x1F,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0xC5, 0xC3, 0xC3, 0xC4, 0xC0, 0xE0, 0x70, 0x38, 0x1F, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x30, 0x20, 0x60, 0x40, 0xC0, 0xC0, 0xC0, 0xE0, 0x78, 0x3E, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x10, 0x20, 0x60, 0x40, 0xC0, 0xC0, 0xC2, 0xC2, 0xE1, 0x60, 0x71, 0x3E, 0x1C, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x40, 0xC0, 0xC0, 0xC3, 0xE8, 0x71, 0x62, 0x62, 0x42, 0xC1, 0xC1, 0xE3, 0x65, 0x78, 0x30, 0x00
};

constexpr uint8_t Urinal[] PROGMEM
{
  0x00, 0x00, 0x00, 0xF0, 0x08, 0xE8, 0xEA, 0xEF, 0xE8, 0xE8, 0x08, 0xF0, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0F, 0x10, 0x27, 0x43, 0x4B, 0x43, 0x27, 0x10, 0x0F, 0x00, 0x00, 0x00
};

constexpr uint8_t Person[] PROGMEM
{
  0x00, 0x00, 0x00, 0x80, 0xC0, 0xCE, 0xFF, 0xFF, 0xFF, 0xCE, 0xC0, 0x80, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x1F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x1F, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x01, 0x02, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x02, 0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00
};

constexpr uint8_t Yes[] PROGMEM
{
  0x00, 0x10, 0x28, 0x48, 0x88, 0x10, 0x20, 0x10, 0x88, 0xC4, 0xE2, 0x71, 0x39, 0x1E, 0x0C,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};

constexpr uint8_t No[] PROGMEM
{
  0x00, 0x00, 0xC6, 0x29, 0x11, 0x82, 0xC4, 0x82, 0x11, 0x39, 0xDE, 0x8C, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00
};

constexpr uint8_t Chooser[] PROGMEM
{
  0x00, 0x00, 0x00, 0x10, 0x28, 0x48, 0x88, 0x08, 0x88, 0xC8, 0xE8, 0x70, 0x20, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};


constexpr uint8_t Alert[] PROGMEM
{
  0x00, 0x00, 0x00, 0x80, 0xC0, 0xCE, 0xFF, 0xFF, 0xFF, 0xCE, 0x80, 0x3C, 0xFE, 0x3C, 0x00,
  0x00, 0x00, 0x1F, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x31, 0xE4, 0x0E, 0x04, 0x00,
  0x00, 0x00, 0x00, 0x01, 0x02, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x02, 0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00
};

const byte cMove[] PROGMEM = {
  0x90, 91, 0, 6, 0x80, 0, 0, 0x90, 92, 0, 6, 0x80, 0, 0, 0x90, 93, 0, 6, 0x80, 0, 0, 0x90, 94, 0, 6, 0x80,
  0, 0, 0x90, 95, 0, 6, 0x80,
  0xf0
};

const byte cWin[] PROGMEM = {
  0x90, 72, 0, 58, 0x90, 84, 0x91, 96, 1, 154, 0x80, 0x81,
  0xf0
};

const byte cLose[] PROGMEM = {
  0x90, 24, 0x91, 24, 0x92, 34, 0, 110, 0x80, 0x81, 0x82, 0, 38, 0x90, 24, 0x91, 24, 0x92, 24, 0x93, 34, 0, 110, 0x80, 0x81, 0x82,
  0x83,
  0xf0
};

const byte cLeave[] PROGMEM = {
  0x90, 59, 0, 110, 0x80, 0, 38, 0x90, 54, 0, 110, 0x80, 0, 38, 0x90, 56, 0, 111, 0x80, 0, 38, 0x90, 49, 0, 111, 0x80,
  0, 38, 0x90, 61, 0, 111, 0x80,
  0xf0
};

const byte cJoin[] PROGMEM = {
  0x90, 61, 0, 110, 0x80, 0, 38, 0x90, 49, 0, 110, 0x80, 0, 38, 0x90, 56, 0, 111, 0x80, 0, 38, 0x90, 54, 0, 111, 0x80,
  0, 38, 0x90, 49, 0, 111, 0x80,
  0xf0
};

const byte cErr[] PROGMEM = {
  0x90, 24, 0x91, 24, 0x92, 34, 0, 110, 0x80, 0x81, 0x82, 0, 38, 0x90, 24, 0x91, 24, 0x92, 24, 0x93, 34, 0, 110, 0x80, 0x81, 0x82,
  0x83, 0, 40, 0x90, 34, 0x91, 24, 0, 150, 0x80, 0x81,
  0xf0
};

const byte cTheme[] PROGMEM = {
  0x90, 24, 0, 69, 0x80, 1, 174, 0x90, 60, 0x91, 36, 0, 69, 0x81, 0, 180, 0x90, 59, 0, 250, 0x90, 24, 0x91, 60, 0, 69,
  0x80, 0, 180, 0x81, 0, 250, 0x90, 36, 0, 69, 0x80, 1, 174, 0x90, 24, 0, 69, 0x80, 1, 174, 0x90, 36, 0x91, 59, 0, 69,
  0x80, 0, 180, 0x90, 60, 0x81, 0, 250, 0x90, 24, 0x91, 59, 0, 69, 0x80, 0, 180, 0x81, 0, 250, 0x90, 36, 0, 69, 0x80, 1, 174,
  0x90, 24, 0, 69, 0x80, 1, 174, 0x90, 36, 0x91, 60, 0, 69, 0x80, 0, 180, 0x90, 59, 0x81, 0, 250, 0x90, 24, 0x91, 57, 0, 69,
  0x80, 0, 180, 0x81, 0, 250, 0x90, 36, 0, 69, 0x80, 1, 174, 0x90, 24, 0, 69, 0x80, 1, 174, 0x90, 36, 0x91, 57, 0, 69,
  0x80, 0, 180, 0x90, 59, 0x81, 0, 250, 0x90, 57, 0x91, 24, 0, 69, 0x81, 0, 180, 0x90, 55, 0, 250, 0x90, 36, 0, 69, 0x80,
  1, 174, 0x90, 24, 0, 69, 0x80, 1, 174, 0x90, 55, 0x91, 36, 0, 69, 0x81, 0, 180, 0x90, 57, 0, 250, 0x90, 55, 0x91, 24,
  0, 62, 0x81, 0, 187, 0x90, 53, 0, 250, 0x90, 36, 0, 62, 0x80, 0, 187, 0x90, 52, 0, 250, 0x90, 53, 0x91, 24, 0, 62,
  0x81, 0, 187, 0x90, 52, 0, 250, 0x90, 50, 0x91, 36, 0, 62, 0x81, 0, 187, 0x80, 0, 250, 0x90, 24, 0, 250, 0x80,
  0xf0
};

const byte cOver[] PROGMEM = {
  0x90, 60, 0, 62, 0x90, 62, 0, 62, 0x90, 63, 0, 62, 0x90, 65, 0, 62, 0x90, 66, 0, 62, 0x90, 67, 0, 62, 0x90, 69,
  0, 62, 0x90, 70, 0, 62, 0x90, 72, 1, 244, 0x90, 70, 1, 244, 0x90, 67, 1, 244, 0x90, 63, 1, 244, 0x90, 66, 3, 232,
  0x90, 65, 3, 232, 0x90, 63, 7, 208, 0x80,
  0xf0
};

int choices[][6] = {
  {2, 0, 0, 0, 0, 1}, // Level 0
  {1, 0, 0, 2, 0, 2}, // Level 1
  {0, 2, 0, 2, 0, 1}, // Level 2
  {1, 0, 0, 0, 0, 1}, // Level 3
  {2, 0, 2, 0, 2, 0}, // Level 4
  {1, 0, 2, 2, 0, 1}, // Level 5
  {0, 2, 0, 1, 2, 2}, // Level 6
  {2, 2, 1, 1, 2, 2}, // Level 7
  {0, 2, 0, 2, 0, 2}, // Level 8
  {2, 2, 2, 2, 1, 2}, // Level 9
};

const char* myStrings[] = {
  "Maximum Buffer",
  "Mind the Gap",
  "No Bathroom Buddies",
  "Hug the Wall",
  "Just Wait",
  "Either Side",
  "Don't Pair Up",
  "Imperfect World",
  "Scarcity Economics",
  "Nature Calls"
};

int selectedChoice; 
int level = 0;     
float cursorY = 0;   
float animationSpeed = 0.01; 
int cF = 0;
int cC = 0;
int bladder = 126;
int bTick = 0;
int bTock = 0;
int tT = 0;
int uHeight = 25;
int flag4 = 0;
int flag8 = 0;
int score = 0;
int sX = 76;
int cHeight = 10;
int leavePlay = 0;
int joinPlay = 0;
int gameMode = 0;
unsigned long startTime = 0;
unsigned long elapsedTime = 0;

void showAnswer() {
  while (true) {
    arduboy.pollButtons();
    if (arduboy.justPressed(A_BUTTON) || arduboy.justPressed(B_BUTTON) || arduboy.justPressed(UP_BUTTON) || arduboy.justPressed(DOWN_BUTTON) || arduboy.justPressed(LEFT_BUTTON) || arduboy.justPressed(RIGHT_BUTTON)) {
      break; 
    }
    for (int i = 0; i < 6; i++) {
      if (choices[level][i] == 1) {
        arduboy.drawBitmap(i * 20 + 5, uHeight, Urinal, 15, 15, cF); //Urinal
      }
    }
    if (level == 4) {
      if (flag4) {
        arduboy.drawBitmap(2 * 20 + 5, uHeight, Urinal, 15, 15, cF); //Urinal
      }
    }
    else if (level == 8) {
      if (flag8) {
        arduboy.drawBitmap(2 * 20 + 5, uHeight, Urinal, 15, 15, cF); //Urinal
        arduboy.drawBitmap(4 * 20 + 5, uHeight, Urinal, 15, 15, cF); //Urinal
      }
    }
    arduboy.display();
    cF = !cF;
    delay(65);
  }
  level++;
  if (level > 9) {
    gameMode = 2;
    elapsedTime = millis() - startTime;
  }
  bladder = 126;
  selectedChoice = 0;
}

void setup() {
  arduboy.boot();
  arduboy.flashlight();
  arduboy.audio.begin();
  tunes.initChannel(PIN_SPEAKER_1);
  tunes.initChannel(PIN_SPEAKER_2);
  arduboy.systemButtons();
  //if only there was an arduboy.beginNoLogo()
}


void loop() {
  if (!arduboy.nextFrame()) return;
  if (gameMode == 0) {
    arduboy.clear();
    arduboy.drawBitmap(0, 0, Title, 128, 64, 1);
    arduboy.display();
    while (true) {
      arduboy.pollButtons();
      if (!tunes.playing())
        tunes.playScore(cTheme);
      if (arduboy.justPressed(A_BUTTON) || arduboy.justPressed(B_BUTTON) || arduboy.justPressed(UP_BUTTON) || arduboy.justPressed(DOWN_BUTTON) || arduboy.justPressed(LEFT_BUTTON) || arduboy.justPressed(RIGHT_BUTTON)) {
        break; 
      }
    }
    level = 0;
    bladder = 126;
    flag4 = 0;
    flag8 = 0;
    score = 0;
    leavePlay = 0;
    joinPlay = 0;
    gameMode = 1;
    startTime = millis();
    tunes.stopScore();
  }
  else if (gameMode == 1) {
    arduboy.pollButtons();
    arduboy.fillRect(0, 0, 128, uHeight - 5, 0);
    arduboy.fillRect(0, 56, 128, 10, 0);
    if (arduboy.justPressed(A_BUTTON)) {
      if (level == 4) {
        if (selectedChoice == 2 && flag4) {
          arduboy.println("Correct!");
          tunes.playScore(cWin);
          score++;
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, Yes, 15, 10, 1); //check
        }
        else if (choices[level][selectedChoice] == 2) {
          arduboy.println("Incorrect!");
          tunes.playScore(cErr); // occupied
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, No, 15, 10, 1); //x
          arduboy.fillRect(selectedChoice * 20 + 5, uHeight - 5,  15, 26, 0);
          arduboy.drawBitmap(selectedChoice * 20 + 5, uHeight - 5, Alert, 15, 26, 1); //Alert
        }
        else {
          arduboy.println("Incorrect!");
          tunes.playScore(cLose);
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, No, 15, 10, 1); //x
        }
      }
      else if (level == 8) {
        if ((selectedChoice == 2 && flag8) || (selectedChoice == 4 && flag8)) {
          arduboy.println("Correct!");
          tunes.playScore(cWin);
          score++;
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, Yes, 15, 10, 1); //check
        }
        else if (choices[level][selectedChoice] == 2) {
          arduboy.println("Incorrect!");
          tunes.playScore(cErr);
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, No, 15, 10, 1); //x
          arduboy.fillRect(selectedChoice * 20 + 5, uHeight - 5,  15, 26, 0);
          arduboy.drawBitmap(selectedChoice * 20 + 5, uHeight - 5, Alert, 15, 26, 1); //Alert
        }
        else {
          arduboy.println("Incorrect!");
          tunes.playScore(cLose);
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, No, 15, 10, 1); //x
        }
      }
      else { // normal level
        if (choices[level][selectedChoice] == 1) {
          arduboy.println("Correct!");
          tunes.playScore(cWin);
          score++;
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, Yes, 15, 10, 1); //check
        }
        else if (choices[level][selectedChoice] == 2) {
          arduboy.println("Incorrect!");
          tunes.playScore(cErr);
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, No, 15, 10, 1); //x
          arduboy.fillRect(selectedChoice * 20 + 5, uHeight - 5,  15, 26, 0);
          arduboy.drawBitmap(selectedChoice * 20 + 5, uHeight - 5, Alert, 15, 26, 1); //Alert
        }
        else {
          arduboy.println("Incorrect!");
          tunes.playScore(cLose);
          arduboy.setCursor(sX, 0);
          arduboy.print("Score:");
          arduboy.print(score);
          int strWidth = strlen(myStrings[level]) * 6;
          arduboy.setCursor((128 - strWidth) / 2, 56);
          arduboy.print(myStrings[level]);
          arduboy.drawBitmap(selectedChoice * 20 + 5, cHeight, No, 15, 10, 1); //x
        }
      }
      arduboy.display();
      showAnswer();
    }
    arduboy.clear(); // Clear the screen before each frame

    for (int i = 0; i < 6; i++) {
      if (choices[level][i] == 0) {
        arduboy.drawBitmap(i * 20 + 5, uHeight, Urinal, 15, 15, 1); //Urinal
      }
      else if (choices[level][i] == 1) {
        arduboy.drawBitmap(i * 20 + 5, uHeight, Urinal, 15, 15, 1); //Urinal
      }
      else if (choices[level][i] == 2) {
        arduboy.drawBitmap(i * 20 + 5, uHeight - 5, Person, 15,26, 1); //occupied
      }
    }

    if (level == 4) {
      if (selectedChoice == 5) flag4 = 1;
      if (flag4) {
        if (!leavePlay) {
          tunes.playScore(cLeave);
          leavePlay = 1;
        }
        arduboy.fillRect(2 * 20 + 5, uHeight - 5, 15, 26, 0);
        arduboy.drawBitmap(2 * 20 + 5, uHeight, Urinal, 15, 15, 1); //Urinal
      }
    }
    
    if (level == 8) {
      if (bladder < 80) flag8 = 1;
      if (flag8) {
        if (!joinPlay) {
          tunes.playScore(cJoin);
          joinPlay = 1;
        }
        arduboy.drawBitmap(0 * 20 + 5, uHeight - 5, Person, 15,26, 1); //occupied
      }
    }
    
    arduboy.drawLine(1,58,126,58);
    arduboy.drawLine(1,63,126,63);
    arduboy.drawLine(0,59,0,62);
    arduboy.drawLine(127,59,127,62);
    arduboy.fillRect(1, 59, bladder, 4, 1);

    bTick++;
    if (level == 8) {
      bTick++;
    }
    if (level == 9) {
      bTick = 7;
    }
    if (bTick > 6) {
      bTick = 0;
      bladder--;
      bTock++;
    }

    if (bTock > 6) {
      bTock = 0;
      tT = !tT;
      tunes.tone(200 * (1 + tT), 20);
    }

    if (bladder < 1) {
      arduboy.setCursor(0, 0);
      arduboy.println("Failed!");
      tunes.playScore(cLose);
      arduboy.setCursor(sX, 0);
      arduboy.print("Score:");
      arduboy.print(score);
      showAnswer();
    }

    cursorY = 6 * sin(millis() * animationSpeed);
    arduboy.drawBitmap(selectedChoice * 20 + 4, cursorY + 3, Chooser, 15, 10, 1); //Chooser
    arduboy.display();

    if (arduboy.justPressed(LEFT_BUTTON) && selectedChoice > 0) {
      selectedChoice--;
      tunes.playScore(cMove);
    }

    if (arduboy.justPressed(RIGHT_BUTTON) && selectedChoice < 5) {
      selectedChoice++;
      tunes.playScore(cMove);
    }
  }
  else if (gameMode == 2) {
    arduboy.clear();
    tunes.stopScore();
    tunes.playScore(cOver);
    arduboy.drawBitmap(28, 2, GameOver, 100, 48, 1);
    arduboy.setCursor(0, 44);
    arduboy.print("Score:");
    arduboy.println(score);
    arduboy.print("Time: ");
    arduboy.print(elapsedTime / 1000); // Display seconds
    arduboy.print(".");
    arduboy.print(elapsedTime % 1000); // Display fractions of a second
    arduboy.print("s");
    arduboy.display();
    while (true) {
      arduboy.pollButtons();
      if (arduboy.justPressed(A_BUTTON) || arduboy.justPressed(B_BUTTON) || arduboy.justPressed(UP_BUTTON) || arduboy.justPressed(DOWN_BUTTON) || arduboy.justPressed(LEFT_BUTTON) || arduboy.justPressed(RIGHT_BUTTON)) {
        break; // Exit the loop when any button is pressed
      }
    }
    gameMode = 0;
    tunes.stopScore();
  }
}
4 Likes

That is freakin’ funny!

No source code? How are we (and chatGPT) to learn from this masterpiece?

I wonder what happens if chatGPT starts ingesting stuff that it helped generate. Does it learn from its own mistakes?

Just posted the code, has plenty of room for improvement lots of code-reuse I could break into functions but “it works” and “I’m done” so… ship it!

screenshot_20231020225106

Here is my high score, I made a few mistakes lets see who can beat it.

1 Like

screenshot_20231021171558

Yeah!

Better.

screenshot_20231021175153

I took the liberty of adding it to the cart:

Please don’t use arduboy.audio.on() in setup(). This will force sound on even if the user has chosen to mute sound in EEPROM. The arduboy.audio.begin() is sufficient to enable audio and will honour the mute setting in EEPROM.

Add arduboy.systemButtons() after arduboy.flashlight(). This will allow the user to enable or disable sound by holding the B button during power up and pressing UP to enable sound or DOWN to mute, and save that setting in EEPROM.

If you wish, you can add your own in-game system for enabling and muting sound, either instead of or in addition to systemButtons().

1 Like

As I suggest to anyone who doesn’t, please post a licence so people can know what they can do with your code. (Without a licence, in many countries you can legally only examine the code.)

Lol, I love this! I just recently found out about urinal memes and that there are hidden laws/rules to choosing which urinal to use. Who knew you had to do all these calculations just to use a urinal. Luckily for me, I don’t use public restrooms.

Oh yeah good point that was there at some point for debugging I took it out

But you didn’t add in arduboy.systemButtons(), so now sound can’t be enabled or muted unless a different game is loaded.

And after @bateske gave me so much gripe over my lovely music in Shattered Lands :stuck_out_tongue:

1 Like

As I’ve pointed out in the past, there is. It’s named beginDoFirst() (possiby followed by waitNoButtons() if necessary).

Lol what really?

What’s the idea of the naming behind this, sorry that I missed it before. I guess I gotta go in and read the docs end to end again lol…

It was an inspiration for sure

1 Like

Who cares about peeing etiquette. If you gotta go, you gotta go … fast! :sweat_smile:

4 Likes

image

The intent is to make it easy to possibly to save some program space by using a function that is equivalent to bootLogo() but uses a rendering function that is also used elsewhere, thus allowing the rendering code to be shared.

beginDoFirst() does everything that begin() does first, up to the point of calling bootLogo(). So instead calling begin(), you call beginDoFirst(), followed by the most efficient bootLogoXXX(), followed by whatever begin() does after. If there was more than just the single waitNoButtons() call after bootLogo(), I would have included a beginDoLast() function to be used.

However, if you absolutely don’t want a boot logo sequence, you can just call beginDoFirst() and, if necessary, waitNoButtons() (even though a user can choose to suppress the boot logo for all games by setting a flag in system EEPROM).

Screen Shot 2023-10-23 at 12.00.34 PM

Just wanted to share my fastest time with y’all

Screen Shot 2023-10-23 at 12.11.49 PM

idk anything about coding, someone make a tas to see what the fastest time possible is

1 Like

Lol that’s getting close! Nice work!