Hello Im new to programing on arduboy and I tried to get some colision working but I cant. Help please!

Hello Im new to programing on arduboy and I tried to get some colision working but I cant.
I want to make a game where you are a square and you have to shoot enemys.
I wanted to make a colision with the bulet and the enemy.
For now I only programed it so that when you shoot from the right side of the enemy and if the bulet hits, it goes back to your gun.
But for some reason some of the bullets hit the enemy(just when shooting from the right to the left hiting enemy´s right side) and some not… it´s very wierd. Im sory for my bad english.
I really need your help to fix this
Here is my code so far:

#include<Arduboy2.h>
Arduboy2 arduboy;

int blockwidth = 10;
int blockheight = 10;
float blockx = 0;
float blocky = 0;
int right = 0;
int down = 0;
float enemyx = 10;
float enemyy = 10;
int counter = 0;
int gunwidth = 3;
int gunheight = 5;
float gunx = 0;
float guny = 0;
int buletwidth = 2;
int buletheight = 3;
float buletx = 0;
float bulety = 0;
int playerdirection = 0;
int buletdirection = 0;
int buletdone = 0;

const unsigned char PROGMEM background[] = {
// width, height,
8, 8,
0x81, 0x00, 0x12, 0x40, 0x04, 0x11, 0x00, 0x04, 
};
const unsigned char PROGMEM enemy[] =
{
// width, height,
16, 16,
0xfe, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0x01, 0xc1, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0xfe, 
0x7f, 0x80, 0x9c, 0xbc, 0xb0, 0xb0, 0xb2, 0xb2, 0xb3, 0xb0, 0xb0, 0xb0, 0xbc, 0x9c, 0x80, 0x7f, 
};

void setup(){
  arduboy.begin();
  arduboy.setFrameRate(60);
  arduboy.initRandomSeed();
  arduboy.display();

  blockx = WIDTH / 2 - blockwidth / 2;
  blocky = HEIGHT / 2 - blockheight / 2;
  gunx = WIDTH / 2 - gunwidth / 2;
  guny = HEIGHT / 2 - gunwidth / 2;
  buletx = gunx;
  bulety = guny;
  buletdone = 2;
}

void renderBlock(){
  arduboy.fillRect(blockx,blocky,blockwidth, blockheight);
}

void handleGameInput() {
  if (arduboy.pressed(LEFT_BUTTON)) {
    blockx -= 1,5;
    if (blockx < 0) {
      blockx = 0;
    }
    gunx = blockx -5;
    guny = blocky;
    if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 1;
    gunwidth = 5;
    gunheight = 3;
    buletmove();
  } if (arduboy.pressed(RIGHT_BUTTON)) {
    blockx += 1,5;
    if (blockx + blockwidth > WIDTH) {
      blockx = WIDTH - blockwidth;
    }
    gunx = blockx +10;
    guny = blocky;
    if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 2;
    gunwidth = 5;
    gunheight = 3;
    buletmove();
  }
  if (arduboy.pressed(UP_BUTTON)){
    blocky -= 1,5;
    if (blocky < 0){
      blocky = 0;
    }
    guny = blocky - 5;
    gunx = blockx;
    if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 3;
    gunwidth = 3;
    gunheight = 5;
    buletmove();
  }
  if (arduboy.pressed(DOWN_BUTTON)){
    blocky += 1,5;
    if (blocky + blockheight > HEIGHT) {
      blocky = HEIGHT - blockheight;
    }
    guny = blocky +10;
    gunx = blockx;
     if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 4;
    gunwidth = 3;
    gunheight = 5;
    buletmove();
  }
  
}
void renderenemy(){
  counter = counter +1;
  if(enemyx < 0){
    enemyx = 0;
  }
  if(enemyx > 112){
    enemyx = 112;
  }
  if(enemyy < 0){
    enemyy = 0;
  }
  if(enemyy > 48){
    enemyy = 48;
  }
  if(right == 2){
    enemyx = enemyx +0.5;  
  }
  if(right == 1){
    enemyx = enemyx -0.5;
  }
  if(down == 2){
    enemyy = enemyy +0.5;
  }
  if(down == 1){
    enemyy = enemyy -0.5;
  }
  if(counter == 25){
    right = random(1,4);
    down = random(1,4);
    counter = 0;
  }
  Sprites::drawOverwrite(enemyx, enemyy, enemy, 0);
}

