CopyEntity

Blitz3D Forums/Blitz3D Programming/CopyEntity

Colvette(Posted 2006) [#1]
Hello again, chaps!

I'm having trouble with CopyEntity, it seems.

I've made an array of types, the first field of which is supposed to be a pointer to a sprite. I have 2 functions -

1) which sets up each group of sprites
2) one which renders each group of sprites

The set-up function executes right every time (as far as I can tell), but when the render function tries to execute for the third time, it decides the entity it's trying to access doesn't exist. This, specifically, is the sprite image pointer.

All the other information contained within the type list is correct, as far as I can tell...

Is there any way to check the success or otherwise of the CopyEntity command? Or perhaps a way to lift the limit on the amount of entities I can create?

Thanks!


big10p(Posted 2006) [#2]
We really need to see some code.

You are only calling your setup function only once, right? i.e. outside the main loop.


Colvette(Posted 2006) [#3]
Yup - only called once. It must be failing in there, though...


stayne(Posted 2006) [#4]
isn't there a CopySprite command?


Stevie G(Posted 2006) [#5]

isn't there a CopySprite command?


Nope.


I'm assuming that you first create the sprite entity then hide it and every instance of the sprite is simply a copyentity.

Are you freeing any sprites during the main loop and if so how are you doing it?

Some code would be good.

Stevie


Sir Gak(Posted 2006) [#6]
Code, baby.


DJWoodgate(Posted 2006) [#7]

Or perhaps a way to lift the limit on the amount of entities I can create?



How many sprites are you trying to create? I seem to remember there being a sprite limit, though not what it is exactly. Anyway one would hope that if sprite creation failed for some reason the pointer returned would be zero though I do not think it is that graceful.

In fact I have just tried it and you would probably get a memory access violation at renderworld (here somewhere between 16000 and 17000 sprites!), so I do not think that is your problem.


jfk EO-11110(Posted 2006) [#8]
Just for in case it's not the problem DJWoodgate just described:
When you use CopyEntity, it will return a handle. When the handle is zero, the entity wasn't created for some reason. Tho, this never happened to me.

Copyentity creates an instance of the original. Now when you remove the original, but keep the instance, there will be a new original. Although I am not sure if this is a ghost copy, somewhere stored intenally, or if it's gonna be one of the instances. If it's one of the instances, there may arise some problems when you continously delete the "new original" entity.

BTW: Whenever you free an entity in your code, you should set it's handle to zero. So you will be able at any time to check for the existance of an entity without to risk a MAV.


Colvette(Posted 2006) [#9]
The code is below.

I'm not freeing any sprites yet - just trying to allocate about 50 of them, so far. The code below has some lines edited out because I was trying to work out what was happening with it, but I've drawn a blank so far.

Any ideas?




octothorpe(Posted 2006) [#10]
[code] or [codebox]


Colvette(Posted 2006) [#11]
voila! :)


octothorpe(Posted 2006) [#12]
Random = Rand (0, CarTypes)


Here is the offending line. You're rolling a random number from 0 to 10 (an eleven-sided die!) When you call BuildRoad( 4, 0, 10 ), the random number generated is 10, which you have no Case for; thus, Road ( RoadNumber, i )\CarHandle remains 0 and you throw an "Entity Does Not Exist" error when you try to position it in DrawRoad().

The line should read Rand(0, CarTypes-1).

Array elements start at 0, so if you're using a constant to keep track of the number of something, you need to iterate from 0..COUNT-1 instead of 0..COUNT. You'll need to go through the rest of your code and fix things to reflect this fact. Here are examples of some of the changes you'll need to make:

Const TotalRoads = 30 ; this stays the same - it's more intuitive to keep track of the number of elements instead of the index of the last element

Dim Road.Car ( TotalRoads-1, 30-1 )
Dim TotalCars ( TotalRoads-1 )


	For i = 0 To TotalRoads-1
		For j = 0 To 30-1


One last thing: your Select...Case usage is non-standard - but it still works! You're doing this

Select True
	Case n = 0
	Case n = 1


but most people do this

Select n
	Case 0
	Case 1


Since both ways seem to work, this is only a style issue.


octothorpe(Posted 2006) [#13]
You may want to turn your Car1, Car2, etc. variables into an array like so:

Dim CarSpriteBlueprint(CarTypes-1)
CarSpriteBlueprint(0) = LoadSprite("Sprites\Army Truck Vert.bmp",52)
CarSpriteBlueprint(1) = LoadSprite("Sprites\Austin Vert.bmp",52)
CarSpriteBlueprint(2) = LoadSprite("Sprites\Buick Vert.bmp",52)
CarSpriteBlueprint(3) = LoadSprite("Sprites\Caddy Vert.bmp",52)
CarSpriteBlueprint(4) = LoadSprite("Sprites\Hot Dog Vert.bmp",52)
CarSpriteBlueprint(5) = LoadSprite("Sprites\Merc Vert.bmp",52)
CarSpriteBlueprint(6) = LoadSprite("Sprites\Muscle Car Vert.bmp",52)
CarSpriteBlueprint(7) = LoadSprite("Sprites\Police Car Vert.bmp",52)
CarSpriteBlueprint(8) = LoadSprite("Sprites\Sports Car Vert.bmp",52)
CarSpriteBlueprint(9) = LoadSprite("Sprites\Viper Vert.bmp",52)
For i = 0 To CarTypes-1
	ScaleSprite CarSpriteBlueprint(i),1,2.3
	HideEntity CarSpriteBlueprint(i)
Next


Then you can replace this:

		Random = Rand (0, CarTypes-1)
		Select True
			Case Random = 0
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car1 )
			Case Random = 1
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car2 )
			Case Random = 2
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car3 )
			Case Random = 3
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car4 )
			Case Random = 4
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car5 )
			Case Random = 5
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car6 )
			Case Random = 6
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car7 )
			Case Random = 7
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car8 )
			Case Random = 8
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car9 )
			Case Random = 9
				Road ( RoadNumber, i )\CarHandle = CopyEntity ( Car10 )
		End Select


with this:

		Road ( RoadNumber, i )\CarHandle = CopyEntity ( CarSpriteBlueprint(Rand (0, CarTypes-1)) )



Colvette(Posted 2006) [#14]
Excellent! That seems to have worked!

Thanks a lot! :)


octothorpe(Posted 2006) [#15]
Glad to be of help. :)


Colvette(Posted 2006) [#16]
So - now I've got it working, having made all the changes you suggested, the routine for rendering the roads seems *crushingly* slow. Are sprites really slow in Blitz?

*confused* (again!)


octothorpe(Posted 2006) [#17]
Oh.

You only need to render once per frame. Remove the call to RenderWorld() in DrawRoad(). You only need to call it in your main game loop.

Sprites are too slow to use for particle effects because they don't share "surfaces," but you should be fine using them for actors (i.e. cars.)


Colvette(Posted 2006) [#18]
Done that already - that was only there for debugging purposes. The main loop now looks like this:

While Not KeyDown(1) 

	If KeyDown (203) Then X#=X#-0.5
	If KeyDown (205) Then X#=X#+0.5
	If KeyDown (200) Then Y#=Y#+0.5
	If KeyDown (208) Then y#=y#-0.5
	If KeyDown (16)  Then z#=z#+0.5
	If KeyDown (17)  Then z#=z#-0.5
	PositionEntity cam,X#,Y#,Z# 

	For i = 0 To TotalRoads-1
		DrawRoad ( i, TotalCars-1 )
		RenderWorld
		Flip
	Next

Wend 


and the draw road function now looks like this:
Function DrawRoad ( RoadNumber, CarTotal )

	For i = 0 To CarTotal

		PositionEntity Road ( RoadNumber, i )\CarHandle, Road ( RoadNumber, i )\X, Road ( RoadNumber, i)\Y, 5
		RotateSprite Road ( RoadNumber, i )\CarHandle, Road ( RoadNumber, i )\Angle

	Next		

End Function


all looks OK to me?


Colvette(Posted 2006) [#19]
Oops! Just noticed why! Doh! :)