Rychlost kuliček   zodpovězená otázka

VB.NET, WinForms

Zdravím,

tvořím program kuličky na kterém se učím pracovat s grafikou.

Nemůžu ale přijít na to jak po nárazu kuličky do jiné změnit rychlost a směr kuličky.

Přikládám celý zdroják:

Public Class Form1
    Dim m_Dx As Integer
    Dim m_Dy As Integer
    Dim m_X As Integer
    Dim m_Y As Integer
    Dim m_Dx1 As Integer
    Dim m_Dy1 As Integer
    Dim m_X1 As Integer
    Dim m_Y1 As Integer
    Dim m_Dx2 As Integer
    Dim m_Dy2 As Integer
    Dim m_X2 As Integer
    Dim m_Y2 As Integer
    Dim m_Dx3 As Integer
    Dim m_Dy3 As Integer
    Dim m_X3 As Integer
    Dim m_Y3 As Integer
    Dim m_Dx4 As Integer
    Dim m_Dy4 As Integer
    Dim m_X4 As Integer
    Dim m_Y4 As Integer
    Dim m_Dx5 As Integer
    Dim m_Dy5 As Integer
    Dim m_X5 As Integer
    Dim m_Y5 As Integer
    Dim m_Dx6 As Integer
    Dim m_Dy6 As Integer
    Dim m_X6 As Integer
    Dim m_Y6 As Integer
    Dim m_Dx7 As Integer
    Dim m_Dy7 As Integer
    Dim m_X7 As Integer
    Dim m_Y7 As Integer
    Dim m_Dx8 As Integer
    Dim m_Dy8 As Integer
    Dim m_X8 As Integer
    Dim m_Y8 As Integer
    Dim m_Dx9 As Integer
    Dim m_Dy9 As Integer
    Dim m_X9 As Integer
    Dim m_Y9 As Integer

    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode() Then
            Timer2.Enabled = True
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim rnd As New Random
        m_Dx = rnd.Next(1, 4)
        m_Dy = rnd.Next(1, 4)
        m_X = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx1 = rnd.Next(1, 4)
        m_Dy1 = rnd.Next(1, 4)
        m_X1 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y1 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx2 = rnd.Next(1, 4)
        m_Dy2 = rnd.Next(1, 4)
        m_X2 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y2 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx3 = rnd.Next(1, 4)
        m_Dy3 = rnd.Next(1, 4)
        m_X3 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y3 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx4 = rnd.Next(1, 4)
        m_Dy4 = rnd.Next(1, 4)
        m_X4 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y4 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx5 = rnd.Next(1, 4)
        m_Dy5 = rnd.Next(1, 4)
        m_X5 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y5 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx6 = rnd.Next(1, 4)
        m_Dy6 = rnd.Next(1, 4)
        m_X6 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y6 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx7 = rnd.Next(1, 4)
        m_Dy7 = rnd.Next(1, 4)
        m_X7 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y7 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx8 = rnd.Next(1, 4)
        m_Dy8 = rnd.Next(1, 4)
        m_X8 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y8 = rnd.Next(0, Me.ClientSize.Height - 50)
        m_Dx9 = rnd.Next(1, 4)
        m_Dy9 = rnd.Next(1, 4)
        m_X9 = rnd.Next(0, Me.ClientSize.Width - 50)
        m_Y9 = rnd.Next(0, Me.ClientSize.Height - 50)
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        m_X += m_Dx
        If m_X < 0 Then
            m_Dx = -m_Dx
            Beep()
        ElseIf m_X + 50 > Me.ClientSize.Width Then
            m_Dx = -m_Dx
            Beep()
        End If
        m_Y += m_Dy
        If m_Y < 0 Then
            m_Dy = -m_Dy
            Beep()
        ElseIf m_Y + 50 > Me.ClientSize.Height Then
            m_Dy = -m_Dy
            Beep()
        End If
        'dalsi_misto
        m_X1 += m_Dx1
        If m_X1 < 0 Then
            m_Dx1 = -m_Dx1
            Beep()
        ElseIf m_X1 + 50 > Me.ClientSize.Width Then
            m_Dx1 = -m_Dx1
            Beep()
        End If
        m_Y1 += m_Dy1
        If m_Y1 < 0 Then
            m_Dy1 = -m_Dy1
            Beep()
        ElseIf m_Y1 + 50 > Me.ClientSize.Height Then
            m_Dy1 = -m_Dy1
            Beep()
        End If
        'dalsi_misto
        m_X2 += m_Dx2
        If m_X2 < 0 Then
            m_Dx2 = -m_Dx2
            Beep()
        ElseIf m_X2 + 50 > Me.ClientSize.Width Then
            m_Dx2 = -m_Dx2
            Beep()
        End If
        m_Y2 += m_Dy2
        If m_Y2 < 0 Then
            m_Dy2 = -m_Dy2
            Beep()
        ElseIf m_Y2 + 50 > Me.ClientSize.Height Then
            m_Dy2 = -m_Dy2
            Beep()
        End If
        'dalsi_misto
        m_X3 += m_Dx3
        If m_X3 < 0 Then
            m_Dx3 = -m_Dx3
            Beep()
        ElseIf m_X3 + 50 > Me.ClientSize.Width Then
            m_Dx3 = -m_Dx3
            Beep()
        End If
        m_Y3 += m_Dy3
        If m_Y3 < 0 Then
            m_Dy3 = -m_Dy3
            Beep()
        ElseIf m_Y3 + 50 > Me.ClientSize.Height Then
            m_Dy3 = -m_Dy3
            Beep()
        End If
        'dalsi_misto
        m_X4 += m_Dx4
        If m_X4 < 0 Then
            m_Dx4 = -m_Dx4
            Beep()
        ElseIf m_X4 + 50 > Me.ClientSize.Width Then
            m_Dx4 = -m_Dx4
            Beep()
        End If
        m_Y4 += m_Dy4
        If m_Y4 < 0 Then
            m_Dy4 = -m_Dy4
            Beep()
        ElseIf m_Y4 + 50 > Me.ClientSize.Height Then
            m_Dy4 = -m_Dy4
            Beep()
        End If
        'dalsi_misto
        m_X5 += m_Dx5
        If m_X5 < 0 Then
            m_Dx5 = -m_Dx5
            Beep()
        ElseIf m_X5 + 50 > Me.ClientSize.Width Then
            m_Dx5 = -m_Dx5
            Beep()
        End If
        m_Y5 += m_Dy5
        If m_Y5 < 0 Then
            m_Dy5 = -m_Dy5
            Beep()
        ElseIf m_Y5 + 50 > Me.ClientSize.Height Then
            m_Dy5 = -m_Dy5
            Beep()
        End If
        'dalsi_misto
        m_X6 += m_Dx6
        If m_X6 < 0 Then
            m_Dx6 = -m_Dx6
            Beep()
        ElseIf m_X6 + 50 > Me.ClientSize.Width Then
            m_Dx6 = -m_Dx6
            Beep()
        End If
        m_Y6 += m_Dy6
        If m_Y6 < 0 Then
            m_Dy6 = -m_Dy6
            Beep()
        ElseIf m_Y6 + 50 > Me.ClientSize.Height Then
            m_Dy6 = -m_Dy6
            Beep()
        End If
        'dalsi_misto
        m_X7 += m_Dx7
        If m_X7 < 0 Then
            m_Dx7 = -m_Dx7
            Beep()
        ElseIf m_X7 + 50 > Me.ClientSize.Width Then
            m_Dx7 = -m_Dx7
            Beep()
        End If
        m_Y7 += m_Dy7
        If m_Y7 < 0 Then
            m_Dy7 = -m_Dy7
            Beep()
        ElseIf m_Y7 + 50 > Me.ClientSize.Height Then
            m_Dy7 = -m_Dy7
            Beep()
        End If
        'dalsi_misto
        m_X8 += m_Dx8
        If m_X8 < 0 Then
            m_Dx8 = -m_Dx8
            Beep()
        ElseIf m_X8 + 50 > Me.ClientSize.Width Then
            m_Dx8 = -m_Dx8
            Beep()
        End If
        m_Y8 += m_Dy8
        If m_Y8 < 0 Then
            m_Dy8 = -m_Dy8
            Beep()
        ElseIf m_Y8 + 50 > Me.ClientSize.Height Then
            m_Dy8 = -m_Dy8
            Beep()
        End If
        'dalsi_misto
        m_X9 += m_Dx9
        If m_X9 < 0 Then
            m_Dx9 = -m_Dx9
            Beep()
        ElseIf m_X9 + 50 > Me.ClientSize.Width Then
            m_Dx9 = -m_Dx9
            Beep()
        End If
        m_Y9 += m_Dy9
        If m_Y9 < 0 Then
            m_Dy9 = -m_Dy9
            Beep()
        ElseIf m_Y9 + 50 > Me.ClientSize.Height Then
            m_Dy9 = -m_Dy9
            Beep()
        End If
        Me.Invalidate()
    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        e.Graphics.Clear(Me.BackColor)
        e.Graphics.FillEllipse(Brushes.Gold, m_X, m_Y, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkOrange, m_X, m_Y, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X + 10, m_Y + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X + 11, m_Y + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Red, m_X1, m_Y1, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkRed, m_X1, m_Y1, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X1 + 10, m_Y1 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X1 + 11, m_Y1 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.White, m_X2, m_Y2, 40, 40)
        e.Graphics.DrawEllipse(Pens.Gray, m_X2, m_Y2, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X2 + 10, m_Y2 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X2 + 11, m_Y2 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Green, m_X3, m_Y3, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkGreen, m_X3, m_Y3, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X3 + 10, m_Y3 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X3 + 11, m_Y3 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Pink, m_X4, m_Y4, 40, 40)
        e.Graphics.DrawEllipse(Pens.MediumPurple, m_X4, m_Y4, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X4 + 10, m_Y4 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X4 + 11, m_Y4 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Gray, m_X5, m_Y5, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkGoldenrod, m_X5, m_Y5, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X5 + 10, m_Y5 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X5 + 11, m_Y5 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Blue, m_X6, m_Y6, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkBlue, m_X6, m_Y6, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X6 + 10, m_Y6 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X6 + 11, m_Y6 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Orange, m_X7, m_Y7, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkOrange, m_X7, m_Y7, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X7 + 10, m_Y7 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X7 + 11, m_Y7 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Aqua, m_X8, m_Y8, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkSeaGreen, m_X8, m_Y8, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X8 + 10, m_Y8 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X8 + 11, m_Y8 + 10, 3, 21)
        e.Graphics.FillEllipse(Brushes.Purple, m_X9, m_Y9, 40, 40)
        e.Graphics.DrawEllipse(Pens.DarkBlue, m_X9, m_Y9, 40, 40)
        e.Graphics.DrawEllipse(Pens.White, m_X9 + 10, m_Y9 + 10, 4, 20)
        e.Graphics.DrawEllipse(Pens.White, m_X9 + 11, m_Y9 + 10, 3, 21)
    End Sub

    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        End
    End Sub

