Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (575) Games in Android Showcase (154) games submitted by our members Games in WIP (624) 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 3457 times) 0 Members and 1 Guest are viewing this topic.
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
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.
alesky

Junior Devvie

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!
alesky

Junior Devvie

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)

Orangy Tang

JGO Kernel

Medals: 57
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 ]
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.
theagentd

« JGO Bitwise Duke »

Medals: 432
Projects: 2
Exp: 8 years

 « 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.
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.
theagentd

« JGO Bitwise Duke »

Medals: 432
Projects: 2
Exp: 8 years

 « 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!

Myomyomyo.
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
 Games published by our own members! Check 'em out!
theagentd

« JGO Bitwise Duke »

Medals: 432
Projects: 2
Exp: 8 years

 « 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.
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
Mandelbrot

Senior Newbie

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

Ok guys =) First i wish to thank you really much.
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 targetpublic 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
theagentd

« JGO Bitwise Duke »

Medals: 432
Projects: 2
Exp: 8 years

 « 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 thrownx = 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.

Junior Devvie

 « 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.
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
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.

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 positionpx = _player.getX();py = _player.getY();// grenade position x = px;y = py;// target positiontx = _target.getX();ty = _target.getY();// Delta (distance between target and player)dx =  (tx - px);dy =  (ty - py);// duration of the grenade move in msduration = 2000;// step is the number of cycle (update)step = (duration / Configuration.FRAMES_PER_SECOND);// x and y velocitiesvx = 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
theagentd

« JGO Bitwise Duke »

Medals: 432
Projects: 2
Exp: 8 years

 « 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 somethingin constructor(Point _player, Point _target){// player positionpx = _player.getX();py = _player.getY();// grenade position x = px;y = py;// target positiontx = _target.getX();ty = _target.getY();// Delta (distance between target and player)dx =  (tx - px);dy =  (ty - py);// duration of the grenade move in msduration = 2000;// step is the number of cycle (update)step = (duration / Configuration.FRAMES_PER_SECOND);// x, y and z velocitiesvx = 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.
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
theagentd

« JGO Bitwise Duke »

Medals: 432
Projects: 2
Exp: 8 years

 « Reply #20 - Posted 2012-10-24 23:35:39 »

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

Myomyomyo.
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 positiveint h_distance, velocity;int frames;int currframe = 0;boolean calculated = false;// the update methodpublic 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.

 ClaasJG (21 views) 2015-04-27 13:36:51 BurntPizza (33 views) 2015-04-23 03:42:11 theagentd (35 views) 2015-04-22 16:23:07 Riven (50 views) 2015-04-16 10:48:47 Duke0200 (59 views) 2015-04-16 01:59:01 Fairy Tailz (42 views) 2015-04-14 20:13:12 Riven (45 views) 2015-04-12 21:36:37 bus hotdog (61 views) 2015-04-10 02:39:32 CopyableCougar4 (66 views) 2015-04-10 00:51:04 BurntPizza (71 views) 2015-04-06 22:06:58
 theagentd 23x BurntPizza 17x wessles 15x 65K 11x kingroka123 11x alwex 11x kevglass 8x Rayvolution 7x Riven 7x chrislo27 7x Hanksha 7x Olo 7x Ecumene 7x ra4king 7x Spasi 6x KevinWorkman 6x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 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