Types And Entitydistance

Blitz3D Forums/Blitz3D Beginners Area/Types And Entitydistance

Newbie31(Posted 2014) [#1]
Hello,

I'm having problems with getting a distance calculation with entitydistance() between the player controlled mesh and the type generated rooms. I have no idea how to make this work and would like some help please?

Here is my code, the problem is in my final function......I think.





stayne(Posted 2014) [#2]
Just out of curiosity try this:

If EntityDistance( player_mesh , world\room_mesh , 1) < 10


Newbie31(Posted 2014) [#3]
returns error "too many parameters"


Guy Fawkes(Posted 2014) [#4]


In Main Loop:

distfromtoent# = Distance3D#(EntityX#(entfrom, 1), EntityY#(entfrom, 1), EntityZ#(entfrom, 1), EntityX#(entto, 1), EntityY#(entto, 1), EntityZ#(entto, 1))

If distfromtoent# < 10.0
    ;Insert what I should do next here
EndIf


Insert below code ABOVE Flip and UNDER RenderWorld.

Text GraphicsWidth()/2, GraphicsHeight()/2, "Distance from ent1 to ent2: "+distfromtoent#, 1, 1


Finally, below your Main Loop's "Until", "Forever", "Wend", or "End":



Hope this helps :)

Enjoy! :)

Sincerely,

~GF


Floyd(Posted 2014) [#5]
		;If EntityDistance( player_mesh , world\room_mesh ) < 10			;Doesn't Work
		If EntityDistance( player_mesh , cube ) < 10				;Does Work
What do "Doesn't Work" and "Does Work" mean?

In both cases you are testing if EntityDistance( player_mesh, SomethingElse ) is less than 10. The test succeeds (Works) if the distance is in fact less than 10. It fails if the distance is not less than 10.

Perhaps you were expecting EntityDistance to somehow determine the closest points on the entities and measure that distance. For example two spheres, each with radius 1. Suppose the centers are 2 units apart. The spheres are actually touching and you might consider the distance to be zero.

But EntityDistance is just using the two entity positions, effectively measuring "center to center". The distance is 2.


Stevie G(Posted 2014) [#6]
The Distance3d function is completely pointless as entitydistance does exactly the same thing.

Really, if your rooms are uniform in size and placement you should be able to determine which room you are in by the coordinates of the player alone.

Alternatively, you need to compare the x and z axis' rather than the distance:

tformpoint 0,0,0,player_mesh, world\room_mesh
if abs( tformedx() ) < 10 and abs( tformedz() ) < 10 then
;I'm in this room
Endif


Newbie31(Posted 2014) [#7]
What I'm am aiming for is a little bit like the old 2d games, where the player is a disproportionate size to the building and when you get within a certain distance you are offered the option to enter the area. then the game loads a higher poly version of the area.(like final fantasy 7 world map.)


		;If EntityDistance( player_mesh , world\room_mesh ) < 10			;Doesn't Work
		If EntityDistance( player_mesh , cube ) < 10				;Does Work



I like to put notes at the edge of my code when something isn't working. Usually the lines are interchangible and commenting out one and subbing in the other just how I check where the problem is eg.
What I mean is :



	If EntityDistance( player_mesh , world\room_mesh ) < 10			;Doesn't Work
		Text ProjectedX() , ProjectedY() , "Within open Distance."
	EndIf


this code does not display text as it should when the player_mesh is within 10 units of the room. However


	If EntityDistance( player_mesh , cube ) < 10				
		Text ProjectedX() , ProjectedY() , "Within open Distance."
	EndIf


this code does display text when the player_mesh is within 10 units of the cube.

I think the problem is that the entitydistance command is having problems retrieving the individual "mesh (world\room_mesh)" position.

I thought about trying it like guy fawkes suggests, (I actually did use this method in and earlier version of the code ) but I was having problems clearing the world when the player enters a room. In another thread other members suggested I put as much could into types, which is what I do now.

What my code currently does.
1. creates a giant cube and flips the mesh, and applies collision.
2. creates a player and camera and assigns a way to move them.
3. creates 6 rooms (using a type), positions, textures and apllies collision.

Now I want to have text appear when the player is within a certain range of them, which is where I'm stuck?

Eventually I want the code I want it to do something like this.

	If EntityDistance( player_mesh , world\room_mesh ) < 10			
		Text ProjectedX , ProjectedY ," Press Return to enter " + world\room_name$
		If KeyHit( 28 )
			ClearWorld
			player_mesh = CreateSphere()
			camera01 = CreateCamera()
			loadhighpoly_interior()
		EndIf
	EndIf




Floyd(Posted 2014) [#8]
I still think the appearance of the cubes is the source of the confusion. If you are close to the surface of a big cube then visually you are near the cube. But you are still far from the center, which is all EntityDistance() cares about.

In fact, the way the room_mesh cubes are positioned and scaled it seems to be impossible to actually get within 10 units of the center, unless you are inside the cube.


stayne(Posted 2014) [#9]
Try creating a simple cube in a 3D modeling app like Blender, create another small cube at the door and name it something like door_pivot, then search for that child once loaded and attach a pivot to it (CreatePivot I think). Use that pivot to judge distance because as Floyd said you are working with the center of the cube. Or not :)


Guy Fawkes(Posted 2014) [#10]
The Distance3d function is completely pointless as entitydistance does exactly the same thing.

Really, if your rooms are uniform in size and placement you should be able to determine which room you are in by the coordinates of the player alone.

Alternatively, you need to compare the x and z axis' rather than the distance:

tformpoint 0,0,0,player_mesh, world\room_mesh
if abs( tformedx() ) < 10 and abs( tformedz() ) < 10 then
;I'm in this room
Endif


VERY good idea, Stevie! :)


Stevie G(Posted 2014) [#11]
Simply print the distance to each of the rooms on screen - you'll soon see what Floyd is talking about.

Due to the collisions you have set on the rooms you'll never get within 10 units as the collisions prevent penetration. Why do you have collisions at all? There are loads of different ways to do this but here are a few options:

1. Check for < 11 instead of 10
2. Check for actual collisions, see entitycollided etc.. to determine which room you are touching rather than using entitydistance.
3. Remove collisions from the rooms and stick with the < 10 entitydistance
4. Remove collisions from the rooms and use tformpoint to check the x and z axis distance.


Newbie31(Posted 2014) [#12]
I feel an idiot now. I always assumed that the entitydistance command was the distance between the two closest points on the object. You were right, when I turn off the collisions it worked. Thanks everybody.


Guy Fawkes(Posted 2014) [#13]
No prob! ;)


stayne(Posted 2014) [#14]
Couldn't he just move the call to RPG_WORLD_HUD() before UpdateWorld()?


Newbie31(Posted 2014) [#15]
Heyo,

I have new problem now with the same if updated code. My code is pretty much the same. This is what is does.

1. Creates world and objects, and assign movement controls
2. Textures and applies collision.
3. Checks if the player_mesh is within a certain distance of the room.
4. If RETURN is pressed clears the world and remakes it.( for all it just appears as the player mesh position is reset.)

The problem is when you press RETURN it displays a 'entity does not exist' error in the line.
If EntityDistance( player_mesh , world\room_mesh ) < 13


I suspect that it has something to do with where I am placing the function but I don't know much about it.

If I disable the function.
Function RPG_WORLD_HUD()
	
	For world.room = Each room
	;	CameraProject( camera01 , EntityX( world\room_mesh ) , EntityY( world\room_mesh ) , EntityZ( world\room_mesh ) )  
	;	Text ProjectedX() , ProjectedY() , "" + world\room_name$
		If EntityDistance( player_mesh , world\room_mesh ) < 13
			Text (GraphicsWidth() / 5 ) * 2 , GraphicsHeight() / 2 ," Press RETURN to enter " + world\room_name$
		EndIf
	Next
	
End Function

Then everything works fine? Any Help?

Complete Code:



RemiD(Posted 2014) [#16]
If you activate the debugmode (Menu>Program>Debug enabled), you can see which is the entity which does not exist anymore in the BlitzDebugger window (displayed at the bottom after you have built and ran the code)

Also learn to use Debuglog(""), this is a really useful command to find and then fix bugs.


Floyd(Posted 2014) [#17]
It's not immediately clear how to tell if an entity exists.

Graphics3D 600, 400, 0, 2
SetBuffer FrontBuffer()
Print

Global ent  ; will be an entity

Print "value of ent before creating anything: " + ent

ent = CreateSphere()
Print "           ent is now a sphere, value: " + ent

FreeEntity ent
Print "entity freed, no longer exists, value: " + ent

; ent does not exist, but value of variable is still non-zero.
; If ent had been reset to zero you could test if it exists.
; That doesn't happen automatically, but you can do it yourself.

ent = 0  ; do this after 'FreeEntity ent'

WaitKey

If you manually set the entity variable to zero after FreeEntity then you can later test if that variable is zero to see if an entity exists.

You have to do this for each freed entity. The scattergun approach of ClearWorld will just make things unmanageable, as you have discovered.


RemiD(Posted 2014) [#18]
I agree with what Floyd explained, i do the same.


Newbie31(Posted 2014) [#19]
I'm not sure I understand but I wrote this:
		If KeyHit(28)
		
		;Free entity.
		free_world_type()
		
		ClearWorld()
		
		RPG_WORLD_CREATE()
		;---------Load Default Player -------
		player_mesh = CreateSphere()																;Load the default player mesh this must be loaded here or else thhe movement in the game loop or function will return an error.
		PositionEntity player_mesh , 0 , 1 , 0														;Position the entity.
		ScaleEntity player_mesh , 0.5 , 0.5 , 0.5													;Scale the entity.
		EntityType player_mesh , PLYR																;Set entity collision type.
		EntityRadius player_mesh , .5																;Set entity collision radius.
		player_pivot = CreatePivot( player_mesh )													;Create a pivot at the center of the player for the camera to follow.
		PositionEntity player_pivot , 0 , 1 , 0														;Position the pivot. (This should be close to the player)
		camera01 = CreateCamera( player_mesh )														;Create camera - IMPORTANT This is cleared with the clearworld command and should be created immediately after.														
		PositionEntity camera01 , 0 , 5 , -10														;Position the camera.
		
	EndIf
	
	UpdateWorld																				;Update World
	RenderWorld																				;Render World
	
;--------------------------------------	
	
	RPG_HUD_TEST()
	
	RPG_WORLD_HUD()
	
	Flip



;-----
In functions
;-----

Function free_world_type()
	
	For world.room = Each room
		FreeEntity world\room_mesh
		world\room_mesh = 0
	Next
	
End Function

Function RPG_HUD_TEST()
	
	Color 255 , 255 , 255
	Rect 0 , 0  , 500 , 100 , 1
	For world.room = Each room
		
		If world\room_mesh <> 0
			Color 0 , 0 , 0
			Text 0 , world\room_test_text_pos_y ," entity '" + world\room_mesh + "' exists, and is named '" + world\room_name$ + "'."
		ElseIf world\room_mesh = 0
			Text 0 , world\room_test_text_pos_y ," entity '" + world\room_mesh + "' does not exists."
		EndIf
		
	Next
End Function


Function RPG_WORLD_HUD()
	
	For world.room = Each room
		CameraProject( camera01 , EntityX( world\room_mesh ) , EntityY( world\room_mesh ) , EntityZ( world\room_mesh ) )  
		Text ProjectedX() , ProjectedY() , "" + world\room_mesh
		If EntityDistance( player_mesh , world\room_mesh ) < 13
			Text (GraphicsWidth() / 5 ) * 2 , GraphicsHeight() / 2 ," Press RETURN to enter " + world\room_name$
		EndIf
	Next
	
End Function



but I still get 'entity does not exist' error.


RemiD(Posted 2014) [#20]
Which entity does not exist ?
At which line ?

See in the BlitzDebugger window


Newbie31(Posted 2014) [#21]
I found the problem. When I was using clearworld, I was clearing the old type (world\room_mesh) and creating a new one but my entitydistance was trying to find the old type which didn't exist any longer. The solution was to delete the old type immediately before clearworld so it could start again.
	For world.room = Each room
		Delete world
	Next


My code now that works:


Thanks anyway for your help.