Java-Gaming.org Hi !
 Featured games (90) games approved by the League of Dukes Games in Showcase (777) Games in Android Showcase (231) games submitted by our members Games in WIP (856) 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
 Damage Formula  (Read 11929 times) 0 Members and 1 Guest are viewing this topic.
neoskunk

Junior Devvie

 « Posted 2008-10-22 04:30:14 »

i have a game such that you choose angle and power and try to hit your opponent.   i currently calculate the distance the ball lands from the players.   what is a good formula anyone has used relating distance to the amount of damage the player recieves?
CommanderKeith
 « Reply #1 - Posted 2008-10-22 09:18:27 »

Maybe bullet speed would be a good one? So low-arc long distance shots will be powerful, and so will high-arc mortar-style shots.

SwampChicken
 « Reply #2 - Posted 2008-10-22 09:39:01 »

is gravity involved?
 Games published by our own members! Check 'em out!
neoskunk

Junior Devvie

 « Reply #3 - Posted 2008-10-22 18:03:16 »

yes gravity is involved.
Riven

« JGO Overlord »

Medals: 1357
Projects: 4
Exp: 16 years

 « Reply #4 - Posted 2008-10-22 19:02:18 »

extremely simply put:

damage = impact + explosion force

impact = velocity * mass
or
impact = velocity * mass * dot(target face normal, bullet heading normal) / target absorbtion

explosion force in 3D = explosion energy / distance^3
explosion force in 2D = explosion energy / distance^2

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #5 - Posted 2008-10-22 19:40:28 »

