Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (495)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Shooting a grenade  (Read 3115 times)
0 Members and 1 Guest are viewing this topic.
Offline Mandelbrot

Senior Newbie





« Posted 2012-10-23 09:20:55 »

Hi everybody,

I'm working on a tiled based game,
In this game there are a player and a bot.

Actually the player can shot the target with a straight shot

The shots properties looks like something like that:

1  
2  
3  
4  
dx = target.x - player.x ;
dy = target.y - player.y ;
x = player.x + velocity * dx;
y = player.y + velocity * dy;


But now, i wish the player shot a grenade on the target.

Something like that :


My problem is that i don't know how to make a parabola between two points when the Y are differents.

If someone have an idea, i 'll be happy.
Thank.

-----------------------------------------------------
I am French, be indulgent with my written words please
Offline Phased
« Reply #1 - Posted 2012-10-23 09:24:11 »

Best might be some projectile motion physics equations may help, I'm not to sure.
Offline alesky

Junior Member


Medals: 3
Exp: 15 years


mmm....


« Reply #2 - Posted 2012-10-23 09:39:11 »

may be you can use this b-spline algorith that i designed
this is the link

you will need only to define 3 point and it will create the curve for you
your will need only to draw the sprite for the point the te algorithm will give you until the end of the path

you can use
1) start point  (same coordinate of first sprite)
2) intermediant point bertween the two sprite
3) end point (same coordinate of target sprite)

this could be nice also becouse the speed is not costant during the path and will create something like 3d effect

http://www.java-gaming.org/topics/static-path-builder-object-for-2d/27600/view.html


Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline alesky

Junior Member


Medals: 3
Exp: 15 years


mmm....


« Reply #3 - Posted 2012-10-23 10:01:09 »

i created a test to verify if the desing was good with my implemention

with Bspline your only question is to find a common way to determine the intermediant point
i found this equation

T= targer
P=Plyaer
I= intermediant point

case if T.y < P.y
Ix = P.x +  2/3 (T.x-P.x)
Iy = T.y+(1/3 (T.y-P.y))

case if T.y > P.y
Ix = P.x + 1/3 (T.x-P.x)
Iy = P.y+(1/3 (P.y-T.y))

case if T.y = P.y
Ix = P.x + 1/2 (T.x-P.x)
Iy = P.y + 1/2 (T.x-P.x)

 
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #4 - Posted 2012-10-23 12:24:12 »

This isn't too hard once you realise the way to do it is to split the movement into it's horizontal and vertical components. For simplicity we'll assume 3d, and you can translate that into your 2d perspective however you like.

Your inputs will be your start and end positions, and gravity. Your output you're trying to find will be the launch velocity you need to give to the projectile. Once you've got that, you can simulate it's movement under gravity the normal way and it'll hit the target.

First, you need to solve horizontally:

Ye olde movement equation:
s = ut + 0.5at^2

Horizontally we have no acceleration, so eliminate 0.5at^2

We can calculate distance s by finding the vector between the start and end points, then calculating it's length.

Then we pick an arbitrary speed that we want it to move along the ground, substitute in and we can work out t, the time it will take to go from start point to end point.

Vertically:
s = ut + 0.5at^2

We want to start and end at the same height, so distance s is zero.
Acceleration is just gravity (careful of the sign).
Time we know from the horizontal calculation.

That simply gives us an equation with just unknown vertical speed u:
u = (-0.5 * gravity * time)^2) / time

You calculate that u, and that's your vertical speed. So now your launch velocity is just the horizontal speed and the vertical speed. Done!

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #5 - Posted 2012-10-23 12:42:25 »

Your code makes the granade go fast at the beginning, goig slower and slower at the end, this is not how an thrown object behaves.


First load the degrees and speed (at the initialisation, these stay the same).

1  
2  
3  
4  
float degrees = (float)Math.atan2(target.y - player.y, target.x - player.x);

xspeed = (float)(-velocity*(Math.cos(rotation) - Math.sin(rotation)));
yspeed = (float)(velocity*(Math.sin(rotation) + Math.cos(rotation)));


