Hei!
Tein alla olevan ohjelman, jossa Picturebox jahtaa toista (liikkumasuuntia ei vielä ole kaikkia valmiina). Ongelmana on saada kiinnijäämistilanne eli objektien törmäystutkimus paremmaksi. Tällä hetkellä pitää tehdä tosi pienet boxit, jotta törmäys onnistuu (koska koordinaattien on oltava täysin samat).
Olen yrittänyt kasvattaa boxien kokoa ja lisätä samalla "törmäysaluetta" laittamalla esim. X-10 ja X+10 sinne sun tänne, samoin erisuuruusmerkkejä yhtäsuuruuksien tilalle, mutta mikään ei ole johtanut toivottuun lopputulokseen.
Olen yrittänyt myöskin selvittää, miten käytetään ominaisuutta/komentoa Margin(), jonka pitäisi kertoa objektien etäisyys, mutta ohjevalikon neuvot ovat jotenkin sekavia.
Joten jos voitte hieman muokata ohjelmaani tai vinkata, mitä tehdä, niin kovasti kiitoksia!
P.S. Alla on nyt "hyötykäytössä" näppäimistönlukukoodi tälle .NET-versiolle, eli kiitos vielä Antti Laaksoselle aiemmasta muunnoksesta!
Public Class Form1
Dim nappaimet(0 To 255) As Boolean
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Timer1.Enabled = True
nappaimet(e.KeyCode) = True
End Sub
Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
Timer1.Enabled = False 'Pysäyttää ajastimen ja samalla siis kuvan liikkumisen
nappaimet(e.KeyCode) = False
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If nappaimet(37) = True Then
pctVipeltaja.Location = New Point(pctVipeltaja.Location.X - 1, pctVipeltaja.Location.Y)
End If
If nappaimet(38) = True Then
pctVipeltaja.Location = New Point(pctVipeltaja.Location.X, pctVipeltaja.Location.Y - 1)
End If
If nappaimet(68) = True Then
pctJahtaaja.Location = New Point(pctJahtaaja.Location.X + 1, pctJahtaaja.Location.Y)
End If
If nappaimet(87) = True Then
pctJahtaaja.Location = New Point(pctJahtaaja.Location.X, pctJahtaaja.Location.Y - 1)
End If
If pctVipeltaja.Location.X = pctJahtaaja.Location.X And pctVipeltaja.Location.Y = pctJahtaaja.Location.Y Then
MsgBox("Kiinni jäit!")
Timer1.Stop()
End
End If
End Sub
End ClassSinun tulee katsoa molempien boxien koko alueet. Eli siis location.x ja location.x+width ja .y+height. Näin katat koko alueen.
Näistä sinun tulee muodostaa and or lause, jossa käyt läpi yhtäsuuruus operaattoreilla kaikki mahdolliset suunnat, josta laatikko voi tulla.
Esim (en nyt tarkalleen muista minkä pisteen location palauttaa VB:ssä. tässä oletetaan että se palauttaa ylävasemman pisteen). obj1 sijaitsee vasemmassa yläkulmassa nähden obj2:sta. Näin tahdot tarkastaa onko obj1.x+width > obj2.x ja onko obj1.y+height < obj2.y. Törmäys mahdollinen. Jatka lauseen ehtoja siten, että kun obj1 on obj2:n oikealla puolella obj1.x > obj2.x+width, kunnes saat rajattua koko alueen.
Tämä on siis metodi mitä minä olen käyttänyt. Parempiakin löytyy varmasti.
Yritin seuraavanlaista, mutta törmäys tapahtuu heti kun jotakin liikautan vähääkään. Vaikka Vipeltäjä on Jahtaajan oikealla puolella reilusti, ja boxit ovat ihan pieniä. Onko mainitsemasi width ja height käytettävissä näin vai jotenkin muuten? Onko esim. width suoraan boxin leveys?
Ymmärrän, että minun pitää käyttää yhtäsuuruusoperaattoreita lopulta, mutta näin testimielessä kummastuttaa liian aikainen törmäys tuolla < merkin avulla.
If (pctVipeltaja.Location.X < pctJahtaaja.Location.X + Width Then
MsgBox("Kiinni jäit!")
Timer1.Stop()
End
End IfKaivoin erään tilemap testini, jossa testasin myös hahmon aktiota talon kanssa.
Left, right, top ja down ovat talolaatikon rajat.
If Hahmo.Left + Hahmo.Width > left And Hahmo.Top + Hahmo.Height > top And Hahmo.Top < down And Hahmo.Left < right Then
MsgBox("Party IN DA HOUSE")
ElseIf Hahmo.Left < right And (Hahmo.Top + Hahmo.Height < top Or Hahmo.Top > down) Then
' debug
' MsgBox("hmm2")
...Hei upsi!
ehdottaisin, että 'unohtaisit' Timerin siksi aikaa, kunnes olet hieman enemmän sinut navigoinnin kanssa...oheinen esimerkki antaa hieman suuntaa siitä, kuinka asiaa voisi ehkä lähestyä...
'...
Dim törmäys As Boolean = False
'...
'...
Private Sub MainFormKeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs)
If Not törmäys Then '** Jos muutujan arvo on EPÄTOSI Formin KeyDown
'tapahtumassa niin annetaan ohjelman reagoida tapauskohtaisesti
'nuolinäppäinten painamiseen...
Select Case e.KeyValue
'törmäilijä siirtyy näytöllä pykälän vasemmalle
Case 37: törmäilijä.Left -= 1
'törmäilijä siirtyy näytöllä pykälän ylöspäin
Case 38:törmäilijä.Top -= 1
'törmäilijä siirtyy näytöllä pykälän oikealle
Case 39: törmäilijä.Left += 1
'törmäilijä siirtyy näytöllä pykälän alaspäin
Case 40: törmäilijä.Top += 1
End Select
'tutkitaan tapausta törmäilijän vasemman sivun
'sijaint X-koordinaateissa
Select Case törmäilijä.Left
'tapaus törmäysobjektin vasemman sivun sijaint
'miinus törmäilijän leveys
Case törmäysobjekti.Left - törmäilijä.Width
'jos törmäilijän yläsivun sijainti Y-koordinaateissa
'on suurempi kuin törmäysobjektin yläsivun sijainti
'miinus törmäilijän korkeus miinus 1 ja kuitenkin pienempi
'kuin törmäysobjektin yläsivun sijainti Y-koordinaateissa
'plus törmäysobjektin korkeus plus 1 niin...
IF törmäilijä.Top > törmäysobjekti.Top - törmäilijä.Height -1 And törmäilijä.Top < törmäysobjekti.Top + törmäysobjekti.Height +1 Then
'** törmäyksen sattuessa asetetaan muuttujan arvo
'arvoon TOSI, jolla estetään ohjelmaa reagoimasta nuoli-
'näppäinten painamiseen...
törmäys = True: messageBox.Show("TÖRMÄYS VASEMMALTA!")
'otetaan pieni irtiotto törmäysobjektista
törmäilijä.Left -=1
End if
Case törmäysobjekti.Left + törmäysobjekti.Width
IF törmäilijä.Top > törmäysobjekti.Top - törmäilijä.Height -1 And törmäilijä.Top < törmäysobjekti.Top + törmäysobjekti.Height +1 Then
törmäys = True: messageBox.Show("TÖRMÄYS OIKEALTA!")
törmäilijä.Left +=1
End if
End Select
'tutkitaan vielä tapausta törmäilijän yläsivun
'sijaint Y-koordinaateissa
Select Case törmäilijä.Top
'tapaus törmäysobjektin yläsivun sijaint
'miinus törmäilijän korkeus
Case törmäysobjekti.Top - törmäilijä.Height
'jos törmäilijän vasemman sivun sijainti X-koordinaateissa
'on suurempi kuin törmäysobjektin vasemman sivun sijainti
'miinus törmäilijän leveys miinus 1 ja kuitenkin pienempi
'kuin törmäysobjektin vasemman sivun sijainti X-koordinaateissa
'plus törmäysobjektin leveys plus 1 niin...
IF törmäilijä.Left > törmäysobjekti.Left - törmäilijä.Width -1 And törmäilijä.Left < törmäysobjekti.Left + törmäysobjekti.Width +1 Then
törmäys = True: messageBox.Show("TÖRMÄYS YLHÄLTÄ!")
törmäilijä.Top -=1
End if
Case törmäysobjekti.Top + törmäysobjekti.Height
IF törmäilijä.Left > törmäysobjekti.Left - törmäilijä.Width -1 And törmäilijä.Left < törmäysobjekti.Left + törmäysobjekti.Width +1 Then
törmäys = True: messageBox.Show("TÖRMÄYS ALHALTA!")
törmäilijä.Top +=1
End if
End Select
End If
End Sub
Private Sub MainFormKeyUp(sender As System.Object, e As System.Windows.Forms.KeyEventArgs)
'** kun näppäin sitten vapautetaan, asetetaan muuttujan
'arvo takaisin arvoon EPÄTOSI ja ohjelma reagoi jälleen
'nuolinäppäinten painamiseen
törmäys = False
End SubAihe on jo aika vanha, joten et voi enää vastata siihen.