Adding sound - error 48 [Solved]

when i try to add sound to my game i get this error on upload – 48: error: ‘playSound’ was not declared in this scope.

in varible i have
// Sounds
const byte PROGMEM bing [] = {
0x90,0x30, 0,107, 0x80, 0x90,0x60, 1,244, 0x80, 0xf0};

void setup

//trying to get sound
playSound(bing);
delay(1500);

Any ideas on what im doing wrong?

Show all of the code please.

1 Like

playSound is not a function in any library that I know of.

If you want to play sounds on the Arduboy when using the standard Arduboy2 library, you need to pick a compatible sound library, include it in your sketch, and then use the particular functions that it provides to produce sound.

There are a number of sound libraries that can be used with the Arduboy, including:

You can even just use the Arduino tone() function, but there’s really no need since the ArduboyTones library can do the same thing (and more) and produces less code.

Which library you choose depends on what features you want and the amount program memory that you can afford to have it use.

The ArduboyTones library is generally the simplest to use and produces the smallest code.

ArduboyPlaytune provides the same features that were available in the original Arduboy library.

ArdVoice is intended to produce crude speech.

ATMlib (Arduboy Tracker Music library) plays sophisticated multichannel ChipTune type music and effects.


It looks like your bing[] array is in the format that ArduboyPlaytune uses. To play it, you will need to include and set up the ArduboyPlaytune library and use the playScore() (not playSound()) function:

To use this with the Arduboy2 library, you would include it after Arduoby2.h:

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

and create an object for it after the Arduboy2 object:

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

You then need to initialise the library in your setup() function:

  // audio setup
  tunes.initChannel(PIN_SPEAKER_1);
#ifndef AB_DEVKIT
  // if not a DevKit
  tunes.initChannel(PIN_SPEAKER_2);
#else
  // if it's a DevKit
  tunes.initChannel(PIN_SPEAKER_1); // use the same pin for both channels
  tunes.toneMutesScore(true);       // mute the score when a tone is sounding
#endif

The PlayTune example sketch included in the Arduboy2 library is an example of using ArduboyPlaytune
File > Examples > Arduboy2 > PlayTune


If you’re writing a new sketch, you may find that using ArduboyTones is sufficient and simpler. To do this you need to include it after Arduboy2.h:

#include <Arduboy2.h>
#include <ArduboyTones.h>

and create an object for it after the Arduboy2 object:

Arduboy2 arduboy;
ArduboyTones sound(arduboy.audio.enabled);

You then use the sound.tone() or sound.tones() functions to play your sounds.

The latest version of Flappy Ball is a good example of using ArduboyTones.

2 Likes

huh ok ill post my code up so u can see what 1) im working with

and 2) what im trying to merge.

after scouring the internet for games the last few days i have found some Ardrino games that work with Arduboy, with jsut some wimple code changes. and im trying to add them together in an effort to learn.

So after doing the part 7 of how to build a game.

http://community.arduboy.com/t/make-your-own-arduboy-game-part-7-make-pong-from-scratch/2615

i have come to the end of building my Pong game. Code to follow.

i have tried to add the sound i got from a much older game ment for Ardrino/arduboy that works in ways i havnt seen on/in other games… that code to follow next.

//E.Thorn (Cronck)
//February 18th, 2017
//pong_game_clone

//Include the Arduboy Library
#include <Arduboy2.h>
//Initialize the arduboy device 
Arduboy2 arduboy;

// Variables are added before setup to initialize our game programs
// we can add value to a varible at the same time
int gamestate = 0;
int justpressed = 0;
int ballx = 62;
int bally = 0;
int ballsize = 4;
int ballright = 1;
int balldown = 1;
int paddlewidth = 4;
int paddleheight = 9;
int playerx = 0;
int playery = 0;
int computerx = 127 - paddlewidth;
int computery = 0;
int playerscore = 0;
int computerscore = 0;
void resetgame() {
  ballx = 63;
  playerscore = 0;
  computerscore = 0;
}
// Sounds
const byte PROGMEM bing [] = {
0x90,0x30, 0,107, 0x80, 0x90,0x60, 1,244, 0x80, 0xf0};