Now the throwing speed is constant, so no delays at the beginning or end.
Now you just have to calculate an halve circle (z) depending on where the granade is between the enemy and the player.
Add the value of z to the y position whe drawing the granade and done.
Offline theagentd
« Reply #6 - Posted 2012-10-23 13:53:37 »

Your code makes the granade go fast at the beginning, goig slower and slower at the end, this is not how an thrown object behaves.


First load the degrees and speed (at the initialisation, these stay the same).

1  
2  
3  
4  
float degrees = (float)Math.atan2(target.y - player.y, target.x - player.x);

xspeed = (float)(-velocity*(Math.cos(rotation) - Math.sin(rotation)));
yspeed = (float)(velocity*(Math.sin(rotation) + Math.cos(rotation)));


Now the throwing speed is constant, so no delays at the beginning or end.
Now you just have to calculate an halve circle (z) depending on where the granade is between the enemy and the player.
Add the value of z to the y position whe drawing the granade and done.



It's better to at least reuse sin and cos between the two, but it's even better to just calculate the direction vector instead. One sqrt is better than an atan2 + sin + cos.

1  
2  
3  
4  
5  
float dx =  target.x - player.x, dy = target.y - player.y;
float multiplier = velocity / (float)sqrt(dx*dx + dy*dy);

xspeed = dx * multiplier;
yspeed = dy * multiplier;

Myomyomyo.
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #7 - Posted 2012-10-23 16:29:03 »

Yeah math isnt my best, i understand your code is faster then mine.
But i was just giving a simple example.
Offline theagentd
« Reply #8 - Posted 2012-10-23 17:53:40 »

Yeah math isnt my best, i understand your code is faster then mine.
But i was just giving a simple example.
I know. I did it your way in the beginning too, so don't take it personally!  persecutioncomplex

Myomyomyo.
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #9 - Posted 2012-10-23 18:02:03 »

Your version is good for some calculations, but in most cases i need the rotation for the images anyways.
I just copied the code from the gun rotation of my game Smiley
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd
« Reply #10 - Posted 2012-10-23 18:20:19 »

In that case I still think it's faster to do a separate atan2() to get the angle and still use the vector approach, since I'm fairly sure sqrt() is faster than sin() + cos().

Myomyomyo.
Offline RobinB

JGO Ninja


Medals: 44
Projects: 1
Exp: 3 years


Spacegame in progress


« Reply #11 - Posted 2012-10-23 19:01:02 »

I see, i thought creating new variables would be costly, but im wrong.
Your function would make each call 20 times faster than my function, even with only one sin + cos.
Awsome, learned a new trick haha Smiley
Offline Mandelbrot

Senior Newbie





« Reply #12 - Posted 2012-10-23 19:29:37 »

Ok guys =) First i wish to thank you really much.
Thanks for your answers.
Great forum, Great people !
Ok, so, i saw yours answers, but It’s not yet absolutely good for me.
I note I’m in the good to topic : Newbie and debugging ^^

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
My constructor : 
//The Points are the nodes references, cases where are player and target
public ShotPlayer(Game _game, Point _player, Point _target)
{
   // px py tx and ty are the positions in pixel on the frame
  // player position in pixel (the center of the case)
  px = (_player.getX() * Configuration.CASE_WIDTH) + (Configuration.CASE_WIDTH / 2);
   py = (_player.getY() * Configuration.CASE_HEIGHT) + (Configuration.CASE_HEIGHT / 2);
   // target position in pixel (the center of the case)
  tx = (_target.getX() * Configuration.CASE_WIDTH) + (Configuration.CASE_WIDTH / 2);
   ty = (_target.getY()* Configuration.CASE_HEIGHT) + (Configuration.CASE_HEIGHT / 2);
   // Delta (distance between target and player
  dx = tx- px;
   dy = ty - py;
   // Position of the grenade
  x = px;
   y = py;
}



