Skip to main content
gamedev.net
🔒 Locked

x

Started by Carbon101 Feb 13, 2012 at 1:50 AM 14 replies 8.1k views
Original Post
Carbon101
Carbon101

...

freeworld
freeworld
how bout doing this each frame...


ballPosition += ballVelocity * frameTime;

// ballPosition is the position the ball is
// ballVelocity is how fast the ball is moving
// frametime is the amount of time that passed since last frame


I prefer using vectors, which are basically just x, y and z coordinates, to represent my positions and velocities. You could use single variables aswell...


ballX += velocityX * frameTimer;
ballY += velocityY * frameTimer;


Think about how you implemented the paddle movement, just this time instead of waiting for player input, it moves automatically.
maxfire
maxfire
Simply adding velocity to X and Y is fine but what about when you need to calculate the bounce? surly we need to be a little more accurate using cos sin and bounce angle/ facing direction is better no?


_VelocityX = int ( cos( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * ( _CurrentMovementSpeed * _FrameDeltaTime ) ) );
_VelocityY = int ( sin( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * (_CurrentMovementSpeed * _FrameDeltaTime ) ) );

p.s _FrameDeltaTime = time it took to complete one cycle or the gameloop. This means the ball travels the same distance no matter the frame rate

then we can use


_Ball->x += _VelocityX;
_Ball->y += _VelocityY;
SeiryuEnder
SeiryuEnder
Just a note, it's generally a good idea to put large amounts of code between [.CODE][./CODE] tags.
Makes things easier to read and doesn't bloat the thread as much.
before-it-was-popular
before-it-was-popular

...can you give me an explanation as to why you recommended sin and cos. I am familiar with the functions, but I am really interested in know how they relate to game programming. An in depth explanation on what sin and cos will be doing in my game, and or maybe other games you might have examples for, in terms of application.

At least for two dimensions, you can represent vectors like velocity in two ways: an angle and a length, or an x-component length and a y-component length. Sine and cosine convert from the angle-length way to the component way. More precisely, given an angle, sine tells you what fraction of the length sticks out in the y direction and cosine tells you what fraction sticks out in the x direction. There are other uses, but that's the one that MaxFire is talking about, and it's one of the most important.

It's useful to use the angle-length form when you want to modify the angle directly - say, by adding five degrees. When you want to do other calculations with the vector, like adding it to another vector, it's usually easiest to convert it into components so that you can deal with each component separately; that's when you need to use sine and cosine. For example, in a top-down racing game you might store the angle so you can rotate the car's velocity clockwise and counterclockwise when the player presses left and right. When the player starts to move forward, then, you would want to get the x- and y-components of the car's velocity so you could add it to the car's position every frame.

In this case I assume MaxFire is recommending you store the angle because you need to ensure that the ball bounces off the paddle at the correct angle. This is not actually necessary if all your walls and paddles are all at right angles; when the ball hits a vertical wall, you can just flip the sign of the x-component of the velocity, and similarly with the y-component for a horizontal wall collision. This will always produce the correct bounce angle.

Later you'll probably want to add a little randomness to the bounces; otherwise, they'll always occur at exactly the same angles, which gets boring. Having the angle to play with does make that easier because you can use it to change the direction easily without changing the speed, but if you're trying to keep things simpler for the moment the sign-flip might be better.
maxfire
maxfire
Well I guess before-it-was-popular took the words right out of my mouth nice explanation m8

but may I add that if you simply add speed to X and Y when you want to move at an angle ( NE, SE, SW, NW ) then you will probably be adding or subtracting speed to both X and Y this gives the unwanted effect of doubling the speed of the ball ( you are the full amount to both X and Y ). You could of course compensate for this by keeping track of the latest direction you want to travel in and halving the appropriate velocity ( hard coding all directions ) but then we may as use an angle in the first place tongue.png

If you need help implementing cos and sin give us a howler il plot out some example code for ya
maxfire
maxfire
I have never used allegro 5 but I will create some sudo code that you will be able to convert to your needs, il post this tonight for you . And if you are using a game loop rather than event driven you will probably need a queue.
maxfire
maxfire
ok so you have you game loop, I will just lay out how I would do the basic movement. If I was to do the whole thing you wouldnt be learning anythign tongue.png

im not sure how you code your controls work but I will use arrow keys for player 1 and WS for player 2

finally not knowing your framwework means that i will made logical substitutions on how events may be handled

ok well I scratched this together using notepad on my laptop as my computer has died on me so sorry for any syntax errors

main(int)
{
Player player1;
player player2;
While(!end)
{
//events
if(event)
{
string button = event.getButton(); //this is totally made up for this example many frameworks handle this differantly I know SDL has its own event lableing system ( yes string is very bad way of doing this but makes it clearer as an example)
bool upordown = event.upordown(); // again I dont know your framework so making this up to make scence if( button == up || button == down )
{
player1.HandleEvent( button );// each object should know how to handle its own even in my oppinion
}
else if( button == W || button == S )
{
player2.HandleEvent( button, upordown ):
}
else
{
//anything elts like program close/exit for example
}
}
//updates
player1.Update();
player2.Update();

//drawing
player1.Draw();
player2.Draw();
}
return 0;
}

