Cant get this to work

Blitz3D Forums/Blitz3D Programming/Cant get this to work

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

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.

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.

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.

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

ok, here is my whole code, don't make fun of it, can someone try to see why the crashes are not detected.

Graphics3D 1280,1024,32

Const PLANE1=1,SCENE=2,TERRAIN=3

health=100

Collisions PLANE1,SCENE,2,3
Collisions PLANE1,TERRAIN,2,3

HidePointer

palm1=LoadMesh("palm1.3ds")
EntityType palm1,SCENE
HideEntity palm1

water=CreatePlane()
PositionEntity water,0,-100,0
texwater=LoadTexture("water.jpg")
EntityTexture water,texwater
ScaleTexture texwater,500,500

;terr=LoadMesh("terrain 1.3ds")
terr=LoadTerrain("terrain.png")
ScaleEntity terr,100,10000,100
PositionEntity terr,0,-2700,0
texterr=LoadTexture( "stone.jpg" )
ScaleTexture Texterr,5,5
EntityTexture terr,Texterr
EntityType terr,TERRAIN

ScaleEntity palm1, 15,15,15      ;you don't need to specify these each Loop
EntityType palm1,SCENE           ;copyentity() copies entity commands as well as the mesh

For a = 1 To 3000

palm1=CopyEntity(palm1) 
bx# = Rnd (2000,50000)
by# = 0           ;this number actually doesn't matter
bz# = Rnd (2000,50000)
terrain_height# = TerrainY(terr, bx,by,bz)
PositionEntity palm1, bx,terrain_height, bz 

Next

plane=LoadMesh("befighter3.3ds")
ScaleMesh plane,0.1,0.1,-0.1
;RotateEntity plane,0,180,0
;FitMesh plane,-0.5,-1,-3,3,2,6
;PositionEntity plane,7000,2000,7000
PositionEntity plane,1,10,1
EntityType plane,PLANE1
FlipMesh plane

light=CreateLight()
TurnEntity light,45,45,0

target=CreatePivot( plane )
PositionEntity target,0,5,-12

tex2=LoadTexture("dusk.jpg")
sky=CreateSphere()
EntityTexture sky,tex2
ScaleEntity sky,5000,5000,5000
FlipMesh sky
EntityFX sky,8

;Global sky = create_skybox()
;PositionEntity sky,0,35,0

camera=CreateCamera()
CameraFogMode camera,1
CameraFogRange camera,0,3000
CameraRange camera,1,6000
CameraFogColor camera,222,252,255

While Not KeyHit(1)

	;If EntityCollided(palm1,TERRAIN)=False Then MoveEntity palm1,0,-10,0

PositionEntity sky,EntityX(plane),EntityY(plane),EntityZ(plane)
;TurnEntity sky,0,0.03,0

If KeyDown(30) Then speedgoal#=speedgoal#+.05
If KeyDown(44) Then speedgoal#=speedgoal#-.05

If speed#<speedgoal# And speed#<10 Then speed#=speed#+.01 : gear$="First Gear"
If speed#>speedgoal# And speed#<10 Then speed#=speed#-.01 : gear$="First Gear"

If speed#<speedgoal# And speed#<20 And speed#>10 Then speed#=speed#+.04 : gear$="Second Gear"
If speed#>speedgoal# And speed#<20 And speed#>10 Then speed#=speed#-.04 : gear$="Second Gear"

If speed#<speedgoal# And speed#<30 And speed#>20 Then speed#=speed#+.08 : gear$="Third Gear"
If speed#>speedgoal# And speed#<30 And speed#>20 Then speed#=speed#-.08 : gear$="Thrid Gear"

If speed#<speedgoal# And speed#<50 And speed#>30 Then speed#=speed#+.1 : gear$="Forth Gear"
If speed#>speedgoal# And speed#<50 And speed#>30 Then speed#=speed#-.1 : gear$="Forth Gear"

If speed#>speedgoal# And speed#=50 Then speed#=speed#-.1 : gear$="FULL SPEED"
If speed#=50 Then gear$="FULL SPEED"

If speed#<0 Then speed#=0
If speed#>50 Then speed#=50
If speedgoal#<0 Then speedgoal#=0
If speedgoal#>50 Then speedgoal#=50

If speed<5 Then MoveEntity plane,0,-1,speed#

turnleftspeed#=speed#*.5
turnrightspeed#=speed#*-.5
If turnleftspeed#>5 Then turnleftspeed#=5
If turnrightspeed#<-5 Then turnrightspeed#=-5

