Player hit one wall but not the other

Understanding the language, error messages, etc.

Player hit one wall but not the other

Postby Terramet » Mon Jul 28, 2014 11:13 am

Firstly wasn't sure whether to put this here or in the games development. This is the first time I am coding a game using this. I have learnt another programming language in the past and looked at C++ briefly however I don't know much. Everything that I have learnt about coding in the gamebuino so far has come from the beginner and intermediate examples that were provided. I had decided that I wanted to make a simple game to make sure I understood all what I had looked through so far. The game I am making will eventually consist of a wall (2 walls is how i set it up) that moves towards the player with a gap in it, if the player goes through the gap they get a point and the wall resets to the other side of the screen with a different position, after getting a certain amount of points the wall would begin to speed up. The code currently is only set to send the wall at the player and doesn't remove the wall or reset it or count a point. The problem I am having is that if the player touches wall2 (the wall set to move along the bottom of the screen) they die and the game over screen shows up, however if the player touches wall1 they pass right through it and don't die at all.
Code:
Code: Select all
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb = Gamebuino();
static unsigned char PROGMEM explode0[] = {
  8, 8,
  B00010000,
  B01000001,
  B00000100,
  B10010000,
  B00000100,
  B01000001,
  B00001000,
  B10100100,
};

static unsigned char PROGMEM explode1[] = {
  8, 8,
  B00000000,
  B01000001,
  B00000100,
  B00010000,
  B00000100,
  B01000000,
  B00001000,
  B00000000,
};

static unsigned char PROGMEM explode2[] = {
  8, 8,
  B00000000,
  B00000000,
  B00000000,
  B00010000,
  B00000100,
  B01000000,
  B00001000,
  B00000000,
};

//Record
typedef struct
{
  int x;
  int y;
  int vx;
  int vy;
  byte w;
  byte h;
  byte size;
  boolean exist;
  int score;
}  PlayerStruct;
PlayerStruct Player = (PlayerStruct) {
  0, 0, 0, 0, true, 0
};

//Record
typedef struct
{
  byte x;
  byte y;
  byte w;
  byte h;
  int vx;
} Wall1Struct;
Wall1Struct Wall1 = (Wall1Struct){
  0
};

//Record
typedef struct
{
  byte x;
  byte y;
  byte w;
  byte h;
  int vx;
} Wall2Struct;
Wall2Struct Wall2 = (Wall2Struct){
  0
};
//Variables
boolean GameReset = true;
boolean GameFirstRun = true;
boolean paused = false;

//Function
boolean wallHit (int px, int py, int pw, int ph, int wx, int wy, int ww, int wh)
{
 if (gb.collideRectRect(px, py, pw, ph, wx, wy, ww, wh)){
      byte AnimationDelay=40;
      gb.sound.playCancel();
      gb.display.drawBitmap(Player.x - Player.size, Player.y - Player.size, explode2);
      gb.display.update();
      delay(AnimationDelay);
      gb.display.drawBitmap(Player.x - Player.size, Player.y - Player.size, explode1);
      gb.display.update();
      delay(AnimationDelay);
      gb.display.drawBitmap(Player.x - Player.size, Player.y - Player.size, explode0);
      gb.display.update();
      delay(AnimationDelay);
      gb.display.drawBitmap(Player.x - Player.size, Player.y - Player.size, explode1);
      gb.display.update();
      delay(AnimationDelay);
      gb.display.drawBitmap(Player.x - Player.size, Player.y - Player.size, explode2);
      gb.display.update();
      delay(AnimationDelay);
      gb.sound.playTick();
      return true;
    }
  else return false;
}
 
void setup()
//Code runs once
{
  randomSeed(gb.battery.voltage + gb.backlight.ambientLight);
  gb.begin();
  gb.titleScreen(F("Impossible Game - Terramet"));
  gb.battery.show = false;
}

void loop()
//code runs continuously
{
  if (GameReset){
    if (!GameFirstRun)
    {
      gb.display.clear();
      gb.display.fontSize = 1;
      gb.display.print("Game Over!\n");
      gb.display.print("Score:\n");
      gb.display.print(Player.score);
      gb.sound.playCancel();
      gb.display.update();
      Player.score = 0;
      delay(5000);
    }
   
    //Initialising Variables
   
    GameReset = false;
    GameFirstRun = false;
   
    Wall1.w = 4;
    Wall1.h = 48;
    Wall1.x = LCDWIDTH - Wall1.w;
    Wall1.y = 20 - 54;
    Wall1.vx = 1;
   
    Wall2.w = 4;
    Wall2.h = 48;
    Wall2.x = LCDWIDTH - Wall2.w;
    Wall2.y = Wall1.y + 54;
    Wall2.vx = 1;
 
    Player.w = 4;
    Player.h = 4;
    Player.x = (LCDWIDTH - Player.w) / 2;
    Player.y = (LCDHEIGHT - Player.h) / 2;
    Player.size = 4;
    Player.vx = 2;
    Player.vy = 2;
  }
  if (gb.update()) {
    if (gb.buttons.pressed(BTN_C)) {
      paused = !paused;
    }
    if (!paused) {
      //move the player using the buttons
      if(gb.buttons.repeat(BTN_RIGHT, 1)){
        Player.x = min(LCDWIDTH - Player.w, Player.x + Player.vx);
      }
           
      if(gb.buttons.repeat(BTN_LEFT, 1)){
        Player.x = max(0, Player.x - Player.vx);
      }
     
      if(gb.buttons.repeat(BTN_UP, 1)){
        Player.y = max(0, Player.y - Player.vy);
      }
     
      if(gb.buttons.repeat(BTN_DOWN, 1)){
        Player.y = min(LCDHEIGHT - Player.h, Player.y + Player.vy);
      }
     
      //Move walls towards player
      Wall1.x = Wall1.x - Wall1.vx;
      Wall2.x = Wall2.x - Wall2.vx;
      }
    }
    //Draw the game objects
    gb.display.drawRect(Player.x, Player.y, Player.size, Player.size);
    gb.display.fillRect(Wall1.x, Wall1.y, Wall1.w, Wall1.h);
    gb.display.fillRect(Wall2.x, Wall2.y, Wall2.w, Wall2.h);
    //Check for wall collision
    GameReset = wallHit (Player.x, Player.y, Player.w, Player.h, Wall1.x, Wall1.y, Wall1.w, Wall1.h);
    if (GameReset != true) {
      GameReset = wallHit (Player.x, Player.y, Player.w, Player.h, Wall2.x, Wall2.y, Wall2.w, Wall2.h);
    }
   }
}


