1

I am new to programming in the C language. I just decided to pick it up for fun; I have hobbyist experience in Javascript, Java, and a few other languages. For whatever reason, I decided to learn C in the context of developing a program for the Gameboy Classic. So I installed the GBDK, which I understand is outdated. It comes with an LCC compiler. I use VisualBoy Advance to emulate my program.

I am trying to create a simple Breakout clone. So far, I have successfully programmed the paddle with user input. However, I've run into a problem with the ball: it isn't checking for a collision with the paddle. After doing tons of tests, research, and asking around on other sites, I still cannot resolve this problem.

Here is the complete code:

#include <gb/gb.h>
#include "Sprites/paddle.c"
#include "Sprites/ball.c"

int paddleX = 72;
int paddleY = 136;
int paddleSpeed = 1;

int ballAngle = 270;
int ballX = 84;
int ballY = 75;

void setSprites() {
    SPRITES_8x8;

    //paddle////////////////////////////

    set_sprite_data(0, 4, paddle);
    set_sprite_tile(0, 0);
    move_sprite(0, paddleX, paddleY);

    set_sprite_tile(1, 1);
    move_sprite(1, paddleX+8, paddleY);

    set_sprite_tile(2, 2);
    move_sprite(2, paddleX+16, paddleY);

    set_sprite_tile(3, 3);
    move_sprite(3, paddleX+24, paddleY);

    //ball////////////////////////////////

    set_sprite_data(4, 1, ball);
    set_sprite_tile(4, 4);
    move_sprite(4, ballX, ballY);

    SHOW_SPRITES;
}

void movePaddle() {
    if(joypad() == J_LEFT) {
        if(paddleX <= 8) {
            paddleX = 8;
        }
        else {
            paddleX -= 1;
        }
    }
    if(joypad() == J_RIGHT) {
        if(paddleX >= 136) {
            paddleX = 136;
        }
        else {
            paddleX += 1;
        }
    }
    move_sprite(0, paddleX, paddleY);
    move_sprite(1, paddleX+8, paddleY);
    move_sprite(2, paddleX+16, paddleY);
    move_sprite(3, paddleX+24, paddleY);
}

void moveBall() {
    if(ballAngle == 270) {
        if((ballY >= paddleY-8) && (ballX >= paddleX-8) && (ballX <= 
                paddleX+24)) {
            ballAngle = 90;
        }
        else {
            ballY += 1;
        }
    }
    if(ballAngle == 90) {
        ballY -= 1;
    }
    move_sprite(4, ballX, ballY);
}

void main() {
    setSprites();
    while(1) {
        movePaddle();
        moveBall();

        delay(20);
    }
}

