View Full Version : [vb net 2008] collisione di due oggetti
superbau
17-10-2009, 13:20
salve,
ho due oggetti , A e B. Vorrei far scaturire una azione alla loro collisione.
Io il codice g'à l'ho fatto, però è abbastanza statico, nel senso che se ho pochi oggetti da gestire, potrebbe anche andare bene, ma se ne ho molti risulta alquanto snervante.
vi posto uno stralcio di come ho risolto. Mi piacerebbe trovare una soluzione dinamica che vada bene per tutti i miei oggetti che richiedano una azione alla loro collisione.
grazie mille.
Label1.Text = PictureBox1.Location.X
Label2.Text = PictureBox1.Location.Y
Label8.Text = premuto
'metti l'oggetto o frontale o dietro
If e.KeyCode And asdS = 0 Then
FronteRetro(PictureBox1, PictureBox2, PictureBox4)
End If
'poporing movimento
If e.KeyCode = Keys.A Then
If PictureBox1.Location.X <= 0 Then
Else
Dim kar As Integer
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
kar = PosizioneX - Rovel
If (PictureBox1.Location.X = 272) And (PictureBox1.Location.Y <= 228 And PictureBox1.Location.Y >= 168) Then
Else
PictureBox1.Location = New Point(kar, PosizioneY)
End If
End If
premuto = "Ovest"
End If
[...]
If e.KeyCode = Keys.W Then
Dim kar As Integer
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
kar = PosizioneY - Rovel
If ((PictureBox1.Location.Y = 228) And (PictureBox4.Location.X + 256 >= PictureBox1.Location.X)) Or (PictureBox1.Location.Y <= 0) Then
asdS = 1
PictureBox1.SendToBack()
PictureBox4.BringToFront()
Else
asdS = 0
PictureBox1.Location = New Point(PosizioneX, kar)
End If
premuto = "Nord"
Nelle parti evidenziate in grassetto ho fatto in modo che quando l'oggetto pilotato dalla pressione dei tasti, arriva alle coordinate specifiche, questo si debba fermare come se avesse un muoro dinanzi.
Questo funziona, ma se devo inserire molti altri oggetti, mi sembra che in questo modo risulti un po come dire.. "incasinata la cosa", anche se fattibile.
Il problema non è tanto farla la cosa, ma nella fase di aggiornamento della routine o nel debug dopo un lungo tempo che non lavoro su questo progetto.
Mi piacerebbe in definitiva, riuscire a trovare una soluzione dinamica dove si possano intercettare le varie collisioni e poterla così applicare semplicemente a tutti gli oggetti.
superbau
17-10-2009, 13:28
questo giro mi rispondo da solo ^_^
ho trovato qui la spiegazione.
http://www.dreamincode.net/forums/showtopic35291.htm
praticamente basta usare:
If OGGETTO1.Bounds.IntersectsWith(OGGETTO2.Bounds) Then
ora modifico il codice :)
Dim MovimentoPic1 As Integer
Select e.KeyCode
Case Keys.A
If PictureBox1.Location.X <= 0 Or (PictureBox1.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'destra
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneX + Speed
PictureBox1.Location = New Point(MovimentoPic1, PosizioneY)
Else
'sinistra
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneX - Speed
PictureBox1.Location = New Point(MovimentoPic1, PosizioneY)
End If
premuto = "Ovest"
Case Keys.D
If PictureBox1.Location.X >= 812 Or (PictureBox1.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'sinistra
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneX - Speed
PictureBox1.Location = New Point(MovimentoPic1, PosizioneY)
Else
'destra
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneX + Speed
PictureBox1.Location = New Point(MovimentoPic1, PosizioneY)
End If
premuto = "Est"
Case Keys.W
If (PictureBox1.Location.Y <= 0) Or (PictureBox1.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'giu
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneY + Speed
PictureBox1.Location = New Point(PosizioneX, MovimentoPic1)
Else
'su
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneY - Speed
asdS = 0
PictureBox1.Location = New Point(PosizioneX, MovimentoPic1)
End If
premuto = "Nord"
Case Keys.S
If (PictureBox1.Location.Y >= 344) Or (PictureBox1.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'su
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneY - Speed
asdS = 0
PictureBox1.Location = New Point(PosizioneX, MovimentoPic1)
Else
'giu
PosizioneX = PictureBox1.Location.X
PosizioneY = PictureBox1.Location.Y
MovimentoPic1 = PosizioneY + Speed
PictureBox1.Location = New Point(PosizioneX, MovimentoPic1)
End If
premuto = "Sud"
End Select
l'unico incoveniente e che mi toccherà fare un if lunghissimo tanti quanti sono gli oggetti interessati, ma cmq, è sempre meglio di prima
If (PictureBox1.Location.Y >= 344) Or (PictureBox1.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
se qualcuno conosce un metodo ancora + snello, lo ringrazio anticipatamente.
heheh oggi continuo a rispondemi da solo " me la faccio e me la dico" lol.. mi sa che devo dormire prima di nott e^_^
al posto del costrutto if che ho usato basta che usa
For Each picturebox As System.Windows.Forms.Control In Me.Controls
...
Next
superbau
17-10-2009, 14:51
accidenti non mi si riesce di ottimizzare il codice... l'oggetto in questione che dovrebbe far partire il msgbox ha come tag muro
For Each picturebox As System.Windows.Forms.Control In Me.Controls
If PictureBox1.Bounds.IntersectsWith(picturebox.Bounds) Then
If picturebox.Tag = "muro" Then
MsgBox("contatto oggetto")
End If
Else
Select Case e.KeyCode
Case Keys.A
.....
superbau
17-10-2009, 15:19
For Each Elemento As PictureBox In Me.Controls
If PictureBox1.Bounds.IntersectsWith(Elemento.Bounds) Then
If Elemento.Tag = "muro" Then
MsgBox("contatto oggetto")
Else
MsgBox("nessun contatto")
End If
Else
ho provato anche così.. ma non miesce nullla... mi dice che non posso castare elementi label con picturebox.. uhm non capisco.. un errore di forma sicuramente.. non riesco a comprenderlo
alla fine son arrivato a questo:
Dim c As Control
For Each c In Me.Controls
If TypeOf c Is PictureBox Then
If c.Tag = "muro" Then
MsgBox("trovato")
Else
End If
End If
Next
ma sto benedetto msgbox non vuol apparire :)
alla fine son arrivato a questo:
...
...
ma sto benedetto msgbox non vuol apparire :)
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then MsgBox("trovato")
End If
Next
è lo stesso codice del tuo, solo reso più snello, comunque funziona, a patto che ci sia almeno una PictureBox che abbia Tag = "muro". ;)
superbau
19-10-2009, 12:39
niente da fare non vuol sapere di andare, mi esce sempre fuori muro non trovato! .. si che nel picturebox4 nella sua propietà alla voce tag ho messo "muro"... uff..
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then MsgBox("trovato")
Else
MsgBox("non trovato")
End If
Next
niente da fare non vuol sapere di andare, mi esce sempre fuori muro non trovato! .. si che nel picturebox4 nella sua propietà alla voce tag ho messo "muro"... uff..
Momento, nel codice VB passi la stringa "muro", perciò .Tag = "muro".
Se lo inserisci direttamente a design nella Proprietà Tag della PictureBox, ovviamente va messa la stringa "secca", muro, senza virgolette.
superbau
20-10-2009, 08:36
sisi è senza virgolette nel design, ma non riesce di prendermela. non capisco il motivo.
Bisogna però sistemare il codice. Se vuoi gestire il trovato / non-trovato, questo :
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then MsgBox("trovato")
Else
MsgBox("non trovato")
End If
Next
Non è corretto : per ogni PictureBox che trova darà "non trovato" ogni volta che ne incontra una con Tag <> "muro". E' più logico che restituisca Vero o Falso una volta sola, se muro esiste o meno fra tutte le PictureBox... :
Dim trovato As Boolean = False
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then
MsgBox("trovato")
trovato = True
Exit For
End If
End If
Next
If trovato = False Then MsgBox("non trovato")
superbau
20-10-2009, 09:27
mi restituisce sempre non trovato
Private Sub KeyDownControlli(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
'------------------------------------------
'movimentooooooooooooooooooooooooooooooooo
'------------------------------------------
Dim trovato As Boolean = False
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then
MsgBox("trovato")
trovato = True
Exit For
End If
End If
Next
If trovato = False Then MsgBox("non trovato")
http://digilander.libero.it/superbau/murop4.jpg
1. Sicuro che quel Tag non contenga spazi ?
2. Se quel KeyDownControlli è quello che penso io ( http://www.hwupgrade.it/forum/showpost.php?p=29310762&postcount=2 ), non mi spiego : Handles Me.KeyDown...
superbau
20-10-2009, 10:22
si il KeyDownControlli è quello che hai linkato, e non ci sono spazi nel tag :(
si il KeyDownControlli è quello che hai linkato, e non ci sono spazi nel tag :(
Ma perchè "Handles Me.KeyDown" ? KeyDownControlli aveva senso proprio per gestire da un'unica routine tutti gli Handler personalizzati... :mbe:
In ogni caso, da me funziona, evidentemente c'è qualcos'altro che non va sul tuo progetto...
superbau
20-10-2009, 10:36
hai ragione, non me ne ero accorto, grazie.
superbau
20-10-2009, 10:38
se può servire posto l'intero codice della sezione interessata...
Private Sub KeyDownControlli(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
'------------------------------------------
'movimentooooooooooooooooooooooooooooooooo
'------------------------------------------
Dim trovato As Boolean = False
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then
MsgBox("trovato")
trovato = True
Exit For
End If
End If
Next
If trovato = False Then MsgBox("non trovato")
Label1.Text = PoporingDelPlayer.Location.X
Label2.Text = PoporingDelPlayer.Location.Y
Label8.Text = premuto
'metti l'oggetto o frontale o dietro
If e.KeyCode And asdS = 0 Then
FronteRetro(PoporingDelPlayer, PictureBox2, PictureBox4)
End If
'poporing movimento
Dim MovimentoPic1 As Integer
Select Case e.KeyCode
Case Keys.A
If (PoporingDelPlayer.Location.X <= 0) Or (PoporingDelPlayer.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'destra
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneX + Speed + speedRespinta
PoporingDelPlayer.Location = New Point(MovimentoPic1, PosizioneY)
Else
'sinistra
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneX - Speed
PoporingDelPlayer.Location = New Point(MovimentoPic1, PosizioneY)
End If
premuto = "Ovest"
Case Keys.D
If (PoporingDelPlayer.Location.X >= 812) Or (PoporingDelPlayer.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'sinistra
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneX - Speed - speedRespinta
PoporingDelPlayer.Location = New Point(MovimentoPic1, PosizioneY)
Else
'destra
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneX + Speed
PoporingDelPlayer.Location = New Point(MovimentoPic1, PosizioneY)
End If
premuto = "Est"
Case Keys.W
If (PoporingDelPlayer.Location.Y <= 0) Or (PoporingDelPlayer.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'giu
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneY + Speed + speedRespinta
PoporingDelPlayer.Location = New Point(PosizioneX, MovimentoPic1)
Else
'su
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneY - Speed
asdS = 0
PoporingDelPlayer.Location = New Point(PosizioneX, MovimentoPic1)
End If
premuto = "Nord"
Case Keys.S
If (PoporingDelPlayer.Location.Y >= 344) Or (PoporingDelPlayer.Bounds.IntersectsWith(PictureBox4.Bounds)) Then
'su
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneY - Speed - speedRespinta
asdS = 0
PoporingDelPlayer.Location = New Point(PosizioneX, MovimentoPic1)
Else
'giu
PosizioneX = PoporingDelPlayer.Location.X
PosizioneY = PoporingDelPlayer.Location.Y
MovimentoPic1 = PosizioneY + Speed
PoporingDelPlayer.Location = New Point(PosizioneX, MovimentoPic1)
End If
premuto = "Sud"
End Select
''''''''''''''''''''''''''''''''''
' Coordinate0001 primo giocatore
''''''''''''''''''''''''''''''''''
If cooPplayer = 1 Then
PoporingDelPlayer = PictureBox1
Dim DocPx1 As New XmlDocument()
DocPx1.Load(Coordinate0002)
Dim pathPx1 As String = Coordinate0001
Dim elementPx1 As XmlElement = DocPx1.DocumentElement
'recupero il valore all'interno del primo figlio dell'elemento root
Dim nodePx1 As XmlNode = elementPx1.FirstChild
For Each nodePx1 In elementPx1.ChildNodes
If nodePx1.Name.Equals("x") Then
'imposto il valore
nodePx1.InnerText = PosizioneX
'salvo le modifiche
DocPx1.Save(pathPx1)
End If
Next
For Each nodePx1 In elementPx1.ChildNodes
If nodePx1.Name.Equals("y") Then
'imposto il valore
nodePx1.InnerText = PosizioneY
'salvo le modifiche
DocPx1.Save(pathPx1)
End If
Next
End If
''''''''''''''''''''''''''''''''''
' Coordinate0001 secondo giocatore
''''''''''''''''''''''''''''''''''
If cooPplayer = 2 Then
PoporingDelPlayer = PictureBox8
Dim DocPx1 As New XmlDocument()
DocPx1.Load(Coordinate0002)
Dim pathPx1 As String = Coordinate0002
Dim elementPx1 As XmlElement = DocPx1.DocumentElement
'recupero il valore all'interno del primo figlio dell'elemento root
Dim nodePx1 As XmlNode = elementPx1.FirstChild
For Each nodePx1 In elementPx1.ChildNodes
If nodePx1.Name.Equals("x") Then
'imposto il valore
nodePx1.InnerText = PosizioneX
'salvo le modifiche
DocPx1.Save(pathPx1)
End If
Next
For Each nodePx1 In elementPx1.ChildNodes
If nodePx1.Name.Equals("y") Then
'imposto il valore
nodePx1.InnerText = PosizioneY
'salvo le modifiche
DocPx1.Save(pathPx1)
End If
Next
End If
End Sub
superbau
20-10-2009, 10:40
eppure cribbio puntandolo direttamente funziona! la scritta Ciao mi esce..
Private Sub KeyDownControlli(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
'------------------------------------------
'movimentooooooooooooooooooooooooooooooooo
'------------------------------------------
If PictureBox4.Tag = "muro" Then
MsgBox("ciao")
End If
Dim trovato As Boolean = False
For Each c As Control In Me.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then
MsgBox("trovato")
trovato = True
Exit For
End If
End If
Next
If trovato = False Then MsgBox("non trovato")
Non ti aspetterai che passi al setaccio tutto il tuo codice... :D ( per pietà, usa l'indentazione ! :D ).
Comunque credo sia chiaro il perchè. Ha a che fare con quel discorso sulle PictureBox, sovrapposizioni e trasparenze. Se hai una PictureBox di sfondo ( chiamiamola pcb_sfondo ) e avevi impostato .Parent = pcb_sfondo, come ti consigliai, ovviamente adesso il For Each va fatto sulle PictureBox che stanno su quel container.
Dim trovato As Boolean = False
For Each c As Control In pcb_sfondo.Controls
If TypeOf (c) Is PictureBox Then
If c.Tag = "muro" Then
MsgBox("trovato")
trovato = True
Exit For
End If
End If
Next
If trovato = False Then MsgBox("non trovato")
;)
superbau
20-10-2009, 17:57
ah okay, grazie, provo poi ti faccio sapere, grazie, sicuramente è il problema del parent.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.