If KeyHit(2) Then speedgoal#=50

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

	;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
	
	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

	
	If health<1 Then RuntimeError("YOU DIED!!")

	If KeyDown(203) Then TurnEntity plane,0,0,turnleftspeed#
	If KeyDown(205) Then TurnEntity plane,0,0,turnrightspeed#
	If KeyDown(200) Then TurnEntity plane,1,0,0
	If KeyDown(208) And speed#>0.5 TurnEntity plane,-1,0,0
	MoveEntity plane,0,0,speed#

	dx#=EntityX( target,True )-EntityX( camera )
		dy#=EntityY( target,True )-EntityY( camera )
		dz#=EntityZ( target,True )-EntityZ( camera )
		TranslateEntity camera,dx*.1,dy*.1,dz*.1
		
	PointEntity camera,plane
	
		UpdateWorld
	
	RenderWorld
	Text 10,10,"ACTUAL SPEED = "+speed#
	Text 10,20,"SPEED GOAL = "+speedgoal#
	Text 10,30,""+gear$
	Text 10,50,"LEFT TURN SPEED = "+turnleftspeed#
    Text 10,60,"RIGHT TURN SPEED = "+turnrightspeed#
	Text 500,10,"STATUS = "+status+"     HEALTH = "+health
	Text 500,20,"COORDINATES 
	Text 500,30," X="+EntityX(plane)
	Text 500,40," Y="+EntityY(plane)
	Text 500,50," Z="+EntityZ(plane)
	Flip

Wend

End


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.

Nope, just tried it commenting that line makes the plane inside out...

Hah, I should have noticed this earlier. Make your Health variable at the top of your code global.

I'm sorry but that didn't work either...

Ok copy and paste this. I added a collision code.

Graphics3D 1024,768,32

Const PLANE1=1,SCENE=2,TERRAIN=3

Global health=100
Global status$ 

Collisions PLANE1,SCENE,2,3
Collisions PLANE1,TERRAIN,2,3

HidePointer

palm1=LoadMesh("palm1.3ds")
;palm1 = CreateCylinder()
EntityType palm1,SCENE
HideEntity palm1

water=CreatePlane()
PositionEntity water,0,-100,0
;EntityColor water, 0,0,255
texwater=LoadTexture("water.jpg")
EntityTexture water,texwater
ScaleTexture texwater,500,500

;terr=LoadMesh("terrain 1.3ds")
terr=LoadTerrain("terrain.png")
ScaleEntity terr,100,10000,100
PositionEntity terr,0,-2700,0
texterr=LoadTexture( "stone.jpg" )
ScaleTexture Texterr,5,5
EntityTexture terr,Texterr
EntityType terr,TERRAIN

ScaleEntity palm1, 15,15,15      ;you don't need to specify these each Loop
EntityType palm1,SCENE           ;copyentity() copies entity commands as well as the mesh

For a = 1 To 3000

palm1=CopyEntity(palm1) 
bx# = Rnd (2000,50000)
by# = 0           ;this number actually doesn't matter
bz# = Rnd (2000,50000)
terrain_height# = TerrainY(terr, bx,by,bz)
PositionEntity palm1, bx,terrain_height, bz 

Next

plane=LoadMesh("befighter3.3ds")
;plane = CreateCube()
ScaleMesh plane,0.1,0.1,-0.1
;RotateEntity plane,0,180,0
;FitMesh plane,-0.5,-1,-3,3,2,6
;PositionEntity plane,7000,2000,7000
PositionEntity plane,1,10,1
EntityType plane,PLANE1
;EntityRadius plane, 1,1
FlipMesh plane

light=CreateLight()
TurnEntity light,45,45,0

target=CreatePivot( plane )
PositionEntity target,0,5,-12

tex2=LoadTexture("dusk.jpg")

sky=CreateSphere()
EntityTexture sky,tex2
EntityColor sky, 150,150,150
ScaleEntity sky,5000,5000,5000
FlipMesh sky
EntityFX sky,8

;Global sky = create_skybox()
;PositionEntity sky,0,35,0

camera=CreateCamera()
CameraFogMode camera,1
CameraFogRange camera,0,3000
CameraRange camera,1,6000
CameraFogColor camera,222,252,255

While Not KeyHit(1)

	;If EntityCollided(palm1,TERRAIN)=False Then MoveEntity palm1,0,-10,0

PositionEntity sky,EntityX(plane),EntityY(plane),EntityZ(plane)
;TurnEntity sky,0,0.03,0



If KeyDown(30) Then speedgoal#=speedgoal#+.05
If KeyDown(44) Then speedgoal#=speedgoal#-.05

If speed#<speedgoal# And speed#<10 Then speed#=speed#+.01 : gear$="First Gear"
If speed#>speedgoal# And speed#<10 Then speed#=speed#-.01 : gear$="First Gear"

