whats wrong here
Blitz3D Forums/Blitz3D Beginners Area/whats wrong here
| ||
for some reason unknown too me i get ( object does not exist ) when i kill an enemy. Please Help. theres no media so you can copy and paste to see what i'm talkin about. ********************************************* Type Player Field x Field y End Type Type Enemy Field x Field y End Type Type Bullet Field x Field y End Type SeedRnd MilliSecs() Graphics 600,400 SetBuffer BackBuffer() Global BulletTimer=MilliSecs() create_player() create_enemy() While Not KeyHit(1) update_player() update_enemy() update_bullet() kills() Flip Cls Wend End Function kills() ;NEEDS WORK... BAD REAL BAD For e.enemy=Each enemy For b.bullet=Each bullet If RectsOverlap(e\x,e\y,10,10,b\x,b\y,10,10) Delete e End If Next Next End Function Function create_player() p.Player=New Player p\x=300 p\y=350 End Function Function update_player() For p.Player=Each Player Color 100,100,100 Rect p\x,p\y,20,20 If KeyDown(203) p\x=p\x-2 If KeyDown(205) p\x=p\x+2 If KeyHit(57) And MilliSecs()>BulletTime Then Create_Bullet(p\x,p\y) Next End Function Function create_enemy() For i=1 To 5 e.Enemy=New Enemy e\x=Rnd(10,500) e\y=Rnd(10,100) Next End Function Function update_enemy() For e.Enemy=Each Enemy Color 200,200,200 Rect e\x,e\y,10,10 Next End Function Function create_bullet(x,y) b.Bullet=New Bullet b\x=x+5 b\y=y-15 BulletTimer=MilliSecs() End Function Function update_bullet() For b.Bullet=Each Bullet Color 200,0,0 Rect b\x,b\y,10,10 b\y=b\y-3 If b\y<1 Then Delete b Next End Function |
| ||
Type Player Field x Field y End Type Type Enemy Field x Field y Field destroy ; <<<<------------------ add to check End Type Type Bullet Field x Field y End Type SeedRnd MilliSecs() Graphics 600,400 SetBuffer BackBuffer() Global BulletTimer=MilliSecs() create_player() create_enemy() While Not KeyHit(1) update_player() update_enemy() update_bullet() kills() Flip Cls Wend End Function kills() ;NEEDS WORK... BAD REAL BAD For e.enemy=Each enemy For b.bullet=Each bullet If RectsOverlap(e\x,e\y,10,10,b\x,b\y,10,10) e\destroy=1 ;<<<<<< ---------------------- End If Next If e\destroy=1 Delete e; <<<<< ------ destroy 'safely' Next End Function Function create_player() p.Player=New Player p\x=300 p\y=350 End Function Function update_player() For p.Player=Each Player Color 100,100,100 Rect p\x,p\y,20,20 If KeyDown(203) p\x=p\x-2 If KeyDown(205) p\x=p\x+2 If KeyHit(57) And MilliSecs()>BulletTime Then Create_Bullet(p\x,p\y) Next End Function Function create_enemy() For i=1 To 5 e.Enemy=New Enemy e\x=Rnd(10,500) e\y=Rnd(10,100) Next End Function Function update_enemy() Color 200,200,200 For e.Enemy=Each Enemy num=num+1 Rect e\x,e\y,10,10 Text e\x,e\y+10,num Next End Function Function create_bullet(x,y) b.Bullet=New Bullet b\x=x+5 b\y=y-15 BulletTimer=MilliSecs() End Function Function update_bullet() Color 200,0,0 For b.Bullet=Each Bullet Rect b\x,b\y,10,10 b\y=b\y-3 If b\y<1 Then Delete b Next End Function I add a new field to check the 'destroy' of the enemy, and the last check in the last loop will destroy 'safely' the type. In your example you destroyed the type and THEN it will be looked for the next loop... |
| ||
copied and pasted what u posted works ok for me, no matter i changed the resolution so i had all five aliens on screen, got an error on one the error occurs when two bullets are on the screen a work round whilst you figure it out is to use another field called 'visible' flagged as true/false. Type Player Field x Field y End Type Type Enemy Field x Field y Field vis ; added this End Type Type Bullet Field x Field y End Type SeedRnd MilliSecs() Graphics 600,600 SetBuffer BackBuffer() Global BulletTimer=MilliSecs() create_player() create_enemy() While Not KeyHit(1) update_player() update_enemy() update_bullet() kills() Flip Cls Wend End Function kills() ;NEEDS WORK... BAD REAL BAD For e.enemy=Each enemy For b.bullet=Each bullet If RectsOverlap(e\x,e\y,10,10,b\x,b\y,10,10) e\vis = False ; added this - removed delete End If Next Next End Function Function create_player() p.Player=New Player p\x=300 p\y=350 End Function Function update_player() For p.Player=Each Player Color 100,100,100 Rect p\x,p\y,20,20 If KeyDown(203) p\x=p\x-2 If KeyDown(205) p\x=p\x+2 If KeyHit(57) And MilliSecs()>BulletTime Then Create_Bullet(p\x,p\y) Next End Function Function create_enemy() For i=1 To 5 e.Enemy=New Enemy e\x=Rnd(10,500) e\y=Rnd(10,100) e\vis = True ; added this Next End Function Function update_enemy() For e.Enemy=Each Enemy Color 200,200,200 If e\vis = True ; added this Rect e\x,e\y,10,10 EndIf; added this Next End Function Function create_bullet(x,y) b.Bullet=New Bullet b\x=x+5 b\y=y-15 BulletTimer=MilliSecs() End Function Function update_bullet() For b.Bullet=Each Bullet Color 200,0,0 Rect b\x,b\y,10,10 b\y=b\y-3 If b\y<1 Then Delete b Next End Function |
| ||
thax. |
| ||
Hi, when posting code, it helps to set the code off in the posting commands [ code ] and [ /code ] (without the blanks between the brackets). |
| ||
Solution is to swap your nested For/Each's around in your collision code:Function kills() ;NEEDS WORK... BAD REAL BAD For b.bullet=Each bullet For e.enemy=Each enemy If RectsOverlap(e\x,e\y,10,10,b\x,b\y,10,10) Delete e End If Next Next End Function Alternatively, just exit the For/Each loop after deleting the enemy: Function kills() ;NEEDS WORK... BAD REAL BAD For e.enemy=Each enemy For b.bullet=Each bullet If RectsOverlap(e\x,e\y,10,10,b\x,b\y,10,10) Delete e Exit End If Next Next End FunctionBasically what you were doing wrong - when the first bullet collides with the enemy, you delete the enemy type itself. Your original code then proceeded to check the rest of the bullets for collisions against the now non-existent enemy. This is why it only caused an error if there was more than one bullet active at the time of collision. |