• Create Account

We're offering banner ads on our site from just \$5!

### #ActualServant of the Lord

Posted 27 December 2012 - 11:18 PM

In addition to what Bacterius said, 'char' also isn't the appropriate variable type for deciding whether you are moving up and down. chars are for written characters, like written numbers and letters and things. Neither is int appropriate, which is for numbers for math.

A decent choice would be a bool.

bool movingLeft = true; //If false, you are moving right.
bool movingUp = true; //If false, you are moving down.

A better choice would be enums.

enum HorizontalDirection{Right, Left};
enum VerticalDirection{Up, Down};

//Or:
enum Direction{NorthWest, North, NorthEast, East, SouthEast, South, SouthWest, West};

A choice better still would be enums with a bit flag, though the syntax may seem really weird at first.

enum Direction{None = 0, Up = 1, Down = 2, Left = 4, Right = 8};
typdef unsigned int DirectionFlags;

DirectionFlags direction = None;

direction |= Left; //Add to 'direction' that we are *also* heading left.

if(direction & Down) //Check if 'direction' contains 'Down' in it.

Any of those three are generally acceptable, but char is would be a very unusual choice to use there (even though it works) unless you have a special reason to use it.

Another option is to give velocities, and make the velocities negative or positive. A negative "vertical velocity" means you head up, while a positive one means you head down (or vice-versa):

int verticalVelocity = 0; //Not moving vertically.
verticalVelocity = 1; //Moving up.
verticalVelocity = 3; //Moving up really fast.
verticalVelocity = -1; //Moving down.

box.x += verticalVelocity; //Using the velocity (without caring whether it's zero, negative, or postive) to move the box.

As Bacterius hinted at, the problem is that your if() collision checks for the walls are checking whether the ball is colliding with the bottom wall AND the side wall at the same time when you want the wall to bounce back even if it's only touching one wall. You also want to swap x and y individually, not together. (Also, your fourth if() statements you copy+pasted the symbols and forgot to swap the plus and minus).

//IF the box is NOT past the right side of the screen AND is below the bottom.
if(!(box.x >= SCREEN_W) && box.y >= SCREEN_H)

What happens if the box is past the right side of the screen? Why would you not reverse the vertical direction then?