If speed#<speedgoal# And speed#<20 And speed#>10 Then speed#=speed#+.04 : gear$="Second Gear"
If speed#>speedgoal# And speed#<20 And speed#>10 Then speed#=speed#-.04 : gear$="Second Gear"

If speed#<speedgoal# And speed#<30 And speed#>20 Then speed#=speed#+.08 : gear$="Third Gear"
If speed#>speedgoal# And speed#<30 And speed#>20 Then speed#=speed#-.08 : gear$="Thrid Gear"

If speed#<speedgoal# And speed#<50 And speed#>30 Then speed#=speed#+.1 : gear$="Forth Gear"
If speed#>speedgoal# And speed#<50 And speed#>30 Then speed#=speed#-.1 : gear$="Forth Gear"

If speed#>speedgoal# And speed#=50 Then speed#=speed#-.1 : gear$="FULL SPEED"
If speed#=50 Then gear$="FULL SPEED"

If speed#<0 Then speed#=0
If speed#>50 Then speed#=50
If speedgoal#<0 Then speedgoal#=0
If speedgoal#>50 Then speedgoal#=50

If speed<5 Then MoveEntity plane,0,-.01,speed#

turnleftspeed#=speed#*.5
turnrightspeed#=speed#*-.5
If turnleftspeed#>5 Then turnleftspeed#=5
If turnrightspeed#<-5 Then turnrightspeed#=-5

If KeyHit(2) Then speedgoal#=50

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

	;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
	

For collision_id = 1 To CountCollisions(plane)
	collision_entity = CollisionEntity(plane, collision_id)
		If GetEntityType(collision_entity) = TERRAIN
			impact_speed# = speed
				crash_damage(impact_speed)
		End If 
Next



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

	
	If health<1 Then RuntimeError("YOU DIED!!")

	If KeyDown(203) Then TurnEntity plane,0,0,turnleftspeed#
	If KeyDown(205) Then TurnEntity plane,0,0,turnrightspeed#
	If KeyDown(200) Then TurnEntity plane,1,0,0
	If KeyDown(208) And speed#>0.5 TurnEntity plane,-1,0,0
	MoveEntity plane,0,0,speed#

	dx#=EntityX( target,True )-EntityX( camera )
		dy#=EntityY( target,True )-EntityY( camera )
		dz#=EntityZ( target,True )-EntityZ( camera )
		TranslateEntity camera,dx*.1,dy*.1,dz*.1
		
	PointEntity camera,plane
	
		UpdateWorld
	
	RenderWorld
	Text 10,10,"ACTUAL SPEED = "+speed#
	Text 10,20,"SPEED GOAL = "+speedgoal#
	Text 10,30,""+gear$
	Text 10,50,"LEFT TURN SPEED = "+turnleftspeed#
    Text 10,60,"RIGHT TURN SPEED = "+turnrightspeed#
	Text 500,10,"STATUS = "+status+"     HEALTH = "+health
	Text 500,20,"COORDINATES 
	Text 500,30," X="+EntityX(plane)
	Text 500,40," Y="+EntityY(plane)
	Text 500,50," Z="+EntityZ(plane)
	Flip

Wend

Function crash_damage(impact_speed)
	If impact_speed > 2 
		health = healh -1
		status$ = "SOFT COLLISION"
	ElseIf impact_speed > 10
		health = health - 5
		status$ = "MEDIUM COLLISION"
	ElseIf impact_speed > 15
		health = health - 10
		status$ = "HARD COLLISION"
	ElseIf impact_speed > 20
		health = health - 50
		status$ = "DEADLY COLLISION"
	End If 
End Function 



Thank you for typing this up for me. The game is only registering soft collisions though.

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.


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.


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


I've found that I have to put

If Entity <> 0

EndIf


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

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.

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.

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

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.

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:
;Example 1:
x=12 ;%1100
y=3   ;%0011
If x + y Then dostuff
;If 12 + 3 Then dostuff
;If 15<>0 Then dostuff
;If %1111<>%0000 Then dostuff

;Example 2:
x=12 ;%1100
y=3   ;%0011
If x And y Then dostuff
;If 12 And 3 Then dostuff
;If %1100 And %0011 Then dostuff
;If %0000<>%0000 Then dostuff

;Example 3:
x=12 ;%1100
y=3   ;%0011
If (x<>0) And (y<>0) Then dostuff
;If (12<>0) And (3<>0) Then dostuff
;If (%1100<>%0000) And (%0011<>%0000) Then dostuff
;If %0001 And %0001 Then dostuff

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.

Thanks for the explanation. :)