Gamestudio Links
Zorro Links
Newest Posts
AlpacaZorroPlugin v1.3.0 Released
by kzhao. 05/20/24 20:05
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
3 registered members (kzhao, alibaba, 7th_zorro), 642 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
2D bouncing at an angle. SOLVED #298307
11/13/09 18:16
11/13/09 18:16
Joined: Oct 2008
Posts: 67
C
Crypton Offline OP
Junior Member
Crypton  Offline OP
Junior Member
C

Joined: Oct 2008
Posts: 67
Basically I'm creating a pong game for learning purposes and I have come to a point where I need to change direction of my "ball".

My question is, how could I calculate the angle that ball must bounce off when colliding with the defined edge and with platforms?

Right now I have something like this (inside function main):
//ball_dir is randomly generated value between 30 and 150.
Code:
//Move ball with a direction
         ballx += spd*cosv(ball_dir)*time_step;
         bally += spd*sinv(ball_dir)*time_step;
         
         //Collision with "walls"
         -------------------------------------
         if ((ballx > game_minx & ballx+6 < game_maxx)){ //game_minx = 1/3 of screen_size.x and game_maxx = 2/3 screen_size.x  
            
            ball_dir = ball_dir; //Keep the direction
         }else{//If out of boundaries
            ball_dir = (180 - abs(ball_dir)); //Change the direction
         }

         //Checking collision with platforms!
         if (rect_collision(P_ball.pos_x, P_ball.pos_y, P_ball.size_x, P_ball.size_y, P_ai.pos_x, P_ai.pos_y, P_ai.size_x, P_ai.size_y)
            | rect_collision(P_ball.pos_x, P_ball.pos_y, P_ball.size_x, P_ball.size_y, P_player.pos_x, P_player.pos_y, P_player.size_x, P_player.size_y)){
            ball_dir = (180 - abs(ball_dir)); //Trying to change dir here.
         }



But (180 - dir) doesn't always work. I have also searched the internet for vectors to calculate new vector to move on, but I don't know how to implement them in LiteC or is it even practical in this case.

Any suggestion solving this?

Last edited by Crypton; 11/18/09 20:29. Reason: solved

New into Gamestudio and eager to learn it..
Stuff and games done in 2D: LINK
Re: 2D bouncing at an angle. [Re: Crypton] #298315
11/13/09 19:38
11/13/09 19:38
Joined: Oct 2009
Posts: 149
Germany
M
muffel Offline
Member
muffel  Offline
Member
M

Joined: Oct 2009
Posts: 149
Germany
I would use vec_bounce

muffel

Re: 2D bouncing at an angle. [Re: muffel] #298316
11/13/09 19:41
11/13/09 19:41
Joined: Feb 2009
Posts: 3,207
Germany, Magdeburg
Rei_Ayanami Offline
Expert
Rei_Ayanami  Offline
Expert

Joined: Feb 2009
Posts: 3,207
Germany, Magdeburg
i think this doesn't work in 2D wink

Re: 2D bouncing at an angle. [Re: Rei_Ayanami] #298318
11/13/09 19:47
11/13/09 19:47
Joined: Oct 2009
Posts: 149
Germany
M
muffel Offline
Member
muffel  Offline
Member
M

Joined: Oct 2009
Posts: 149
Germany
why??
if you sets the z-value allways to zero, it should work in 2D, I think.

muffel

Re: 2D bouncing at an angle. [Re: muffel] #298338
11/14/09 11:04
11/14/09 11:04
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline
Expert
Joey  Offline
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
you have to mirror the colliding direction along the normal. that's simple and works in every dimension, given you're in hilbert space.

n normal
c colliding vector
b bouncing vector

b = |<c,n>|*n + (c+|<c,n>|*n) = 2*|<c,n>|*n + c

to implement it you only need to know that |<,>| is abs(vec_dot(...)) here and the normal points away from the surface and has length 1 (use vec_normalize).

sample:
your screen has coordinates x growing from left to right, y from top to bottom. your ball has speed (5,3), the normal of your right screen side is (-1,0). then b is
b = 2*|<(5,3),(-1,0)>|*(-1,0) + (5,3) = 2*|5*(-1)+3*0|*(-1,0) + (5,3) = 10*(-1,0) + (5,3) = (-5,3)
as expected.

another example. your surface normal is angular in the top left, so the normal is something like (3,4)/5 (this is normalized to 1!). your ball has speed (-3,-10), so b is
b = 2*|<(3,4)/5,(-3,-10)>|*(3,4)/5 + (-3,-10) = 2*|(-9/5-40/5)|*(3,4)/5 + (-3,-10) = (8.76,5.68)
and again the length is preserved, as expected.

i hope you get it done now wink

greetings, joey.

