Cant get this to work

Blitz3D Forums/Blitz3D Programming/Cant get this to work

Oiduts Studios(Posted 2009) [#1]
I have tried this over and over again and it will not work is there anybody that can tell me what to do please? There are no errors, it just wont take any health off or display the status.

If speed#>2 And EntityCollided(plane,TERRAIN) Then status$="SOFT COLLISION" : health=health-1
endif
If speed#>10 And EntityCollided(plane,TERRAIN) Then status$="MEDIUM COLLISION" : health=health-5
endif
If speed#>15 And EntityCollided(plane,TERRAIN) Then status$="HARD COLLISION" : health=health-10
endif
If speed#>20 And EntityCollided(plane,TERRAIN) Then status$="DEADLY COLLISION" : health=health-50
endif

This Code will work though.

If EntityCollided(plane,TERRAIN) Then
status$="SOFT COLLISION" : health=health-1
endif


Drak(Posted 2009) [#2]
Try breaking it up into readable code. Try this:

If speed#>2 And EntityCollided(plane,TERRAIN) 
   status$="SOFT COLLISION" 
   health=health-1 
elseif speed#>10 And EntityCollided(plane,TERRAIN) 
   status$="MEDIUM COLLISION" 
   health=health-5
elseif speed#>15 And EntityCollided(plane,TERRAIN) 
   status$="HARD COLLISION" 
   health=health-10
elseif speed#>20 And EntityCollided(plane,TERRAIN) 
   status$="DEADLY COLLISION" 
   health=health-50
endif



I try not to place more than one command in each line. I think it's good practice and you can easily read which each line does.


Sledge(Posted 2009) [#3]
Hmmm, for one line try...
If speed#>2 And EntityCollided(plane,TERRAIN) : status$="SOFT COLLISION" : health=health-1 : EndIf

...but I agree with Drak in that it's better to make it readable.


Oiduts Studios(Posted 2009) [#4]
well... the only reason i have it in different lines is so it could fit into the forum box. In my actual code they look like sledge's.


Sacha(Posted 2009) [#5]
Im not sure about it but I think you use EntityCollided in a wrong way :

Afaik EntityCollided() will return 1 if the entities collided since last check. Hence when you do :

If entitycollided(a,b) and condition > 0 then dosomething()
If entitycollided(a,b) and condition < 0 then dosomething()

the second line "entitycollided(a,b)" will never be 1 because the entities didnt collide since last check (previous "if" line).

Do something like :

collision = entitycollided(a,b)
if collision and condition > 0 then ...
if collision and condition > 10 then ...
if collision and condition > 20 then ...


Oiduts Studios(Posted 2009) [#6]
ok, here is my whole code, don't make fun of it, can someone try to see why the crashes are not detected.




Drak(Posted 2009) [#7]
Your plane MAY be inside-out. You've flipped the normals with the "flipmesh plane" command. Try commenting that line out and see if it works.


Oiduts Studios(Posted 2009) [#8]
Nope, just tried it commenting that line makes the plane inside out...


Drak(Posted 2009) [#9]
Hah, I should have noticed this earlier. Make your Health variable at the top of your code global.


Oiduts Studios(Posted 2009) [#10]
I'm sorry but that didn't work either...


Drak(Posted 2009) [#11]
Ok copy and paste this. I added a collision code.




Oiduts Studios(Posted 2009) [#12]
Thank you for typing this up for me. The game is only registering soft collisions though.


Sacha(Posted 2009) [#13]
In your original code you have :

if speed > 2
dosomething1
elseif speed > 10
dosomething2
endif

"dosomething2" will never be done since a speed greater than 10 is also greater than 2. hence it will only do the "dosomething1" line

use this :

If EntityCollided(plane,Terrain) > 0
	If speed#>20
		status$="DEADLY COLLISION" 
		health=health-50
	ElseIf speed#>15
		status$="HARD COLLISION" 
		health=health-10
	ElseIf speed#>10
		status$="MEDIUM COLLISION" 
		health=health-5
	ElseIf speed#>2
		status$="SOFT COLLISION" 
		health=health-1 
	EndIf
EndIf


also define your global vars like so you dont have to add the type symbol everytime ("status$")

global Status$
...
status = "string"
...
text 10,10,status


and if you want to use lines like
If speed#>2 And EntityCollided(plane,TERRAIN) Then status$="SOFT COLLISION" : health=health-1 
If speed#>10 And EntityCollided(plane,TERRAIN) Then status$="MEDIUM COLLISION" : health=health-5
If speed#>15 And EntityCollided(plane,TERRAIN) Then status$="HARD COLLISION" : health=health-10
If speed#>20 And EntityCollided(plane,TERRAIN) Then status$="DEADLY COLLISION" : health=health-50


add ">0" to the EntityCollided() :

If speed#>2 And EntityCollided(plane,TERRAIN)>0 Then status$="SOFT COLLISION" : health=health-1 
If speed#>10 And EntityCollided(plane,TERRAIN)>0 Then status$="MEDIUM COLLISION" : health=health-5
If speed#>15 And EntityCollided(plane,TERRAIN)>0 Then status$="HARD COLLISION" : health=health-10
If speed#>20 And EntityCollided(plane,TERRAIN)>0 Then status$="DEADLY COLLISION" : health=health-50


Note that this method is still bad because when the speed is > 15 its also >10 and >2 so every lines will be done, hence giving 1 + 5 + 10 damage, instead of just 10.


Last note, you will also need to change your plane direction upon collision, because else it will keep collide at everyframe hence making it lose all life in a glimpse.


Stevie G(Posted 2009) [#14]

and if you want to use lines like

If speed#>2 And EntityCollided(plane,TERRAIN) Then status$="SOFT COLLISION" : health=health-1
If speed#>10 And EntityCollided(plane,TERRAIN) Then status$="MEDIUM COLLISION" : health=health-5
If speed#>15 And EntityCollided(plane,TERRAIN) Then status$="HARD COLLISION" : health=health-10
If speed#>20 And EntityCollided(plane,TERRAIN) Then status$="DEADLY COLLISION" : health=health-50



add ">0" to the EntityCollided() :

If speed#>2 And EntityCollided(plane,TERRAIN)>0 Then status$="SOFT COLLISION" : health=health-1
If speed#>10 And EntityCollided(plane,TERRAIN)>0 Then status$="MEDIUM COLLISION" : health=health-5
If speed#>15 And EntityCollided(plane,TERRAIN)>0 Then status$="HARD COLLISION" : health=health-10
If speed#>20 And EntityCollided(plane,TERRAIN)>0 Then status$="DEADLY COLLISION" : health=health-50




A number > 0 is assumed to be true so the > 0 is unecessary.


Sacha(Posted 2009) [#15]

A number > 0 is assumed to be true so the > 0 is unecessary.



True, but EntityCollided() returns an entity pointer. Altough it appears as a number like "15904320" its not an integer. Surprisingly yet, if that pointer is the only condition, it will work. If theres other conditions, it wont.

Try the following code, uncommenting either the first or second entity line.

Graphics3D 800,600,16,2

;entity = CreatePivot()
;entity = 1321321

If entity DebugLog "This always works"
If 2>1 And entity DebugLog "This works only if entity is an Integer - not an entity pointer"

Stop
End



GIB3D(Posted 2009) [#16]
I've found that I have to put

If Entity <> 0

EndIf


or else it won't give me the right results.


Matty(Posted 2009) [#17]
If entity DebugLog "This always works"
If 2>1 And entity DebugLog "This works only if entity is an Integer - not an entity pointer"


That is incorerct. the pointer is an integer, the reason it is not working the way you expect is due to the nature of the 'and' operator.

The and is combining the bits in the entity value with '1' as 2 is always greater than 1. What you are in effect saying is " if (1 AND Entity) then .... which will only work if the 1st bit of the 32bit integer representing the entity handle is also 1.

What you should be saying is

IF a>b AND entity<>0 then

ENDIF

that is how the AND statements and other bitwise operators NOT Boolean operators in blitz work.


Sacha(Posted 2009) [#18]
I was wrong on the difference between pointer/integer, however the example code is still valid. The "2>1" condition is just an example, it could be "x=3".
What im saying is that it seems inconsistent that a pointer can give either a "True" when used like this :

entity = createcube()
If Entity Then ...

or a "False" when used like this :

entity = createcube()
x = 3
If x=3 and Entity Then ...

It might be a thing to make easier the check for existante of entities (if entity ...) but the inconsistent behavior feels not so clean.


Axel Wheeler(Posted 2009) [#19]
Still the same thing, I think. Now you have:

If x = (3 and Entity) then...

When you want to say:

If (x = 3) and Entity then ...

...which is really...

If (x = 3) and (Entity > 0) then ...

Are you taking issue with the order of operations? (Squeak of chairs as a hush falls over the room) :-)

So it looks like if you put a number followed by And, it will always trigger the bitwise usage of And. That's how it knows when to use that form. I could be wrong though...


Sacha(Posted 2009) [#20]
Ah I see.
In my mind, AND had was an implicit condition separator ... since I only use it for "If" lines, I forgot it meant more than that. I suppose the "problem" comes from what you explained.

But in the end, whatever the real reason is, you can use simply "entity" as a condition when its alone in the "if" line, but you have to use some form of check ("entity<>0") when you use it along others conditions in the if line.


Subirenihil(Posted 2009) [#21]
AND is not a boolean operator in Blitz, it is a bitwise operator.

The bitwise operator in Blitz are:
Xor, Or, And, Not

The reason that AND (OR, XOR, and NOT also work) works in IF statements is shown in the examples below:

The commented IF lines in each example are identical to the the uncommented one. And if you hadn't figured it out, the one's and zeros with percent signs in front are binary.

In example 1, everything is fine because it is a simple addition equation.

But example 2 gives the error that many people do not expect. The commented lines (hopefully) explain why.

Example 3 is the corrected version of example 2.


Sacha(Posted 2009) [#22]
Thanks for the explanation. :)