//The setup() function runs once when you turn your Arduboy on
void setup() {
  //Start the Arduboy properly and display the Arduboy logo
  arduboy.begin();
  //Seed the random number generator
  srand(7/8);
  //Set the game to 60 frames per second
  arduboy.setFrameRate(60);
  //trying to get sound
  playSound(bing);
  delay(1500);
  //Get rid of the Arduboy logo and clear the screen
  arduboy.clear();
}

//The loop() function repeats forever after setup() is done
void loop() {
  
  //Prevent the Arduboy from running too fast
  if(!arduboy.nextFrame()) {
    return;
  }
  
  //Clear whatever is printed on the screen
  arduboy.clear();
  
  //Gameplay code goes here
  switch( gamestate ) {
    case 0:
      //Title screen
      arduboy.setCursor(30, 25);
      arduboy.print("PONG Clone");
      //Change the gamestate
      if(arduboy.pressed(A_BUTTON) and justpressed == 0) {
        justpressed = 1;
        gamestate = 1;
      }
      break;
    case 1:
      //Gameplay screen
      arduboy.setCursor(20, 0);
      arduboy.print(playerscore);
      arduboy.setCursor(101, 0);
      arduboy.print(computerscore);
      
      //Draw the ball
      arduboy.fillRect(ballx, bally, ballsize, ballsize, WHITE);
      
      //Move the ball right
      if(ballright == 1) {
        ballx = ballx + 1;
      }
      //Move the ball left
      if(ballright == -1) {
        ballx = ballx - 1;
      }
      
      //Move the ball down
      if(balldown == 1) {
        bally = bally + 1;
      }
      //Move the ball up
      if(balldown == -1) {
        bally = bally - 1;
      }
      //Reflect the ball off of the top of the screen
      if(bally == 0) {
        balldown = 1;
      }
      //Reflect the ball off of the bottom of the screen
      if(bally + ballsize == 63) {
        balldown = -1;
      }
      
      //Draw the player's paddle
      arduboy.fillRect(playerx, playery, paddlewidth, paddleheight, WHITE);
      //If the player presses Up and the paddle is not touching the top of the screen, move the paddle up
      if(arduboy.pressed(UP_BUTTON) and playery > 0) {
        playery = playery - 1;
      }
      //If the player presses down and the paddle is not touching the bottom of the screen, move the paddle down
      if(arduboy.pressed(DOWN_BUTTON) and playery + paddleheight < 63) {
        playery = playery + 1;
      }
      
      //Draw the computer's paddle
      arduboy.fillRect(computerx, computery, paddlewidth, paddleheight, WHITE);
      // if statement for AI purpose, this gives a delay to npc reaction time
      if(ballx > 115 or rand() % 20 == 1){
           //If the ball is higher than the computer's paddle, move the computer's paddle up
           if(bally < computery) {
           computery = computery - 1;
           }
           //If the bottom of the ball is lower than the bottom of the computer's paddle, move the comptuer's paddle down
           if(bally + ballsize > computery + paddleheight) {
             computery = computery + 1;
           }
      }
      //If the ball moves off of the screen to the left...
      if(ballx < -10) {
        //Move the ball back to the middle of the screen
        ballx = 63;
        //Give the computer a point
        computerscore = computerscore + 1;
      }
      //If the ball moves off of the screen to the right....
      if(ballx > 130) {
        //Move the ball back to the middle of the screen
        ballx = 63;
        //Give the player a point
        playerscore = playerscore + 1;
      }
      //Check if the player wins
      if(playerscore == 5) {
        gamestate = 2;
      }
      //Check if the computer wins
      if(computerscore == 5) {
        gamestate = 3;
      }
      //If the ball makes contact with the player's paddle, bounce it back to the right
      if(ballx == playerx + paddlewidth and playery < bally + ballsize and playery + paddleheight > bally) {
        ballright = 1;
      }
      //If the ball makes contact with the computer's paddle, bounce it back to the left
      if(ballx + ballsize == computerx and computery < bally + ballsize and computery + paddleheight > bally) {
        ballright = -1;
      }
      break;
    case 2:
      //Win screen
      arduboy.setCursor(30, 25);
      arduboy.print("You WON!");
      //Change the gamestate
      if(arduboy.pressed(A_BUTTON) and justpressed == 0) {
        justpressed = 1;
        resetgame();
        gamestate = 0;
      }
      break;
    case 3:
      //Game over screen
      arduboy.setCursor(30, 25);
      arduboy.print("Game Over Man!");
      //Change the gamestate
      if(arduboy.pressed(A_BUTTON) and justpressed == 0) {
        justpressed = 1;
        resetgame();
        gamestate = 0;
      }
      break;
  }
  //Check if the button is being held down
  if(arduboy.notPressed(A_BUTTON)) {
    justpressed = 0;
  }

  //Refresh the screen to show whatever's printed to it
  arduboy.display();
}

