seek&destroy enemies
BlitzPlus Forums/BlitzPlus Programming/seek&destroy enemies
| ||
Hi, I'm well on my way with my Defender/horizontal shooter, but I'm having problems with an enemy type that should hunt down the player and shoot at him. The problem is that I have managed to have the enemy find the player and move to where he is, but it moves in a more or less straight line and I would like to have it moving around the player in circles when it gets there. Any ideas are welcome. |
| ||
A relatively simple way of doing that would be to pick a (random) point *nearby* the player to fly to. Then when you get there, pick another point close to the player. (In the meanwhile you keep shooting at the player.) This will not give you circles but the enemy will fly close to the player in an annoying way! ;) To get circles you could first fly towards the player, then when you are close (as close as the size of the circle) start flying in a circle. For a circle you would need to adjust the flying angle a little bit each time, or do things with sinus and cosinus, I am not sure right away. Or, as an approximation of a circle, you could pick points in sequence that are on a circle. So, when you are close enough to the player, first take a point directly above the player (North), fly there, then take the next point (North-East), then the next (East) and so on. (Assuming you want to circle clockwise.) The enemy would need to keep track of these directions (like "current point is East") and using if-then or a select statement decide where to fly next. This way the enemy will fly in something that resembles a circle (a hexagon if I am not mistaken, 8 corners). If the ship turns in a realistic way (by changing the directional angle) this may result in it flying a circle. This depends on how you have programmed movement (8 directional movement, or 360 degree movement, or another method). Well I hope that made some sense! ;) |
| ||
for indeed just use sine and cosine to determine where to fly to... x - x position of target y - y position of target r - distance away from target counter - starts at 0 and counts round to 359 before looping back again So... You just make you're guy aim at: x+(sin(counter)*r) y+(cos(counter)*r) Job done... Increase the increments of counter to make it circle it faster. Increase R to make it circle further away. |
| ||
Little example :);Homing example, by Jeppe Nielsen 2003 Global playerx# Global playery# Global distance#=100 Type enemy Field x#,y# Field vx#,vy# Field ax#,ay# Field vmax# Field amax# End Type Graphics3D 800,600,16,2 ;create ten enemies at random locations For n=1 To 10 ;play with last number ;enemynew(x,y,vmax,amax) enemynew(Rnd(800),Rnd(600),Rnd(0.5,4.5),Rnd(0.08,0.1)) Next Repeat Cls Text 10,10,"Move player with mouse" Text 10,30,"LMB - Resize allowed distance to player" Text 10,50,"RMB - Add enemies" If click=0 playerx=MouseX() playery=MouseY() EndIf If MouseDown(1) And click=0 click=1 clickx=MouseX() clicky=MouseY() EndIf If MouseDown(1) And click=1 dx=(MouseX()-clickx) dy=(MouseY()-clicky) distance#=Sqr(dx*dx+dy*dy) EndIf If MouseDown(1)=False And click=1 click=0 EndIf If MouseDown(2)>0 enemynew(Rnd(800),Rnd(600),Rnd(2.5,2.5),Rnd(0.08,0.1)) EndIf enemyupdate() enemydraw() Rect playerx-5,playery-5,10,10,0 Oval playerx-distance#,playery-distance#,distance#*2,distance#*2,0 Flip Until KeyDown(1) End Function enemynew.enemy(x,y,vmax#,amax#) e.enemy=New enemy e\x#=x e\y#=y e\vmax#=vmax# e\amax#=amax# Return e End Function Function enemyupdate() For e.enemy=Each enemy dx#=(playerx-e\x) dy#=(playery-e\y) l#=Sqr(dx#*dx#+dy#*dy#) dx#=(dx#/l#)*e\amax# dy#=(dy#/l#)*e\amax# ;if close enough escape target If l#<=distance# dx#=-dx# dy#=-dy# EndIf ;check against all other enemies, to avoid them dxx#=0 dyy#=0 co=0 For ee.enemy=Each enemy If ee<>e dex#=(e\x-ee\x) dey#=(e\y-ee\y) l#=Sqr(dex#*dex#+dey#*dey#) dxx#=dxx#+(dex#/l#)*e\amax# dyy#=dyy#+(dey#/l#)*e\amax# co=co+1 EndIf Next dxx#=dxx#/Float(co) dyy#=dyy#/Float(co) dx#=(dx#+dxx#)/2 dy#=(dy#+dyy#)/2 e\ax#=e\ax#+dx# e\ay#=e\ay#+dy# acc#=Sqr(e\ax#*e\ax#+e\ay#*e\ay#) ;Check if current acceleration is more than allowed If acc#>e\amax# e\ax#=(e\ax#/acc#)*e\amax e\ay#=(e\ay#/acc#)*e\amax EndIf e\vx#=e\vx#+e\ax# e\vy#=e\vy#+e\ay# vel#=Sqr(e\vx#*e\vx#+e\vy#*e\vy#) ;Check if current velocity is more than allowed If vel#>e\vmax# e\vx#=(e\vx#/vel#)*e\vmax e\vy#=(e\vy#/vel#)*e\vmax EndIf ; add velocity to position e\x#=e\x#+e\vx# e\y#=e\y#+e\vy# Next End Function Function enemydraw() For e.enemy=Each enemy Rect e\x-3,e\y-3,6,6,0 Next End Function Hope it is of use :-) |
| ||
Personally I'd just give the alien a velocity which it adds to it's co-ordinates each frame and make it so it can only alter it's velocity by a small amount each frame. That way it'll aim at the player and overshoot, but then decellerate and effectively buzz around the player like a bee. |
| ||
Thank you all for the answers so far. I like your example Jeppe, I'm not that great with math, which might be why I have trouble with stuff like this. But I tried it out and it looks very interesting. I'll try and see if I can incorporate the idea into my game. Your AlphaGUI looks interesting too, I'm downloading it now to look at it further. Jeppe: Tak for svaret. |
| ||
Velbekommen |