TL;DR: The player dies if they touch wall2 but not if they touch wall1, and i cannot find why this happens.
Terramet
 
Posts: 3
Joined: Mon Jul 28, 2014 10:56 am

Re: Player hit one wall but not the other

Postby Tiash » Mon Jul 28, 2014 1:45 pm

You can use only one struct for both walls, like this:
Code: Select all
typedef struct
{
  byte x;
  byte y;
  byte w;
  byte h;
  int vx;
} Wall_Struct;
Wall_Struct Wall1 = {0};
Wall_Struct Wall2 = {0};


But I think your problem is attributable to this line of code:
Code: Select all
 Wall1.y = 20 - 54;

when y became a negative number. In this case, probably, the function that test collision (gb.collideRectRect) fails

EDIT: this change can help you:
Code: Select all
    Wall1.w = 4;
    Wall1.h = 14;
    Wall1.x = LCDWIDTH - Wall1.w;
    Wall1.y = 0;
    Wall1.vx = 1;
   
    Wall2.w = 4;
    Wall2.h = 48;
    Wall2.x = LCDWIDTH - Wall2.w;
    Wall2.y = Wall1.h + 6;
    Wall2.vx = 1;
User avatar
Tiash
 
Posts: 18
Joined: Sat Jul 12, 2014 7:28 am
Location: Italy

Re: Player hit one wall but not the other

Postby Terramet » Mon Jul 28, 2014 2:12 pm

Thanks very much, it was the fact that wall1.y became negative. It was just a constant at that time so that i could mess around with making things work, its going to eventually use the random function. I didn't know at the time that it couldn't be a negative number as I was just assuming about how collideRectRect worked.
Terramet
 
Posts: 3
Joined: Mon Jul 28, 2014 10:56 am

Re: Player hit one wall but not the other

Postby Tiash » Mon Jul 28, 2014 3:05 pm

But actually I do not understand why the function fails
User avatar
Tiash
 
Posts: 18
Joined: Sat Jul 12, 2014 7:28 am
Location: Italy

Re: Player hit one wall but not the other

Postby Limited » Mon Jul 28, 2014 11:28 pm

Bytes won't actually go negative, they will wrap around to 255. Therefore if you have 5 in a variable and minus 6, you'll get 255. That will be why that function failed.
Limited
 
Posts: 13
Joined: Sat May 31, 2014 7:25 pm

Re: Player hit one wall but not the other

Postby rodot » Mon Jul 28, 2014 11:35 pm

Limited wrote:Bytes won't actually go negative, they will wrap around to 255.

On the Performance optimization page of the wiki there is some random stuff I wrote one day I was bored, including considerations about data types. Just my 2 cents.
User avatar
rodot
Site Admin
 
Posts: 1290
Joined: Mon Nov 19, 2012 11:54 pm
Location: France

Re: Player hit one wall but not the other

Postby Tiash » Tue Jul 29, 2014 7:20 am

Limited wrote:Bytes won't actually go negative, they will wrap around to 255. Therefore if you have 5 in a variable and minus 6, you'll get 255. That will be why that function failed.

it's right, I had not considered that it was of type byte :D

it is interesting to note that when the byte is passed to gb.display.fillRect, being converted to int8_t, you do not notice the difference on the screen (which can be negative)
User avatar
Tiash
 
Posts: 18
Joined: Sat Jul 12, 2014 7:28 am
Location: Italy

Re: Player hit one wall but not the other

Postby Limited » Tue Jul 29, 2014 8:01 pm

Tiash wrote:
Limited wrote:Bytes won't actually go negative, they will wrap around to 255. Therefore if you have 5 in a variable and minus 6, you'll get 255. That will be why that function failed.

it's right, I had not considered that it was of type byte :D

it is interesting to note that when the byte is passed to gb.display.fillRect, being converted to int8_t, you do not notice the difference on the screen (which can be negative)

Its converted to int8_t yes, however that won't magically turn a non-negative byte to a negative int. Its converted because the display button is int8_t
Limited
 
Posts: 13
Joined: Sat May 31, 2014 7:25 pm

Re: Player hit one wall but not the other

Postby yodasvideoarcade » Wed Jul 30, 2014 4:35 pm

I didn't know there's a function called gb.collideRectRect ... does this exist?
Where is it described?
User avatar
yodasvideoarcade
 
Posts: 102
Joined: Sat Apr 19, 2014 10:48 am
Location: Frankfurt/Germany


Return to Programming Questions

Who is online

Users browsing this forum: No registered users and 59 guests

cron