1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
public void update() 
{
if (x > Configuration.WINDOW_WIDTH || y > Configuration.WINDOW_HEIGHT || y < 0 || x < 0 )
   game.removeShotsPlayerEntity(this);
   else
   {
// It is here where i must update the position of the grenade.
// I delete my linear function (the straight shot)
// But I didn’t know how to implement yours code… Sorry…
// Do you think the structure is good ?
// Do you think I’ll clear my pb… I wish
}
}


If you could still help me...



-----------------------------------------------------
I am French, be indulgent with my written words please
Offline theagentd
« Reply #13 - Posted 2012-10-23 20:29:16 »

I haven't read this whole thread but here goes.

You have x and y, and you know the direction to the target, the distance (break out sqrt(dx*dx + dy*dy) into a variable) and the (2D) velocity. From this you can calculate the time it takes from it to get from the thrower to the target (time = distance / velocity). Since what you're trying to do is throw a grenade in 3D, you have to do the calculations in 3D. We just add a third coordinate Z which represent the height the grenade is above ground. We then do the calculations that Orangy Tang posted to calculate the start velocity U (u = (-0.5 * gravity * time)^2) / time). With this we can use the original formula (s = ut + 0.5at^2) to calculate at what height the grenade is at at a certain time t.

The whole thing looks something like this (untested):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
//When thrown, calculate these once:

float dx =  target.x - player.x, dy = target.y - player.y;
float distance (float)sqrt(dx*dx + dy*dy);
float multiplier = velocity / distance;

float xSpeed = dx * multiplier;
float ySpeed = dy * multiplier;

float totalAirTime = distance / velocity;

float temp = -0.5 * GRAVITY * totalAirTime;
float upSpeed = (temp * temp) / totalAirTime;


//Each frame calculate these. time is the time that has passed since it was thrown

x = player.x + xSpeed * time; //The bug was here. Old: x = xSpeed*time;
y = player.y + ySpeed * time; //And here. Old: y = ySpeed*time;
z = upSpeed * time + 0.5 * GRAVITY * time * time;

//Then just draw the grenade at x, y-z. y-z moves the grenade "up" based on the z coordinate, which should give you the effect of speed.
drawGrenade(x, y-z);


GRAVITY should be a constant for the gravity applied to all grenades. It controls the force the grenade is thrown at upwards (higher gravity must be countered by a higher throwing force). You'll have to experiment. You can even try with 0 gravity or negative gravity. =S

Good luck!

Myomyomyo.
Offline Best Username Ever

Junior Member





« Reply #14 - Posted 2012-10-23 21:27:03 »

You need to work in three dimensions. Use parametric projectile physics to get a simple and accurate projectile path. Your overhead view probably emulates an angled view instead of a direct overhead view. (If you were using a direct overhead view, then you would basically only see the tops of characters' heads and you could throw grenades on straight line paths instead of parabolas. You're probably using an angled view, of course, judging by the sign.) Use theagentd's code. You may need to change the coefficients of y - z part depending on the view angle and other projection-related stuff.
Offline Mandelbrot

Senior Newbie





« Reply #15 - Posted 2012-10-24 04:47:18 »

Thanks a lot,
i'll try to finish it today (after work)
thanks you for yours answers =)
It was great help for me.
I'll say you when it'll be good.

-----------------------------------------------------
I am French, be indulgent with my written words please
Offline SHC
« Reply #16 - Posted 2012-10-24 08:39:48 »

Try this
1. Calculate the horizontal distance.
2. Calculate the no. of frames to reach the destination.
       
1  
int nframes = h_dist/velocity;

3. For half the frames move up along with horizontal dist and go down for the next half frames.

Offline Mandelbrot

Senior Newbie





« Reply #17 - Posted 2012-10-24 11:50:10 »

Hi,

SHC your solution is simple,
but how i tried it.
The result is too straight.

The agent D, i like your solution, but i do not understand all of it.
I can not define the velocity and le gravity and the temp.