This is the old FloatyBall game that still works on my Arduboy .ino code. i had to add it and bitmaps.ccp and hitmaps.h to a folder (which i still dont even know why that is) but it all works with some neat old gameboy ish start up sound

----- code of that game below —

/*
  FlappyBall (aka FloatyBall) for the Arduboy
  Written by Chris Martinez, 3/5/2014
  Modified by Scott Allen, April 2016
*/
#include <SPI.h>
#include <EEPROM.h>
#include <Arduboy.h>
#include "bitmaps.h"

Arduboy arduboy;

// Things that make the game work the way it does
#define FRAMES_PER_SECOND 30   // The update and refresh speed
#define FRAC_BITS 6            // The number of bits in the fraction part of a fixed point int

// The following values define how fast the ball will accelerate and how high it will jump.
// They are given as fixed point integers so the true value is multiplied by (1 << FRAC_BITS)
// to give the value used. The resulting values must be integers.
#define BALL_ACCELERATION 16      // (0.25) the ball acceleration in pixels per frame squared
#define BALL_JUMP_VELOCITY (-144) // (-2.25) The inital velocity of a ball jump in pixels per frame
// ---------------------------

// This value is an offset to make it easier to work with negative numbers.
// It must be greater than the maximum number of pixels that Floaty will jump above
// the start height (based on the acceleration and initial velocity values),
// but must be low enough not to cause an overflow when added to the maximum
// screen height as an integer.
#define NEG_OFFSET 64

// Pipe
#define PIPE_ARRAY_SIZE 4  // At current settings only 3 sets of pipes can be onscreen at once
#define PIPE_MOVE_DISTANCE 2   // How far each pipe moves per frame
#define PIPE_GAP_MAX 30        // Maximum pipe gap
#define PIPE_GAP_MIN 18        // Minimum pipe gap
#define PIPE_GAP_REDUCE 5      // Number of points scored to reduce gap size
#define PIPE_WIDTH 12
#define PIPE_CAP_WIDTH 2
#define PIPE_CAP_HEIGHT 3      // Caps push back into the pipe, it's not added length
#define PIPE_MIN_HEIGHT 6      // Higher values center the gaps more
#define PIPE_GEN_FRAMES 32     // How many frames until a new pipe is generated

// Ball
#define BALL_RADIUS 4
#define BALL_Y_START ((HEIGHT / 2) - 1) // The height Floaty begins at
#define BALL_X 32              // Floaty's X Axis

// Storage Vars
byte gameState = 0;
unsigned int gameScore = 0;
unsigned int gameHighScore = 0;
char pipes[2][PIPE_ARRAY_SIZE]; // Row 0 for x values, row 1 for gap location
byte pipeGap = PIPE_GAP_MAX;    // Height of gap between pipes to fly through
byte pipeReduceCount = PIPE_GAP_REDUCE; // Score tracker for pipe gap reduction
char ballY = BALL_Y_START;      // Floaty's height
char ballYprev = BALL_Y_START;  // Previous height
char ballYi = BALL_Y_START;     // Floaty's initial height for the current arc
int ballV = 0;                  // For height calculations (Vi + ((a * t) / 2))
byte ballFrame = 0;             // Frame count for the current arc
char ballFlapper = BALL_RADIUS; // Floaty's wing length
char gameScoreX = 0;
char gameScoreY = 0;
byte gameScoreRiser = 0;