If you're talking about distance-related damage (as I believe you are), then you can either make the damage lifetime-based (which I recommend) or you can calculate the length of the bullet's travel path in order to scale the damage, which will be more accurate for your purposes (very fast bullets over a long distance do more damage than one fired straight up at a slow speed), but more costly (you've got to calculate Euclidean distances several times per shot).

With lifetime-based, all you need to do is store the bullet's birth time when it is first created, then when it hits something apply damage that is somehow relative to the current time minus its birth time.

With length-based, you'll need to store a variable that contains the total length of the travel path, then every X milliseconds find the distance between the last polled point and the current point and then add it to the total. Finally when the bullet hits do this one more time and use the resulting total to apply the damage.

Now if I'm reading this totally wrong and you basically want the bullets to have an explosion radius when they land and anything towards the inside of the explosion is hurt more than stuff on the outside, all you need to do is, upon impact, find anything within the explosion radius and then say damage = (distanceToObject / explosionRadius) * maximumExplosionDamage.

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #6 - Posted 2008-10-23 00:14:05 »

wow thanks for all the replies i didnt know there were so many ways to implement this.  for now i think i will keep it simple and use the last formula you gave demon.  i have a quick question on collision detection too.   currently i am using rectangles for collision detection.   however, in certain situations, particularly when the bullet is shot with more power(aka a larger change in x per frame) the game will not detect the collision until the bullet is inside the bounding rectangle.  is there a good way around this?  i was thinking maybe decrease change in x per frame and increase frame rate ?
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #7 - Posted 2008-10-23 02:32:52 »

Ah, now collision detection I could talk about for hours and hours. There are plenty of good ways and plenty of bad ways to do collision detection, but in general the more accurate it is the more processor you're going to need. The method you're using right now uses what are called AABB's or Axis Aligned Bounding Boxes. Typically a smart way to do it is have increasing levels of precision – first you use AABB's, then if there is collision along the AABB, you next check to see if there is collision along the actual objects geometry (typically complex geometric solids), etc.

But that's not really going to answer your question. If AABB's are enough for you, then that's fine. The problem you've found will happen if you are moving your objects discretely. Moving something discretely means that you're moving it in sort of instantaneous intervals – the object goes immediately from X to X + Velocity. This obviously isn't how the real world works and will cause problems for any velocity changes that are even slightly large. What you want is a continuous change. The problem is that because you're using a discrete system (a computer with a timer), you can only simulate continuous change. There are a lot of different ways to do this, but in order to do any of them you've got to know something about the level's geometry.

If everything is considered a square, then you can easily determine if you're going to hit one by projecting a ray out the distance you're expecting to go. This is pretty easy to do. I'm out of time for the moment, but check out:

http://www.harveycartel.org/metanet/tutorials/tutorialA.html

It's a great tutorial on a way to do collision detection.

Alternatively, you can pretend you don't know the level geometry at all (like in the scenario of the Worms games where collision happens on a bitmap image), and brute force it. This is easier so you might want to do this. Basically, instead of moving your object to X + Velocity, you make a loop to move it X + 1pixel until you reach X + Velocity or until it hits something.

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #8 - Posted 2008-10-23 03:21:01 »

This is a rough sketch of my game board....

Let me elaborate a bit first.  The problem was that the explosion would happen inside the blue boxs or below ground level.  To get rid of this problem on the ground i simply
draw the explosion at (Y,getXPos()(of ball)).  Thus the explosion always happens right at ground level and changes x according to where the ball collides.

the main problem i run into is that the center and side blocks can be hit from left, right, or top.   i cant use the solution i used on the ground becuase the ground can only be hit from one side.

is there a way to determine what side of the block the balll collides with?  and if there is a much easier way to do this please explain.  I am perfectly content with just AABB as you mention above.  It does not need to involve complex geometric shapes.
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #9 - Posted 2008-10-23 04:24:42 »

Yes, you can do what I briefly mentioned at the end.

Normally, you move your bullet like so:
 1 `bullet.position += bullet.velocity;`

Instead you want to move it pixel by pixel. Assuming your velocity is measured in pixels (which I assume it is), you'd do it like this:
 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 `//Store our destination vector (position).Vector destination = bullet.position + bullet.velocity;//Store the normalized velocity vector so that we move only one pixel at a time.Vector change = new Vector(bullet.velocity.x / bullet.velocity.magnitude, bullet.velocity.y / bullet.velocity.magnitude);//Now move the bullet along until we reach our destination or hit something.while (bullet.position != destination){     Vector lastPosition = bullet.position;     if (Math.abs(destination.x - bullet.position.x) < change.x)          bullet.position.x = destination.x;     else          bullet.position.x += change.x;     if (Math.abs(destination.y - bullet.position.y) < change.y)          bullet.position.y = destination.y;     else          bullet.position.y += change.y;     if (bullet.collidesWithSomething())     {          bullet.position = lastPosition;          break;     }}`

That code won't really run as is but it should give you the idea of what you want to do. Basically you move it at small increments until it hits something. Then you don't ever have to worry about being stuck inside something so you won't have to move it on top.

If you do still want to move stuff on top, then all you need to do is have a maximum distance you can move the Y at one time in terms of adjustment (like 10 pixels or something), then if in order to clear the rectangle you're colliding with you've got to move up more than 10 pixels, that means you are actually hitting the side of the block, so you calculate reflection and don't allow it to move in the first place.

See my work:
OTC Software
 Games published by our own members! Check 'em out!
neoskunk

Junior Devvie

 « Reply #10 - Posted 2008-10-23 20:12:04 »

ok that makes sense however im a little confused.  as it stands now to move the ball i have something like this....

 1  2  3  4 `locx += dx;locy += dy;drawImage(whatever,locx,locy);`

i dont have the movement down to a single variable velocity as it looks like you say.
I could probably calculate the velocity vector given the above information but is that necessary?

also won't moving the bullet a pixel at a time make it appear to be moving much slower than before?
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #11 - Posted 2008-10-23 21:23:43 »

Nah, you can do it like you have it rather than having one velocity variable.

Basically just do the exactly above but think of dx as velocity.x and dy as velocity.y.

For any Vector you create up there you just need two floats, one for the X and one for the Y.

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #12 - Posted 2008-10-23 22:50:55 »

how would i go about calculating the magnitude the way im doing it?
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #13 - Posted 2008-10-24 01:36:29 »

how would i go about calculating the magnitude the way im doing it?
The magnitude of a vector is also called its length. Think of a right triangle. A right triangle is formed of two legs and a hypotenuse. If you align the triangle so that one leg is the Y axis and another leg is the X axis, then you are effectively representing a vector. The length of the leg on the X axis is the X component (for you, dx), and the length of the leg on the Y axis is the Y component (for you, dy), and the hypotenuse is the actual vector. So to find the magnitude, all you need to do is find the length of the hypotenuse.

You probably know what to do from here, but you will be using pythagoreans theorem to find the length.

magnitude = Math.sqrt(dx*dx + dy*dy);

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #14 - Posted 2008-10-24 06:05:19 »

Just after a first attempt it looks like this....

 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 `destinationX = locx + dx;            destinationY = locy + dy;            magnitude = (float)Math.sqrt(dx*dx + dy*dy);            changeX = dx / magnitude;            changeY = dy / magnitude;            dy += 0.3;                                    while (locx != destinationX && locy != destinationY)            {                lastPositionX = locx;                lastPositionY = locy;                                if(Math.abs(destinationX - locx) < changeX)                    locx = destinationX;                else                    locx += changeX;                                    if(Math.abs(destinationY - locy) < changeY)                    locy = destinationY;                else                    locy += changeY;}                `

things work well when the player on the left is shooting but when the player on the right shoots (aka the dx is negative) the game gets permanently stuck in the while loop.  what could be causing this?

i believe it has something to do with this statement....

 1 `if(Math.abs(destinationX - locx ) < changeX)`

if dx is negative than changeX will also be negative....therefore this statement will never evaluate true becuase an absolute value will never be less than a negative.   however i dont even know how the first shot is working since my dy is negative on both...
neoskunk

Junior Devvie

 « Reply #15 - Posted 2008-10-24 07:35:47 »

ok well it works like this....

 1  2  3  4  5  6  7  8  9 `if(Math.abs(destinationX - locx) < Math.abs(changeX))                    locx = destinationX;                else                    locx += changeX;                                    if(Math.abs(destinationY - locy) < Math.abs(changeY))                    locy = destinationY;                else                    locy += changeY;`

everything seems to work perfect like this.   is this maybe what you meant to type or is this gonna cause a problem?

also another problem if dx = 0 (aka shooting straight up) the above won't work.
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #16 - Posted 2008-10-24 20:13:14 »

Yeah, using the absolute value of the change is fine. Basically you're just seeing if how far you have left to move is less than the change you want to take. If it is, then you just want to match the destination.

As for shooting up, I don't understand why that wouldn't work. Can you elaborate on what is going wrong? Because dx = 0, it should always go into that else statement and have locx += changeX. Because changeX is 0, locX will remain the same, which is actually what you want if you're shooting straight up.

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #17 - Posted 2008-10-24 23:35:35 »

Ok well when i shoot straight up the ball appears just above the characters head but then stays right there. no movement.  so i think there is something wrong with the y value becuase it is not incrementing as it should.  you are correct x should not change but y should.  i think maybe it has something to do with the magnitude because when dx = 0 the magnitude will evaluate to Math.sqrt(dy*dy); which is just dy thus for changeY you will have dy/dy which is just 1.   i think what is happening is both if statements are evaluating to true right away therefore the ball is just placed at the first destination and does not move.
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #18 - Posted 2008-10-25 00:00:44 »

The changeY will become 1 when dx is 0 because your change vector (changeX and changeY) is simply a normalized vector. A normalized vector basically says on a scale of 0 to 1 this is what percent of your vector's total length is taken up by this component, and this is what percent by the other component, etc. Its magnitude will always be 1. A normalized vector is basically used to determine the direction of the vector, then you can multiply a float to determine its length. So, if a normalized 2D vector has no X component, its Y component will have a value of 1. Similarly, if the Y is 0, the X will be 1.

So, that's not the problem – it's the way it's supposed to be. Your theory of both statements being true could be correct... use some println's to test if you're right. I'm going to guess that you're not, however, unless something in your program isn't what you typed.

My guess is that your bullet is being spawned on top of something. Are you sure the bullet is appearing above the player's head and not colliding with the player? It's not going to go anywhere if it hits something, which I think is much more likely to be your problem. You've got to exclude collision with the player or make the bullet appear away from him. If it collides with something immediately, it's just going to go to its last position (the original position) and then break out of the while loop.

Next time rather than saying "it doesn't work when I shoot it up," instead really think about the actual situation. True, you're seeing the problem only when you're shooting up, so it's perfectly logical to reach that conclusion. However, you need to also consider other possibilities. You correctly identified that one way to exit your while loop is if the bullet reaches its destination immediately. But you didn't acknowledge the other possibility where the break statement is – if the bullet collides with something it will also stop. So in order to test if that's really the case, you should shoot a bullet up in the middle of nowhere, because you've got to figure out for which reason you're exiting the while loop.

You could also quite simply put a println in the if (collidesWithSomething) method to see if we're getting there. Remember that println's are your best friend in order to figure out what's really going on under the hood!

See my work:
OTC Software
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #19 - Posted 2008-10-25 00:05:02 »

On another note, this is a good illustration of a potential problem with that collision method. What do you do if something is created already colliding with something else? It's never going to be able to move. A good way to fix it is to see if there is already a collision at the beginning of the collision method. If there is one, you've got to figure out the best way to end that collision.

One way is to do what you've done already, which is simply to move your object up until it's not colliding. You've already noticed, however, that this can cause a lot of problems on its own. Instead a good way to do this is to find the closest boundary point where there is not a collision, and move there instead.

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #20 - Posted 2008-10-25 08:27:50 »

you are correct except it is not colliding with anything.....

the bullets themselves do not collide with players only ground/walls/etc. and then explode doing damage to players.

therefore i dont think that is the problem.....
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #21 - Posted 2008-10-25 18:52:38 »

All right, then you've got to put in some print lines and find out the root of the problem!

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #22 - Posted 2008-10-25 23:34:02 »

seems to work after changing this statement...

 1 `while (locx != destinationX && locy != destinationY)`

to

 1 `while (locx != destinationX || locy != destinationY)`

does that seem right?
Eli Delventhal

JGO Kernel

Medals: 42
Projects: 11
Exp: 10 years

Game Engineer

 « Reply #23 - Posted 2008-10-26 02:55:36 »

Ah, yup, you're right! My fault.  Very well done fixing that bug though. Basically it originally said that it would only continue as long as both components were wrong, but you want it to continue as long as either is wrong.

Glad it's working now!

See my work:
OTC Software
neoskunk

Junior Devvie

 « Reply #24 - Posted 2008-10-26 03:33:10 »

is there a certain case where this would still fail?   every now and again the ball will stop at the height of its path.

i think i fixed it.  it had something to do with my data type conversions.
Pages: [1]
 ignore  |  Print

 hadezbladez (273 views) 2018-11-16 13:46:03 hadezbladez (152 views) 2018-11-16 13:41:33 hadezbladez (283 views) 2018-11-16 13:35:35 hadezbladez (67 views) 2018-11-16 13:32:03 EgonOlsen (2122 views) 2018-06-10 19:43:48 EgonOlsen (2145 views) 2018-06-10 19:43:44 EgonOlsen (1358 views) 2018-06-10 19:43:20 DesertCoockie (1954 views) 2018-05-13 18:23:11 nelsongames (1597 views) 2018-04-24 18:15:36 nelsongames (2244 views) 2018-04-24 18:14:32
 Deployment and Packagingby mudlee2018-08-22 18:09:50Java Gaming Resourcesby gouessej2018-08-22 08:19:41Deployment and Packagingby gouessej2018-08-22 08:04:08Deployment and Packagingby gouessej2018-08-22 08:03:45Deployment and Packagingby philfrei2018-08-20 02:33:38Deployment and Packagingby philfrei2018-08-20 02:29:55Deployment and Packagingby philfrei2018-08-19 23:56:20Deployment and Packagingby philfrei2018-08-19 23:54:46
 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