End Class

Poradí někdo kdo s tím má skušenosti?

Děkuji.

Pavel

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Myslím, že v tomhle zdrojovém kódu je chyba na první pohled. Zkuste si nastudovat pole. Provádět stejnou operaci pro více položek tak, že rozkopírujete kód a přepíšete proměnné je strašné a proti všem konvencím.

Podrobný popis v tomto článku: http://www.vbnet.cz/Article.aspx?id=43

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Nejen pole, já bych v tom šel ještě dál:

Public Class clsKulicka
    private _Dx As Integer
    private _Dy As Integer
    private _X As Integer
    private _Y As Integer

    Public Property Dx As Integer
        Get
            Return _Dx
        End Get
        Set (ByVal value As Integer)
            _Dx = value
        End Set
    End Property

    Public Property Dy As Integer
        Get
            Return _Dy
        End Get
        Set (ByVal value As Integer)
            _Dy = value
        End Set
    End Property

  Public Property X As Integer
        Get
            Return _X
        End Get
        Set (ByVal value As Integer)
            _X = value
        End Set
    End Property

    Public Property Y As Integer
        Get
            Return _Y
        End Get
        Set (ByVal value As Integer)
            _Y = value
        End Set
    End Property

End Class

Public Class Form1
    
    dim m_K(0 To 9) as Kulicka

    Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If e.KeyCode() Then
            Timer2.Enabled = True
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim rnd As New Random
        For i as Short = 0 To 9
             m_K(i) = new clsKulicka()
             With m_K(i)
               .Dx = rnd.Next(1, 4)
               .Dy = rnd.Next(1, 4)
               .X = rnd.Next(0, Me.ClientSize.Width - 50)
               .Y = rnd.Next(0, Me.ClientSize.Height - 50)
             End With
        Next
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        For i As Short = 0 To 9
          With m_K(i)
              .X += .Dx
              If .X < 0 Then
                  .Dx = -.Dx
                  Beep()
              ElseIf .X + 50 > Me.ClientSize.Width Then
                  .Dx = -.Dx
                  Beep()
              End If
              .Y += .Dy
              If .Y < 0 Then
                  .Dy = -.Dy
                  Beep()
              ElseIf .Y + 50 > Me.ClientSize.Height Then
                  .Dy = -.Dy
                  Beep()
              End If
          End With
          'dalsi_misto
        Next
        Me.Invalidate()
    End Sub

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        Dim m_Brush As SolidBrush() = new SolidBrush() _
                                    {
                                      Brushes.Gold,  Brushes.Red,  Brushes.White,  Brushes.Green,  
                                      Brushes.Pink,  Brushes.Gray,  Brushes.Blue,  Brushes.Orange,  
                                      Brushes.Aqua,  Brushes.Purple  
                                    }
        Dim m_Pen As Pen()=new Pen() _
                                   { 
                                     Pens.DarkOrange,  Pens.DarkRed,  Brushes.Gray,  Brushes.DarkGreen,  
                                     Brushes.MediumPurple,  Brushes.DarkGoldenrod,  Brushes.DarkBlue,  Brushes.DarkOrange,  
                                     Brushes.DarkSeaGreen,  Brushes.DarkBlue  
                                   }
        e.Graphics.Clear(Me.BackColor) 
        For i As Short = 0 To 9   
          With m_K(i)
            e.Graphics.FillEllipse(m_Brush(i), .X, .Y, 40, 40)
            e.Graphics.DrawEllipse(m_Pen(i), .X, .Y, 40, 40)
            e.Graphics.DrawEllipse(Pens.White, .X + 10, .Y + 10, 4, 20)
            e.Graphics.DrawEllipse(Pens.White, .X + 11, .Y + 10, 3, 21)
          End With 
        Next
      End Sub

    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        End
    End Sub

