Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Aavesoturi »

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 8-)
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. :D
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
User avatar
vilQuri
Active Member
Posts: 239
Joined: Wed Aug 29, 2007 6:25 pm
Location: Turku

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by vilQuri »

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.
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by koodaaja »

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.
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Aavesoturi »

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.
Riippuu vähän: interpoloinnit päällä homma on laskennallisesti jo niin raskas cb:lle, että piirron osuus nopeuden puutteesta jää aika pieneksi.
Tuohan nyt muutenkin on hyvin optimoimaton prototyyppi versio, kunhan kokeilin tekniikkaa. Jos intoa riittää niin siitä vaan parantelemaan.
tuhoojabotti
Advanced Member
Posts: 485
Joined: Tue Aug 28, 2007 3:53 pm
Location: Suomi, Finland
Contact:

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by tuhoojabotti »

spiderbotille hiiri ohjaus

Code: Select all

If MouseHit(1) Then FireString(player,-WrapAngle(GetAngle(ObjectX(player),ObjectY(player),MouseWX(),MouseWY())))
muistakaa pistää joku kuva hiirelle! ;)
Imagedev.tuhoojabotti.com — “Programmer (noun): An organism that turns caffeine into code.”
Vieras

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Vieras »

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?
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Aavesoturi »

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?
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

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Vieras »

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
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Aavesoturi »

Vieras wrote:Näinhän se piti tehdä? Kuitenkin, kartta tuli, mutta törmäys ei reagoi.
Sulla on koko setup collision killissä, esim. näin toimii:
SetupCollision Actor(numGroups,k,1), kartta,2,4,2
Tosin tuo automaattinen törmäily ei toimi kauheen hyvin tässä yleisesti ottaen.
Vieras

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Vieras »

Aavesoturi wrote:
Vieras wrote:Näinhän se piti tehdä? Kuitenkin, kartta tuli, mutta törmäys ei reagoi.
Sulla on koko setup collision killissä, esim. näin toimii:
SetupCollision Actor(numGroups,k,1), kartta,2,4,2
Tosin tuo automaattinen törmäily ei toimi kauheen hyvin tässä yleisesti ottaen.
Ä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än

Code: Select all

 And ObjectsOverlap (Actor(g,0,1), map, 1)=0 
tuon 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.
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Aavesoturin koodeja - keskeneräisiä projuja ja prototyyppejä

Post by Aavesoturi »

Vieras wrote:Lisäsin pätkän

Code: Select all

 And ObjectsOverlap (Actor(g,0,1), map, 1)=0 
tuon 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.
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.

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
Post Reply