
▲ 3 r/arduino
OLED SPI Display keeps on glitching
I successfully uploaded the code on this project Arduboy Pocket Watch from https://www.hackster.io/tusharmagar/arduboy-pocket-watch-d19a1c to my Arduino Pro Micro but it only works when I reset it. I've tried burning the bootloader but the screen keeps on glitching and crashing and looking not at all coherent. Attached below is the code, photo of OLED display's current state and the circuit diagram I followed. For the circuit diagram I've only connected the OLED, RTC, button and Pro Micro on a breadboard. Battery charging module and LIPO battery should be ignored.
#include <Arduboy2.h>
#include <SPI.h>
#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include "Tinyfont.h"
#include "limits.h"
#define GROUND_HEIGHT 46
#define OBSTACLE_DELAY_MAX 512
#define OBSTACLE_DELAY_MIN 96
#define BONUS_DELAY_MAX 1024
#define BONUS_DELAY_MIN 512
tmElements_t tm;
enum State {
Intro,
Play,
Pause,
Over,
Credits
};
struct Position {
int x;
int y;
};
struct Velocity {
int x;
int y;
};
struct Size {
unsigned int width;
unsigned int height;
};
struct Object {
Position pos;
Velocity vel;
Rect box;
unsigned int frame;
unsigned int type;
boolean action;
};
struct Star {
Position pos;
unsigned int frame;
};
struct Particle {
Position pos;
unsigned int life;
unsigned int lifeCount;
};
const byte spriteLogoA[] PROGMEM = {
0x3e, 0x63, 0xc9, 0x9d, 0x39, 0x7b, 0xf2, 0xf6, 0xf4, 0xe4, 0xc8, 0xd8, 0x90, 0xb0, 0xa0, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xc0, 0x60, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0x60, 0x40, 0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1, 0x7, 0xc, 0x19, 0x73, 0xc7, 0x9f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfd, 0xfd, 0xfc, 0xff, 0xff, 0xff, 0x9f, 0xf, 0xf, 0xf, 0xf, 0x1f, 0x1f, 0x1e, 0x3c, 0x3d, 0x7d, 0xf9, 0xfb, 0xf2, 0xe6, 0xcc, 0x98, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x1f, 0xc3, 0xf8, 0xff, 0xff, 0xf3, 0x5, 0x3, 0x45, 0x8b, 0x17, 0xaf, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xe0, 0xc0, 0x1, 0x3, 0xf, 0x1f, 0x7f, 0xff, 0xfe, 0xf8, 0xf3, 0xc6, 0x1c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0x1f, 0xc0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xfc, 0xfc, 0xfe, 0xff, 0x7f, 0x3f, 0x9f, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf0, 0x80, 0x00, 0x1, 0xf, 0xff, 0xff, 0xff, 0xfc, 0x1, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7, 0x70, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x8f, 0xe3, 0xf9, 0xfc, 0xfe, 0x3f, 0x87, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, 0xf0, 0xff, 0xff, 0xff, 0x1f, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0xc0, 0x41, 0x47, 0x4c, 0x49, 0x6b, 0x2b, 0xab, 0xab, 0xbb, 0x99, 0xdd, 0xcc, 0xee, 0xe7, 0xf7, 0xf3, 0xf9, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x9f, 0xc7, 0xf0, 0xf8, 0xfe, 0x7f, 0x3f, 0x8f, 0xe7, 0x31, 0x1c, 0x7, 0x00, 0x00, 0x00, 0x00, 0x7, 0xc, 0x19, 0x13, 0x37, 0x27, 0x6f, 0xcf, 0x9f, 0xbf, 0xbf, 0x3f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0xbf, 0xbf, 0xbf, 0x9f, 0xcf, 0x67, 0x27, 0x33, 0x19, 0xc, 0x6, 0x3, 0x1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1, 0x1, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x1, 0x1, 0x1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const byte spriteBackgroundA[] PROGMEM = {
0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
};
const byte spriteBackgroundB[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x4, 0x2, 0x2, 0x2, 0x4, 0x18, 0x20, 0x10, 0x10, 0x10, 0x20, 0x18, 0x4, 0x2, 0x2, 0x2, 0x4, 0x18, 0x20, 0x10, 0x10, 0x10, 0x20, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54,
};
const byte spriteMoon[] PROGMEM = {
0xe0, 0xf8, 0xfc, 0xfe, 0xe, 0x3, 0x1, 0x1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x1f, 0x3f, 0x7f, 0x7f, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0x70, 0x78, 0x38, 0x1c, 0x7,
};
const byte spriteStar_0[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x8, 0x00, 0x00, 0x00 };
const byte spriteStar_1[] PROGMEM = { 0x00, 0x00, 0x00, 0x8, 0x1c, 0x8, 0x00, 0x00 };
const byte spriteStar_2[] PROGMEM = { 0x00, 0x00, 0x00, 0x8, 0x14, 0x8, 0x00, 0x00 };
const byte spriteStar_3[] PROGMEM = { 0x00, 0x00, 0x8, 0x8, 0x36, 0x8, 0x8, 0x00 };
const byte spriteStar_4[] PROGMEM = { 0x00, 0x00, 0x8, 0x00, 0x2a, 0x00, 0x8, 0x00 };
const byte *animationFramesStar[] = { spriteStar_0, spriteStar_1, spriteStar_2, spriteStar_3, spriteStar_4 };
const byte spriteUnicorn_0[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x8, 0x7c, 0x1c, 0x1c, 0x1e, 0x7f, 0x2, 0x3, 0x3, 0x00, 0x00, 0x00,
};
const byte spriteUnicorn_1[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x20, 0x30, 0x10, 0x38, 0x78, 0x38, 0x38, 0x38, 0x7c, 0x3e, 0x5, 0x6, 0x6, 0x00, 0x00,
};
const byte spriteUnicorn_2[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xe0, 0x50, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2, 0x3, 0x1, 0xf, 0x3, 0x3, 0x3, 0xf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const byte spriteUnicornMask_0[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0xd0, 0x20, 0x00, 0x00, 0x00, 0x10, 0x28, 0x24, 0x74, 0x82, 0x62, 0x22, 0x61, 0x80, 0x7d, 0x4, 0x4, 0x3, 0x00, 0x00,
};
const byte spriteUnicornMask_1[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0x40, 0x00, 0x20, 0x50, 0x48, 0x28, 0x44, 0x84, 0x44, 0x44, 0x44, 0x82, 0x41, 0x3a, 0x9, 0x9, 0x6, 0x00,
};
const byte spriteUnicornMask_2[] PROGMEM = {
0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x10, 0xa8, 0x94, 0x9a, 0x64, 0x00, 0x00, 0x00, 0x2, 0x5, 0x4, 0xe, 0x10, 0xc, 0x4, 0xc, 0x10, 0xf, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const byte *animationFramesUnicorn[] = { spriteUnicorn_0, spriteUnicorn_1, spriteUnicorn_2 };
const byte *animationFramesUnicornMask[] = { spriteUnicornMask_0, spriteUnicornMask_1, spriteUnicornMask_2 };
const byte spriteStar[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x6c, 0x7c, 0x3f, 0x37, 0x7c, 0x6c, 0x4, 0x00, 0x00, 0x00, 0x00,
};
const byte spriteStarMask[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x6a, 0x92, 0x83, 0x40, 0x48, 0x83, 0x92, 0x6a, 0x4, 0x00, 0x00, 0x00,
};
const byte spriteGhost[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x3f, 0x3f, 0x33, 0x3f, 0x3e, 0x18, 0x10, 0x00, 0x00, 0x00,
};
const byte spriteGhostMask[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x21, 0x4c, 0x40, 0x40, 0x4c, 0x40, 0x41, 0x26, 0x28, 0x18, 0x00, 0x00,
};
const byte *spritesObject[] = { spriteGhost, spriteStar };
const byte *spritesObjectMask[] = { spriteGhostMask, spriteStarMask };
boolean btnPressed, dpadPressed;
unsigned int counterState, counterBackgroundA, counterBackgroundB = 0;
int scoreBonusDuration = 0;
long score, scoreHI = 0;
Arduboy2 arduboy;
Tinyfont arduboyTinyFont = Tinyfont(arduboy.sBuffer, Arduboy2::width(), Arduboy2::height());
State state = Intro;
Object unicorn, objects[3];
Particle particles[24];
Star stars[9] = {
{ { 2, 13 }, 1 },
{ { 23, 3 }, 4 },
{ { 27, 24 }, 2 },
{ { 42, 7 }, 0 },
{ { 59, 16 }, 4 },
{ { 77, 8 }, 1 },
{ { 92, 21 }, 0 },
{ { 109, 9 }, 3 },
{ { 116, 17 }, 0 }
};
// ------------------------------------------------------------------------------------
void setup() {
RTC.read(tm);
arduboy.begin();
particlesReset();
statePlayReset();
scoreHI = EEPROM.read(EEPROM_STORAGE_SPACE_START);
}
void loop() {
arduboy.clear();
if (!arduboy.nextFrame()) {
return;
}
if (arduboy.everyXFrames(32)) {
randomSeed(analogRead(0)); // reset random
}
stateUpdate();
arduboy.display();
}
// ------------------------------------------------------------------------------------
void stateUpdate() {
counterState = ((counterState + 1) > UINT_MAX) ? 0 : counterState;
switch (state) {
case State::Play:
statePlayUpdate();
break;
case State::Over:
stateOverUpdate();
break;
default:
stateIntroUpdate();
break;
}
}
void stateSwitch(State stateNew) {
counterState = 0;
counterBackgroundA, counterBackgroundB = 0;
switch (stateNew) {
case State::Intro:
statePlayReset();
break;
}
state = stateNew;
};
// STATE INTRO: -----------------------------------------------------------------------
void stateIntroUpdate() {
counterState += 1;
arduboy.drawBitmap(10, 0, spriteLogoA, 50, 58, WHITE);
arduboyTinyFont.setCursor(15, 60);
for (byte i = (8 - intLength(scoreHI)); i > 0; i--) {
arduboyTinyFont.print("0");
}
arduboyTinyFont.print(scoreHI);
//////////////////////////////////////////////////////////////////////////////
arduboy.setCursor(70,15);
arduboy.setTextSize(2);
arduboy.print(tm.Hour);
arduboy.print(":");
arduboy.print(tm.Minute);
arduboy.setCursor(70,40);
arduboy.setTextSize(1);
arduboy.print(tm.Day);
arduboy.write('/');
arduboy.print(tm.Month);
arduboy.write('/');
arduboy.print(tmYearToCalendar(tm.Year));
arduboy.display();
if ((arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON)) && !btnPressed) {
stateSwitch(State::Play);
}
btnPressed = (arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON));
}
// STATE Over: ---------------------------------------------------------------------
void stateOverUpdate() {
arduboy.setCursor(37, 18);
arduboy.print("GAME OVER");
for (byte i = 0; i < 3; i++) {
if (objects[i].type == 0) {
objectRender(objects[i]);
}
}
unicornRender();
scoreRender();
if (arduboy.pressed(B_BUTTON) && !btnPressed) {
if (score > scoreHI) {
scoreHI = score;
EEPROM.update(EEPROM_STORAGE_SPACE_START, scoreHI);
}
stateSwitch(State::Intro);
}
btnPressed = arduboy.pressed(B_BUTTON);
}
// STATE PLAY: ------------------------------------------------------------------------
void statePlayUpdate() {
counterState += 1;
if (arduboy.pressed(B_BUTTON) && unicorn.action) {
unicorn.vel.y = -3;
counterState = 0;
}
btnPressed = (arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON));
backgroundLayerOneRender();
backgroundLayerTwoRender();
backgroundLayerThreeRender();
objectsUpdate();
unicornUpdate();
scoreUpdate();
}
void statePlayReset() {
score = 0;
scoreBonusDuration = 0;
unicornSetup();
objectsSetup();
}
// UNICORN ----------------------------------------------------------------------------
void unicornSetup() {
unicorn = { { 48, GROUND_HEIGHT }, { 0, 0 }, { 0, 0, 7, 8 }, 0, 7, true };
}
void unicornUpdate() {
if (counterState%10 == 0) {
unicorn.vel.y += 1;
}
unicorn.pos.y = min(unicorn.pos.y + unicorn.vel.y, GROUND_HEIGHT);
unicorn.pos.x = min(unicorn.pos.x + unicorn.vel.x, arduboy.width() - 12);
unicorn.pos.x = max(unicorn.pos.x + unicorn.vel.x, -4);
unicorn.box.x = unicorn.pos.x + 4;
unicorn.box.y = unicorn.pos.y - 9;
if (unicorn.pos.y >= GROUND_HEIGHT) {
unicorn.action = true;
unicorn.vel.y = 0;
}
else {
unicorn.action = false;
}
unicornRender();
particlesRender();
}
void unicornRender() {
if (unicorn.action) {
if (arduboy.everyXFrames(6)) {
unicorn.frame = ((unicorn.frame + 1) > 2) ? 0 : unicorn.frame + 1;
}
}
else {
unicorn.frame = 0;
}
arduboy.drawBitmap(unicorn.pos.x, unicorn.pos.y - 15, animationFramesUnicornMask[unicorn.frame], 16, 16, BLACK);
arduboy.drawBitmap(unicorn.pos.x, unicorn.pos.y - 15, animationFramesUnicorn[unicorn.frame], 16, 16, WHITE);
}
// OBJECTS ---------------------------------------------------------------------------
void objectsSetup() {
objects[0] = { { -16, GROUND_HEIGHT }, { -1, 0 }, { 0, 0, 8, 8 }, 0, 0, true };
objects[1] = { { -16, GROUND_HEIGHT }, { -1, 0 }, { 0, 0, 8, 8 }, 0, 0, true };
objects[2] = { { -16, 22 }, { -1, 0 }, { 0, 0, 8, 8 }, 0, 1, true };
for (byte i = 0; i < 3; i++) {
objects[i] = objectReset(objects[i]);
}
}
void objectsUpdate() {
for (byte i = 0; i < 3; i++) {
objects[i].pos.x += objects[i].vel.x;
objects[i].box.x = objects[i].pos.x + 4;
objects[i].box.y = objects[i].pos.y - 8;
if (objects[i].pos.x >= -8) {
Rect boxA = { unicorn.box.x, unicorn.box.y, unicorn.box.width, unicorn.box.height };
Rect boxB = { objects[i].box.x, objects[i].box.y, objects[i].box.width, objects[i].box.height };
if (arduboy.collide(boxA, boxB)) {
if (objects[i].type == 0) {
state = State::Over;
}
else if (objects[i].type == 1){
objects[i] = objectReset(objects[i]);
if (scoreBonusDuration <= 0) {
particlesReset();
}
scoreBonusDuration += 50;
}
}
objectRender(objects[i]);
}
else {
objects[i] = objectReset(objects[i]);
}
}
}
void objectRender(Object object) {
arduboy.drawBitmap(object.pos.x, object.pos.y - 15, spritesObjectMask[object.type], 16, 16, BLACK);
arduboy.drawBitmap(object.pos.x, object.pos.y - 15, spritesObject[object.type], 16, 16, WHITE);
// arduboy.drawRect(object.box.x, object.box.y, object.box.width, object.box.height, 1); // Collision Box Debug
}
Object objectReset(Object object){
if (object.type == 0) {
object.pos.x = arduboy.width() + random(OBSTACLE_DELAY_MIN, OBSTACLE_DELAY_MAX);
for (byte i = 0; i < 3; i++) {
if (objects[i].type == 0) {
if (objects[i].pos.x >= arduboy.width()) {
if ((rand()%4) > 2) {
object.pos.x = objects[i].pos.x + 10;
object.pos.y = GROUND_HEIGHT;
}
else {
object.pos.x = objects[i].pos.x + random(OBSTACLE_DELAY_MIN, OBSTACLE_DELAY_MAX);
object.pos.y = GROUND_HEIGHT - random(0, 12);
}
}
}
}
}
if (object.type == 1) {
object.pos.x = arduboy.width() + random(BONUS_DELAY_MIN, BONUS_DELAY_MAX);
}
return object;
}
// BACKGROUND -------------------------------------------------------------------------
void backgroundLayerOneRender() {
arduboy.drawBitmap(12, 4, spriteMoon, 16, 16, WHITE);
for (byte i = 0; i < 9; i++) {
if (arduboy.everyXFrames(8)) {
stars[i].frame = ((stars[i].frame + 1) > 4) ? 0 : stars[i].frame + 1;
}
arduboy.drawBitmap(stars[i].pos.x, stars[i].pos.y, animationFramesStar[stars[i].frame], 8, 8, WHITE);
}
}
void backgroundLayerTwoRender() {
if (arduboy.everyXFrames(2)) {
counterBackgroundA = ((counterBackgroundA + 1) >= 24) ? 0 : counterBackgroundA + 1;
}
for (byte i = 0; i <= 6; i++) {
arduboy.drawBitmap(((i * 24) - counterBackgroundA), 28, spriteBackgroundA, 24, 36, WHITE);
}
}
void backgroundLayerThreeRender() {
if (arduboy.everyXFrames(1)) {
counterBackgroundB = ((counterBackgroundB + 1) >= 24) ? 0 : counterBackgroundB + 1;
}
for (byte i = 0; i <= 6; i++) {
arduboy.drawBitmap(((i * 24) - counterBackgroundB), 41, spriteBackgroundB, 24, 24, BLACK);
}
}
// SCORE -----------------------------------------------------------------------------
void scoreUpdate() {
if (arduboy.everyXFrames(16)) {
scoreBonusDuration = max(0, (scoreBonusDuration - 1));
if (scoreBonusDuration > 0){
score += 10;
}
score = min(99999999, (score + 1));
}
scoreRender();
}
void scoreRender() {
if (score > scoreHI) {
arduboyTinyFont.setCursor(77, 4);
arduboyTinyFont.print("HI");
}
else {
arduboyTinyFont.setCursor(87, 4);
}
for (byte i = (8 - intLength(score)); i > 0; i--) {
arduboyTinyFont.print("0");
}
arduboyTinyFont.print(score);
}
// HELPERS ----------------------------------------------------------------------------
int intLength(int i) {
int j = 0;
for(; i; i /= 10) j++;
return (j == 0) ? 1 : j;
}
void particlesRender() {
if (scoreBonusDuration <= 0) {
return;
}
for (byte i = 0; i < 24; i++) {
particles[i].pos.x -= 1;
if (particles[i].lifeCount > particles[i].life) {
particles[i].life = 8 + rand()%32;
particles[i].lifeCount = 0;
particles[i].pos.y = unicorn.pos.y - 3 + ((rand()%2 > 0) ? (rand()%4 * -1) : rand()%4);
particles[i].pos.x = unicorn.pos.x + 4;
}
else {
particles[i].lifeCount += 1;
}
arduboy.drawPixel(particles[i].pos.x, particles[i].pos.y - 1, 0);
arduboy.drawPixel(particles[i].pos.x, particles[i].pos.y, 1);
}
}
void particlesReset() {
for (int i = 0; i < 24; ++i) {
particles[i] = { { 0, 0 }, 0 };
}
};
u/Easy_Ingenuity5811 — 14 hours ago