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 Class
Sinun 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 If
Kaivoin 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 Sub
Aihe on jo aika vanha, joten et voi enää vastata siihen.