UPDATE v1.4!!! 2P mode is now in beta!!
I made my first game today and yesterday, rolly the dot’s adventure! This is only beta, so
I will be updating a lot, so you might have to check this a lot.
I built it in half-block, half-code.
// cm:esp8266:nibble
/*=====================================/
//Rolly's adventure v1.4 by 8-bit_noob//
////////////////////////////////////////
menu: 0: In menu
1: Pressed
2: 1P mode
3: 2P mode
4: How 2 play
*/
#include <Arduino.h>
#include <CircuitOS.h>
#include <Nibble.h>
//vars
bool guide;
int guidepage;
int menu;
int btnPressed;
int btnPressed2;
int EX;
int EY;
int X;
int Y;
int X2;
int Y2;
int CX;
int CY;
int UX;
int UY;
int Points;
int Points2;
int Speed;
int Selected;
int lives;
int lives2;
int money;
int money2;
bool uexists;
Display* display;
Sprite* sprite;
void initvars(){
btnPressed = 0;
btnPressed2 = 0;
UX = mathRandomInt(10, 120);
UY = 10;
CX = mathRandomInt(10, 120);
CY = 10;
EX = mathRandomInt(10, 120);
EY = 10;
X = 64;
Y = 110;
X2 = 20;
Y2 = 110;
Points = 0;
Points2 = 0;
Speed = 1;
lives = 3;
lives2 = 3;
money = 0;
money2 = 0;
guide = false;
guidepage = 0;
if(mathRandomInt(1, 3) == 1){
uexists = true;
}else{
uexists = false;
}
}
//button presses and releases
void BTN_UP_press(){
if(Selected > 0){
Selected--;
}
}
void BTN_DOWN_press(){
if(Selected < 2){
Selected++;
}
}
void BTN_A_press(){
if(menu == 0){
menu = Selected + 2;
}else{
btnPressed2 = -(ceil((Speed / 20)) + 1);
}
}
void BTN_B_press(){
if(guide && guidepage < 1){
guidepage++;
}else{
btnPressed2 = (ceil((Speed / 20)) + 1);
}
}
void BTN_LEFT_press(){
btnPressed = -(ceil((Speed / 20)) + 1);
}
void BTN_RIGHT_press(){
btnPressed = (ceil((Speed / 20)) + 1);
}
void BTN_LEFT_release(){
btnPressed = 0;
}
void BTN_A_release(){
btnPressed2 = 0;
}
void BTN_B_release(){
btnPressed2 = 0;
}
void BTN_C_press(){
menu = 1;
}
void BTN_C_release(){
menu = 0;
}
int mathRandomInt(int min, int max) {
if (min > max) {
// Swap min and max to ensure min is smaller.
int temp = min;
min = max;
max = temp;
}
return min + (rand() % (max - min + 1));
}
void BTN_RIGHT_release(){
btnPressed = 0;
}
void setup() {
Nibble.begin();
display = Nibble.getDisplay();
sprite = display->getBaseSprite();
Input::getInstance()->setBtnPressCallback(BTN_LEFT, BTN_LEFT_press);
Input::getInstance()->setBtnPressCallback(BTN_RIGHT, BTN_RIGHT_press);
Input::getInstance()->setBtnReleaseCallback(BTN_LEFT, BTN_LEFT_release);
Input::getInstance()->setBtnReleaseCallback(BTN_RIGHT, BTN_RIGHT_release);
Input::getInstance()->setBtnPressCallback(BTN_C, BTN_C_press);
Input::getInstance()->setBtnPressCallback(BTN_UP, BTN_UP_press);
Input::getInstance()->setBtnPressCallback(BTN_DOWN, BTN_DOWN_press);
Input::getInstance()->setBtnPressCallback(BTN_A, BTN_A_press);
Input::getInstance()->setBtnPressCallback(BTN_B, BTN_B_press);
Input::getInstance()->setBtnReleaseCallback(BTN_A, BTN_A_release);
Input::getInstance()->setBtnReleaseCallback(BTN_B, BTN_B_release);
initvars();
menu = 0;
Selected = 0;
sprite->setTextSize(1);
sprite->setTextFont(1);
sprite->setTextColor(TFT_BLACK);
}
void loop() {
Input::getInstance()->loop(0);
if(menu==2){
if(lives<1){
menu = 0;
}
if(money > 19){
money = 0;
lives++;
}
//this is the 1P mode
sprite->setTextColor(TFT_BLACK);
//wraparound
if(X<5){
X=120;
}else if(X>125){
X=10;
}
//move
X += btnPressed;
//drawing
sprite->clear(TFT_CYAN);
sprite->drawString("v1.4", 100, 110);
sprite->drawString((String("Points: ") + String(Points)), 5, 5);
sprite->drawString((String("$") + String(money)), 94, 5);
sprite->drawString((String("Lives:") + String(lives)), 5, 17);
sprite->fillRect(0, 120, 128, 8, TFT_GREEN);
//rolly!
sprite->fillCircle(X, 110, 10, TFT_YELLOW);
sprite->fillCircle((X - 3), 105, 2, TFT_BLACK);
sprite->fillCircle((X + 3), 105, 2, TFT_BLACK);
//evil dude
sprite->fillCircle(EX, EY, 10, TFT_RED);
sprite->fillCircle((EX - 3), (EY - 5), 2, TFT_BLACK);
sprite->fillCircle((EX + 3), (EY - 5), 2, TFT_BLACK);
//coin
sprite->fillCircle(CX, CY, 10, TFT_DARKCYAN);
sprite->fillCircle(CX, CY, 5, TFT_DARKGREEN);
//evil dude coll
//rolly hit evil dude?
if ((X-EX)*(X-EX)+(Y-EY)*(Y-EY)<400) {
EX = mathRandomInt(10, 120);
EY = 10;
Points -= ceil((Speed / 7)) + 1;
lives--;
}else if (EY < 120) { //enemy still allowed to move?
EY += (ceil((Speed / 15)) + 1);
} else { //enemy hit bottom.
Speed += 1;
EX = mathRandomInt(10, 120);
EY = 10;
Points += ceil((Speed / 7)) + 1;
}
//coin coll
//rolly hit coin?
if ((X-CX)*(X-CX)+(Y-CY)*(Y-CY)<400) {
CX = mathRandomInt(10, 120);
CY = 10;
Points += ceil((Speed / 4)) + 2;
money++;
}else if (CY < 120) { //coin still allowed to move?
CY += (ceil((Speed / 20)) + 1);
} else { //coin hit bottom.
CX = mathRandomInt(10, 120);
CY = 10;
Points -= ceil((Speed / 9)) + 1;
}
}else if(menu == 3){
if(lives<1 || lives2<1){
menu = 0;
}
if(money > 19){
money = 0;
lives++;
}
if(money2 > 19){
money2 = 0;
lives2++;
}
//this is the 2P mode
sprite->setTextColor(TFT_BLACK);
//wraparound
if(X<5){
X=120;
}else if(X>125){
X=10;
}
if(X2<5){
X2=120;
}else if(X2>125){
X2=10;
}
//move
X += btnPressed;
X2 += btnPressed2;
//drawing
sprite->clear(TFT_CYAN);
sprite->drawString("v1.4", 100, 110);
sprite->drawString((String("1Pts:") + String(Points)), 5, 5);
sprite->drawString((String("1$") + String(money)), 5, 15);
sprite->drawString((String("1Life:") + String(lives)), 5, 25);
sprite->drawString((String("2Pts:") + String(Points2)), 65, 5);
sprite->drawString((String("2$") + String(money2)), 65, 15);
sprite->drawString((String("2Life:") + String(lives2)), 65, 25);
sprite->fillRect(0, 120, 128, 8, TFT_GREEN);
//rolly!
sprite->fillCircle(X, 110, 10, TFT_YELLOW);
sprite->fillCircle((X - 3), 105, 2, TFT_BLACK);
sprite->fillCircle((X + 3), 105, 2, TFT_BLACK);
//rolly2!
sprite->fillCircle(X2, 110, 10, TFT_ORANGE);
sprite->fillCircle((X2 - 3), 105, 2, TFT_BLACK);
sprite->fillCircle((X2 + 3), 105, 2, TFT_BLACK);
//evil dude
sprite->fillCircle(EX, EY, 10, TFT_RED);
sprite->fillCircle((EX - 3), (EY - 5), 2, TFT_BLACK);
sprite->fillCircle((EX + 3), (EY - 5), 2, TFT_BLACK);
//coin
sprite->fillCircle(CX, CY, 10, TFT_DARKCYAN);
sprite->fillCircle(CX, CY, 5, TFT_DARKGREEN);
//ultra-coin
if(uexists){
sprite->fillCircle(UX, UY, 10, TFT_PINK);
sprite->fillCircle(UX, UY, 5, TFT_PURPLE);
}
//evil dude coll
//rolly hit evil dude?
if ((X-EX)*(X-EX)+(Y-EY)*(Y-EY)<400) {
EX = mathRandomInt(10, 120);
EY = 10;
Points -= ceil((Speed / 7)) + 1;
lives--;
}else if((X2-EX)*(X2-EX)+(Y2-EY)*(Y2-EY)<400){ //rolly2 hit evil dude?
EX = mathRandomInt(10, 120);
EY = 10;
Points2 -= ceil((Speed / 7)) + 1;
lives2--;
}else if (EY < 120) { //enemy still allowed to move?
EY += (ceil((Speed / 15)) + 1);
} else { //enemy hit bottom.
Speed += 1;
EX = mathRandomInt(10, 120);
EY = 10;
Points += ceil((Speed / 7)) + 1;
if(mathRandomInt(1, 4) == 1){
uexists = true;
}else{
uexists = false;
}
}
//coin coll
//rolly hit coin?
if ((X-CX)*(X-CX)+(Y-CY)*(Y-CY)<400) {
CX = mathRandomInt(10, 120);
CY = 10;
Points += ceil((Speed / 4)) + 2;
money++;
}else if((X2-CX)*(X2-CX)+(Y2-CY)*(Y2-CY)<400){ //rolly2 hit coin?
CX = mathRandomInt(10, 120);
CY = 10;
Points2 += ceil((Speed / 4)) + 2;
money2++;
}else if (CY < 120) { //coin still allowed to move?
CY += (ceil((Speed / 20)) + 1);
} else { //coin hit bottom.
CX = mathRandomInt(10, 120);
CY = 10;
}
//coin coll
//rolly hit ULTRAcoin?
if ((X-UX)*(X-UX)+(Y-UY)*(Y-UY)<400 && uexists) {
UX = mathRandomInt(10, 120);
UY = 10;
Points += ceil(Speed) + 2;
money += 8;
}else if((X2-UX)*(X2-UX)+(Y2-UY)*(Y2-UY)<400 && uexists){ //rolly2 hit ULTRAcoin?
UX = mathRandomInt(10, 120);
UY = 10;
Points2 += ceil(Speed) + 2;
money2 +=8;
}else if (UY < 120 && uexists) { //ULTRAcoin still allowed to move?
UY += (ceil((Speed / 20)) + 1);
}else if (uexists){ //ULTRAcoin hit bottom.
UX = mathRandomInt(10, 120);
UY = 10;
uexists = false;
}
}else if(menu == 4){
//this is controls
guide = true;
sprite->clear(TFT_BLACK);
sprite->drawString("<- MENU B ->", 5, 110);
if(guidepage == 0){
sprite->drawString("In 1P mode, you are", 0, 5);
sprite->drawString("the yellow circle and", 0, 15);
sprite->drawString("want to get the dark", 0, 25);
sprite->drawString("blue coins and avoid", 0, 35);
sprite->drawString("the red circles! Use", 0, 45);
sprite->drawString("left and right buttons", 0, 55);
sprite->drawString("to move. If you get", 0, 65);
sprite->drawString("hit by the red circle", 0, 75);
sprite->drawString("you lose a life. Lose", 0, 85);
sprite->drawString("all and game over.", 0, 95);
}else if(guidepage == 1){
sprite->drawString("Gain $1 by getting a", 0, 5);
sprite->drawString("coin. Get $20 for an", 0, 15);
sprite->drawString("extra life. Press", 0, 25);
sprite->drawString("MENU to exit. 2P mode", 0, 35);
sprite->drawString("is just 1P mode with", 0, 45);
sprite->drawString("the player 2 as an", 0, 55);
sprite->drawString("orange circle and move", 0, 65);
sprite->drawString("with A and B. There is", 0, 75);
sprite->drawString("also a pink coin that", 0, 85);
sprite->drawString("is worth $8.", 0, 95);
}
}else{
//this is the menu
initvars();
menu = 0;
sprite->setTextColor(TFT_WHITE);
sprite->clear(TFT_BLACK);
sprite->drawString("Rolly adventure 1", 0, 5);
sprite->drawString("By 8-bit_noob", 0, 100);
//draw arrows
if(Selected > 0){
sprite->fillTriangle(50, 50, 60, 40, 70, 50, TFT_GREEN);
}
if(Selected < 2){
sprite->fillTriangle(50, 70, 60, 80, 70, 70, TFT_GREEN);
}
//modes
if(Selected == 0){
sprite->drawString("A to play 1P", 5, 54);
}else if(Selected == 1){
sprite->drawString("2P (beta)", 5, 54);
}else{
sprite->drawString("How to play?", 5, 54);
}
}
display->commit();
}
//you have reached the end!
Copy and paste into circuitblocks and compile.
It might not be that good though
How to play
Either get the game for the nibble and select the menu option “How to play”, or look through the code.(Hint: line 377)