edit: if you want to use your own variables, not vectors, know that
|<a,b>| = abs(ax*bx + ay*by)
as i used it in the examples. normalizing surface vectors can also be done by hand, just use
n_normalized = n / |<n,n>| = n / ||n||

Re: 2D bouncing at an angle. [Re: Joey] #298387
11/14/09 16:17
11/14/09 16:17
Joined: Oct 2008
Posts: 67
C
Crypton Offline OP
Junior Member
Crypton  Offline OP
Junior Member
C

Joined: Oct 2008
Posts: 67
Thanks! Seems logical enough but still having problems implementing.
basically as I can see that formula is calculated by vec_bounce, so i tried to use it. Doesn't work the way it should..

Tried to make
VECTOR vBall;
definitions for my ball vector but engine started crashing.

So I tried with this, seems logical to me. The LiteC version of your given formula:
vec_cross(vBall, 2*abs(vec_dot(vBall, vector(1,0,0))), vector(1,0,0));


//EDIT:
Tried also with


if (vBall[1]+6 > game_maxx){ //Right side of the game area
var a = 2*abs(vec_dot(vBall, vector(1,0,0)));
vBall = vec_scale(vBall, a);
vBall = vec_add(vBall, vBall);
}

as I forgot to add vBall at the end. But still, same effect.