There are nine different possible "states": (assuming the ball is smaller than the screen and can't touch the top and bottom at the same time).
1. Not colliding with any wall.
2. Colliding with the top
3. Colliding with the bottom
4. Colliding with the left
5. Colliding with the right
6. Colliding with the top AND right
7. Colliding with the top AND left
8. Colliding with the bottom AND right
9. Colliding with the bottom and left

You only need to explicitly check for four states...

1. Colliding right
2. Colliding bottom
3. Colliding left
4. Colliding top

...but make each check not block the other states from being checked - in this situation, you don't use 'else' or 'if else', just 'if', so zero, one, or more 'if's can be triggered on the same run through.

1. "Colliding NOT right AND colliding bottom"
2. "Colliding NOT bottom AND colliding right"
3. "Colliding NOT left AND colliding top"
4. "Colliding NOT top AND colliding right"

...which is over-complicating the matter, and in that complication, accidentally hides/disguises the fact that it's not actually checking all the possibilities.

### #2Servant of the Lord

Posted 27 December 2012 - 11:17 PM

In addition to what Bacterius said, 'char' also isn't the appropriate variable type for deciding whether you are moving up and down. chars are for written characters, like written numbers and letters and things. Neither is int appropriate, which is for numbers for math.

A decent choice would be a bool.

bool movingLeft = true; //If false, you are moving right.
bool movingUp = true; //If false, you are moving down.

A better choice would be enums.

enum HorizontalDirection{Right, Left};
enum VerticalDirection{Up, Down};

//Or:
enum Direction{NorthWest, North, NorthEast, East, SouthEast, South, SouthWest, West};

A choice better still would be enums with a bit flag, though the syntax may seem really weird at first.

enum Direction{None = 0, Up = 1, Down = 2, Left = 4, Right = 8};
typdef unsigned int DirectionFlags;

DirectionFlags direction = None;

direction |= Left; //Add to 'direction' that we are *also* heading left.

if(direction & Down) //Check if 'direction' contains 'Down' in it.

Any of those three are generally acceptable, but char is would be a very unusual choice to use there (even though it works) unless you have a special reason to use it.

Another option is to give velocities, and make the velocities negative or positive. A negative "vertical velocity" means you head up, while a positive one means you head down (or vice-versa):

int verticalVelocity = 0; //Not moving vertically.
verticalVelocity = 1; //Moving up.
verticalVelocity = 3; //Moving up really fast.
verticalVelocity = -1; //Moving down.

box.x += verticalVelocity; //Using the velocity (without caring whether it's zero, negative, or postive) to move the box.

As Bacterius hinted at, the problem is that your if() collision checks for the walls are checking whether the ball is colliding with the bottom wall AND the side wall at the same time when you want the wall to bounce back even if it's only touching one wall. You also want to swap x and y individually, not together. (Also, your fourth if() statements you copy+pasted the symbols and forgot to swap the plus and minus).

//IF the box is NOT past the right side of the screen AND is below the bottom.
if(!(box.x >= SCREEN_W) && box.y >= SCREEN_H)

What happens if the box is past the right side of the screen? Why would you not reverse the vertical direction then?

There are nine different possible "states": (assuming the ball is smaller than the screen and can't touch the top and bottom at the same time).
1. Not colliding with any wall.

2. Colliding with the top

3. Colliding with the bottom

4. Colliding with the left

5. Colliding with the right

6. Colliding with the top AND right

7. Colliding with the top AND left

8. Colliding with the bottom AND right

9. Colliding with the bottom and left

You only need to explicitly check for four states...

1. Colliding right

2. Colliding bottom

3. Colliding left

4. Colliding top

...but make each check not block the other states from being checked - in this situation, you don't use 'else' or 'if else', just 'if', so zero, one, or more 'if's can be triggered on the same run through.

1. "Colliding NOT right AND colliding bottom"

2. "Colliding NOT bottom AND colliding right"

3. "Colliding NOT left AND colliding top"

4. "Colliding NOT top AND colliding right"

...which is over-complicating the matter, and in that complication, accidentally hides/disguises the fact that it's not actually checking all the possibilities.

### #1Servant of the Lord

Posted 27 December 2012 - 11:15 PM

In addition to what Bacterius said, 'char' also isn't the appropriate variable type for deciding whether you are moving up and down. chars are for written characters, like written numbers and letters and things. Neither is int appropriate, which is for numbers for math.

A decent choice would be a bool.

bool movingLeft = true; //If false, you are moving right.
bool movingUp = true; //If false, you are moving down.

A better choice would be enums.

enum HorizontalDirection{Right, Left};
enum VerticalDirection{Up, Down};

//Or:
enum Direction{NorthWest, North, NorthEast, East, SouthEast, South, SouthWest, West};

A choice better still would be enums with a bit flag, though the syntax may seem really weird at first.

enum Direction{None = 0, Up = 1, Down = 2, Left = 4, Right = 8};
typdef unsigned int DirectionFlags;

DirectionFlags direction = None;

direction |= Left; //Add to 'direction' that we are *also* heading left.

if(direction & Down) //Check if 'direction' contains 'Down' in it.

Any of those three are generally acceptable, but char is would be a very unusual choice to use there (even though it works) unless you have a special reason to use it.

Another option is to give velocities, and make the velocities negative or positive. A negative "vertical velocity" means you head up, while a positive one means you head down (or vice-versa):

int verticalVelocity = 0; //Not moving vertically.
verticalVelocity = 1; //Moving up.
verticalVelocity = 3; //Moving up really fast.
verticalVelocity = -1; //Moving down.

box.x += verticalVelocity; //Using the velocity (without caring whether it's zero, negative, or postive) to move the box.

[/code]

As Bacterius hinted at, the problem is that your if() collision checks for the walls are checking whether the ball is colliding with the bottom wall AND the side wall at the same time when you want the wall to bounce back even if it's only touching one wall. You also want to swap x and y individually, not together. (Also, your fourth if() statements you copy+pasted the symbols and forgot to swap the plus and minus).

//IF the box is NOT past the right side of the screen AND is below the bottom.
</p><div>if(!(box.x >= SCREEN_W) && box.y >= SCREEN_H)

What happens if the box is past the right side of the screen? Why would you not reverse the vertical direction then?

There are nine different possible "states": (assuming the ball is smaller than the screen and can't touch the top and bottom at the same time).
1. Not colliding with any wall.

2. Colliding with the top

3. Colliding with the bottom

4. Colliding with the left

5. Colliding with the right

6. Colliding with the top AND right

7. Colliding with the top AND left

8. Colliding with the bottom AND right

9. Colliding with the bottom and left

You only need to explicitly check for four states...

1. Colliding right

2. Colliding bottom

3. Colliding left

4. Colliding top

...but make each check not block the other states from being checked - in this situation, you don't use 'else' or 'if else', just 'if', so zero, one, or more 'if's can be triggered on the same run through.

1. "Colliding NOT right AND colliding bottom"

2. "Colliding NOT bottom AND colliding right"

3. "Colliding NOT left AND colliding top"

4. "Colliding NOT top AND colliding right"

...which is over-complicating the matter, and in that complication, accidentally hides/disguises the fact that it's not actually checking all the possibilities.

PARTNERS