Visualizzazione dei risultati da 1 a 5 su 5

Discussione: [VB.NET] Ellisse

  1. #1

    [VB.NET] Ellisse

    Sto provando ad usare le GDI+ di VB.NET

    Vorrei iniziare creando una palla rossa che si muove

    Ho così una form con un Timer
    Questo è il codice che ho utilizzato

    codice:
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim rett As New RectangleF(x, y, 20, 20)
            x += 2
            y += 2
            MyBase.CreateGraphics.Clear(Form2.DefaultBackColor)
            MyBase.CreateGraphics.DrawEllipse(New Pen(New SolidBrush(Color.Red)), rett)
            MyBase.CreateGraphics.FillEllipse(New SolidBrush(Color.Red), rett)
        End Sub
    Pero' ogni volta che entra nel timer devo prima resettare il Form e poi ricreare una ellisse e riempirla. Non si puo' creare un oggetto ellisse PUBLIC e poi spostarlo in base alle coordinate nel timer?? Oppure gdi+ è un implementazione senza stato?

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,465
    Ogni controllo visuale traccia, quando necessario, il proprio contenuto all'interno dell'area grafica occupata sul video.

    Quando il controllo visuale viene coperto parzialmente o totalmente, oppure si modificano le proprietà che influiscono direttamente sull'aspetto del controllo stesso, il suo contenuto viene "invalidato", pertanto appena possibile il controllo provvederà ad aggiornare il proprio stato e ridisegnare il contenuto.

    L'effetto di questo comportamento dovresti verificarlo sul form in cui stai lavorando: se disegni un ellisse, anche ferma, riducendo e ripristinando la form esso sparisce perchè il controllo Form traccia nuovamente il contenuto ricoprendo l'ellisse disegnato.

    Tenendo conto di questo comportamento, forse dovresti innanzitutto spostare il tuo codice all'interno di uno UserControl di cui fai l'override del metodo OnPaint, responsabile del tracciamento grafico, in cui sfrutti l'oggetto Graphics passato come argomento per tracciare i contenuti del controllo personalizzato creato da te.

    Puoi mantenere nella classe del controllo la posizione attuale dell'ellisse usando la struttura Point; quando il timer dà il proprio "tick", aggiorni il valore della posizione di conseguenza e chiami il metodo Invalidate all'interno del codice del tuo controllo per segnalare al "sistema" che il suo aspetto grafico non è più valido e deve essere ridisegnato; a quel punto, verrà (prima o poi) richiamato il metodo OnPaint in cui disegnerai nuovamente l'ellisse nella nuova posizione, eventualmente riempiendo lo sfondo del controllo per cancellare definitivamente i contenuti precedenti.

    L'effetto collaterale che potrai ottenere sarà un po' di naturale "flickering", cui puoi ovviare usando diverse tecniche, quali l'uso di un'immagine che funge da tela di lavoro nella quale riproduci l'aspetto grafico del controllo, senza mostrare tale immagine, tracciandola in un colpo solo sul controllo alla fine dell'elaborazione.

    Si tratta ovviamente di indicazioni molto teoriche, quindi ti lascio il compito di individuare classi e relativi metodi necessari per realizzare il tutto.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Quindi in sostanza dovrei creare un UserControl di nome "PALLA"
    inserirgli un timer interno del controllo, fare l'ovverride del metodo OnPaint così ad ogni richiamo di ridisegno (ad esempio il resize della Form) la palla verrà ridisegnata

    Allora ho provato a creare un UserControl con un Timer "Tmr_Palla:
    codice:
    Private punto As Point
        Private grandezza As Size
    
        Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs)
            disegnaPalla(grandezza, Color.Red)
        End Sub
        Private Function disegnaPalla(ByVal dimensione As Size, ByVal colore As Color)
            Dim posizione As Point
            posizione.X = 0
            posizione.Y = 0
            Dim rett As New RectangleF(posizione.X, posizione.Y, dimensione.Width, dimensione.Height)
            MyBase.CreateGraphics.Clear(Palla.DefaultBackColor)
            MyBase.CreateGraphics.DrawEllipse(New Pen(New SolidBrush(Color.Red)), rett)
            MyBase.CreateGraphics.FillEllipse(New SolidBrush(colore), rett)
        End Function
        Private Sub Palla_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            punto.X = 0
            punto.Y = 0
            grandezza.Width = 20
            grandezza.Height = 20
        End Sub
    
        Private Sub tmr_Palla_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr_Palla.Tick
            punto.X += 1
            punto.Y += 1
            MyBase.Location = punto
        End Sub
    Succede pero' che la palla compare un alto a sinistra della form e cominica a muoversi quando sono ancora in fase di Design-Time....Allora vorrei impostare una proprieta' di Design (quelle nel riquadro delle Proprietà di Visual Studio e settare una varibile start di tipo boolean....Ho provato con
    codice:
       Public Property Start()
            Get
                Return tmr_Palla.Enabled
            End Get
            Set(ByVal Value As Boolean)
                tmr_Palla.Enabled = Value
            End Set
        End Property
    ma non funge

    Inoltre nella msdn cè scritto di mettere nella funzione overridata
    MyBase.OnPaint(pe)

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,465
    Nella spiegazione precedente, immaginavo che il controllo personalizzato si riferisse all'area in cui si può muovere la "palla", piuttosto che alla palla stessa, ma probabilmente si può implementare anche così.

    Se fai l'override dell'evento OnPaint, devi richiamare nell'implementazione anche il metodo ereditato usando l'identificatore MyBase (come indicato su MSDN).

    Nel tuo codice non è visibile la creazione del Timer, ma suppongo che esso debba essere disabilitato subito al momento della creazione e abilitato solo a runtime, magari chiamando metodi opportuni che inserirai nella classe del controllo personalizzato oppure impostando una proprietà.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    chiamando metodi opportuni che inserirai nella classe del controllo personalizzato oppure impostando una proprietà
    Il timer l'ho inserito dall'IDE Visuale e ho impostato la proprieta' Enabled=True (quindi la risetto su False), naturalmente potrei definirlo come pubblico e accedere dall'esterno a questa proprietà oppure crearmi un metodo (come dici tu) ma preferirei capire come inserire una nuova proprietà che fossa visibile anche nell'IDE di Visual Studio.... Sapresti indicarmi come fare?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.