Ok, I think I got it working now
It's actually a very simple process, The hard part was making an "allowed Damage" so the player isn't super sensitive. The reason this was difficult is because sometimes only half the damage is received in the first loop and the rest the second time the program loops.
I made a little picture to illustrate this
``|
``|
--|---
``|
``|
``|
imagine that the "|" signs represent the players velocity, and that
"-" represents the floor. See how some of the objects movement
will go through the floor, we calculate the damage recieved by
taking the difference of where the object should be and where it is
relocated to (the floor) based on the collisions. However in this
case, not all of the damage is assigned in the first loop.
--|--
``|
``|
now the velocity is smaller, and the rest of the damage is
assigned.
Hope that clears it up.
So all the damage will be assigned just as it should, but the problem was that notice how 3 damage was dealt the first time, and 2 the second time.
Well what if you want the maximum allowed damage to be 4.
The player should recieve a total of 5 damage from this fall
However the first loop only deals 3 damage which is lower than 4 so no hp loss, and same for the second loop.
So the trick was to make it add up the damage from 2 collision checks and then see if it is enough damage to assign. I hope that works out all the bugs, please let me know if it doesn't.
health as integer : health = 100
gravity as float : gravity = 0.1
velocity as float : velocity = 0.0
allowedDamage as byte : allowedDamage = 4
y# = 0.0
oldy# = 0.0
sync on : sync rate 30
hide mouse
do
cls
`oldy will store the initial value of y
oldy# = y#
`velocity increases by the amount of gravity NOTE: GRAVITY SHOULD BE NEGATIVE FOR 3D APPS.
velocity = velocity + gravity
`move y by it's current speed (velocity)
y# = y# + velocity
`just a precaution, don't worry about this yet.
if pass = 1 then pass = 2
`this is where you check for collisions.
if y# >= 475
`relocate the object based on the collision
y# = 475
` (y# - oldy#) should give us the new velocity of the object after collision
`so velocity - (y# - oldy#) is the change in velocity
`below we store this value in "damage" variable
damage = damage + velocity - (y# - oldy#)
`then we need to set velocity to the new value above (y# - oldy#) so we will be ready for the next loop.
velocity = y# - oldy#
`this will tell us how many times we have calculated the damage
`remember...we need to calculate it for 2 loops not just 1.
if pass = 0 then pass = 1
endif
`I origionally had "if (damage < 0) and (pass = 2)"
`however there is no need to check for damage because if pass=2 then we have already assigned some damage
`so if pass=2 collision checks have already been performed for 2 loops.
if pass = 2
`reset pass variable
pass = 0
`if the amount of damage done in the 2 loops is greater than "allowedDamage" then subtract difference from health.
if damage > allowedDamage then health = health - damage
`reset damage
damage = 0
endif
`DRAW "WORLD"
circle 320, y#, 4
line 0, 475, 640, 475
print velocity
print health
sync
loop
lots of comments.
The total damage done in that example is 9, so if allowedDamage is 9 or greater no damage is dealt.
It should be easy to apply this to a 3D application, and will work with sloped surfaces, just make sure gravity is negative.
NOTE: you can always do further calculations for the damage. Like you could try doing "health = health - damage + allowedDamage" to make a smaller value or try multiplying damage by 2 or whatever.
I havn't experimented with this in an actual game so I don't know what calculation works the best.
The right man in the wrong place can make all the difference in the world. -- GMan