// Sounds
const byte PROGMEM bing [] = {
0x90,0x30, 0,107, 0x80, 0x90,0x60, 1,244, 0x80, 0xf0};
const byte PROGMEM intro [] = {
0x90,72, 1,244, 0x80, 0x90,60, 1,244, 0x80, 0x90,64, 1,244, 0x80, 0x90,69, 1,244, 0x80, 0x90,67, 
1,244, 0x80, 0x90,60, 1,244, 0x80, 0x90,72, 1,244, 0x80, 0x90,60, 1,244, 0x80, 0x90,64, 1,244, 
0x80, 0x90,69, 1,244, 0x80, 0x90,67, 1,244, 0x80, 0x90,60, 1,244, 0x80, 0x90,69, 1,244, 0x80, 
0x90,57, 1,244, 0x80, 0x90,60, 1,244, 0x80, 0x90,65, 1,244, 0x80, 0x90,62, 1,244, 0x80, 0x90,57, 
1,244, 0x80, 0x90,69, 1,244, 0x80, 0x90,57, 1,244, 0x80, 0x90,60, 1,244, 0x80, 0x90,67, 1,244, 
0x80, 0x90,62, 1,244, 0x80, 0x90,65, 1,244, 0x80, 0x90,72, 7,208, 0x80, 0xf0};
const byte PROGMEM point [] = {
0x90,83, 0,75, 0x80, 0x90,88, 0,225, 0x80, 0xf0};
const byte PROGMEM flap [] = {
0x90,24, 0,125, 0x80, 0xf0};
const byte PROGMEM horns [] = {
0x90,60, 1,44, 0x80, 0x90,50, 0,150, 0x80, 0,150, 0x90,48, 0,150, 0x80, 0x90,55, 2,238, 
0x80, 0x90,62, 3,132, 0x80, 0x90,60, 0,37, 0x80, 0x90,59, 0,37, 0x80, 0x90,57, 0,37, 0x80, 
0x90,55, 0,37, 0x80, 0x90,53, 0,18, 0x80, 0x90,52, 0,18, 0x80, 0x90,50, 0,18, 0x80, 0x90,48, 
0,18, 0x80, 0x90,47, 0,18, 0x80, 0x90,45, 0,18, 0x80, 0x90,43, 0,18, 0x80, 0x90,41, 0,18, 
0x80, 0xf0};
const byte PROGMEM hit [] = { 
0x90,60, 0,31, 0x80, 0x90,61, 0,31, 0x80, 0x90,62, 0,31, 0x80, 0xf0};

void setup() {
  arduboy.begin();
  arduboy.setFrameRate(FRAMES_PER_SECOND);
  playSound(bing);
  delay(1500);
  arduboy.clear();
  arduboy.drawSlowXYBitmap(0,0,floatyball,128,64,1);
  arduboy.display();
  playSound(intro);
  delay(500);
  arduboy.setCursor(18,55);
  arduboy.print("Press Any Button");
  arduboy.display();

  while (!arduboy.buttonsState()) { } // Wait for any key press
  debounceButtons();

  arduboy.initRandomSeed();
  for (byte x = 0; x < PIPE_ARRAY_SIZE; x++) { pipes[0][x] = 0; }  // Set all pipes offscreen
}