void gun(){
  arduboy.fillRect(gunx,guny,gunwidth,gunheight);
  arduboy.fillRect(buletx,bulety,buletwidth,buletheight);
}

void buletmove(){
  if (playerdirection == 1){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 1;
      }
    }
  }
  if (playerdirection == 2){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 2;
      }
    }
  }
  if (playerdirection == 3){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 3;
      }
    }
  }
  if (playerdirection == 4){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 4;
      }
    }
  }
  buletmove1();
}

void buletmove1(){
  if(buletdirection == 1){
    buletdone = 1;
    buletwidth = 3;
    buletheight = 2;
    buletx = buletx -2;
    if(buletx < -3){
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
      buletdone = 2;
    }
    if(buletx == enemyx + 16 && enemyy < bulety + buletheight && enemyy + 16 > bulety){
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
      buletdone = 2;
    }
  }
  if(buletdirection == 2){
    buletdone = 1;
    buletwidth = 3;
    buletheight = 2;
    buletx = buletx +2;
    if(buletx > 131){
      buletdone = 2;
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
    }
  }
  if(buletdirection == 3){
    buletdone = 1;
    buletwidth = 2;
    buletheight = 3;
    bulety = bulety -2;
    if(bulety < -3){
      buletdone = 2;
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
    }
  }
  if(buletdirection == 4){
    buletdone = 1;
    buletwidth = 2;
    buletheight = 3;
    bulety = bulety +2;
    if(bulety > 67){
      buletdone = 2;
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
    }
  }
}

void colisionenemy(){
  
}

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

  arduboy.clear();
  arduboy.pollButtons();
  //=====================
  //For each column on the screen
  for (int backgroundx = 0; backgroundx < 128; backgroundx = backgroundx + 8) {
  //For each row in the column
    for ( int backgroundy = 0; backgroundy < 64; backgroundy = backgroundy + 8) {
      //Draw a background tile
      Sprites::drawOverwrite(backgroundx, backgroundy, background, 0);
    }
  }
  renderBlock();
  handleGameInput();
  renderenemy();
  gun();
  buletmove();

  //=====================
  arduboy.display();

}

Ok, so your problem sounds like you’re not checking collisions correctly. In your program you’ll want to be able to check two rectangles against each other.

struct Point {
        uint16_t X;
        uint16_t Y;
};

struct Rectangle {
        Point Min;
        Point Max;
};

These will be your collision box structures.
Now to check for overlap you need to check both the X and Y to see if there is overlap on either this is called AABB collision detection.

Here I’m defining a function to check if they are colliding

bool AreColliding(Rectangle box1, Rectangle box2){
        if((box1.Min.X > box2.Max.X)||(box1.Max.X < box2.Min.X)) return false;
        if((box1.Min.Y > box2.Max.Y)||(box1.Max.Y < box2.Min.Y)) return false;
        return true
}

image

2 Likes

ok… this is a bit complicated for my programing skills… these are functions I have not seen or used before. But I will try to understand and use it on my game. thank you for your help!

1 Like

Do you not understand what im doing here?

So you created a function named “AreColliding” for 2 variables: Rectangle box 1 and 2 right?
I don´t know what bool stands for though… :sweat_smile:

That bool is the return type. functions have a return type most of your code has a return type of void which means it just doesent return anything.
you can also have these as return types

void
uint8_t
uint16_t
uint32_t
string
char
int
bool

Edit: You can also return your own objects such as structs or classes so you could actualy return the intersection of the two objects if you wanted to instead of a bool

Rectangle IsColliding(Rectangle box1, Rectangle box2)
1 Like

hmm. ok :thinking:

Imagine a function as a magic black box (which you know the contents of)
Input ==> Function ==> Output

1 Like

Yes. I understand that.
I am very new to programing… that´s why I am having a hard time you know :sweat_smile:
and I learned most of these things just from the first 7 lessons I found here on the community´s educational section.

3 Likes

@AlexToma,

I edited your post to format the code that you included. Please do this yourself for any code you post in the future.

To format a block of code start with three backticks followed by the letters cpp on a line by itself. Place your code after this line. Then add a line consisting of just three backticks after your code.

```cpp
(put your code here)
```

1 Like

Ok. Im sory and thank you for your advice. I will keep it in mind. Im new to the community.

