'Blitzmax: Strict 'Homing example, by Jeppe Nielsen 2003 'mouse position: Global playerx# Global playery# Global distance#=100 Global enemylist:TList = CreateList() Type enemy Field x#,y# Field vx#,vy# Field ax#,ay# Field vmax# Field amax# Function enemynew:enemy(x,y,vmax#,amax#) Local e:enemy=New enemy enemylist.addlast(e) e.x#=x e.y#=y e.vmax#=vmax# e.amax#=amax# Return e End Function Function enemydraw() For Local e:enemy=EachIn enemylist SetColor 0,0,255 DrawRect e.x-3,e.y-3,6,6 Next End Function Function enemyupdate() For Local e:enemy=EachIn enemylist Local dx#=(playerx-e.x) Local dy#=(playery-e.y) Local 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 Local dxx#=0 Local dyy#=0 Local co=0 For Local otherEnemy:enemy=EachIn enemylist If otherEnemy<>e Local dex#=(e.x-otherEnemy.x) Local dey#=(e.y-otherEnemy.y) 'Avoid other enemies. Comment out these 3 lines to remove avoidance. 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# Local 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# Local 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 End Type 'SetGraphicsDriver GLMax2DDriver() Graphics 640,480 'Create ten enemies at random locations Local n:Int For n=1 To 10 'play with last number 'enemynew(x,y,vmax,amax) enemy.enemynew(Rnd(800),Rnd(600),Rnd(5,5), 10)'Rnd(0.08,0.1)) Next Local click:Int = 0 Local clickx:Int = 0 Local clicky:Int = 0 Repeat Cls DrawText "Move player with mouse",10,10 DrawText "LMB - Resize allowed distance to player",10,30 DrawText "RMB - Add enemies",10,50 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 Local dx:Int=(MouseX()-clickx) Local dy:Int=(MouseY()-clicky) distance#=Sqr(dx*dx+dy*dy) EndIf If MouseDown(1)=False And click=1 click=0 EndIf If MouseDown(2)>0 enemy.enemynew(Rnd(800),Rnd(600),Rnd(2.5,2.5),Rnd(0.08,0.1)) EndIf enemy.enemyupdate() enemy.enemydraw() 'DrawRect playerx-5,playery-5,10,10 SetAlpha 0.8 SetColor 255,0,0 SetBlend(LIGHTBLEND) DrawOval playerx-distance#,playery-distance#,distance#*2,distance#*2 SetAlpha 1 Flip Until KeyDown(KEY_ESCAPE) Or AppTerminate() End
Code archives/Algorithms/Homing physics ( 2D )
This code has been declared by its author to be Public Domain code.
Download source code
| Allow enemies to chase player, with velocity and acceleration. |
;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 |
Comments
Dud! I've been here many time and I had not seen the original code. Nice.