void loop() {
  if (!arduboy.nextFrame())
    return;

  if (arduboy.pressed(LEFT_BUTTON)) { // If the button for sound toggle is pressed
    if (arduboy.audio.enabled()) {    // If sound is enabled
      stopSound();                    // Stop anything that's playing
      arduboy.audio.off();            // Mute sounds
    } else {
      arduboy.audio.on();             // Enable sound
      playSound(bing);                // Play a sound to indicate sound has been turned on
    }
    debounceButtons();                // Wait for button release
  }

  arduboy.clear();

  // ===== State: Wait to begin =====
  if (gameState == 0) {     // If waiting to begin
    drawFloor();
    drawFloaty();
    drawInfo();             // Display usage info

    if (jumpPressed()) {    // Wait for a jump button press
      gameState = 1;        // Then start the game
      stopSound();          // Stop any playing sound
      beginJump();          // And make Floaty jump
    }
  }

  // ===== State: Playing =====
  if (gameState == 1) {     // If the game is playing
    // If the ball isn't already rising, check for jump
    if ((ballYprev <= ballY) && jumpPressed()) {
      beginJump();          // Jump
    }

    moveFloaty();

    if (ballY < BALL_RADIUS) {  // If Floaty has moved above the top of the screen
      ballY = BALL_RADIUS;      // Set position to top
      startFalling();           // Start falling
    }

    if (arduboy.everyXFrames(PIPE_GEN_FRAMES)) { // Every PIPE_GEN_FRAMES worth of frames
      generatePipe();                  // Generate a pipe
    }

    for (byte x = 0; x < PIPE_ARRAY_SIZE; x++) {  // For each pipe array element
      if (pipes[0][x] != 0) {           // If the pipe is active
        pipes[0][x] = pipes[0][x] - PIPE_MOVE_DISTANCE;  // Then move it left
        if (pipes[0][x] + PIPE_WIDTH < 0) {  // If the pipe's right edge is off screen
          pipes[0][x] = 0;              // Then set it inactive
        }
        if (pipes[0][x] + PIPE_WIDTH == (BALL_X - BALL_RADIUS)) {  // If the pipe passed Floaty
          gameScore++;                  // Increment the score
          pipeReduceCount--;            // Decrement the gap reduction counter
          gameScoreX = BALL_X;                  // Load up the floating text with
          gameScoreY = ballY - BALL_RADIUS - 8; //  current ball x/y values
          gameScoreRiser = 15;          // And set it for 15 frames
          playSound(point);
        }
      }
    }

    if (gameScoreRiser > 0) {  // If we have floating text
      gameScoreY--;
      if (gameScoreY >= 0) { // If the score will still be on the screen
        arduboy.setCursor(gameScoreX, gameScoreY);
        arduboy.print(gameScore);
        gameScoreX = gameScoreX - 2;
        gameScoreRiser--;
      } else {
        gameScoreRiser = 0;
      }
    }

    if (ballY + BALL_RADIUS > (HEIGHT-1)) {  // If the ball has fallen below the screen
      ballY = (HEIGHT-1) - BALL_RADIUS;      // Don't let the ball go under :O
      gameState = 2;                        // Game over. State is 2.
    }
    // Collision checking
    for (byte x = 0; x < PIPE_ARRAY_SIZE; x++) { // For each pipe array element
      if (pipes[0][x] != 0) {                 // If the pipe is active (not 0)
        if (checkPipe(x)) { gameState = 2; }  // If the check is true, game over
      }
    }

    drawPipes();
    drawFloor();
    drawFloaty();

    // Reduce pipe gaps as the game progresses
    if ((pipeGap > PIPE_GAP_MIN) && (pipeReduceCount <= 0)) {
      pipeGap--;
      pipeReduceCount = PIPE_GAP_REDUCE;  // Restart the countdown
    }
  }

  // ===== State: Game Over =====
  if (gameState == 2) {  // If the gameState is 2 then we draw a Game Over screen w/ score
    if (gameScore > gameHighScore) { gameHighScore = gameScore; }
    arduboy.display();              // Make sure final frame is drawn
    playSound(hit);                 // Hit sound
    delay(100);                     // Pause for the sound
    startFalling();                 // Start falling from current position
    while (ballY + BALL_RADIUS < (HEIGHT-1)) {  // While floaty is still airborne
      moveFloaty();
      arduboy.clear();
      drawPipes();
      drawFloor();
      drawFloaty();
      arduboy.display();
      while (!arduboy.nextFrame()) { }  // Wait for next frame
    }
    playSound(horns);                    // Sound the loser's horn
    arduboy.drawRect(16,8,96,48, WHITE); // Box border
    arduboy.fillRect(17,9,94,46, BLACK); // Black out the inside
    arduboy.drawSlowXYBitmap(30,12,gameover,72,14,1);
    arduboy.setCursor(56 - getOffset(gameScore),30);
    arduboy.print(gameScore);
    arduboy.setCursor(69,30);
    arduboy.print("Score");

    arduboy.setCursor(56 - getOffset(gameHighScore),42);
    arduboy.print(gameHighScore);
    arduboy.setCursor(69,42);
    arduboy.print("High");

    arduboy.display();
    delay(1000);         // Give some time to stop pressing buttons

    while (!jumpPressed()) { } // Wait for a jump button to be pressed
    debounceButtons();

    gameState = 0;       // Then start the game paused
    playSound(intro);    // Play the intro
    gameScore = 0;       // Reset score to 0
    gameScoreRiser = 0;  // Clear the floating score
    for (byte x = 0; x < PIPE_ARRAY_SIZE; x++) { pipes[0][x] = 0; }  // set all pipes inactive
    ballY = BALL_Y_START;   // Reset to initial ball height
    pipeGap = PIPE_GAP_MAX; // Reset the pipe gap height
    pipeReduceCount = PIPE_GAP_REDUCE; // Init the pipe gap reduction counter
  }

  arduboy.display();  // Finally draw this thang
}