2 Likes

Lol I have to laugh how easy collision and overlap is here. I’ve been fooling around in UE4 and messing with complex collision and physics, and the math hurts my brain. Here it’s just 2 lines of code.

Great info!

1 Like

@Dreamer2345’s on the right track, though there’s already a Point and Rect struct and an Arduboy2::collide function in the Arduboy2 library.

There’s no need to redefine them.

Specifically you can do:

// Creates a 'Rect' with (x, y, width, height)
Rect bulletRect(buletx, bulety, buletwidth, buletheight);

// Creates a 'Rect' with (x, y, width, height)
Rect enemyRect(enemyx, enemyy, 16, 16);

// Checks if the two rectangles are intersecting
if(Arduboy2::collide(bulletRect, enemyRect))
{
  // Code to run if the bullet has touched the enemy
}
Example (click arrow to show)
#include<Arduboy2.h>
Arduboy2 arduboy;

int blockwidth = 10;
int blockheight = 10;
float blockx = ((WIDTH / 2) - (blockwidth / 2));
float blocky = ((HEIGHT / 2) - (blockheight / 2));
int right = 0;
int down = 0;
float enemyx = 10;
float enemyy = 10;
int counter = 0;
int gunwidth = 3;
int gunheight = 5;
float gunx = ((WIDTH / 2) - (gunwidth / 2));
float guny = ((HEIGHT / 2) - (gunwidth / 2));
int bulletwidth = 2;
int bulletheight = 3;
float bulletx = gunx;
float bullety = guny;
int playerdirection = 0;
int bulletdirection = 0;
int bulletdone = 2;

const unsigned char background[] RROGMEM
{
  // width, height,
  8, 8,
  0x81, 0x00, 0x12, 0x40, 0x04, 0x11, 0x00, 0x04,
};
const unsigned char enemy[] PROGMEM
{
  // width, height,
  16, 16,
  0xfe, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0x01, 0xc1, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0xfe,
  0x7f, 0x80, 0x9c, 0xbc, 0xb0, 0xb0, 0xb2, 0xb2, 0xb3, 0xb0, 0xb0, 0xb0, 0xbc, 0x9c, 0x80, 0x7f,
};

void setup(){
  arduboy.begin();
  arduboy.setFrameRate(60);
  arduboy.initRandomSeed();
  arduboy.display();
}

void renderBlock(){
  arduboy.fillRect(blockx, blocky, blockwidth, blockheight);
}

void handleGameInput() {
  if (arduboy.pressed(LEFT_BUTTON)) {
    blockx -= 1.5;

    if (blockx < 0) {
      blockx = 0;
    }

    gunx = blockx -5;
    guny = blocky;

    if(bulletdirection == 0){
      bulletx = gunx;
      bullety = guny;
    }

    playerdirection = 1;
    gunwidth = 5;
    gunheight = 3;
    bulletmove();
  }

  if (arduboy.pressed(RIGHT_BUTTON)) {
    blockx += 1.5;

    if (blockx + blockwidth > WIDTH) {
      blockx = WIDTH - blockwidth;
    }

    gunx = blockx +10;
    guny = blocky;

    if(bulletdirection == 0){
      bulletx = gunx;
      bullety = guny;
    }

    playerdirection = 2;
    gunwidth = 5;
    gunheight = 3;
    bulletmove();
  }

  if (arduboy.pressed(UP_BUTTON)){
    blocky -= 1.5;

    if (blocky < 0){
      blocky = 0;
    }

    guny = blocky - 5;
    gunx = blockx;

    if(bulletdirection == 0){
      bulletx = gunx;
      bullety = guny;
    }

    playerdirection = 3;
    gunwidth = 3;
    gunheight = 5;
    bulletmove();
  }

  if (arduboy.pressed(DOWN_BUTTON)){
    blocky += 1.5;

    if (blocky + blockheight > HEIGHT) {
      blocky = HEIGHT - blockheight;
    }

    guny = blocky +10;
    gunx = blockx;

    if(bulletdirection == 0){
      bulletx = gunx;
      bullety = guny;
    }

    playerdirection = 4;
    gunwidth = 3;
    gunheight = 5;
    bulletmove();
  }

}
void renderenemy(){
  counter = counter +1;

  if(enemyx < 0){
    enemyx = 0;
  }

  if(enemyx > 112){
    enemyx = 112;
  }

  if(enemyy < 0){
    enemyy = 0;
  }

  if(enemyy > 48){
    enemyy = 48;
  }

  if(right == 2){
    enemyx = enemyx +0.5;
  }

  if(right == 1){
    enemyx = enemyx -0.5;
  }

  if(down == 2){
    enemyy = enemyy +0.5;
  }

  if(down == 1){
    enemyy = enemyy -0.5;
  }

  if(counter == 25){
    right = random(1, 4);
    down = random(1, 4);
    counter = 0;
  }

  Sprites::drawOverwrite(enemyx, enemyy, enemy, 0);
}

