Moving Objects in small increments
-
Hi, I got a ball hitting a paddle and I want it's X velocity to increase/decrease depending on where it hits the paddle. The code below works with whole numbers but not for numbers like "0.67" or "2.45". I'm looking for a way to animate objects moving at smaller increments for better precision. Thanks.
int speed=Ball_List[b]->speed;
// Paddle center.
int paddle_center = Player->Location.X + Player->Width / 2;// Ball center.
int ball_center = Ball_List[b]->gameBall->Location.X + Ball_List[b]->gameBall->Width / 2;// Find the location on the paddle that the ball hit
int paddle_location = ball_center - paddle_center;// change angle according to distance from center of paddle.
double a=(90-paddle_location);
double angle = (Math::PI / 180) * a; // angle in radians.
Ball_List[b]->xVel = speed*Math::Cos(angle);
Ball_List[b]->yVel = -speed*Math::Sin(angle);// Move the ball
Ball_List[b]->gameBall->Location = Point(Ball_List[b]->gameBall->Location.X + Ball_List[b]->xVel, Ball_List[b]->gameBall->Location.Y + Ball_List[b]->yVel);
[/code] -
Hi, I got a ball hitting a paddle and I want it's X velocity to increase/decrease depending on where it hits the paddle. The code below works with whole numbers but not for numbers like "0.67" or "2.45". I'm looking for a way to animate objects moving at smaller increments for better precision. Thanks.
int speed=Ball_List[b]->speed;
// Paddle center.
int paddle_center = Player->Location.X + Player->Width / 2;// Ball center.
int ball_center = Ball_List[b]->gameBall->Location.X + Ball_List[b]->gameBall->Width / 2;// Find the location on the paddle that the ball hit
int paddle_location = ball_center - paddle_center;// change angle according to distance from center of paddle.
double a=(90-paddle_location);
double angle = (Math::PI / 180) * a; // angle in radians.
Ball_List[b]->xVel = speed*Math::Cos(angle);
Ball_List[b]->yVel = -speed*Math::Sin(angle);// Move the ball
Ball_List[b]->gameBall->Location = Point(Ball_List[b]->gameBall->Location.X + Ball_List[b]->xVel, Ball_List[b]->gameBall->Location.Y + Ball_List[b]->yVel);
[/code] -
I tried using doubles but for a value like 0.6 the ball doesn't move at all. The box control takes doubles but will round them down to the nearest integer. Is there a way to do this over the course of X number of frames? I'm using non-integers for the box control's position. Right now there's only about 6 different directions the ball takes when hitting the paddle. I need finer control over the speed of the ball. This problem happens with any sort of animation I try to do. What if I wanted smooth acceleration of a game object? This wouldn't be possible with the problem I'm encountering.
-
I tried using doubles but for a value like 0.6 the ball doesn't move at all. The box control takes doubles but will round them down to the nearest integer. Is there a way to do this over the course of X number of frames? I'm using non-integers for the box control's position. Right now there's only about 6 different directions the ball takes when hitting the paddle. I need finer control over the speed of the ball. This problem happens with any sort of animation I try to do. What if I wanted smooth acceleration of a game object? This wouldn't be possible with the problem I'm encountering.
Ah, okay gotcha. Well, in that case you can use floats or doubles for the position and the velocity. It's just a matter of rounding the position to an int before using it to display the ball. Or of course, you could keep an integer position of last impact, along with an integer number of frames since it occured and a double velocity, or position increment per frame. Each time you display, just show the ball at [impact.x + frames*velocity.x, impact.y + frames*velocity.y] But the easier is to just keep the position and velocity as doubles, converting to an int when using for display purposes. (You might also have to add code that will check if the ball is within a threshold distance, since non-integers will mean your ball wont hit the walls or paddle 'exactly' - well not at the exact moment of a frame, anyway.
-
Ah, okay gotcha. Well, in that case you can use floats or doubles for the position and the velocity. It's just a matter of rounding the position to an int before using it to display the ball. Or of course, you could keep an integer position of last impact, along with an integer number of frames since it occured and a double velocity, or position increment per frame. Each time you display, just show the ball at [impact.x + frames*velocity.x, impact.y + frames*velocity.y] But the easier is to just keep the position and velocity as doubles, converting to an int when using for display purposes. (You might also have to add code that will check if the ball is within a threshold distance, since non-integers will mean your ball wont hit the walls or paddle 'exactly' - well not at the exact moment of a frame, anyway.
I'm not sure I understand. Do you understand what I'm trying to do? after the ball hits the paddle it should move left/right depending on how far from the center it is. Just need finer precision on the angle(xvel) of the ball. Thanks. I tried something like this. I took a number like 1.65 and did
1.65 - Math::Floor(1.65)
to get just the decimal part of the number 0.65.Then every frame I added 0.65 to 0.65 and checked if it was >= 1. If it was I added 1.0 to the left/right property of the box. I then repeated that. The problem with it was I wasn't encounting for the speed of the ball. If the speed of the ball is 6 it moves 6 frames every timer tick. The code I was trying only moved 1 pixel at a time. I'm just not sure on the math to incorporate the speed into it.
-
I'm not sure I understand. Do you understand what I'm trying to do? after the ball hits the paddle it should move left/right depending on how far from the center it is. Just need finer precision on the angle(xvel) of the ball. Thanks. I tried something like this. I took a number like 1.65 and did
1.65 - Math::Floor(1.65)
to get just the decimal part of the number 0.65.Then every frame I added 0.65 to 0.65 and checked if it was >= 1. If it was I added 1.0 to the left/right property of the box. I then repeated that. The problem with it was I wasn't encounting for the speed of the ball. If the speed of the ball is 6 it moves 6 frames every timer tick. The code I was trying only moved 1 pixel at a time. I'm just not sure on the math to incorporate the speed into it.
Sorry about that. Um, I think I understand your intention. It sounds to me much like a game of pong or similar. Lord knows what I've done with my old code. I can't be bothered even think about the physics right now, but I've thrown together some code that will throw a red dot into a parabolic arc. In such a path, we'll have to both be able to have small increments of movement, and be able to vary them. You just have to assign the ball's velocity and position in an appropriate way for your application. Enjoy. :)
#include <windows.h>
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);/* Make the class name into a global variable */
= "CodeBlocksWindowsApp";int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass *//\* The Window structure \*/ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /\* This function is called by windows \*/ wincl.style = CS\_DBLCLKS; /\* Catch double-clicks \*/ wincl.cbSize = sizeof (WNDCLASSEX); /\* Use default icon and mouse-pointer \*/ wincl.hIcon = LoadIcon (NULL, IDI\_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI\_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC\_ARROW); wincl.lpszMenuName = NULL; /\* No menu \*/ wincl.cbClsExtra = 0; /\* No extra bytes after the window class \*/ wincl.cbWndExtra = 0; /\* structure or the window instance \*/ /\* Use Windows's default colour as the background of the window \*/ wincl.hbrBackground = (HBRUSH) COLOR\_BACKGROUND; /\* Register the window class, and if it fails quit the program \*/ if (!RegisterClassEx (&wincl)) return 0; /\* The class is registered, let's create the program\*/ hwnd = CreateWindowEx ( 0, /\* Extended possibilites for variation \*/ szClassName, /\* Classname \*/ "Click to release a ball", /\* Title Text \*/ WS\_OVERLAPPEDWINDOW, /\* default window \*/ CW\_USEDEFAULT, /\* Windows decid
-
I'm not sure I understand. Do you understand what I'm trying to do? after the ball hits the paddle it should move left/right depending on how far from the center it is. Just need finer precision on the angle(xvel) of the ball. Thanks. I tried something like this. I took a number like 1.65 and did
1.65 - Math::Floor(1.65)
to get just the decimal part of the number 0.65.Then every frame I added 0.65 to 0.65 and checked if it was >= 1. If it was I added 1.0 to the left/right property of the box. I then repeated that. The problem with it was I wasn't encounting for the speed of the ball. If the speed of the ball is 6 it moves 6 frames every timer tick. The code I was trying only moved 1 pixel at a time. I'm just not sure on the math to incorporate the speed into it.
I got bored. Here try if this if you like - it's two balls, a red one and a white one. If you hit the red one with the white one it will move in a direction away from the white one before being slowed to a halt by friction. Of course your collision handling stuff will be different(hopefully pixel-accurate, unlike mine) for the paddle and the ball, but it's the same concepts at work. :rose:
#include <math.h>
#include <windows.h>
#include <windowsx.h>
#include <wingdi.h>/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);void handleCollisions();
/* Make the class name into a global variable */
= "CodeBlocksWindowsApp";int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass *//\* The Window structure \*/ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /\* This function is called by windows \*/ wincl.style = CS\_DBLCLKS; /\* Catch double-clicks \*/ wincl.cbSize = sizeof (WNDCLASSEX); /\* Use default icon and mouse-pointer \*/ wincl.hIcon = LoadIcon (NULL, IDI\_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI\_APPLICATION); wincl.hCursor =LoadCursor (NULL, IDC\_ARROW); wincl.lpszMenuName = NULL; /\* No menu \*/ wincl.cbClsExtra = 0; /\* No extra bytes after the window class \*/ wincl.cbWndExtra = 0; /\* structure or the window instance \*/ /\* Use Windows's default colour as the background of the window \*/ wincl.hbrBackground = (HBRUSH) COLOR\_BACKGROUND; /\* Register the window class, and if it fails quit the program \*/ if (!RegisterClassEx (&wincl)) return 0; /\* The class is registered, let's create the program\*/ hwnd = CreateWindowEx ( 0, /\* Extended possibilites for variation \*/ szClassName, /\* Classname \*/ "Click to release a ball", /\* Title Text \*/ WS\_OVERLAPPEDWINDOW, /\* default window \*/ CW\_USEDEFAULT, /\* Windows decides the position \*/
-
I got bored. Here try if this if you like - it's two balls, a red one and a white one. If you hit the red one with the white one it will move in a direction away from the white one before being slowed to a halt by friction. Of course your collision handling stuff will be different(hopefully pixel-accurate, unlike mine) for the paddle and the ball, but it's the same concepts at work. :rose:
#include <math.h>
#include <windows.h>
#include <windowsx.h>
#include <wingdi.h>/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);void handleCollisions();
/* Make the class name into a global variable */
= "CodeBlocksWindowsApp";int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass *//\* The Window structure \*/ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /\* This function is called by windows \*/ wincl.style = CS\_DBLCLKS; /\* Catch double-clicks \*/ wincl.cbSize = sizeof (WNDCLASSEX); /\* Use default icon and mouse-pointer \*/ wincl.hIcon = LoadIcon (NULL, IDI\_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI\_APPLICATION); wincl.hCursor =LoadCursor (NULL, IDC\_ARROW); wincl.lpszMenuName = NULL; /\* No menu \*/ wincl.cbClsExtra = 0; /\* No extra bytes after the window class \*/ wincl.cbWndExtra = 0; /\* structure or the window instance \*/ /\* Use Windows's default colour as the background of the window \*/ wincl.hbrBackground = (HBRUSH) COLOR\_BACKGROUND; /\* Register the window class, and if it fails quit the program \*/ if (!RegisterClassEx (&wincl)) return 0; /\* The class is registered, let's create the program\*/ hwnd = CreateWindowEx ( 0, /\* Extended possibilites for variation \*/ szClassName, /\* Classname \*/ "Click to release a ball", /\* Title Text \*/ WS\_OVERLAPPEDWINDOW, /\* default window \*/ CW\_USEDEFAULT, /\* Windows decides the position \*/
Thanks for the examples. The first one has smooth transitions in motion. Exactly what I need. However I'm using .net(managed code) not winAPI. It seems .net rounds the floats down to a whole number? Would you be able to help me with the formula for moving an object using my previous post idea? Thanks.
-
Thanks for the examples. The first one has smooth transitions in motion. Exactly what I need. However I'm using .net(managed code) not winAPI. It seems .net rounds the floats down to a whole number? Would you be able to help me with the formula for moving an object using my previous post idea? Thanks.
That's okay. I had fun playing around with it.
Cyclone_S wrote:
However I'm using .net(managed code) not winAPI. It seems .net rounds the floats down to a whole number?
I'd be very surprised. You're not giving it the impression that this is your intention, by (I don't know, say) multiplying floats with ints - I've no idea what the result is - real or integer.. I don't understand, you have the formula for moving the ball. - BallPos += Velocity - You also have a way of applying gravity or friction - just alter the velocity. Perhaps you'd be better off in the right forum? Perhaps http://www.codeproject.com/Forums/3785/Managed-Cplusplus-CLI.aspx[^] or http://www.codeproject.com/Forums/1649/Csharp.aspx[^] All the best. :)