void drawInfo() {
  byte ulStart;     // Start of underline to indicate sound status
  byte ulLength;    // Length of underline

  arduboy.setCursor(6, 3);
  arduboy.print("A,B,Up,Down: Jump");
  arduboy.setCursor(6, 51);
  arduboy.print("Left: Sound On/Off");

  if (arduboy.audio.enabled()) {
    ulStart = 13 * 6;
    ulLength = 2 * 6 - 1;
  } else {
    ulStart = 16 * 6;
    ulLength = 3 * 6 - 1;
  }
  arduboy.drawFastHLine(ulStart, 51 + 8, ulLength, WHITE); // Underline the current sound mode
  arduboy.drawFastHLine(ulStart, 51 + 9, ulLength, WHITE);
}

void drawFloor() {
  arduboy.drawFastHLine(0, HEIGHT-1, WIDTH, WHITE);
}

void drawFloaty() {
  ballFlapper--;
  if (ballFlapper < 0) { ballFlapper = BALL_RADIUS; }  // Flapper starts at the top of the ball
  arduboy.drawCircle(BALL_X, ballY, BALL_RADIUS, BLACK);  // Black out behind the ball
  arduboy.drawCircle(BALL_X, ballY, BALL_RADIUS, WHITE);  // Draw outline
  arduboy.drawLine(BALL_X, ballY, BALL_X - (BALL_RADIUS+1), ballY - ballFlapper, WHITE);  // Draw wing
  arduboy.drawPixel(BALL_X - (BALL_RADIUS+1), ballY - ballFlapper + 1, WHITE);  // Dot the wing
  arduboy.drawPixel(BALL_X + 1, ballY - 2, WHITE);  // Eye
}

void drawPipes() {
  for (byte x = 0; x < PIPE_ARRAY_SIZE; x++){
    if (pipes[0][x] != 0) {    // Value set to 0 if array element is inactive,
                               // otherwise it is the xvalue of the pipe's left edge
      // Pipes
      arduboy.drawRect(pipes[0][x], -1, PIPE_WIDTH, pipes[1][x], WHITE);
      arduboy.drawRect(pipes[0][x], pipes[1][x] + pipeGap, PIPE_WIDTH, HEIGHT - pipes[1][x] - pipeGap, WHITE);
      // Caps
      arduboy.drawRect(pipes[0][x] - PIPE_CAP_WIDTH, pipes[1][x] - PIPE_CAP_HEIGHT, PIPE_WIDTH + (PIPE_CAP_WIDTH*2), PIPE_CAP_HEIGHT, WHITE);
      arduboy.drawRect(pipes[0][x] - PIPE_CAP_WIDTH, pipes[1][x] + pipeGap, PIPE_WIDTH + (PIPE_CAP_WIDTH*2), PIPE_CAP_HEIGHT, WHITE);
      // Detail lines
      arduboy.drawLine(pipes[0][x]+2, 0, pipes[0][x]+2, pipes[1][x]-5, WHITE);
      arduboy.drawLine(pipes[0][x]+2, pipes[1][x] + pipeGap + 5, pipes[0][x]+2, HEIGHT - 3,WHITE);
    }
  }
}

