Törmäystunnistus strategiapeliin.

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
User avatar
-Z-
Devoted Member
Posts: 682
Joined: Tue Aug 28, 2007 3:33 pm
Location: In ur danmaku, grazin ur bullets

Törmäystunnistus strategiapeliin.

Post by -Z- »

Vanhoja foorumeita kaivellessani törmäsin jonezin tekemään strategiapeliesimerkkiin. Yritin lisätä siihen törmäystunnistusta tällaisella pätkällä:

Code: Select all

For iObj.OBJECTS = Each OBJECTS
    For jObj.OBJECTS = Each OBJECTS
        SetupCollision iObj\obj, jObj\obj, 2,2,1
   next jObj
next iObj
Tuli kaikkien suosikkierrori, johtuen arvatenkin siitä että tuossa yritetään laittaa törmäystunnistus myös itseen (vai?). Minulla ei itselläni ole mitään aavistusta että miten tuon saisi tuosta toimimaan. Joten apua kaivataan.

Tässä tämä jonezin alkuperäinen esimerkkikoodi:

Code: Select all

SCREEN 800, 600
//Tyyppikokoelma objekteille
Type OBJECTS
    Field obj //Muuttuja objektin kuvalle
    Field picked As Byte //Muuttuja onko objekti valittu vai eikö ole
End Type

//Ladataan emäukko josta objektit kopioidaan.
ukko = LoadObject("media\guy.bmp")
//Piilotetaan emäukko
ShowObject ukko, OFF

//Teemme objektit ja arvomme niiden paikat
For i = 1 To 10
    newObj.OBJECTS = New(OBJECTS)
    newObj\obj = CloneObject(ukko)
    PositionObject newObj\obj, Rand(-400, 400), Rand(-300, 300)
Next i



Repeat
    //Liikuta kameraa
    TranslateCamera (RightKey() - LeftKey()) * 3, (UpKey() - DownKey()) * 3

    //lopetuskoordinaatit ovat hiiren koordinaateissa
    endX = MouseWX()
    endY = MouseWY()

    //Kun hiirtä pidetään alhaalla, tehdään laskutoimituksia joiden mukaan
    //laatikko piirretään. Laskutoimitukset menevät näin:
    If MouseDown(1) Then
        //Jos aloitus-x-koordinaatti > lopetus-x-koordinaatti, niin lopetus-x-koordinaatti
        //on laatikon vasen sivu ja aloitus-x-koordinaatti oikea.
        //Jos taas aloitus-x-koordinaatti < lopetus-x-koordinaatti, niin päinvastoin.
        If gPickX > endX Then
            sideLeft = endX
            sideRight = gPickX
        Else
            sideLeft = gPickX
            sideRight = endX
        EndIf

        //Sama y-suunnassa oleville koordinaateille
        If gPickY > endY Then
            sideDown = EndY
            sideUp = gPickY
        Else
            sideDown = gPickY
            sideUp = endY
        EndIf

        //Tässä piirrämme laatikon yksinkertaisesti vasemmasta yläkulmasta oikeaan alakulmaan
        //Huomaa että piirrämme laatikon käyttäen MAAILMAKOORDINAATISTOA (drawtoworld on)
        DrawToWorld ON
        Box sideLeft, sideUp, sideRight - sideLeft, sideUp - sideDown, 0
        DrawToWorld OFF
        Else
        //Jos hiirtä ei pidetä pohjassa, aloituskoordinaatti on hiiren koordinaatti.
        //Tässä siis otamme aloituskoordinaatit muistiin.
        gPickX = MouseWX()
        gPickY = MouseWY()
    EndIf

    //Kun hiiri päästetään pohjasta, käymme kaikki objektit läpi ja katsomme onko
    //objekti laatikon sisällä.
    If MouseUp(1) Then
        For iObj.OBJECTS = Each OBJECTS
            iObj\picked = False //Objektien valinnat nollataan (kokeile ilman tätä)
            objX = ObjectX(iObj\obj)
            objY = ObjectY(iObj\obj)

            //Jos objekti on laatikon sisällä, se valitaan.
            If objX > sideLeft And objX < sideRight Then
                If objY < sideUp And objY > sideDown Then
                    iObj\picked = True
                EndIf
            EndIf
        Next iObj
    EndIf

    //Tässä piirrämme ympyrät objektien kohdalle, jotta näkisimme mitkä objekit on valittu.
    DrawGame
    For iObj.OBJECTS = Each OBJECTS
        If iObj\picked = True Then
            DrawToWorld ON
            Circle ObjectX(iObj\obj) - 20, ObjectY(iObj\obj) + 20, 40, 0
            DrawToWorld OFF
        EndIf
    Next iObj
    DrawScreen
