Code: Select all
// Tappelu AI Edition
// Ennakon laskeminen ammukselle
// Tehny Aavesoturi
// Saapi käyttää vapaasti
SCREEN 800,600,0,cbWindowed
// vakiot, joilla voi säätää kaikenlaista
Const maxShots = 20 // maksimi määrä ammuksia kerralla pelissä
Const turnRate = 5.0 // kuinka nopeasti pelaajat kääntyy (astetta / frame)
Const speed = 2.0 // pelaajien liikkumisnopeus (pikseliä / frame)
Const shotRange = 900.0 // ammusten kantama (pikseliä)
Const shotSpeed = 5.0 // ammusten nopeus (pikseliä / frame)
Const loadingTime = 500 // latausaika (millisekuntia)
Const radius = 8 // pelaajan "hahmon" säde (pikseliä)
// end of vakiot
Dim x1#, y1#, x2#, y2#, a1#, a2#, t1, t2
Dim ai_recX#, ai_recY#, a#, theta#, phi#, dir#
Dim points1, points2
Dim shots(maxShots, 3) As Float
// aloituspaikat
x1 = ScreenWidth()/4*3
y1 = ScreenHeight()/2
a1 = 0
x2 = ScreenWidth()/4
y2 = ScreenHeight()/2
a2 = 180
Dim i
// PÄÄLUUPPI
Repeat
Gosub Keys
Gosub AI
Gosub Shots
Gosub Display
Forever
// END OF PÄÄLUUPPI
// Ihmispelaajan nappulat
Keys:
a1 = a1 - ( RightKey()-LeftKey() ) * turnRate
s = UpKey() * speed
x1 = x1 + Cos(a1) * s
y1 = y1 - Sin(a1) * s
If KeyDown(cbKeySpace) And Timer() > t1 + loadingTime Then Fire(x1,y1,a1): t1 = Timer()
Return
// Laskee vakio nopeudella liikkuvalle kohteelle ennakon eli mihin tulisi ampua jotta osuu
// ja kääntää vihupelaajaa sen mukaisesti sekä ampuu jos saa piikille
AI:
a# = GetAngle(x2,y2,x1,y1) 'kulma kohteeseen
theta# = Distance(x1,y1,ai_recX,ai_recY) / shotSpeed 'kohteen ja ammuksen nopeuksien suhde
phi# = theta * Sin( a1 - a )
If Abs(phi) < 1 Then 'phi:n täytyy olla välillä ]-1,1[ jotta arcsin antaisi järkevää tulosta
dir# = a + ASin(phi) 'kulma johon pyritään kääntymään
If Abs(dir-a2) <= turnRate Then 'jos ollaan lähellä, käännytään suoraan
a2 = dir 'tämän voisi laskea huijaamiseksi, koska käännytään tarkemmin kun ihmisen on mahdollista
Else 'jos ollaan kauempana ni käännytään lähemmän suunnan kautta turnRaten verran
a2 = NearestAngle(dir, a2 + turnRate, a2 - turnRate)
EndIf
EndIf
// Jos ollaan tarpeeksi lähellä laskettua kulmaa, ammutaan (2:n asteen tarkkuus on tässä riittävä)
If Abs(dir-a2) < 2 And Timer() > t2 + loadingTime Then Fire(x2,y2,a2): t2 = Timer()
// Otetaan pelaajan koordinaatit muistiin, jotta voidaan laskea pelaajan nopeus
ai_recX = x1
ai_recY = y1
Return
// Liikuttaa, laskee törmäykset, poistaa ja piirtää ammukset
Shots:
For i = 0 To maxShots
If shots(i,0) > 0 Then
shots(i,0) = shots(i,0) - shotSpeed
shots(i,1) = shots(i,1) + Cos(shots(i,3)) * shotSpeed
shots(i,2) = shots(i,2) - Sin(shots(i,3)) * shotSpeed
If Distance(shots(i,1), shots(i,2), x1, y1) < radius * 2 Then shots(i,0) = 0: points2+1
If Distance(shots(i,1), shots(i,2), x2, y2) < radius * 2 Then shots(i,0) = 0: points1+1
Color cbWhite: Dot shots(i,1), shots(i,2)
EndIf
Next i
Return
// Piirtää pelaajat ja pisteet
Display:
Color 255,80,255 : Circle x1-radius,y1-radius,radius*2,OFF
Color cbWhite : Line x1,y1,x1+Cos(a1)*(radius*2),y1-Sin(a1)*(radius*2)
Color 80,248,255 : Circle x2-radius,y2-radius,radius*2,OFF
Color cbWhite : Line x2,y2,x2+Cos(a2)*(radius*2),y2-Sin(a2)*(radius*2)
Color 80,248,255 : Text 10, 10, "Cyan score: "+points2
Color 255,80,255 : Text ScreenWidth() - TextWidth("Magenta score: "+points2)-10, 10, "Magenta score: "+points1
DrawScreen
Return
// Luo uuden ammuksen ja ampuu sen
Function Fire(x#, y#, a#)
Dim i
For i = 0 To maxShots
If shots(i,0) <= 0 Then
shots(i,0) = shotRange
shots(i,1) = x + (radius*2) * Cos(a)
shots(i,2) = y - (radius*2) * Sin(a)
shots(i,3) = a
Exit
EndIf
Next i
End Function
// Palauttaa kulman (ang1 tai ang2), joka on lähimpänä kulmaa ang
Function NearestAngle#(ang#,ang1#,ang2#) 'by Astigma
ang1 = WrapAngle(ang1)
ang2 = WrapAngle(ang2)
If Distance(Cos(ang),Sin(ang),Cos(ang1),Sin(ang1)) < Distance(Cos(ang),Sin(ang),Cos(ang2),Sin(ang2)) Then Return ang1 Else Return ang2
End Function