void generatePipe() {
  for (byte x = 0; x < PIPE_ARRAY_SIZE; x++) {
    if (pipes[0][x] == 0) { // If the element is inactive
      pipes[0][x] = WIDTH;  // Then create it starting right of the screen
      pipes[1][x] = random(PIPE_MIN_HEIGHT, HEIGHT - PIPE_MIN_HEIGHT - pipeGap);
      return;
    }
  }
}

boolean checkPipe(byte x) {  // Collision detection, x is pipe to check
  byte AxA = BALL_X - (BALL_RADIUS-1);  // Hit box for floaty is a square
  byte AxB = BALL_X + (BALL_RADIUS-1);  // If the ball radius increases too much, corners
  byte AyA = ballY - (BALL_RADIUS-1);  // of the hitbox will go outside of floaty's
  byte AyB = ballY + (BALL_RADIUS-1);  // drawing
  byte BxA, BxB, ByA, ByB;
  
  // check top cylinder
  BxA = pipes[0][x];
  BxB = pipes[0][x] + PIPE_WIDTH;
  ByA = 0;
  ByB = pipes[1][x];
  if (AxA < BxB && AxB > BxA && AyA < ByB && AyB > ByA) { return true; } // Collided with top pipe
  
  // check top cap
  BxA = pipes[0][x] - PIPE_CAP_WIDTH;
  BxB = BxA + PIPE_WIDTH + (PIPE_CAP_WIDTH*2);
  ByA = pipes[1][x] - PIPE_CAP_HEIGHT;
  if (AxA < BxB && AxB > BxA && AyA < ByB && AyB > ByA) { return true; } // Collided with top cap
  
  // check bottom cylinder
  BxA = pipes[0][x];
  BxB = pipes[0][x] + PIPE_WIDTH;
  ByA = pipes[1][x] + pipeGap;
  ByB = HEIGHT-1;
  if (AxA < BxB && AxB > BxA && AyA < ByB && AyB > ByA) { return true; } // Collided with bottom pipe
  
  // check bottom cap
  BxA = pipes[0][x] - PIPE_CAP_WIDTH;
  BxB = BxA + PIPE_WIDTH + (PIPE_CAP_WIDTH*2);
  ByB = ByA + PIPE_CAP_HEIGHT;
  if (AxA < BxB && AxB > BxA && AyA < ByB && AyB > ByA) { return true; } // Collided with bottom pipe

  return false; // Nothing hits
}

boolean jumpPressed() { // Return "true" if a jump button is pressed
  return (arduboy.buttonsState() & (UP_BUTTON | DOWN_BUTTON | A_BUTTON | B_BUTTON)) != 0;
}

void beginJump() {
  playSound1(flap);     // Play "flap" sound only if nothing is playing
  ballV = BALL_JUMP_VELOCITY;
  ballFrame = 0;
  ballYi = ballY;
}

void startFalling() {   // Start falling from current height
  ballFrame = 0;        // Start a new fall
  ballYi = ballY;       // Set initial arc position
  ballV = 0;            // Set velocity to 0
}