Forever
Last edited by -Z- on Wed May 14, 2008 8:54 pm, edited 1 time in total.
"Fallout 3 (#10) marked a shift in the industry, a move that saw the western RPG begin to surpass its Japanese counterparts." -IGN top 100 RPGs of all time
Valtzu
Active Member
Posts: 115
Joined: Sun Aug 26, 2007 2:40 pm
Location: Sauvo
Contact:

Re: Törmäystunnistus strategiapeliin.

Post by Valtzu »

No johan olet virheen tehnyt. Luonnollisesti tyyppimuuttujille/jäsenille ei voi/kuulu asettaa törmäystä vaan objekteille ('\obj'), eli

Code: Select all

For iObj.OBJECTS = Each OBJECTS
    For jObj.OBJECTS = Each OBJECTS
        SetupCollision iObj\obj, jObj\obj, 2,2,1
   Next jObj
Next iObj
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Törmäystunnistus strategiapeliin.

Post by koodaaja »

Jos et halua törmäystä itselle, pistä:

Code: Select all

If iObj<>jObj Then SetupCollision iObj\obj, jObj\obj, 2, 2, 1
Olettaen siis, että objektit on tallennettu \obj -kenttään.

Toki on parempi tehdä toinen looppi, joka aloitetaan alusta ja käydään läpi kunnes nuo ovat samat, silloin kaikkia törmäyksiä tulee vain yksi kappale.
User avatar
-Z-
Devoted Member
Posts: 682
Joined: Tue Aug 28, 2007 3:33 pm
Location: In ur danmaku, grazin ur bullets

Re: Törmäystunnistus strategiapeliin.

Post by -Z- »

Valtzu wrote:No johan olet virheen tehnyt. Luonnollisesti tyyppimuuttujille/jäsenille ei voi/kuulu asettaa törmäystä vaan objekteille ('\obj'), eli

Code: Select all

For iObj.OBJECTS = Each OBJECTS
    For jObj.OBJECTS = Each OBJECTS
        SetupCollision iObj\obj, jObj\obj, 2,2,1
   Next jObj
Next iObj
sori, ajatuskatkos. Nimenomaan noin olinkin tuon laittanut, Laitoin sen vain tuohon aloitusviestiin ulkomuistista. korjasin sen siihen.

Eli ongelma siis edelleen ratkaisematta
"Fallout 3 (#10) marked a shift in the industry, a move that saw the western RPG begin to surpass its Japanese counterparts." -IGN top 100 RPGs of all time
User avatar
Jonez
Devoted Member
Posts: 575
Joined: Mon Aug 27, 2007 8:37 pm

Re: Törmäystunnistus strategiapeliin.

Post by Jonez »

Periaatteessa turha tehdä törmäys kaksi kertaa samoille objekteille. Tee törmäys vaikkapa luontivaiheessa (objekti luodaan, käydään muut olemassa olevat objektit läpi ja asetetaan törmäys niihin). Tässä paranneltu versio. Hiiri 2 liikuttaa valittuja objekteja.

Code: Select all

SCREEN 800, 600
//Tyyppikokoelma objekteille
Type OBJECTS
    Field obj //Muuttuja objektin kuvalle
    Field picked As Byte //Muuttuja onko objekti valittu vai eikö ole

    Field cTargetX  
    Field cTargetY
    
End Type

//Ladataan emäukko josta objektit kopioidaan.
ukko = LoadObject("media\guy.bmp")
//Piilotetaan emäukko
ShowObject ukko, OFF