Snippet consisting parts with ball:
(Collision part is somewhere in the middle of main()

Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>

var ball_dir;
var ballx;
var bally;

var vBall[3];
var spd = 20;

var game_start = 0;
var game_minx = 267;
var game_maxx = 533;



PANEL* P_player =
{
   //pos_x = 0; 
   pos_y = 550;
   size_x = 100;
   size_y = 10;
   flags = SHOW | LIGHT;
}

PANEL* P_ai =
{
   pos_x = 0;
   pos_y = 50;
   size_x = 100;
   size_y = 10;
   flags = SHOW | LIGHT;
} 

PANEL* P_ball =
{
   pos_x = 0;
   pos_y = 0;
   size_x = 6;
   size_y = 6; 
   flags = SHOW | LIGHT;
}

function rect_collision(var x1, var y1, var w1, var h1, var x2, var y2, var w2, var h2)
{ 
   
	if (x1 > (x2 + w2) | (x1 + w1) < x2){return (0);}
	if (y1 > (y2 + h2) | (y1 + h1) < y2){return (0);}
	return (1);
}

function hcenter_panel(PANEL* panel)
{
   panel.pos_x = (screen_size.x - panel.size_x)/2;
   //panel.pos_y = (screen_size.y - panel.size_y)/2;
}

function launch_ball()
{
   ball_dir = -60; //-random2(30, 150);
   vBall = vector(spd*cosv(ball_dir)*time_step, spd*sinv(ball_dir)*time_step, 0);
}

function trace_mouse(PANEL* panel)
{
   panel.pos_x = mouse_pos.x-50;
   panel.pos_x = clamp(panel.pos_x,game_minx, game_maxx-100);
}

//==============================================================================================
function main()
{
   video_mode = 7; 
   mouse_mode = 4; 
   random_seed(0);
   wait(3);
   
   hcenter_panel(P_player);
   hcenter_panel(P_ai);
   vec_set(P_ball.blue,vector(0,0,200));
   
   while(1)
   {
      
      trace_mouse(P_player); //move platform with the mouse
      
      
      if (game_start == 0){
         
         //ball is moving with the platform. Works!
         vBall[1] = P_player.pos_x + (P_player.size_x/2) - 3;
         vBall[2] = P_player.pos_y - P_ball.size_y - 1;
         
         //Hitting a left button launches the ball
         if (mouse_left == 1){
         launch_ball();
         game_start = 1;
         }
         
      }else{
         //Keep the ball moving. Wroks!
         vBall[1] += spd*cosv(ball_dir)*time_step;
         vBall[2] += spd*sinv(ball_dir)*time_step;
         
         
         //Collision with walls! ------------------------------------
         if (vBall[1] < game_minx){ //Left side of the game area
         vec_cross(vBall, 2*abs(vec_dot(vBall, vector(1,0,0))), vector(1,0,0));
         //vec_bounce(vBall, vector(1,0,0));
         }
         
         if (vBall[1]+6 > game_maxx){ //Right side of the game area
         vec_cross(vBall, 2*abs(vec_dot(vBall, vector(-1,0,0))), vector(-1,0,0));
         //vec_bounce(vBall, vector(-1,0,0));
         }

         
         if (rect_collision(P_ball.pos_x, P_ball.pos_y, P_ball.size_x, P_ball.size_y, P_ai.pos_x, P_ai.pos_y, P_ai.size_x, P_ai.size_y)
            | rect_collision(P_ball.pos_x, P_ball.pos_y, P_ball.size_x, P_ball.size_y, P_player.pos_x, P_player.pos_y, P_player.size_x, P_player.size_y)){
            //ball_dir = (180 - abs(ball_dir));
         }
         //-----------------------------------------------------------
      }
      //Keep the panel moving along those coordinates
      P_ball.pos_x = vBall[1]; //ballx;
      P_ball.pos_y = vBall[2]; //bally;
      
      //moving AI Platform.
      P_ai.pos_x = P_ball.pos_x - ((P_ai.size_x-P_ball.size_x)/2);
      P_ai.pos_x = clamp(P_ai.pos_x,game_minx, game_maxx-100);
      
            
      draw_line(vector(game_minx,0,0),NULL,100); // move to first corner   
      draw_line(vector(game_maxx,0,0),vector(0,0,255),100);   
      draw_line(vector(game_maxx,599,0),vector(0,0,255),100);   
      draw_line(vector(game_minx,599,0),vector(0,0,255),100);   
      draw_line(vector(game_minx,0,0),vector(0,0,255),100);
      
   wait(1);
   }
   
}
//==============================================================================================



Looking forward to know what i'm doing wrong.


New into Gamestudio and eager to learn it..
Stuff and games done in 2D: LINK
Re: 2D bouncing at an angle. [Re: Crypton] #298411
11/14/09 19:57
11/14/09 19:57
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline
Expert
Joey  Offline
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
it has nothing to do with the cross product. why haven't you tried implementing it word by word as i posted above? it's always slightly modified (which makes it not working). you have to be more careful.

vBall = vec_scale(vBall, a);

i'm not scaling vBall but the normal, this line is wrong. also your normal seems to be pointing in the wrong direction (or it is correct and your coordinate system is different. i just thought i should mention it).

joey

Re: 2D bouncing at an angle. [Re: Joey] #298415
11/14/09 21:19
11/14/09 21:19
Joined: Oct 2008
Posts: 67
C
Crypton Offline OP
Junior Member
Crypton  Offline OP
Junior Member
C

Joined: Oct 2008
Posts: 67
mm yes I got carried away. Didn't think that LiteC was able to multiply vectors like that and looked depthlessly into cross like a multiplication, just got known about it tongue. My code has changed a lot since my last post.

I actually have been able to get the calculation right:

Code:
[code]var c[3] = {480, 543, 0};
var n[3] = {-1, 0, 0};
var b[3];

//n = vec_normalize(n,1);
// b = 2*|<c,n>|*n + c  Bounce vector's formula.
var a;

function main()
{
   video_mode = 7;
   wait(3);
   
   a = 2*abs(vec_dot(c, n));
   vec_set(b, vector(a*n[0], a*n[1],0));
   vec_add(b, c);
}



This is giving me right answers. But Placing it into my pong thing, it won't do the same job.

Code:
//Collision with walls! ------------------------------------
         if (vBall[0] < game_minx){ //Left side of the game area
         
         // b = 2*|<c,n>|*n + c  Bounce vector's formula.
         //Into Parts:
         //a = 2*|c,n|
         //we change (0,0,0) to (a*(-1), a*0, 0) with vec_set
         //add (480, 543,0) and (-a, 0, 0)
         a = 2*abs(vec_dot(vBall, nvec_minx));
            vec_set(vBounce, vector(a*nvec_minx[0], a*nvec_minx[1],0));
            vec_add(vBall, vBounce);

         }



I personally think my movement code for the ball is messing things up, but I can't see any other way of moving my ball...

//Keep the ball moving.
vBall[0] += spd*cosv(ball_dir)*time_step;
vBall[1] += spd*sinv(ball_dir)*time_step;

...to be more precise. I think that bounce vector is right but I can't make it influence ball's movement.

Last edited by Crypton; 11/14/09 21:35.

New into Gamestudio and eager to learn it..
Stuff and games done in 2D: LINK
Re: 2D bouncing at an angle. [Re: Crypton] #298432
11/14/09 23:39
11/14/09 23:39
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline
Expert
Joey  Offline
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
yes, well, you have to alter ball_dir... lol. if you'd said that earlier...

given ball_dir is measured in degrees, starting at 0 when the ball flies to the right and moving counter-clockwise when increasing (90° means up).
then you use a surface angle alpha, measured the same (horizontal plane has 0°, left and right window plane 90°. then you just use

ball_dir += 2*(alpha - ball_dir);

joey.

by the way, the first method is more flexible since you can get surface normals via tracing.

Re: 2D bouncing at an angle. [Re: Joey] #298446
11/15/09 03:30
11/15/09 03:30
Joined: Nov 2009
Posts: 34
S
Sepiantum Offline
Newbie
Sepiantum  Offline
Newbie
S

Joined: Nov 2009
Posts: 34
ball_dir = -ball_dir;

Page 1 of 2 1 2

Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1