void moveFloaty() {
  ballYprev = ballY;                   // Save the previous height
  ballFrame++;                         // Next frame
  ballV += (BALL_ACCELERATION / 2);    // Increase the velocity
                                     // Calculate Floaty's new height:
  ballY = ((((ballV * ballFrame)       // Complete "distance from initial height" calculation
           + (NEG_OFFSET << FRAC_BITS) // Add an offset to make sure the value is positive
           + (1 << (FRAC_BITS - 1)))   // Add 0.5 to round up
            >> FRAC_BITS)              // shift down to remove the fraction part
             - NEG_OFFSET)             // Remove previously added offset
              + ballYi;                // Add the result to the start height to get the new height
}

void playSound(const byte *score) {
  stopSound();                        // Stop any currently playing sound
  if (arduboy.audio.enabled()) {      // If sound is on
    arduboy.tunes.playScore(score);   // play the new sound
  }
}

void playSound1(const byte *score) {
  if (!arduboy.tunes.playing() && arduboy.audio.enabled()) { // If not playing and sound is on
    arduboy.tunes.playScore(score);   // play the new sound
  }
}

void stopSound() {
  if (arduboy.tunes.playing()) {      // If something is playing
    arduboy.tunes.stopScore();        // stop playing
  }
}

void debounceButtons() { // prevent "noisy" buttons from appearing as multiple presses
  delay(100);
  while (arduboy.buttonsState()) { }  // Wait for all keys released
  delay(100);
}

byte getOffset(byte s) {
  if (s > 9999) { return 20; }
  if (s > 999) { return 15; }
  if (s > 99) { return 10; }
  if (s > 9) { return 5; }
  return 0;
}

Ok wow this is all new to me and really cool to see how someones code changed and what changed with it. BC of the links above i now can see the old FloatyBall code vs FlappyBall. the library’s included and that the main diff is the bing sound. older version is spot on nostalgia, while new one dosnt play at start up and when it does play its not as good.

The issue you are having here is trying to call a function that doesn’t exist. You’re on the right track with trying to emulate bits of code that you have seen used in other places, but things can get a little dangerous once you move between sketches.

The root of the problem that @MLXXXp identified is that you don’t actually have a sound library installed. You should take a look at some of the guides by @crait that discuss how to use libraries and should help some. Right now I don’t think he has a sound tutorial available but maybe that’s something we need in the future!

2 Likes

OK i found that ArduboyTones - this code format

// this is a coin like sound
const uint16_t point[] PROGMEM = {
  NOTE_B5,75, NOTE_E6,225, TONES_END
};

while the ArduboyPlaytunes uses this format

// this is a coin like sound
const byte PROGMEM point [] = {
0x90,83, 0,75, 0x80, 0x90,88, 0,225, 0x80, 0xf0};

Both are the SAME sound just different ways of doing things. the FloatyBall game could have used the later style and they wouldn’t have had to try to change their game sounds over to the other version. using this i was able to backwards engineer the sounds into my pong clone now.

Getting the correct translation of code for the Arduboy logo is whats missing in the newer FlappyBall.

//floatyball bing that sounds spot on -- for use with, ArduboyPlaytune
const byte PROGMEM bing [] = {
0x90,0x30, 0,107, 0x80, 0x90,0x60, 1,244, 0x80, 0xf0};

//flappyball bing that sounds wrong -- for use with, ArduboyTones (but its not on the money) 
const uint16_t bing[] PROGMEM = {
  NOTE_FS1,107, NOTE_C4,500, TONES_END
};

does any one know how to translate the Playtunes into a Tones? when comparing the 2 it looks like the 107’s should be right but then the right sound has a 244 and the wrong has a 500 tone. switching these values doesn’t seem to work, more to it i guess.

and thanks for all the help.

BTW something in this old code made playSound work

#include <SPI.h>
#include <EEPROM.h>
#include <Arduboy.h>
#include "bitmaps.h"
...
void setup() {
  arduboy.begin();
  arduboy.setFrameRate(FRAMES_PER_SECOND);
  playSound(bing);
  delay(1500);
...

Still really new so i have no idea.

The playSound() function is near the end of the sketch that you found it in.

1 Like

ohh so its like having an independent library, like building it in as its own support.

1 Like

That’s generally how most programs are written; functions that call other functions. Those functions can either exist in your own program or in a library that your program uses.

3 Likes