CopyEntity
Blitz3D Forums/Blitz3D Programming/CopyEntity
| ||
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! |
| ||
We really need to see some code. You are only calling your setup function only once, right? i.e. outside the main loop. |
| ||
Yup - only called once. It must be failing in there, though... |
| ||
isn't there a CopySprite command? |
| ||
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 |
| ||
Code, baby. |
| ||
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. |
| ||
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. |
| ||
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? |
| ||
[code] or [codebox] |
| ||
voila! :) |
| ||
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. |
| ||
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)) ) |
| ||
Excellent! That seems to have worked! Thanks a lot! :) |
| ||
Glad to be of help. :) |
| ||
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!) |
| ||
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.) |
| ||
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? |
| ||
Oops! Just noticed why! Doh! :) |