The problem rests within one "if statement." Specifically, the:

    if((ballY >= paddleY-8) && (ballX >= paddleX-8) && (ballX <= 
            paddleX+24)) {

condition. It's just not working. I swapped in a test variable that wasn't changed at all during the rest of the program; FAIL. The only way it works is if I hardcode a value (96, for example). However, that is obviously bad because it wouldn't change whenever the paddle moves.

I am completely stumped on this problem. I am new to C, but this seems like a simple thing. Is my compiler broken? Am I doing something unintentionally wrong? Keep in mind that this is designed with the Gameboy Dev Kit, emulated as a classic Gameboy game.

Any help is appreciated. Thanks!

SOLVED: Strange solution. Instead of adding 24 to paddleX, I subtract -24. For whatever reason, that works as intended.

Ben Klayer
  • 61
  • 6
  • 1
    You are missing a closing parenthesis. Is that only in your pasted code here, or in your actual code? – Engineero Dec 20 '18 at 19:31
  • 1
    That's in the posted code. I just fixed it. My parentheses are good in the actual program. – Ben Klayer Dec 20 '18 at 19:33
  • In what way is it not working? What is it doing/not doing that doesn't meet your expectations? Are you getting an error, or just unexpected behavior? What behavior? – Engineero Dec 20 '18 at 19:35
  • 2
    Probably out of you initial problems, but why do you #include c files rather than to compile them separately and make the executable will all the objects ? – bruno Dec 20 '18 at 19:47
  • The ball is supposed to drop, then switch directions and go upwards when it collides with the paddle. This is checked by that "if statement" in the moveBall() function. Theoretically, the collision should happen between (paddleX-8) and (paddleX+24). When I compare ballX to paddleX+24, the ball just falls through the paddle. However, when I eliminate this condition, and just leave in the remaining if statement, the ball acts appropriately if the paddle is below or to the left of the ball. Basically that (ballX <= paddleX+24) doesn't check out. – Ben Klayer Dec 20 '18 at 19:49
  • There are very limited circumstances which justify including `c` files. – Eugene Sh. Dec 20 '18 at 19:50
  • it is abnormal that moveBall() isn't symetric, when angle is 270 you do tests to decide to change angle to 90 or moving 1 step, when angle is 90 you must do the equivalent changing angle to 270 or moving 1 step – bruno Dec 20 '18 at 19:53
  • Your question was somewhat misleading; the condition is more complex that just `(ballX <= paddleX+24)` - I have edited the question to show the entire conditional expression. – Clifford Dec 20 '18 at 19:56
  • Bruno and Eugene -- admittedly, I am rusty with external compilers because I've been working in Javascript for so long. I just followed a tutorial of how to draw graphics in C, specifically with GBDK. I'm unsure what you mean -- care to point me to some resources? – Ben Klayer Dec 20 '18 at 20:02
  • The most logical conclusion seems to be that the value of `ballX` is not what you think it is. Is there a way to display the ball coordinates on-screen or in a debugging terminal while the game runs, so as to check that? – John Bollinger Dec 20 '18 at 20:03
  • Also Bruno -- yup I know that it isn't symmetrical yet. That's a simple addition, just check if it reaches the top of the screen (I actually did this and it worked, I just scrapped it until I could figure out this problem). – Ben Klayer Dec 20 '18 at 20:04
  • John -- no, ballX is fine. The problem is checking (paddleX+24). Because if I hardcode that value -- such as 96, for example -- it works for that one specific case. – Ben Klayer Dec 20 '18 at 20:06
  • All three AND'ed sub expressions must be true, not just `(ballX <= paddleX+24)` - are you sure that is the expression that is false? Does the kit include a debugger - that is a better way to debug this. The whole ball angle thing seems to serve little purpose; you just need a `xincrement` and a `yincrement` and simply swap their sign when the ball bounces. – Clifford Dec 20 '18 at 20:08
  • Could you post the value of `INT_MAX` for this compiler and target? – EOF Dec 20 '18 at 20:23
  • EOF -- what the heck does that mean, and how can I find it? – Ben Klayer Dec 20 '18 at 20:35
  • @BenKlayer, I'm not convinced that your experiment of hardcoding the upper limit on `ballX` in fact does prove that it has the value you expect, though perhaps that's because of my unfamiliarity with your code. I guess, however, that the alternative possibility is that `paddleX` has a different value than you expect. *That* possibility is certainly not ruled out by the experiment you describe. You should prefer to find a way to observe these more directly, rather than by the kind of inference you're using. – John Bollinger Dec 20 '18 at 21:26
  • Certainly, if I comment out all sprite and paddle functions from your code, leaving essentially just an infinite loop calling `moveBall()`, I observe what appears to be exactly the kind of bounce you expect: `ballY` increases at each step until it reaches 128, then starts decreasing at each step. Although it is possible that your development environment is somehow buggy, I'm more inclined to guess that your data are not what you think they are. In any event, I don't see any flaw inherent in the conditional logic you've called out here. – John Bollinger Dec 20 '18 at 21:36
  • SOLVED: Strange solution. Instead of adding 24 to `paddleX`, I subtract -24. For whatever reason, that works as intended. – Ben Klayer Dec 21 '18 at 16:48
  • Also, as a side note: do not use Visual Boy Advance. In addition to various security flaws, this emulator happens to have very bad accuracy when it comes to Game Boy emulation. Use a more recent emulator like BGB (which happen to have a pretty good debugger too), or Gambatte. – Méga Lag Dec 21 '18 at 18:17

0 Answers0