void gun(){
  arduboy.fillRect(gunx, guny, gunwidth, gunheight);
  arduboy.fillRect(bulletx, bullety, bulletwidth, bulletheight);
}

void bulletmove(){
  if (playerdirection == 1){
    if(bulletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        bulletdirection = 1;
      }
    }
  }

  if (playerdirection == 2){
    if(bulletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        bulletdirection = 2;
      }
    }
  }

  if (playerdirection == 3){
    if(bulletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        bulletdirection = 3;
      }
    }
  }

  if (playerdirection == 4){
    if(bulletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        bulletdirection = 4;
      }
    }
  }

  bulletmove1();
}

void bulletmove1(){
  if(bulletdirection == 1){
    bulletdone = 1;
    bulletwidth = 3;
    bulletheight = 2;
    bulletx = bulletx -2;

    if(bulletx < -3){
      bulletx = gunx;
      bullety = guny;
      bulletdirection = 0;
      bulletdone = 2;
    }

    if((bulletx == (enemyx + 16)) && (enemyy < (bullety + bulletheight)) && ((enemyy + 16) > bullety)){
      bulletx = gunx;
      bullety = guny;
      bulletdirection = 0;
      bulletdone = 2;
    }
  }

  if(bulletdirection == 2){
    bulletdone = 1;
    bulletwidth = 3;
    bulletheight = 2;
    bulletx = bulletx +2;

    if(bulletx > 131){
      bulletdone = 2;
      bulletx = gunx;
      bullety = guny;
      bulletdirection = 0;
    }
  }

  if(bulletdirection == 3){
    bulletdone = 1;
    bulletwidth = 2;
    bulletheight = 3;
    bullety = bullety -2;

    if(bullety < -3){
      bulletdone = 2;
      bulletx = gunx;
      bullety = guny;
      bulletdirection = 0;
    }
  }

  if(bulletdirection == 4){
    bulletdone = 1;
    bulletwidth = 2;
    bulletheight = 3;
    bullety = bullety +2;

    if(bullety > 67){
      bulletdone = 2;
      bulletx = gunx;
      bullety = guny;
      bulletdirection = 0;
    }
  }
}

void checkCollisions()
{
  // Creates a 'Rect' with (x, y, width, height)
  Rect bulletRect(bulletx, bullety, bulletwidth, bulletheight);

  // Creates a 'Rect' with (x, y, width, height)
  Rect enemyRect(enemyx, enemyy, 16, 16);

  // Checks if the two rectangles are intersecting
  if(Arduboy2::collide(bulletRect, enemyRect))
  {
    // Code to run if the bullet has touched the enemy
    arduboy.println(F("Collide"));
  }
}

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

  arduboy.clear();
  arduboy.pollButtons();
  //=====================
  //For each column on the screen
  for (int backgroundx = 0; backgroundx < 128; backgroundx = backgroundx + 8) {
  //For each row in the column
    for ( int backgroundy = 0; backgroundy < 64; backgroundy = backgroundy + 8) {
      //Draw a background tile
      Sprites::drawOverwrite(backgroundx, backgroundy, background, 0);
    }
  }
  renderBlock();
  handleGameInput();
  renderenemy();
  gun();
  bulletmove();
  checkCollisions();

  //=====================
  arduboy.display();

}

By the way, I presume you’re from a European country by the fact you’ve written 1,5 instead of 1.5.
Unfortunately in C++ you have to use 1.5 because 1,5 means something different.
(In particular the 1 is ignored and you get just the 5.)


If you’d like any other advice about how to improve your code,
or if you have any other questions, feel free to ask.

3 Likes

I apreciate your help. And yes I am from Portugal but I live in Germany.
Thanks a lot!
You made my day!

1 Like

look I made this code so far and the problem is that I wanted to make it so that on level 3 the enemy gets 5 instead of 3 lives but for some reason when I make it to level 3 the enemy has unlimited lives.
can you please tell me what I have done wrong?
Thanks in advance!

#include<Arduboy2.h>
Arduboy2 arduboy;

int gamestate = 0;
int blockwidth = 10;
int blockheight = 10;
float blockx = 0;
float blocky = 0;
int right = 0;
int down = 0;
float enemyx = 10;
float enemyy = 10;
int counter = 0;
int counter1 = 0;
int counter2 = 0;
int gunwidth = 3;
int gunheight = 5;
float gunx = 0;
float guny = 0;
int buletwidth = 2;
int buletheight = 3;
float buletx = 0;
float bulety = 0;
int playerdirection = 0;
int buletdirection = 0;
int buletdone = 0;
int enemylives;
int enemydied = 1;
int enemylocation = 0;
int playerlives = 3;
int kills = 0;
int lvl = 1;
int lvldone = 0;
#define enemyspeed 0.5;

const unsigned char PROGMEM background[] = {
// width, height,
8, 8,
0x81, 0x00, 0x12, 0x40, 0x04, 0x11, 0x00, 0x04, 
};
const unsigned char PROGMEM enemy[] =
{
// width, height,
16, 16,
0xfe, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0x01, 0xc1, 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x01, 0xfe, 
0x7f, 0x80, 0x9c, 0xbc, 0xb0, 0xb0, 0xb2, 0xb2, 0xb3, 0xb0, 0xb0, 0xb0, 0xbc, 0x9c, 0x80, 0x7f, 
};

void setup(){
  arduboy.begin();
  arduboy.setFrameRate(60);
  arduboy.initRandomSeed();
  arduboy.display();

  blockx = WIDTH / 2 - blockwidth / 2;
  blocky = HEIGHT / 2 - blockheight / 2;
  gunx = WIDTH / 2 - gunwidth / 2;
  guny = HEIGHT / 2 - gunwidth / 2;
  buletx = gunx;
  bulety = guny;
  buletdone = 2;
}

void renderBlock(){
  arduboy.fillRect(blockx,blocky,blockwidth, blockheight);
}

void handleGameInput() {
  if (arduboy.pressed(LEFT_BUTTON)) {
    blockx -= 1,5;
    if (blockx < 0) {
      blockx = 0;
    }
    gunx = blockx -5;
    guny = blocky;
    if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 1;
    gunwidth = 5;
    gunheight = 3;
    buletmove();
  } if (arduboy.pressed(RIGHT_BUTTON)) {
    blockx += 1,5;
    if (blockx + blockwidth > WIDTH) {
      blockx = WIDTH - blockwidth;
    }
    gunx = blockx +10;
    guny = blocky;
    if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 2;
    gunwidth = 5;
    gunheight = 3;
    buletmove();
  }
  if (arduboy.pressed(UP_BUTTON)){
    blocky -= 1,5;
    if (blocky < 0){
      blocky = 0;
    }
    guny = blocky - 5;
    gunx = blockx;
    if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 3;
    gunwidth = 3;
    gunheight = 5;
    buletmove();
  }
  if (arduboy.pressed(DOWN_BUTTON)){
    blocky += 1,5;
    if (blocky + blockheight > HEIGHT) {
      blocky = HEIGHT - blockheight;
    }
    guny = blocky +10;
    gunx = blockx;
     if(buletdirection == 0){
      buletx = gunx;
      bulety = guny;
    }
    playerdirection = 4;
    gunwidth = 3;
    gunheight = 5;
    buletmove();
  }
  
}
void renderenemy(){
  if(enemydied == 1){
    counter = counter +1;
    if(enemyx < 0){
      enemyx = 0;
    }
    if(enemyx > 112){
      enemyx = 112;
    }
    if(enemyy < 0){
      enemyy = 0;
    }
    if(enemyy > 48){
      enemyy = 48;
    }
    if(right == 2){
      enemyx = enemyx +enemyspeed;
    }
    if(right == 1){
      enemyx = enemyx -enemyspeed;
    }
    if(down == 2){
      enemyy = enemyy +enemyspeed;
    }
    if(down == 1){
      enemyy = enemyy -enemyspeed;
    }
    if(counter == 25){
      if(lvl == 1){
        right = random(1,4);
        down = random(1,4);
      }
      if(lvl > 1){
        right = random(1,3);
        down = random(1,3);
      }
      counter = 0;
    }
    Sprites::drawOverwrite(enemyx, enemyy, enemy, 0);
  }
  if(enemydied == 2){
    enemyx = -16;
    enemyy = -16;
    counter1 = counter1 + 1;
    if(counter1 == 50){
      enemydied = 1;
      counter1 = 0;
      if(lvl < 3){
        enemylives = 3;
      }
      if(lvl > 2){
        enemylives = 5;
      }
      enemylocation = random(1,5);
      switch(enemylocation){
        case 1:
        enemyx = 0;
        enemyy = 0;
        break;

        case 2:
        enemyx = 0;
        enemyy = 48;
        break;

        case 3:
        enemyx = 112;
        enemyy = 48;
        break;

        case 4:
        enemyx = 112;
        enemyy = 0;
        break;
      }
      }
    }
  }
void gun(){
  arduboy.fillRect(gunx,guny,gunwidth,gunheight);
  arduboy.fillRect(buletx,bulety,buletwidth,buletheight);
}

void buletmove(){
  if (playerdirection == 1){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 1;
      }
    }
  }
  if (playerdirection == 2){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 2;
      }
    }
  }
  if (playerdirection == 3){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 3;
      }
    }
  }
  if (playerdirection == 4){
    if(buletdone == 2){
      if(arduboy.pressed(A_BUTTON)){
        buletdirection = 4;
      }
    }
  }
  buletmove1();
}

void buletmove1(){
  if(buletdirection == 1){
    buletdone = 1;
    buletwidth = 3;
    buletheight = 2;
    buletx = buletx -2;
    if(buletx < -3){
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
      buletdone = 2;
    }
  }
  if(buletdirection == 2){
    buletdone = 1;
    buletwidth = 3;
    buletheight = 2;
    buletx = buletx +2;
    if(buletx > 131){
      buletdone = 2;
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
    }
  }
  if(buletdirection == 3){
    buletdone = 1;
    buletwidth = 2;
    buletheight = 3;
    bulety = bulety -2;
    if(bulety < -3){
      buletdone = 2;
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
    }
  }
  if(buletdirection == 4){
    buletdone = 1;
    buletwidth = 2;
    buletheight = 3;
    bulety = bulety +2;
    if(bulety > 67){
      buletdone = 2;
      buletx = gunx;
      bulety = guny;
      buletdirection = 0;
    }
  }
}

void checkCollisions()
{
  // Creates a 'Rect' with (x, y, width, height)
  Rect bulletRect(buletx, bulety, buletwidth, buletheight);

  // Creates a 'Rect' with (x, y, width, height)
  Rect enemyRect(enemyx, enemyy, 16, 16);

  Rect playerRect(blockx, blocky, blockwidth, blockheight);

  Rect gunRect(gunx, guny, gunwidth, gunheight);

  // Checks if the two rectangles are intersecting
  if(Arduboy2::collide(bulletRect, enemyRect))
  {
    // Code to run if the bullet has touched the enemy
    buletdone = 2;
    buletx = gunx;
    bulety = guny;
    buletdirection = 0;
    enemylives = enemylives -1;
    if(enemylives == 0){
      kills = kills +1;
    }
  }
  if(Arduboy2::collide(enemyRect, playerRect)){
    enemylives = 0;
    playerlives = playerlives -1;
  }
  if(enemylives == 0){
      enemydied = 2;
    }
  if(playerlives == 0){
    gamestate = 2;
    playerlives = 3;
    blockx = WIDTH / 2 - blockwidth / 2;
    blocky = HEIGHT / 2 - blockheight / 2;
    gunx = WIDTH / 2 - gunwidth / 2;
    guny = HEIGHT / 2 - gunwidth / 2;
  }
}

void Titlescreen(){
  kills = 0;
  arduboy.setCursor(30,10);
  arduboy.print(F("SHOOTER X"));
  arduboy.setCursor(20,25);
  arduboy.print(F("Press B Button"));
  arduboy.setCursor(0,53);
  arduboy.print(F("Made by Alex Toma"));
  if(arduboy.justPressed(B_BUTTON)){
      gamestate = 3;
  }
}

void Gameoverscreen(){
  arduboy.setCursor(30,20);
  arduboy.print(F("Game Over"));
  arduboy.setCursor(30,30);
  arduboy.print(F("Kills:"));
  arduboy.setCursor(67,30);
  arduboy.print(kills);
  if(arduboy.justPressed(B_BUTTON)){
      gamestate = 0;
  }
}

void screeninfo(){
 arduboy.println(F("Lives:"));
 arduboy.println(playerlives);
 arduboy.setCursor(75,0);
 arduboy.println(F("Score:"));
 arduboy.setCursor(110,0);
 arduboy.println(kills);
 if(kills == 15){
  lvl = 2;
  #define enemyspeed 2;
  if(lvldone == 0){
    gamestate = 3;
    lvldone = 1;
  }
 }
 if(kills == 25){
  lvl = 3;
  enemylives = 5;
  #define enemyspeed 3;
  if(lvldone == 1){
    gamestate = 3;
    lvldone = 2;
  }
 }
}

void levl(){
  arduboy.setCursor(40,20);
  arduboy.print(F("LEVEL:"));
  arduboy.setCursor(75,20);
  arduboy.print(lvl);
  counter2 = counter2 +1;
  if(counter2 == 75){
    gamestate = 1;
    counter2 = 0;
  }
}

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

  arduboy.clear();
  arduboy.pollButtons();
  //=====================
  if(gamestate == 0){
    Titlescreen();
  }
  
  if(gamestate == 1){
  //For each column on the screen
  for (int backgroundx = 0; backgroundx < 128; backgroundx = backgroundx + 8) {
  //For each row in the column
    for ( int backgroundy = 0; backgroundy < 64; backgroundy = backgroundy + 8) {
      //Draw a background tile
      Sprites::drawOverwrite(backgroundx, backgroundy, background, 0);
    }
  }
  renderBlock();
  handleGameInput();
  renderenemy();
  gun();
  buletmove();
  checkCollisions();
  screeninfo();//levels here aswell
  }
  
  if(gamestate ==2){
    Gameoverscreen();
  }

  if(gamestate ==3){
    levl();
  }

  //=====================
  arduboy.display();

}

You’re setting enemylives to 5 every update.

 if(kills == 25){
  lvl = 3;
  #define enemyspeed 3;
  if(lvldone == 1){
    gamestate = 3;
    lvldone = 2;
  }
 }

By the way, using #define enemyspeed 3 won’t increase the enemy speed during the game.

Macros (words introduced by #define) only work when the program is being compiled.
When the program has been compiled, any macro made with #define will be substituted with the value is it defined as and can’t be changed.
(Macros are basically just text substitution. I.e. not a very good way to have constant values. constexpr variables are better.)

If you want to change enemyspeed during the game, you need to use a variable instead.


If you want or need any more advice,
or you’d like to learn some more ways to improve your code,
feel free to ask.

2 Likes

thanks again! :smile: :sweat_smile:

1 Like

Don’t worry about it too much.

Remember that I can spot these things because I’ve had a lot of experience, so I know what to look for.


To try to give you a bit of insight:

The first thing I did was play the game to confirm that the problem existed and to know what to look for when the problem is solved.

In this case, I looked for a logic problem first,
but I couldn’t see any obvious ones,
so then I looked at all the places where enemylives was being used and spotted an inconsistency:

 if(kills == 15){
  lvl = 2;
  #define enemyspeed 2;
  if(lvldone == 0){
    gamestate = 3;
    lvldone = 1;
  }
 }
 if(kills == 25){
  lvl = 3;
  enemylives = 5;
  #define enemyspeed 3;
  if(lvldone == 1){
    gamestate = 3;
    lvldone = 2;
  }
 }

The if(kills == 15) branch didn’t have enemylives = 3,
and I’d already seen enemylives being set to 5 in renderenemy, in the if(lvl > 2) branch,
so enemylives = 5 seemed out of place here.

Then I just tested my theory by commenting it out and playing until I could confirm the problem was fixed.

Hopefully that’ll give you (and anyone else reading this) some insight on how to go about looking for a problem.

Not that I have a problem helping you find bugs of course, but as the saying goes:

Give a man a fish and you feed him for a day;
teach a man to fish and you feed him for a lifetime

3 Likes

I am speeachless… :joy: Thanks a lot! You are the best teacher I have ever got!

2 Likes