//player class
class Player
{
public:

//contructor and deconstructor
void Update();
void Draw();
void HandleEvent( string button, bool upordown );

private:

int direction;
int speed;
int _VelocityX;
int _VelocityY;
int X;
int Y;
}
void Player::HandleEvent( string button, bool upordown )
{
//w and up handed in the same way for this example, you can create some sort of id system where w and up return the same id
if( button == w || button == up )
{
if( upordown == true )
{
speed = BALL_SPEED; //probably a const or passed in the constructor
}
else
{
speed = 0;
}

direction = 180;//assumes mathamatic cos and sign where 0 is east direction
}
//elts do the same for down with direction as 90//update velocities if speed is 0 ball will stop

_VelocityX = int ( cos( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * ( _CurrentMovementSpeed * _FrameDeltaTime ) ) );
_VelocityY = int ( sin( ( _RotationAngle + 0.0 ) * M_PI / 180.0 ) * (_CurrentMovementSpeed * _FrameDeltaTime ) ) );

}
void Player::Update()
{
x += _VelocityX;
y += _VelocityY;
}

void Player::Draw()
{
draw however your frameworks draws
}



This is my take on doing something like this, might be some people that disagree but hope it helps. Note the ball movement can be done in exactly the same way but using collision detection to change direction rather than some event from the keyboard smile.png.
Carbon101
Carbon101
Thank you MaxFire, this is very generous of you. You went above and beyond, and I greatly appreciate it. This is the most help I have ever received from the site...(no offense to the people that answered, I appreciate your help as well). I totally understand that you didn't do the all thing, it is all about the learning experience on my part. Thanks again.
maxfire
maxfire
Nps dude happy to help, give us A howler with anything elts
Carbon101
Carbon101
I have a question, was it or is it possible to have ball movement with out classes. Reason I ask is because I haven't started to dive in that area as of yet, soon will. Before you helped me, I used linear equations for ball movement. I want to know if what I did was the right way to go, here is some source code:




int ball_x = 454;
int ball_y = 350;
int ball_rad = 10;
int fx = (ball_y/ball_x) + 1;
int fx1 = (-(ball_y)/ball_x) - 1;
int fx2 = (ball_y/ -(ball_x)) + 1;
int fx3 = (-(ball_y) / -(ball_x)) + 1;


if(!run)
{
if(fx)
{
ball_x = ball_x + 10;
ball_y = ball_y - 10;

}
else if(fx1)
{
ball_x = ball_x + 10;
ball_y = ball_y + 10;

}
else if(fx2)
{
ball_x = ball_x - 10;
ball_y = ball_y - 10;

}
else if(fx3)
{
ball_x = ball_x - 10;
ball_y = ball_y + 10;

}
else
{
rand() * fx * fx1 * fx2 * fx3;



}


al_draw_filled_circle(ball_x, ball_y, ball_rad,al_map_rgb(250,0,0)); // Ball

al_flip_display(); // Helps what has been drawn visible on screen. Switches from blank screen to the actually image
al_clear_to_color(al_map_rgb(0,0,0));
int ball_x = 454;
int ball_y = 350;
int ball_rad = 10;
int fx = (ball_y/ball_x) + 1;
int fx1 = (-(ball_y)/ball_x) - 1;
int fx2 = (ball_y/ -(ball_x)) + 1;
int fx3 = (-(ball_y) / -(ball_x)) + 1;

if(!run)
{
if(fx)
{
ball_x = ball_x + 10;
ball_y = ball_y - 10;
}
else if(fx1)
{
ball_x = ball_x + 10;
ball_y = ball_y + 10;
}
else if(fx2)
{
ball_x = ball_x - 10;
ball_y = ball_y - 10;
}
else if(fx3)
{
ball_x = ball_x - 10;
ball_y = ball_y + 10;
}
else
{
rand() * fx * fx1 * fx2 * fx3;
}

al_draw_filled_circle(ball_x, ball_y, ball_rad,al_map_rgb(250,0,0)); // Ball
al_flip_display(); // Helps what has been drawn visible on screen. Switches from blank screen to the actually image
al_clear_to_color(al_map_rgb(0,0,0));



***Sorry if the source code doesn't appear in the proper format****
maxfire
maxfire
yea you can do it without classes, but if your using c++ then you may as use them. If you are not conformal with classes I suggest reading up on them now because they are one of the core foundation principles of nearly every program .

With your linear equations are you trying to achieve a random direction? it might be slightly over complicating it but if it works then should be fine

Another suggestion for you would be to define a static const for your speed makes it neater and clearer

static const int BALL_SPEED = 10;
Velocity += BALL_SPEED;

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.