End Class

nahlásit spamnahlásit spam 3 / 3 odpovědětodpovědět

A či sa na guličku s tak málo metódami nehodí skôr Structure ako Class?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

A taktiež tie štetce(Brush) a perá(Pen) inicializujete stále nanovo.Čo tak to pole inicializovať v Form1_Load? A na 32bit CPU je (vraj) rýchlejší Integer ako Short.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Také rozhodně dobrá poznámka. Takové věci můžou naprosto zbytečně snižovat výkon.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Ahoj

Skôr ten Class asi. Ale otázka tu padla ako tej gulke po náraze zmeniť smer a rýchlosť. Tak potom z toho treba spraviť Class trošku obrastenejšiu.

Nech má vlastnosti.

.polomer

.rychlost

.farba

.pozicia

potom niečo také ako...

.smerpohybu - smernica priamky po ktorej sa pohybuje

alebo

.bodZaciatkuDrahy

.bodKoncaDrahy

potom metódy na sebavykreslenie

.Draw

prípadne nejaké udalosti čo by riešili prepočet zmeny pohybu pri náraze, so vstupnými parametrami smeru a rýchlosti gulky do ktorej to narazilo.

Ďalej by táto trieda mohla obsahovať časovač, ktorým by si sama v čase menila parametre pozície, potom v udalosti Paint by ste volali už len metódy Draw všetkých guličiek na scéne.

Samozrejme môže byť potreba pohyb danej gulky zastaviť. Na to by boli metodky

.StartPohyb

.StopPohyb

Ako to urobiť čo najelegantnejšie by bola vec Vášho chápania geometrie a vzťahov. Určite treba uvažovať s fyzikálnou realitou aby sa navzájom neodrážali nejak chaoticky, ale spôsobom, že uhol odrazu sa rovná uhlu dopadu. Zistiť si ako riešiť dotyčnice či kolmice atď.

Môj príspevok je staršieho dátumu ako celá diskusia.

Možno sa ako nápad niekomu hodí.

P.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Structure je vhodné jen pro velmi malé a triviální datové typy, např. Point nebo Color. Struktury se hodí pro reprezentaci "hodnot", ne "objektů".

Cokoli složitějšího je lepší dělat přes Class. Kulička ve scéně je objekt, tudíž rozhodně Class. Použitím struktury nic moc neušetříte, spíš naopak - při přiřazování se kopíruje celá položka, není to efektivní v kolekcích atd.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Existuje nejaká odporúčaná hranica(počet bajtov) medzi Structure a Class?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To je jistě ještě lepší řešení.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Děkuji moc všem za odpovědi.

Mrknu na to a přepíšu to.

Pavel

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback