Tekoäly on totta puhuen tehty aika kusisella tavalla. Ongelmasi johtuu turhasta: Repeat - Until Distance() - silmukasta, jonka sisällä ukkoja liikutellaan. Eli ukkoa liikutetaan, kunnes ollaan tarpeeksi lähellä, jonka jälkeen liikutetaan seuraavaa ukkoa jne. Vaihda tämä yksinkertaiseen ehtolauseeseen:
Code: Select all
If Distance2(bottisotilas\obj,sijaintihuijari) > 100 Then
Ongelmat eivät kuitenkaan tähän lopu. Jos teemme äskeisen korjauksen koodiin, ja kokeilemme sitä, huomaamme että ukot nytkähtävät vähän hiirtä kohti ja lopettavat. Tämä johtuu siitä, että ukkoja itse asiassa liikutetaan vain, jos MouseUp( 2 ) = True. Poista itse ukkojen silmukka (for bottisotilaat ...) tästä ehtolauseesta.
Lisäksi suosittelen tekemään sotilaat-lohkoon kaksi ylimääräistä kenttää: targetX ja targetY. Nämä ovat sotilaiden yksilölliset kohteet. Näin voit laittaa esim. kaksi sotilasta liikkumaan pisteeseen (100, 100), ja loput muualle. Pitkällä tähtäimellä tuo "sijaintihuijari"-systeemi ei tule toimimaan:
Code: Select all
Type sotilaat //tämä pidetään objekteille
Field obj
Field targetX
Field targetY
EndType
Uudistettu pääsilmukka. Jos korvaat tämän koodisi omalla, ja lisäät nuo targetX- ja targetY-kentät, pitäisi koodin toimia.
Code: Select all
Repeat
Text 0,10,"X"+MouseWX()
Text 0,30,"Y"+MouseWY()
If MouseUp( 2 ) Then
For is.sotilaat = Each sotilaat
//otetaan ukkojen ja hiiren kulma ylös
kulma = GetAngle( ObjectX( is\obj ), ObjectY( is\obj ), MouseWX(), MouseWY() )
//TargetX- ja Y = hiiren koordinaatit + 100 pikseliä satunnaiseen suuntaan.
is\targetX = MouseWX() - Cos( kulma ) * 100 * Rand( -1, 1 )
is\targetY = MouseWY() + Sin( kulma ) * 100 * Rand( -1, 1 )
Next is
EndIf
nopeus = 5 //nopeus = 5
For is.sotilaat = Each sotilaat
//JOS is\targetX ja -Y ovat eri kuin 0, TAI ukko on tarpeeksi lähellä targettia ...
If is\targetX <> 0 And is\targetY <> 0 And Distance( ObjectX( is\obj ), ObjectY( is\obj ), is\targetX, is\targetY ) >= nopeus Then
//ukon ja kohteen kulma
kulma = GetAngle( ObjectX( is\obj ), ObjectY( is\obj ), is\targetX, is\targetY )
//liikutetaan kohdetta kohti nopeudella "nopeus"
TranslateObject is\obj, Cos( kulma ) * nopeus, -Sin( kulma ) * nopeus
EndIf
Next is
DrawScreen
Forever
Tässä vielä koneeni uumenista kaivettu strategiapeli-esimerkki:
Code: Select all
SCREEN 1024, 768
FrameLimit 40
Type tUkot
Field cX
Field cY
Field cTX
Field cTY
Field cValittu
Field cNopeus
End Type
//luodaan ukot
For i = 1 To 10
iu.tUkot = New( tUkot )
iu\cX = Rand( 0, ScreenWidth() )
iu\cY = Rand( 0, ScreenHeight() )
iu\cTX = iu\cX
iu\cTY = iu\cY
iu\cNopeus = 6
Next i
Repeat
//mousehit tallentaa valinta-boksin aloituskoordinaatit. Mouseup: kaikki boksin sisällä olevat joukot valitaan.
If MouseHit( 1 ) Then
_startX = MouseX()
_startY = MouseY()
ElseIf MouseUp( 1 ) Then
For iu.tUkot = Each tUkot
If iu\cX > _pieninX And iu\cX < _suurinX And iu\cY > _pieninY And iu\cY < _suurinY Then
If iu\cValittu = False Then
valittuja + 1
EndIf
iu\cValittu = True
Else
If iu\cValittu = True Then
valittuja - 1
EndIf
iu\cValittu = False
EndIf
Next iu
_startX = 0
_startY = 0
EndIf
//piirretään valintaboksi.
If _startX <> 0 Or _startY <> 0 Then
_pieninX = Min( _startX, MouseX() )
_pieninY = Min( _startY, MouseY() )
_suurinX = Max( _startX, MouseX() )
_suurinY = Max( _startY, MouseY() )
Box _pieninX, _pieninY, _suurinX - _pieninX, _suurinY - _pieninY, 0
EndIf
//Mouse2 liikuttaa joukkoja.
If MouseHit( 2 ) Then
_posX = -13 * valittuja / 2
_posY = -13 * valittuja / 2
row = 0
For iu.tUkot = Each tUkot
If iu\cValittu = True Then
If row = valittuja / 2 Then
_posY + 13
_posX = -13 * valittuja / 2
EndIf
row + 1
_posX + 13 * row
iu\cTX = MouseX() + _posX
iu\cTY = MouseY() + _posY
EndIf
Next iu
EndIf
//piirretään ja liikutetaan joukkoja.
For iu.tUkot = Each tUkot
If iu\cValittu = True Then
Color cbGreen
Text iu\cTX, iu\cTY, "A"
Color cbRed
Else
Color cbWhite
EndIf
//liikutetaan ukkoja jotka eivät ole päämäärässään.
If Distance( iu\cX, iu\cY, iu\cTX, iu\cTY ) > iu\cNopeus Then
kulma# = GetAngle( iu\cX, iu\cY, iu\cTX, iu\cTY )
iu\cX = iu\cX + Cos( kulma# ) * iu\cNopeus
iu\cY = iu\cY - Sin( kulma# ) * iu\cNopeus
EndIf
Text iu\cX, iu\cY, "A"
Next iu
DrawScreen
Forever