Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
-
- Active Member
- Posts: 163
- Joined: Fri Aug 31, 2007 7:07 pm
- Location: Helsinki
- Contact:
Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Aavesoturin koodeja - keskeneräisiä projekteja ja prototyyppejä
Julkaisen tässä muutaman mielenkiintoisen, mutta kesken jääneen vanhan projun koodit (ja tarpeelliset mediat). Kaikkien ei ollut koskaan tarkoituskaan tullat "valmiiksi" vaan lähinnä tutkia osaanko tehdä jonkun jutun. Huomatkaa, että kaikki koodit ei ehkä edusta parasta ohjelmointityyliä - esim. RFS:ää lähdin alunperin kasaamaan periaatteella "Ei sillä niin väliä kunhan toimii"; se sitten kostautui kun myöhemmin tartuin uudestaan projektiin ja jouduin käyttämään paljon aikaa pelastaakseni koodin täydelliseltä puuroutumiselta.
Ei sisällä mitään mullistavaa, mutta voihan olla, että joku saa jonkun inspiraation
Koodeja saa vapaasti käyttää omiin tarkoituksiinsa (kiitos creditseissä olis kiva )
Formation Based Combat Study
Jossain vaiheessa Total War:eista innostuneena päätin tutkiskella muodostelmiin perustuvaa strategiapelin tekemistä. Päädyin sangen omaperäisiin ratkaisuihin muodostelmien teossa - siellä liikutellaan paljon näkymätöntä apuonjektia ym, mutta jos törmäystarkistuksen unohtaa, niin muodostelmat toimii ihan mukavasti. Homma sisältää myös jonkunlaisen taistelumoraalin mallinnuksen ja esim. selän takaa tai sivustaan hyökkääminen antaa ison bonuksen taistelussa. Bugeja kuitenkin on paljon erityisesti taistelun ja tekoälyn puolella, jotka on täysiä torsoja.
Kontrollit: Aika perus strategia kontrollit: hiiren vasen painike toteuttaa kursorin osoittaman toiminnon (valitse, hyökkää, liiku, ammu), tuplaklikkaus antaa "toteuta komento juosten"-käskyn (jousimiehet vaan hyökkäävät ampumisen sijaan). Viemällä kursorin joukkojen päälle, saa tietoa niiden statuksesta. Kakkospainike avaa valikon josta voi valita muodostelman (tiukka suorakaide, löysä suorakaide ja kiila), säätää muodostelman kokoa (rivien lisäys/vähennys) ja valita korjaavatko ukot muotonsa ennen uuteen suuntaan lähtöä vai ei.
Kuva
Lataa
3d Voxel Terrain Engine
Alkoi yhdessä vaiheessa vokselit himottaa ja niinpä testasin osaisinko rakentaa enginen niille. Pari tutoa tutkittuani homma oli loppuen lopuksi sangen yksinkertaista. Ircissä sitten sain tuotoksen kuvaa näyttäessäni kuulla, että atomimalli oli tehnyt samanlaisen. Minun on tottakai paljon suurempi, parempi ja kauniimpi
(Tiesin kyllä jo alottaessani, että hidashan siitä tulisi - ja niin tulikin. Kuitenkin laatua huonontamalla ja filttereitä poistamalla se on selkeästi reaaliaikainen Kun cb prototyyppi toimi niinkin hyvin, vaihdoin kieltä ja freebasicilla engine puhkesi kukkaan - fps yli 100 vaikka asetukset säätäisi paremmaksi kun cb version parhaassa demo-kuvassa. Lisäsin sitten ominaisuuksia kuten pilvet, maailman proseduraalisen luomisen, animoidun veden ym - kaikki softa pohjaisesti pelkkiä suorakulmioita piirtämällä (tosin eipä niitä suorakulmioita siitä oikein edes erota). )
Kontrollit: Nuolista liikkuu, hiiri katselee.
Herkkuja, oletuksena pois päältä - laita päälle:
F3 - bilineaarinen väri-interpolointi (parantaa laatua dramaattisesti)
F4 - bilineaarinen korkeusinterpolointi
F2 - ilmakehän sinertävyys efekti
+/- - piirtoetäisyyden säätö
F11 - screenshot
Kuva
Lataa
(esimerkki kartat pöllin jostakin tutoriaalista)
Experimental Combat Spider Bot
Pelattuanu String Theory -nimistä peliä, jossa liikutetaan oliota ampumalla seittejä seiniin, päätin kokeilla tehdä omanlaisen version, jossa olisi vihollisiakin. Yllättävän kivuttomasti sain köysi/seitti fysiikan toteutettua, ei tarvinnut edes nettiin tukeutua. Täysin fysikaalisesti korrektia simulaatio ei ole, vaan muokkasin sitä pelattavammaksi tinkimällä realismista. Kuitenkin jokin pieni juttu jäi niiden ampumisessa tai takaisin paluussa pieleen niin, että en koskaan alkanut kehittämään pelillisiä elementtejä. Niinpä käsissä on lähinnä teknologiademo, jossa voi liikuskella köysiä ampumalla. Laitoin laserin ampumaan yhtä seiteistä ihan huvin vuoksi.
Kontrollit: Numpad määrittää mihin suuntaan ammutaan.
Lataa
(Ikävä kyllä koodissa näyttäisi olevan paljon vaihtoehtoisia naru mallinnuksia, enkä nyt enää muista mikä antoi parhaan tuloksen (kommentointi olis kannattanu... ) Laitoin sitten jotain tollasta mikä toimii kohtuu hyvin, tosin köydet ei ole niin "pehmeitä" kun jossain toisessa taktiikassa.)
Reaching for Stars!
Lähes valmiiksi asti päässyt vuoropohjainen avaruusimpperiumipeli, joka on tyssännyt siihen kun en jaksanut viilata heikkoa tekoälyä paremmaksi. Projektit-alueelta löytyy haulla topikki ja projektiblogissani on aiheesta lisää posteja.
Pelin kotisivut
Lataa koodit
Julkaisen tässä muutaman mielenkiintoisen, mutta kesken jääneen vanhan projun koodit (ja tarpeelliset mediat). Kaikkien ei ollut koskaan tarkoituskaan tullat "valmiiksi" vaan lähinnä tutkia osaanko tehdä jonkun jutun. Huomatkaa, että kaikki koodit ei ehkä edusta parasta ohjelmointityyliä - esim. RFS:ää lähdin alunperin kasaamaan periaatteella "Ei sillä niin väliä kunhan toimii"; se sitten kostautui kun myöhemmin tartuin uudestaan projektiin ja jouduin käyttämään paljon aikaa pelastaakseni koodin täydelliseltä puuroutumiselta.
Ei sisällä mitään mullistavaa, mutta voihan olla, että joku saa jonkun inspiraation
Koodeja saa vapaasti käyttää omiin tarkoituksiinsa (kiitos creditseissä olis kiva )
Formation Based Combat Study
Jossain vaiheessa Total War:eista innostuneena päätin tutkiskella muodostelmiin perustuvaa strategiapelin tekemistä. Päädyin sangen omaperäisiin ratkaisuihin muodostelmien teossa - siellä liikutellaan paljon näkymätöntä apuonjektia ym, mutta jos törmäystarkistuksen unohtaa, niin muodostelmat toimii ihan mukavasti. Homma sisältää myös jonkunlaisen taistelumoraalin mallinnuksen ja esim. selän takaa tai sivustaan hyökkääminen antaa ison bonuksen taistelussa. Bugeja kuitenkin on paljon erityisesti taistelun ja tekoälyn puolella, jotka on täysiä torsoja.
Kontrollit: Aika perus strategia kontrollit: hiiren vasen painike toteuttaa kursorin osoittaman toiminnon (valitse, hyökkää, liiku, ammu), tuplaklikkaus antaa "toteuta komento juosten"-käskyn (jousimiehet vaan hyökkäävät ampumisen sijaan). Viemällä kursorin joukkojen päälle, saa tietoa niiden statuksesta. Kakkospainike avaa valikon josta voi valita muodostelman (tiukka suorakaide, löysä suorakaide ja kiila), säätää muodostelman kokoa (rivien lisäys/vähennys) ja valita korjaavatko ukot muotonsa ennen uuteen suuntaan lähtöä vai ei.
Kuva
Lataa
3d Voxel Terrain Engine
Alkoi yhdessä vaiheessa vokselit himottaa ja niinpä testasin osaisinko rakentaa enginen niille. Pari tutoa tutkittuani homma oli loppuen lopuksi sangen yksinkertaista. Ircissä sitten sain tuotoksen kuvaa näyttäessäni kuulla, että atomimalli oli tehnyt samanlaisen. Minun on tottakai paljon suurempi, parempi ja kauniimpi
(Tiesin kyllä jo alottaessani, että hidashan siitä tulisi - ja niin tulikin. Kuitenkin laatua huonontamalla ja filttereitä poistamalla se on selkeästi reaaliaikainen Kun cb prototyyppi toimi niinkin hyvin, vaihdoin kieltä ja freebasicilla engine puhkesi kukkaan - fps yli 100 vaikka asetukset säätäisi paremmaksi kun cb version parhaassa demo-kuvassa. Lisäsin sitten ominaisuuksia kuten pilvet, maailman proseduraalisen luomisen, animoidun veden ym - kaikki softa pohjaisesti pelkkiä suorakulmioita piirtämällä (tosin eipä niitä suorakulmioita siitä oikein edes erota). )
Kontrollit: Nuolista liikkuu, hiiri katselee.
Herkkuja, oletuksena pois päältä - laita päälle:
F3 - bilineaarinen väri-interpolointi (parantaa laatua dramaattisesti)
F4 - bilineaarinen korkeusinterpolointi
F2 - ilmakehän sinertävyys efekti
+/- - piirtoetäisyyden säätö
F11 - screenshot
Kuva
Lataa
(esimerkki kartat pöllin jostakin tutoriaalista)
Experimental Combat Spider Bot
Pelattuanu String Theory -nimistä peliä, jossa liikutetaan oliota ampumalla seittejä seiniin, päätin kokeilla tehdä omanlaisen version, jossa olisi vihollisiakin. Yllättävän kivuttomasti sain köysi/seitti fysiikan toteutettua, ei tarvinnut edes nettiin tukeutua. Täysin fysikaalisesti korrektia simulaatio ei ole, vaan muokkasin sitä pelattavammaksi tinkimällä realismista. Kuitenkin jokin pieni juttu jäi niiden ampumisessa tai takaisin paluussa pieleen niin, että en koskaan alkanut kehittämään pelillisiä elementtejä. Niinpä käsissä on lähinnä teknologiademo, jossa voi liikuskella köysiä ampumalla. Laitoin laserin ampumaan yhtä seiteistä ihan huvin vuoksi.
Kontrollit: Numpad määrittää mihin suuntaan ammutaan.
Lataa
(Ikävä kyllä koodissa näyttäisi olevan paljon vaihtoehtoisia naru mallinnuksia, enkä nyt enää muista mikä antoi parhaan tuloksen (kommentointi olis kannattanu... ) Laitoin sitten jotain tollasta mikä toimii kohtuu hyvin, tosin köydet ei ole niin "pehmeitä" kun jossain toisessa taktiikassa.)
Reaching for Stars!
Lähes valmiiksi asti päässyt vuoropohjainen avaruusimpperiumipeli, joka on tyssännyt siihen kun en jaksanut viilata heikkoa tekoälyä paremmaksi. Projektit-alueelta löytyy haulla topikki ja projektiblogissani on aiheesta lisää posteja.
Pelin kotisivut
Lataa koodit
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Kivaa tavaraa tuo 3D voxel terrain juttu eniten kinnostaa mutta tuo viimeinenkin on ihan kivan oloinen, vosi vaikka vähän muunnella jos siitä saisi jotain kivaa aikaan.
-
- Moderator
- Posts: 1583
- Joined: Mon Aug 27, 2007 11:24 pm
- Location: Otaniemi - Mikkeli -pendelöinti
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Tuosta voxel-höskästä. Jos käyttäisit pienempää määrää värejä ja tekisit kuvan, josta copyboxilla napsisit suorakaiteita, nopeus kasvaisi huimasti.
Hienoja koodinpätkiä kaiken kaikkiaan.
Hienoja koodinpätkiä kaiken kaikkiaan.
-
- Active Member
- Posts: 163
- Joined: Fri Aug 31, 2007 7:07 pm
- Location: Helsinki
- Contact:
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Riippuu vähän: interpoloinnit päällä homma on laskennallisesti jo niin raskas cb:lle, että piirron osuus nopeuden puutteesta jää aika pieneksi.koodaaja wrote:Tuosta voxel-höskästä. Jos käyttäisit pienempää määrää värejä ja tekisit kuvan, josta copyboxilla napsisit suorakaiteita, nopeus kasvaisi huimasti.
Tuohan nyt muutenkin on hyvin optimoimaton prototyyppi versio, kunhan kokeilin tekniikkaa. Jos intoa riittää niin siitä vaan parantelemaan.
-
- Advanced Member
- Posts: 485
- Joined: Tue Aug 28, 2007 3:53 pm
- Location: Suomi, Finland
- Contact:
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
spiderbotille hiiri ohjaus
muistakaa pistää joku kuva hiirelle!
Code: Select all
If MouseHit(1) Then FireString(player,-WrapAngle(GetAngle(ObjectX(player),ObjectY(player),MouseWX(),MouseWY())))
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Nämähän ovat hyvin käytännöllisiä. Tosin, tuohon Formation Based Combat Studyyn en saa laitettua semmoista, että ukoille tulisi törmäys tilekartan kanssa. Miten sen voisi toteuttaa?
-
- Active Member
- Posts: 163
- Joined: Fri Aug 31, 2007 7:07 pm
- Location: Helsinki
- Contact:
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Kokeilepa laittaa CreateFormation funktioon sinne rivin 595 tienoille (missä muodostelman objektit luodaan luuppien sisällä) SetupCollision. Joudut vielä välittämään karttamuuttujan funktiolle joko parametrinä tai globaalina muuttujana.Vieras wrote:Nämähän ovat hyvin käytännöllisiä. Tosin, tuohon Formation Based Combat Studyyn en saa laitettua semmoista, että ukoille tulisi törmäys tilekartan kanssa. Miten sen voisi toteuttaa?
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Näinhän se piti tehdä? Kuitenkin, kartta tuli, mutta törmäys ei reagoi.
Code: Select all
SCREEN 1024,768
SetWindow "Formation Based Combat Study"
cur_point = LoadImage("cur_point.png")
cur_move = LoadImage("cur_move.png")
cur_wait = LoadImage("cur_wait.png")
cur_select = LoadImage("cur_select.png")
cur_attack = LoadImage("cur_attack.png")
cur_shoot = LoadImage("cur_shoot.png")
cur_scroll_up = LoadImage("cur_scroll_up.png")
cur_scroll_down = LoadImage("cur_scroll_down.png")
cur_scroll_left = LoadImage("cur_scroll_left.png")
cur_scroll_right = LoadImage("cur_scroll_right.png")
ShowMouse cur_wait
PositionMouse ScreenWidth()/2, ScreenHeight()/2
DrawScreen
font = LoadFont("Lucida Calligraphy",16)
SetFont font
Const maxgroups = 50
Const actorspergroup = 200
camspd = 5
Dim Actor(maxgroups,actorspergroup,6)
' 0 = alive flag
' 1 = obj
' 2 = unittype
' 3 = targetX
' 4 = targetY
' 5 = state
' 6 = speed
Dim Frm(maxgroups,15) As Float
' 0 = number of members
' 1 = side
' 2 = unittype
' 3 = targetX
' 4 = targetY
' 5 = state ---> 1=form up; 2=move; 3=charge; 4=shoot; 5=fight; 6=flee
' 6 = speed
' 7 = fatigue
' 8 = morale
' 9 = rows in box formation (neg. means a wedge)
'10 = formation type
'11 = moving type --> 0=stick with formation; 2=skirmish
'12 = target group
'13 = timer for firing bows
Global numGroups
Global dummy, greenbow, greenspear, greenhorse, redbow, redspear, redhorse
greenbow = LoadObject("GreenMarksman.png",90): ShowObject greenbow, OFF
'greenbow = LoadAnimObject("ArcherStrip.png", 32, 32, 0, 7): ShowObject greenbow, OFF
greenspear = LoadObject("GreenSpearman.png",90): ShowObject greenspear, OFF
greenhorse = LoadObject("GreenHorseman.png",90): ShowObject greenhorse, OFF
redbow = LoadObject("RedMarksman.png",90): ShowObject redbow, OFF
redspear = LoadObject("RedSpearman.png",90): ShowObject redspear, OFF
redhorse = LoadObject("RedHorseman.png",90): ShowObject redhorse, OFF
dummy = MakeObject()
Const SpriteSize = 16
Type ARROWS
Field obj
Field dist
Field dest
End Type
Const arrowspeed = 8
Const bowrange = 800
Const bowdelay = 4000
arrow = LoadObject("arrow.png",90)
ShowObject arrow, OFF
Global menuicon_halt, menuicon_formclose, menuicon_formloose, menuicon_formwedge, menuicon_addrow, menuicon_subtractrow ,menuicon_yes, menuicon_no
menuicon_halt = LoadImage("menuicon_halt.png")
menuicon_formclose = LoadImage("menuicon_formclose.png")
menuicon_formloose = LoadImage("menuicon_formloose.png")
menuicon_formwedge = LoadImage("menuicon_formwedge.png")
menuicon_addrow = LoadImage("menuicon_addrow.png")
menuicon_subtractrow = LoadImage("menuicon_subtractrow.png")
menuicon_yes = LoadImage("menuicon_yes.png")
menuicon_no = LoadImage("menuicon_no.png")
Global ImgMenu, MenuX, MenuY, MenuG, SecondMenu
Const MenuW = 180
ImgMenu = CreateGradient(MenuW, 7*TextHeight("|"), 150,150,180, 100,100,200, 0)
Global ImgInfo
ImgInfo = CreateGradient(140, 5*TextHeight("|"), 150,255,150, 80,255,80, 1)
Dim unitnames(5) As String
Dim statusnames(10) As String
Dim moralenames(6) As String
Dim fatiguenames(5) As String
unitnames(1) = "Marksmen": unitnames(2) = "Spearmen": unitnames(3) = "Horsemen"
statusnames(0) = "Waiting": statusnames(1) = "Reforming": statusnames(2) = "Moving": statusnames(3) = "Running": statusnames(4) = "Shooting": statusnames(5) = "Fighting": statusnames(6) = "Fleeing"
moralenames(0) = "Broken": moralenames(1) = "Nearly broken": moralenames(2) = "Low morale": moralenames(3) = "Average morale": moralenames(4) = "Good morale": moralenames(5) = "Excellent morale": moralenames(6) = "Touched by gods"
fatiguenames(0) = "Fresh": fatiguenames(1) = "Quite fresh": fatiguenames(2) = "Tired": fatiguenames(3) = "Very tired": fatiguenames(4) = "Exhausted": fatiguenames(5) = "Exhausted"
map=LoadMap("testmap.til","tileset.bmp")
'Group of own bowmen
CreateFormation(greenbow, 24, 1, -400, 200, 0, map, 3)
'Group of own spearmen
CreateFormation(greenspear, 30, 1, -300, 200, 0, map, 2)
'Group of own horsemen
CreateFormation(greenhorse, 25, 1, -300, -200, 0, map, 4)
'4 Groups of enemies
CreateFormation(redspear, 40, 2, 400, 0, 180.0, map, 3)
CreateFormation(redspear, 35, 2, 400, -200, 180.0, map, 3)
CreateFormation(redhorse, 15, 2, 450, 200, 180.0, map, 3)
CreateFormation(redbow, 35, 2, 500, -50, 180.0, map, 2)
selG = 1
plside = 1
DoubleClickDelay = 500
Repeat
Info = 0
Double = 0
If Timer() > mouserecord + DoubleClickDelay Then mouse1 = 0
If MouseHit(1) Then
mouse1+1
If mouse1 = 1 Then mouserecord = Timer()
If mouse1 = 2 Then Double = 1: mouse1 = 0
EndIf
cursor = cur_point
If SecondMenu = 0
CameraPick MouseX(), MouseY()
o = PickedObject()
If o <> 0 Then
If Int(GetWord(ObjectString(o),1,",")) = plside Then
cursor = cur_select
Info = ON: InfoG = Int(GetWord(ObjectString(o),2,","))
If MouseHit(1) Then selG = Int(GetWord(ObjectString(o),2,","))
If MouseHit(2) Then SecondMenu = True: MenuX = MouseX(): MenuY = MouseY(): MenuG = Int(GetWord(ObjectString(o),2,","))
Else
Info = ON: InfoG = Int(GetWord(ObjectString(o),2,","))
If selG <> 0 Then
If Frm(selG,2) = 1 Then cursor = cur_shoot Else cursor = cur_attack
If MouseHit(1) Then
If Frm(selG,2) = 1 Then
CommandFormation(selG, MouseWX(), MouseWY(), 4*(Not Double)+3*Double)
Else
'tempang# = GetAngle(ObjectX(Actor(selG,0,1)), -ObjectY(Actor(selG,0,1)), MouseWX(), -MouseWY())
PositionObject dummy, MouseWX(), MouseWY()
RotateObject dummy, GetAngle2(Actor(selG,0,1), dummy)
MoveObject dummy, 100
CommandFormation(selG, ObjectX(dummy), ObjectY(dummy), 2+Double)
EndIf
EndIf
EndIf
EndIf
Else
If selG <> 0 Then
cursor = cur_move
If MouseHit(1) Then CommandFormation(selG, MouseWX(), MouseWY(), 2+Double)
If MouseHit(2) Then selG = 0
EndIf
EndIf
If MouseX() < 20 Then TranslateCamera -camspd, 0: cursor = cur_scroll_left
If MouseX() > ScreenWidth()-20 Then TranslateCamera camspd, 0: cursor = cur_scroll_right
If MouseY() < 20 Then TranslateCamera 0, camspd: cursor = cur_scroll_up
If MouseY() > ScreenHeight()-20 Then TranslateCamera 0, -camspd: cursor = cur_scroll_down
EndIf
ShowMouse cursor
If KeyUp(cbkeyH) And selG <> 0 Then Frm(selG,5) = 0
If KeyUp(cbkeyC) And selG <> 0 Then Frm(selG,10) = 1: Frm(selG,5) = 1
If KeyUp(cbkeyL) And selG <> 0 Then Frm(selG,10) = 2: Frm(selG,5) = 1
If KeyUp(cbkeyW) And selG <> 0 Then Frm(selG,10) = 3: Frm(selG,5) = 1
If KeyUp(cbKeyA) And selG <> 0 And Frm(selG,10) < 3 Then Frm(selG,9) = Min(Frm(selG,9)+1, Frm(selG,0)): Frm(selG,5) = 1
If KeyUp(cbKeyS) And selG <> 0 And Frm(selG,10) < 3 Then Frm(selG,9) = Max(Frm(selG,9)-1, 1): Frm(selG,5) = 1
If KeyUp(cbkeyF) And selG <> 0 Then Frm(selG,11) = Not Frm(selG,11)
For iAr.ARROWS = Each ARROWS
MoveObject iAr\obj, arrowspeed
iAr\dist = iAr\dist + arrowspeed
If iAr\dist > iAr\dest Then
ObjectPick iAr\obj
o = PickedObject()
If o <> 0 Then
If Distance2(iAr\obj,o) < 24 Then
oppG = Int(GetWord(ObjectString(o),2,","))
oppA = Int(GetWord(ObjectString(o),3,","))
Frm(oppG,8) = Frm(oppG,8) - .005 'decrease morale, arrows are frightening
If Rnd(1) > .666 Then
Actor(oppG,oppA,0) = 0
DeleteObject Actor(oppG,oppA,1)
EndIf
EndIf 'is close enough
EndIf 'object found
DeleteObject iAr\obj
Delete iAr
EndIf 'arrow has landed
Next iAr
For g = 1 To numGroups
If Frm(g,0) = 0 Then Goto SkipGroup
numActors = CountActors(g)
If numActors = 0 Then Frm(g,0) = 0: Goto SkipGroup
If Frm(g,7) > 1.0 Then Frm(g,8) = Frm(g,8) - Frm(g,7) + 1: Frm(g,7) = 1.0
If Frm(g,8) <= 0.0 Then Frm(g,5) = 6
If numActors <= .10 * Frm(g,0) Then Frm(g,5) = 6
// AI ----------------------------------------------------
If Frm(g,1) <> plside And Frm(g,5) <> 6 Then
If Frm(g,7) > .7 Then
Frm(g,5) = 0
ElseIf Frm(g,12) = 0 Or Rand(0,100) = 0 Then
temp = 10000: temp2 = Frm(g,12)
For gg = 1 To numGroups
If Frm(gg,0) > 0 And Frm(gg,1) <> Frm(g,1) Then
If Distance2(Actor(g,0,1),Actor(gg,0,1)) < temp Then temp = Distance2(Actor(g,0,1),Actor(gg,0,1)): Frm(g,12) = gg
EndIf
Next gg
If Frm(g,12) <> temp2 Then
CloneObjectPosition dummy, Actor(Int(Frm(g,12)),0,1)
RotateObject dummy, GetAngle2(Actor(g,0,1), Actor(Int(Frm(g,12)),0,1))
If Frm(g,2) = 1 Then
MoveObject dummy, 20
CommandFormation(g, ObjectX(dummy), ObjectY(dummy), 4)
Else
MoveObject dummy, 100
CommandFormation(g, ObjectX(dummy), ObjectY(dummy))
EndIf
EndIf
ElseIf AngleDistance(ObjectAngle(Actor(g,0,1)), GetAngle2(Actor(g,0,1), Actor(Int(Frm(g,12)),0,1))) > 20 And AngleDistance(ObjectAngle(Actor(g,0,1)), GetAngle2(Actor(g,0,1), Actor(Int(Frm(g,12)),0,1))) < 170 Then
CloneObjectPosition dummy, Actor(Int(Frm(g,12)),0,1)
RotateObject dummy, GetAngle2(Actor(g,0,1), Actor(Int(Frm(g,12)),0,1))
If Frm(g,2) = 1 Then
MoveObject dummy, 20
CommandFormation(g, ObjectX(dummy), ObjectY(dummy), 4)
Else
MoveObject dummy, 100
CommandFormation(g, ObjectX(dummy), ObjectY(dummy))
EndIf
EndIf
If Distance2(Actor(g,0,1), Actor(Int(Frm(g,12)),0,1)) < 50 And Frm(g,5) = -2 Then Frm(g,5) = -3
EndIf
// -------------------------------------------------------
' Change formation?
If Frm(g,5) > 0 And Frm(g,5) <> 6 Then
If Frm(g,5) = 1 Then Frm(g,3) = ObjectX(Actor(g,0,1)): Frm(g,4) = ObjectY(Actor(g,0,1))
ready = True
CloneObjectPosition dummy, Actor(g,0,1)
CloneObjectOrientation dummy, Actor(g,0,1)
If Frm(g,10) < 3 Then ' rectangle formation
A=0
'For j = 1 To RoundUp(NumActors/Frm(g,9))
'For i = -RoundDown(Frm(g,9)/2)+1 To RoundUp(Frm(g,9)/2)
targetx# = Frm(g,3)' + Cos(ObjectAngle(Actor(g,0,1))) * SpriteSize
targety# = Frm(g,4)' + Sin(ObjectAngle(Actor(g,0,1))) * SpriteSize
For j = 1 To Frm(g,9)
guysperrow# = RoundUp(NumActors/Frm(g,9))
For i = -RoundDown(guysperrow/2)+1 To RoundUp(guysperrow/2)
' Find next member alive
Repeat
A+1
If A > Frm(g,0) Then Goto loppu
Until Actor(g,A,0) <> 0
' Set the place in formation
PositionObject dummy, ObjectX(Actor(g,0,1)) + Cos(ObjectAngle(Actor(g,0,1))-90) * SpriteSize*((Frm(g,10)=2)+1) * i, ObjectY(Actor(g,0,1)) + Sin(ObjectAngle(Actor(g,0,1))-90) * SpriteSize*((Frm(g,10)=2)+1) * i
MoveObject dummy, -SpriteSize*((Frm(g,10)=2)+1) * j
Actor(g,A,3) = Frm(g,3) + ObjectX(dummy) - ObjectX(Actor(g,0,1))
Actor(g,A,4) = Frm(g,4) + ObjectY(dummy) - ObjectY(Actor(g,0,1))
If Frm(g,11) = 0 Or Frm(g,5) = 1 Then Gosub UpdateFormation: Gosub CheckAttack
Next i
Next j
Else ' wedge formation
A=0: j=0
Repeat
j+1
'MoveObject dummy, -SpriteSize, -SpriteSize*j + 8
MoveObject dummy, 0, -SpriteSize*j + 8(j<>1)
For i = 1 To j
' Find next member alive
Repeat
A+1
If A > Frm(g,0) Then Goto loppu
Until Actor(g,A,0) <> 0
' Set the place in formation
MoveObject dummy, 0, SpriteSize
Actor(g,A,3) = Frm(g,3) + ObjectX(dummy) - ObjectX(Actor(g,0,1))
Actor(g,A,4) = Frm(g,4) + ObjectY(dummy) - ObjectY(Actor(g,0,1))
If Frm(g,11) = 0 Or Frm(g,5) = 1 Then Gosub UpdateFormation: Gosub CheckAttack
Next i
MoveObject dummy, -SpriteSize', -SpriteSize*j + 8
Forever
EndIf
loppu:
If ready = True Then Frm(g,5) = -Abs(Frm(g,5))
ElseIf Frm(g,5) = -2 Or Frm(g,5) = -3
PositionObject dummy, Frm(g,3), Frm(g,4)
If Distance2(Actor(g,0,1), dummy) < Frm(g,6)*1.5 Then
Frm(g,5) = 1
Else
Frm(g,7) = Frm(g,7) + .0005 + .0005*(Frm(g,5)=-3)
MoveObject Actor(g,0,1), Frm(g,6) + .5*(Frm(g,5)=-3)
CloneObjectOrientation dummy, Actor(g,0,1)
For A = 1 To Frm(g,0)
If Actor(g,A,0) <> 0 Then
'MoveObject Actor(g,A,1), Frm(g,6) + .5*(Frm(g,5)=-3)
PositionObject dummy, Actor(g,A,3), Actor(g,A,4)
Gosub UpdateFormation
Gosub CheckAttack
EndIf 'actor alive
Next A
EndIf
ElseIf Frm(g,5) = -4
tempdist# = Distance(ObjectX(Actor(g,0,1)), ObjectY(Actor(g,0,1)), Frm(g,3), Frm(g,4))
If tempdist < bowrange Then
If Timer() > Frm(g,13) + bowdelay Then
For A = 1 To Frm(g,0)
If Actor(g,A,0) <> 0 Then
iAr.ARROWS = New(ARROWS)
iAr\obj = CloneObject(arrow)
CloneObjectPosition iAr\obj, Actor(g,A,1)
CloneObjectOrientation iAr\obj, Actor(g,A,1)
TurnObject iAr\obj, Rnd(-3,3)
iAr\dest = Distance(ObjectX(Actor(g,A,1)), ObjectY(Actor(g,A,1)), Frm(g,3), Frm(g,4)) + Rand(-40,40)
ShowObject iAr\obj, True
EndIf 'actor alive
Next A
Frm(g,13) = Timer()
EndIf
Else 'move closer
Frm(g,7) = Frm(g,7) + .0005
MoveObject Actor(g,0,1), Frm(g,6)
For A = 1 To Frm(g,0)
If Actor(g,A,0) <> 0 Then
MoveObject Actor(g,A,1), Frm(g,6)
Gosub CheckAttack
EndIf 'actor alive
Next A
EndIf
ElseIf Frm(g,5) = 6
'Formations morale is broken -> flee
For A = 1 To Frm(g,0)
If Actor(g,A,0) <> 0 Then
DetermineFleeAngle:
If AngleDistance(ObjectAngle(Actor(g,A,1)), ObjectAngle(Actor(g,0,1))) < 45 Then RotateObject Actor(g,A,1), Rand(0,360): Goto DetermineFleeAngle
MoveObject Actor(g,A,1), Frm(g,6)*1.5
'Gosub CheckAttack
If Distance2(Actor(g,A,1), Actor(g,0,1)) > 1500 Then
Actor(g,A,0) = 0
DeleteObject Actor(g,A,1)
EndIf 'has fled far away
EndIf 'actor alive
Next A
ElseIf Frm(g,5) = -1
Frm(g,5) = 0
ElseIf Frm(g,5) = 0
' Formation does nothing, so lets ease their fatigue...
Frm(g,7) = Max(0, Frm(g,7) - .0001)
EndIf
remstart
For A = 1 To Frm(g,0)
' Avoid collisions
If Actor(g,A,0) <> 0 Then
For B = 1 To Actor(g,0,0)
If A <> B And Actor(g,B,0) <> 0 Then
If Distance2(Actor(g,A,1),Actor(g,B,1)) < 16 Then
AngOffNear = GetAngle2(Actor(g,B,1),Actor(g,A,1))
TranslateObject Actor(g,A,1), Cos(AngOffNear)*2, Sin(AngOffNear)*2
TranslateObject Actor(g,B,1), Cos(180-AngOffNear)*2, Sin(180-AngOffNear)*2
EndIf
EndIf
Next B
EndIf
SkipActor:
Next A
remend
For A = 1 To Frm(g,0)
If Actor(g,A,0) <> 0 and Frm(g,1) = plside and Frm(g,2) = 1 Then
frame = RoundDown(ObjectAngle(Actor(g,A,1)) / 45)
PlayObject Actor(g,A,1), frame, frame
EndIf
Next A
SkipGroup:
Next g
DrawGame
If SecondMenu = 1 Then
klik = DrawMenu()
If klik = 1 Then Frm(MenuG,5) = 0
If klik = 2 Then Frm(MenuG,10) = 1: Frm(MenuG,5) = 1
If klik = 3 Then Frm(MenuG,10) = 2: Frm(MenuG,5) = 1
If klik = 4 Then Frm(MenuG,10) = 3: Frm(MenuG,5) = 1
If klik = 5 And Frm(MenuG,10) < 3 Then Frm(MenuG,9) = Min(Frm(MenuG,9)+1, Frm(MenuG,0)): Frm(MenuG,5) = 1
If klik = 6 And Frm(MenuG,10) < 3 Then Frm(MenuG,9) = Max(Frm(MenuG,9)-1, 1): Frm(MenuG,5) = 1
If klik = 7 Then Frm(MenuG,11) = Not Frm(MenuG,11)
ElseIf Info = ON Then
DrawInfo(MouseX(), MouseY(), InfoG)
EndIf
Color 128,128,128
Text ScreenWidth()-40, 10, FPS()
'Text 10, 10, selG
'Text 10, 20, "Fatigue: " + Frm(selG,7)
'Text 10, 30, "Morale: " + Frm(selG,8)
If KeyHit(cbkeyF11) Then ScreenShot "Snap"+Rand(1000,9999)+".bmp"
DrawScreen
Forever
UpdateFormation:
angletodummy# = GetAngle2(Actor(g,A,1), dummy)
disttodummy# = Distance2(Actor(g,A,1), dummy)
' Execute actions
If disttodummy <= 4
If AngleDistance(ObjectAngle(Actor(g,A,1)), ObjectAngle(Actor(g,0,1))) > .5 Then
RotateObject Actor(g,A,1), CurveAngle(ObjectAngle(Actor(g,0,1)), ObjectAngle(Actor(g,A,1)), 10)
ready = False
EndIf
ElseIf disttodummy => 2
If AngleDistance(ObjectAngle(Actor(g,A,1)), angletodummy) > .5 Then
'RotateObject Actor(g,A,1), angletodummy
RotateObject Actor(g,A,1), CurveAngle(angletodummy, ObjectAngle(Actor(g,A,1)), 10)
If AngleDistance(ObjectAngle(Actor(g,A,1)), angletodummy) < 5.0 Then RotateObject Actor(g,A,1), angletodummy
Else
MoveObject Actor(g,A,1), Frm(g,6) + .5*(Frm(g,5)=-3)
EndIf
ready = False
EndIf
Return
CheckAttack:
' Charge?
ObjectPick Actor(g,A,1)
o = PickedObject()
If o <> 0 Then
If Distance2(Actor(g,A,1),o) < 10 Then
If Int(GetWord(ObjectString(o),1,",")) <> Frm(g,1) Then
oppG = Int(GetWord(ObjectString(o),2,","))
oppA = Int(GetWord(ObjectString(o),3,","))
Frm(g,7) = Frm(g,7) + .01 'add fatigue - fighting is heavy
Frm(oppG,7) = Frm(oppG,7) + .01 'add fatigue - fighting is heavy
sideangle = AngleDistance(ObjectAngle(Actor(g,A,1)), ObjectAngle(o))
attackbonus# = 0: defencebonus# = 0
If sideangle <= 110 Then attackbonus + .3 'flank attack
If sideangle <= 80 Then attackbonus + .4 'rear attack
If Frm(g,2) = 3 Then attackbonus + .5 'horse special charge bonus
If Frm(g,5) = -3 Then attackbonus + .1 'general charge bonus
If Frm(oppG,5) = -3 Then defencebonus + .1 'general charge bonus
If Frm(g,2) = 2 And Frm(oppG,2) = 3 Then attackbonus + .3
If Frm(g,2) = 3 And Frm(oppG,2) = 2 Then defencebonus + .5
If Frm(g,2) = 1 And Frm(oppG,2) = 2 Then defencebonus + .2
If Frm(g,8) <= 0 Then defencebonus + .5
If Rnd(1) + attackbonus - Frm(g,7) + Frm(g,8) > Rnd(1) + defencebonus - Frm(oppG,7) + Frm(oppG,8) Then
Actor(oppG,oppA,0) = 0
DeleteObject Actor(oppG,oppA,1)
Frm(g,8) = Frm(g,8) + .05
Else
Actor(g,A,0) = 0
DeleteObject Actor(g,A,1)
Frm(g,8) = Frm(g,8) - .06
EndIf
Else
'MoveObject Actor(g,A,1), -1
EndIf 'is enemy formation
EndIf 'is close enough
EndIf 'object found
Return
Function AngleDistance#(ang1#, ang2#)
tempA# = Abs(ang1 - ang2)
If tempA > 180.0 Then Return (360.0 - tempA)
Return tempA
End Function
Function Circle2(x#,y#,radius#,fill=0)
Circle x-radius, y-radius, radius*2, fill
End Function
Function Line2(x#,y#,a#,l#)
Line x,y,x+Cos(a)*l,y-Sin(a)*l
End Function
Function CommandFormation(gid, x#, y#, order=2)
Frm(gid,5) = order
Frm(gid,3) = x
Frm(gid,4) = y
RotateObject Actor(gid,0,1), GetAngle(ObjectX(Actor(gid,0,1)), -ObjectY(Actor(gid,0,1)), x, -y)
MoveObject Actor(gid,0,1), SpriteSize
End Function
Function CountActors(gid)
' Count alive members
ret = 0
For A = 1 To Frm(gid,0)
If Actor(gid,A,0) <> 0 Then ret + 1
Next A
Return ret
End Function
Function CreateFormation(sprite, size, side, x#, y#, dir, kartta, rows#=3.0)
numGroups+1
Actor(numGroups,0,0) = 1 'alive flag
Frm(numGroups,0) = size
Frm(numGroups,1) = side
If sprite = greenbow Or sprite = redbow Then Frm(numGroups,2) = 1
If sprite = greenspear Or sprite = redspear Then Frm(numGroups,2) = 2
If sprite = greenhorse Or sprite = redhorse Then Frm(numGroups,2) = 3
Frm(numGroups,6) = 1 + (Frm(numGroups,2)=3) 'speed
Frm(numGroups,7) = 0.0 'fatigue
Frm(numGroups,8) = 1.0 'morale
Frm(numGroups,9) = rows#
Frm(numGroups,10)= 1
Actor(numGroups,0,1) = MakeObject() 'invisible leader
PositionObject Actor(numGroups,0,1), x, y
RotateObject Actor(numGroups,0,1), dir
CloneObjectPosition dummy, Actor(numGroups,0,1)
CloneObjectOrientation dummy, Actor(numGroups,0,1)
k=0
' For j = 1 To RoundUp(size/rows)
'For i = -RoundDown(guysperrow/2)+1 To RoundUp(guysperrow/2)
For j = 1 To rows
guysperrow# = RoundUp(size/rows)
For i = -RoundDown(guysperrow/2)+1 To RoundUp(guysperrow/2)
k+1
If k > Frm(numGroups,0) Then Goto loppu
Actor(numGroups,k,1) = CloneObject(sprite)
' Set the place in formation
PositionObject dummy, ObjectX(Actor(numGroups,0,1)) + Cos(ObjectAngle(Actor(numGroups,0,1))-90) * SpriteSize * i, ObjectY(Actor(numGroups,0,1)) + Sin(ObjectAngle(Actor(numGroups,0,1))-90) * SpriteSize * i
MoveObject dummy, -SpriteSize * j
CloneObjectPosition Actor(numGroups,k,1), dummy
CloneObjectOrientation Actor(numGroups,k,1), Actor(numGroups,0,1)
' Other stuff
ObjectPickable Actor(numGroups,k,1), 2
ObjectString Actor(numGroups,k,1), Str(side) + "," + Str(numGroups) + "," + Str(k)
ShowObject Actor(numGroups,k,1), True
SetupCollision Actor(numGroups,0,1), kartta,1,1,2 <<<<<<<<<<<<------------------------------------TÄÄÄLLÄ
Actor(numGroups,k,0) = 1
Next i
Next j
loppu:
'For A = 1 To Frm(numGroups,0)
' For B = 1 To Frm(numGroups,0)
' If A<>B Then SetupCollision Actor(numGroups,A,1), Actor(numGroups,B,1), 2, 2, 2
' Next B
'Next A
End Function
Function DrawMenu()
'SetFont menufont
'DrawGhostImage ImgMenu, MenuX, MenuY, 0, 50
DrawImage ImgMenu, MenuX, MenuY
TH = TextHeight("|")
posinmenu = MouseY()-MenuY
menuitem = posinmenu/TH+1
'Click?
If MouseUp(1) Then
SecondMenu = 0
If MouseX()=>MenuX Or MouseY()=>MenuY Or MouseX()<=MenuX+MenuW Or MouseY()<=MenuY+6*TH Then Return menuitem
EndIf
If menuitem > 0 And menuitem <= 7 And MouseX()> MenuX And MouseX()<MenuX+MenuW Then
Color 200,200,200 'vaihda tästä valinnan taustaväriä
Box MenuX+2,MenuY+(menuitem-1)*TH,MenuW-4,TH
Color cbBlue 'vaihda tästä valinnan reunuksen väriä
Box MenuX+2,MenuY+(menuitem-1)*TH,MenuW-4,TH,OFF
EndIf
DrawImage menuicon_halt, MenuX+2, MenuY
Color 10,10,50
'If Frm(MenuG,5) = 0 Then Color 150,150,150
Text MenuX+20, MenuY, "Halt H"
Color 10,10,50
DrawImage menuicon_formclose, MenuX+2, MenuY+TH*1
Text MenuX+20, MenuY+TH*1, "Close formation C"
DrawImage menuicon_formloose, MenuX+2, MenuY+TH*2
Text MenuX+20, MenuY+TH*2, "Loose formation L"
DrawImage menuicon_formwedge, MenuX+2, MenuY+TH*3
Text MenuX+20, MenuY+TH*3, "Wedge formation W"
DrawImage menuicon_addrow, MenuX+2, MenuY+TH*4
'If Frm(MenuG,10) <> 3 Then Color 10,10,50 Else Color 150,150,150
Text MenuX+20, MenuY+TH*4, "Add row A"
DrawImage menuicon_subtractrow, MenuX+2, MenuY+TH*5
'If Frm(MenuG,10) <> 3 Then Color 10,10,50 Else Color 150,150,150
Text MenuX+20, MenuY+TH*5, "Subtract row S"
If Frm(MenuG,11) = 0 Then DrawImage menuicon_yes, MenuX+2, MenuY+TH*6 Else DrawImage menuicon_no, MenuX+2, MenuY+TH*6
Text MenuX+20, MenuY+TH*6, "Keep in formation F"' Else Text MenuX+20, MenuY+TH*6, "Skirmish"
Return 0
End Function
Function DrawInfo(x,y,gid)
'DrawGhostImage ImgInfo, x+12, y, 0, 50
DrawImage ImgInfo, x+12, y
TH = TextHeight("|")
Color 20,20,20
Text x+22, y, Str(CountActors(gid))+ " " +unitnames(Int(Frm(gid,2)))
Text x+22, y+TH, ""
If Frm(gid,5) > 0 Then sta = 1 Else sta = Int(Abs(Frm(gid,5)))
Text x+22, y+TH*2, statusnames(sta)
mor = Min( RoundUp(Frm(gid,8)*10/3), 6 )
Text x+22, y+TH*3, moralenames(mor)
Text x+22, y+TH*4, fatiguenames(RoundUp(Frm(gid,7)*5))
End Function
// Tekee väriliun.
Function CreateGradient(w,h,r1,g1,b1,r2,g2,b2,style=0)
bar = MakeImage(w,h)
DrawToImage bar
Select style
Case 0
r_step# = (r2-r1) / Float(w)
g_step# = (g2-g1) / Float(w)
b_step# = (b2-b1) / Float(w)
For i = 0 To w-1
Color r1+i*r_step, g1+i*g_step, b1+i*b_step
Line i,0,i,h-1
Next i
Case 1
r_step# = (r2-r1) / Float(h)
g_step# = (g2-g1) / Float(h)
b_step# = (b2-b1) / Float(h)
For i = 0 To h-1
Color r1+i*r_step, g1+i*g_step, b1+i*b_step
Line 0,i,w-1,i
Next i
Default
asp = Min(w,h)
r_step# = (r2-r1) / Float(asp Shr 1)
g_step# = (g2-g1) / Float(asp Shr 1)
b_step# = (b2-b1) / Float(asp Shr 1)
For i = asp Shr 1 To 1 Step -1
Color r1+i*r_step, g1+i*g_step, b1+i*b_step
Circle2(w Shr 1, h Shr 1, i, ON)
Next i
End Select
DrawToScreen
Return bar
End Function
-
- Active Member
- Posts: 163
- Joined: Fri Aug 31, 2007 7:07 pm
- Location: Helsinki
- Contact:
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Sulla on koko setup collision killissä, esim. näin toimii:Vieras wrote:Näinhän se piti tehdä? Kuitenkin, kartta tuli, mutta törmäys ei reagoi.
SetupCollision Actor(numGroups,k,1), kartta,2,4,2
Tosin tuo automaattinen törmäily ei toimi kauheen hyvin tässä yleisesti ottaen.
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Äh, olisihan tämä pitänyt tajuta. Kiitoksia. Mutta nyt ukkojen törmättyä seinään ne eivät voi liikkua enää toiseen suuntaan, kun ne eivät voi järjestäytyä seinää vasten. Lisäsin pätkänAavesoturi wrote:Sulla on koko setup collision killissä, esim. näin toimii:Vieras wrote:Näinhän se piti tehdä? Kuitenkin, kartta tuli, mutta törmäys ei reagoi.
SetupCollision Actor(numGroups,k,1), kartta,2,4,2
Tosin tuo automaattinen törmäily ei toimi kauheen hyvin tässä yleisesti ottaen.
Code: Select all
And ObjectsOverlap (Actor(g,0,1), map, 1)=0
-
- Active Member
- Posts: 163
- Joined: Fri Aug 31, 2007 7:07 pm
- Location: Helsinki
- Contact:
Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä
Olet laittanu overlap tavaksi laatikkokosketuksen, eli törmäystarkistus vaan katsoo onko objekti kartan ulkoreiunoja rajoittavan neliön sisällä. Itse asiassa ei taitaisi auttaa edes pikselintarkaksi muuttaminen. Katselepa manuaalista vaikkapa CountCollisions komennon ohjetta ja siihen liittyviä komentoja.Vieras wrote:Lisäsin pätkäntuon kohdan ehtoihin, jossa vaihdetaan muodostelmaa. Nyt ne eivät suostu liikkumaan lainkaan. Ja toiseksi, mikseivät vihollisten nuolet tehoa pelaajan ukkoihin? Minulla eivät ainakaan.Code: Select all
And ObjectsOverlap (Actor(g,0,1), map, 1)=0
Ja mitä tulee nuoliin, kyllä ne vahinkoa tekee - huomaa vaan että ne niinkuin ammutaan kaaressa, joten "törmäystarkistus" menee päälle vasta kun nuolet "laskeutuvat" eli ovat tarpeeksi lähellä pistettä johon ne tähdättiin. Tällöinkin nuoli objektin pitää vielä oikeasti osua johonkin kohde muodostelman objekteista ennenkuin päästään heittämään noppaa kuolemasta