//Teemme objektit ja arvomme niiden paikat
For i = 1 To 10
    newObj.OBJECTS = New(OBJECTS)
    newObj\obj = CloneObject(ukko)

    PositionObject newObj\obj, Rand(-400, 400), Rand(-300, 300)

    newObj\cTargetX = ObjectX( newObj\obj )
    newObj\cTargety = ObjectY( newObj\obj )
        
    For io.OBJECTS = Each OBJECTS
        If io <> newObj Then
            SetupCollision newObj\obj, io\obj, 2, 2, 2
        EndIf
    Next io
Next i


Repeat
    //Liikuta kameraa
    TranslateCamera (RightKey() - LeftKey()) * 3, (UpKey() - DownKey()) * 3

    //lopetuskoordinaatit ovat hiiren koordinaateissa
    endX = MouseWX()
    endY = MouseWY()

    //Kun hiirtä pidetään alhaalla, tehdään laskutoimituksia joiden mukaan
    //laatikko piirretään. Laskutoimitukset menevät näin:
    If MouseDown(1) Then
        //Jos aloitus-x-koordinaatti > lopetus-x-koordinaatti, niin lopetus-x-koordinaatti
        //on laatikon vasen sivu ja aloitus-x-koordinaatti oikea.
        //Jos taas aloitus-x-koordinaatti < lopetus-x-koordinaatti, niin päinvastoin.
        If gPickX > endX Then
            sideLeft = endX
            sideRight = gPickX
        Else
            sideLeft = gPickX
            sideRight = endX
        EndIf

        //Sama y-suunnassa oleville koordinaateille
        If gPickY > endY Then
            sideDown = EndY
            sideUp = gPickY
        Else
            sideDown = gPickY
            sideUp = endY
        EndIf

        //Tässä piirrämme laatikon yksinkertaisesti vasemmasta yläkulmasta oikeaan alakulmaan
        //Huomaa että piirrämme laatikon käyttäen MAAILMAKOORDINAATISTOA (drawtoworld on)
        DrawToWorld ON
        Box sideLeft, sideUp, sideRight - sideLeft, sideUp - sideDown, 0
        DrawToWorld OFF
        Else
        //Jos hiirtä ei pidetä pohjassa, aloituskoordinaatti on hiiren koordinaatti.
        //Tässä siis otamme aloituskoordinaatit muistiin.
        gPickX = MouseWX()
        gPickY = MouseWY()
    EndIf

    //Kun hiiri päästetään pohjasta, käymme kaikki objektit läpi ja katsomme onko
    //objekti laatikon sisällä.
    If MouseUp(1) Then
        For iObj.OBJECTS = Each OBJECTS
            iObj\picked = False //Objektien valinnat nollataan (kokeile ilman tätä)
            objX = ObjectX(iObj\obj)
            objY = ObjectY(iObj\obj)

            //Jos objekti on laatikon sisällä, se valitaan.
            If objX > sideLeft And objX < sideRight Then
                If objY < sideUp And objY > sideDown Then
                    iObj\picked = True
                EndIf
            EndIf
        Next iObj
    EndIf

    //Tässä piirrämme ympyrät objektien kohdalle, jotta näkisimme mitkä objekit on valittu.
    DrawGame
    For iObj.OBJECTS = Each OBJECTS
        If iObj\picked = True Then
            DrawToWorld ON
            Circle ObjectX(iObj\obj) - 20, ObjectY(iObj\obj) + 20, 40, 0
            DrawToWorld OFF
            
            If MouseHit( 2 ) Then
                iObj\cTargetX = MouseWX()
                iObj\cTargetY = MouseWY()
            EndIf
        EndIf

        If Distance( ObjectX( iObj\obj), ObjectY( iObj\obj ), iObj\cTargetX, iObj\cTargetY ) > 1 Then    
            kulma# = GetAngle( ObjectX( iObj\obj), -ObjectY( iObj\obj ), iObj\cTargetX, -iObj\cTargetY )
            TranslateObject iObj\obj, Cos( kulma# ) * 3, Sin( kulma# ) * 3             
        EndIf
                  
    Next iObj
    DrawScreen
Forever
-Vuoden 2008 aloittelijan ystävä -palkinnon voittaja-
Image <- protestipelikilpailun voittaja.
Space War
Post Reply