Ja Hallo!
Ich hab schon lang nix mehr fertig gekriegt und da dachte ich mir einfach mal dass ich mich an was Kleinem versuche.
Ein vollwertiger Shooter mit LAN / KI / Graphikeffekten / Story / Scripting / wasweißich wäre etwas zu viel, daher hab ich mich nur der KI angenommen
Hier mal ein Beispiel wie man eine 2D-Topdown-Shooter-KI (auf freiem Feld. Die Berücksichtigung einer Map welcher Art auch immer müsste man selber machen) angehen könnte (inklusive Bots in Teams kämpfen lassen, sogar ein wenig steuern)
BlitzBasic: [AUSKLAPPEN] [EINKLAPPEN] Global gfx_w=800 Global gfx_h=800 Graphics gfx_w,gfx_h,0,2 SetBuffer BackBuffer() AppTitle "TopDown-Shooter-KI-Test auf offenem Feld mit Teambildung" SeedRnd MilliSecs()
Global ctrl_mhit,ctrl_mx,ctrl_my
Local timer=CreateTimer(50)
Const MODE_ERKUNDEN=0 Const MODE_STICK_TOGETHER=-1 Const MODE_DEFENSE=-2
Type team Field x,y Field r,g,b Field kills,loss Field members Field friendlyfire Field leben Field schaden Field speed# Field radius Field schussinterval Field mode Field leader.player End Type
Type player Field x#,y#,w Field leben Field mode Field team.team Field movetimer Field schusstimer Field offsetx,offsety End Type
Type shot Field x#,y#,w Field player.player Field team.team End Type
CreateTeam(50,50,10,20,4,1,100,700) CreateTeam(gfx_w-50,gfx_h-50,10,25,1,2,150,500) CreateTeam(gfx_w-50,50,10,10,2,1.5,80,1000) CreateTeam(50,gfx_h-50,10,40,3,1,200,1200)
CreateTeam(gfx_w/2,gfx_h/2,1,100,5,0,200,200)
Global team_count=5
.menu Repeat MouseInput() Rect gfx_w-150,10,100,20,0 Text gfx_w-100,12,"Kampf!",1 If ctrl_mhit Then If ctrl_mx>gfx_w-150 And ctrl_mx<gfx_w-50 And ctrl_my>10 And ctrl_my<30 Then Goto simu EndIf EndIf Settings() Flip 0:Cls WaitTimer timer Until KeyHit(1) End
.simu Reset() anfang=MilliSecs() Repeat start=MilliSecs() MouseInput() UpdatePlayer() UpdateShots() HUD() Color 255,255,255 Text gfx_w/2,gfx_h-25,"FPS: "+(1000.0/(MilliSecs()-start)),1 Text gfx_w/2,10,"Spielzeit: "+((MilliSecs()-anfang)/1000),1 Flip 0:Cls WaitTimer timer Until KeyHit(1) Goto menu
Function MouseInput() ctrl_mx=MouseX() ctrl_my=MouseY() ctrl_mhit=MouseHit(1) End Function
Function CreateTeam(spawnx,spawny,anzahl,leben,schaden,speed,radius,schussinterval) Local team.team=New team team\x=spawnx team\y=spawny team\r=Rand(50,255) team\g=Rand(50,255) team\b=Rand(50,255) team\friendlyfire=True team\leben=leben team\schaden=schaden team\speed=speed team\radius=radius*radius team\schussinterval=schussinterval team\members=anzahl Local pl.player For i=1 To team\members pl=New player If i=1 Then team\leader=pl pl\team=team Respawn(pl) Next End Function
Function Reset() Delete Each shot Delete Each player Local team.team Local pl.player For team=Each team For i=1 To team\members pl=New player If i=1 Then team\leader=pl pl\team=team Respawn(pl) Next Next End Function
Function Respawn(pl.player) pl\leben=pl\team\leben pl\x=pl\team\x+Rand(-20,20) pl\y=pl\team\y+Rand(-20,20) pl\offsetx=Rand(-30,30) pl\offsety=Rand(-30,30) pl\w=Rand(0,359) End Function
Function UpdatePlayer() Local size=15 Local pl.player,pl2.player Local shot.shot Local msecs=MilliSecs() For pl=Each player If pl\mode=MODE_ERKUNDEN Then ok=True If pl\team\mode=MODE_STICK_TOGETHER Then If pl<>pl\team\leader Then ok=False pl\w=ATan2(pl\team\leader\y-pl\y+pl\offsety,pl\team\leader\x-pl\x+pl\offsetx) EndIf EndIf If ok Then If msecs-pl\movetimer>3000 Then pl\w=pl\w+Rand(-50,50) pl\movetimer=msecs EndIf EndIf pl\x=pl\x+Cos(pl\w)*pl\team\speed pl\y=pl\y+Sin(pl\w)*pl\team\speed If pl\x<0 Or pl\x>gfx_w Or pl\y<0 Or pl\y>gfx_h Then pl\w=pl\w+90 If pl\team\mode=MODE_DEFENSE Then If (pl\x-pl\team\x)*(pl\x-pl\team\x)+(pl\y-pl\team\y)*(pl\y-pl\team\y)>100*100 Then pl\w=ATan2(pl\team\y-pl\y+pl\offsety,pl\team\x-pl\x+pl\offsetx) EndIf EndIf For pl2=Each player If pl\team<>pl2\team Then If (pl\x-pl2\x)*(pl\x-pl2\x)+(pl\y-pl2\y)*(pl\y-pl2\y)<pl\team\radius Then pl\mode=Handle(pl2) Exit EndIf EndIf Next Else pl2=Object.player(pl\mode) If pl2=Null Then pl\mode=0 Else pl\w=ATan2(pl2\y-pl\y,pl2\x-pl\x) If msecs-pl\schusstimer>pl\team\schussinterval Then shot=New shot shot\x=pl\x shot\y=pl\y shot\w=pl\w shot\player=pl shot\team=pl\team pl\schusstimer=msecs EndIf If (pl\x-pl2\x)*(pl\x-pl2\x)+(pl\y-pl2\y)*(pl\y-pl2\y)>pl\team\radius Then pl\mode=0 EndIf EndIf EndIf Color pl\team\r,pl\team\g,pl\team\b Oval pl\x-(size/2),pl\y-(size/2),size,size,0 Line pl\x,pl\y,pl\x+Cos(pl\w)*size,pl\y+Sin(pl\w)*size Next End Function
Function UpdateShots() Local shot.shot Local pl.player Color 255,255,255 For shot=Each shot shot\x=shot\x+Cos(shot\w)*15 shot\y=shot\y+Sin(shot\w)*15 If shot\x<0 Or shot\x>gfx_w Or shot\y<0 Or shot\y>gfx_h Then Delete shot Else For pl=Each player If pl<>shot\player Then If shot\team\friendlyfire=True Or shot\team<>pl\team Then If (pl\x-shot\x)*(pl\x-shot\x)+(pl\y-shot\y)*(pl\y-shot\y)<8*8 Then pl\leben=pl\leben-shot\team\schaden If pl\leben<=0 Then If shot\player<>Null Then shot\player\mode=0 shot\team\kills=shot\team\kills+1 pl\team\loss=pl\team\loss+1 Respawn(pl) EndIf Delete shot Exit EndIf EndIf EndIf Next If shot<>Null Then Oval shot\x-1,shot\y-1,2,2,1 EndIf Next End Function
Function HUD() Local team.team For team=Each team Color team\r,team\g,team\b Oval team\x-80,team\y-80,160,160,0 If (ctrl_mx-team\x)*(ctrl_mx-team\x)+(ctrl_my-team\y)*(ctrl_my-team\y)<80*80 Then Text team\x,team\y-20,"Kills: "+team\kills,1 Text team\x,team\y-5,"Verluste: "+team\loss,1 Select team\mode Case MODE_ERKUNDEN Text team\x,team\y+10,"Erkunden",1 Case MODE_STICK_TOGETHER Text team\x,team\y+10,"Geschlossenes Team",1 Case MODE_DEFENSE Text team\x,team\y+10,"Verteidigung",1 End Select If ctrl_mhit Then team\mode=(team\mode-1) Mod 3 EndIf EndIf Next End Function
Function Settings() Text 10,10,"Anzahl der Teams: "+team_count Line 10,30,150,30 Oval 10+team_count*4-2,25,4,10,1 If MouseDown(1) Then If ctrl_my>25 And ctrl_my<35 Then If ctrl_mx>10 And ctrl_mx<150 Then team_count=(ctrl_mx-10)/4+1 EndIf EndIf EndIf Rect 10,50,70,20,0 Text 12,52,"Spawn-x" Rect 80,50,70,20,0 Text 82,52,"Spawn-y" Rect 150,50,95,20,0 Text 152,52,"Mitglieder" Rect 245,50,60,20,0 Text 247,52,"Leben" Rect 305,50,70,20,0 Text 307,52,"Schaden" Rect 375,50,70,20,0 Text 377,52,"Geschw." Rect 445,50,70,20,0 Text 447,52,"Radius" Rect 515,50,130,20,0 Text 517,52,"Schussintervall" Rect 645,50,110,20,0 Text 647,52,"FriendlyFire" Local team.team Local y=0 For team=Each team team\x=InputField(10,70+y*20,70,20,team\x) team\y=InputField(80,70+y*20,70,20,team\y) team\members=InputField(150,70+y*20,95,20,team\members) team\leben=InputField(245,70+y*20,60,20,team\leben) team\schaden=InputField(305,70+y*20,70,20,team\schaden) team\speed=InputField(375,70+y*20,70,20,team\speed) team\radius=InputField(445,70+y*20,70,20,Sqr(team\radius))^2 team\schussinterval=InputField(515,70+y*20,130,20,team\schussinterval) If ctrl_mhit Then If ctrl_mx>645 And ctrl_mx<645+110 And ctrl_my>70+y*20 And ctrl_my<70+y*20+20 Then team\friendlyfire=Not team\friendlyfire EndIf EndIf Rect 645,70+y*20,110,20,0 If team\friendlyfire Then Text 647,72+y*20,"An" Else Text 647,72+y*20,"Aus" EndIf y=y+1 Next If y>team_count Then For i=1 To (y-team_count) Delete Last team Next ElseIf y<team_count Then For i=1 To (team_count-y) team=New team team\r=Rand(50,255) team\g=Rand(50,255) team\b=Rand(50,255) Next EndIf End Function
Function InputField(x,y,w,h,txt$) Local ret$=txt$ Rect x,y,w,h,0 Text x+2,y+2,txt$ If ctrl_mhit Then If ctrl_mx>x And ctrl_mx<x+w And ctrl_my>y And ctrl_my<y+h Then Color 0,0,0 Rect x+1,y+1,w-2,h-2,1 Color 255,255,255 Flip 0 Locate x+2,y+2 ret$=Input("") EndIf EndIf Return ret$ End Function
Man verzeihe mir, dass der Code kaum kommentiert ist
Bin irgenwie zu faul, aber wenn sich wer echt dafür interessiert werde ich mich anstrengen.
Um die KI in einem eigenen Spiel zu benutzen braucht ihr alle 3 Types, die Konstanten und die Functionen CreateTeam, Reset, UpdatePlayer, UpdateShots und event. Respawn.
Viel Spass beim zuschauen und herumspielen damit.
Achja, wie spielt man das überhaupt? Man kann nur im Einstellungsmenu die Team-Attribute festlegen. Dazu einfach mit der Maus in die Felder klicken und Werte eingeben.
"Ingame" kann man mit der Maus auf die bunten Kreise (Team-Basen) fahren und sich dort den Punktestand anschauen. Bei Klick auf diesen Kreis wird die Team-Taktik geändert. Es gibt "Erkunden", "Geschlossenes Team" und "Verteidigung".
Das Einstellungsmenu ist natürlich kein optischer oder funktionaler Leckerbissen, es tut nur seine Pflicht...
mfG, Christoph.
EDIT 9.1.2010: Code Tags in BB-Code-Tags geändert.
|