I'll stop to annoy you with my grenade throwing.
I'll continu and when i 'll have the solution, i'll post it here =)

To be continue...


If someone want to shoot a target whith a define duration, i do that :


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
in constructor(Point _player, Point _target)
{
// player position
px = _player.getX();
py = _player.getY();

// grenade position
x = px;
y = py;

// target position
tx = _target.getX();
ty = _target.getY();

// Delta (distance between target and player)
dx =  (tx - px);
dy =  (ty - py);

// duration of the grenade move in ms
duration = 2000;
// step is the number of cycle (update)
step = (duration / Configuration.FRAMES_PER_SECOND);


// x and y velocities
vx = dx / step;
vy = dy / step;
}


in update()
{
x += vx;
y += vy;
}


that's all I can do for now =)

-----------------------------------------------------
I am French, be indulgent with my written words please
Offline theagentd
« Reply #18 - Posted 2012-10-24 12:07:58 »

@Mandelbrot

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
private static final float GRAVITY = 0.1f; //or something

in constructor(Point _player, Point _target)
{
// player position
px = _player.getX();
py = _player.getY();

// grenade position
x = px;
y = py;

// target position
tx = _target.getX();
ty = _target.getY();

// Delta (distance between target and player)
dx =  (tx - px);
dy =  (ty - py);

// duration of the grenade move in ms
duration = 2000;
// step is the number of cycle (update)
step = (duration / Configuration.FRAMES_PER_SECOND);


// x, y and z velocities
vx = dx / step;
vy = dy / step;
float temp = -0.5 * GRAVITY * step;
vz = (temp * temp) / step;
}


int ticks = 0;

in update()
{
ticks++;
x = px + vx * ticks;
y = py + vy * ticks;
z = vz * ticks + 0.5 * GRAVITY * ticks * ticks;
}

in draw()
{
//Draw the grenade at (x, y-z) instead of just at (x, y)
}


Does that help? Just add a z variable and a vz variable, and change your draw code to draw the grenade at (x, y-z).

(There was a bug concerning how I calculated the x and y positions in the original code which has been edited and fixed.)

Myomyomyo.
Offline Mandelbrot

Senior Newbie





« Reply #19 - Posted 2012-10-24 16:13:38 »

Hello, I understand the principle.

Bravo, nice explanation.
The result is not yet perfect.
But it now looks like something.
As you pointed out, the grenade flies.
I finish studying the issue.

Thank you for your help.
I hope it could help other people

-----------------------------------------------------
I am French, be indulgent with my written words please
Offline theagentd
« Reply #20 - Posted 2012-10-24 23:35:39 »

Try to adjust the gravity, that should do the trick. =S

Myomyomyo.
Offline SHC
« Reply #21 - Posted 2012-10-26 02:48:33 »

Here's a code example.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
int curr_x, curr_y;
int target_x, target_y;

// Assuming that velocity is positive
int h_distance, velocity;

int frames;

int currframe = 0;

boolean calculated = false;
// the update method
public void update(){
    if (!calculated){
        h_distance = Math.abs(target_x - curr_x);
        frames = h_distance/velocity;
        calculated = true;
    }
    currframe++;
    curr_x += velocity;
    if (currframe<(frames/2)){
        // Move up
       curr_y -= 2; // Adjust it to suit your needs
   } else {
        // Move down
       curr_y += 2;
    }
}


This had worked for me.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Dwinin (28 views)
2014-09-12 09:08:26

Norakomi (57 views)
2014-09-10 13:57:51

TehJavaDev (72 views)
2014-09-10 06:39:09

Tekkerue (37 views)
2014-09-09 02:24:56

mitcheeb (57 views)
2014-09-08 06:06:29

BurntPizza (43 views)
2014-09-07 01:13:42

Longarmx (27 views)
2014-09-07 01:12:14

Longarmx (34 views)
2014-09-07 01:11:22

Longarmx (34 views)
2014-09-07 01:10:19

mitcheeb (40 views)
2014-09-04 23:08:59
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!