Oppure

Loading
14/12/13 18:04
Dice
Vorrei provare a fare il gioco di battaglia navale con la windows form, però non so bene come fare.

Innanzi tutto vorrei chiedervi: nel gioco di battaglia navale, come potrei usare l'ereditarietà?

Creo la classe madre Nave, che poi si specializza in: Sottomarini, Incrociatori, Portaerei, ecc...; però non so quali attributi dare alla classe madre e alle classi derivate.

Come potrei fare?

Poi un altro dubbio che ho è:come faccio a creare la tabella dove ci andranno le immagini delle navi?


Grazie mille in anticipo
aaa
14/12/13 20:29
amreo
Puoi farlo usando GDI+ e i metodi draw/fill di Graphics.
all' inizio dichiari una variabile Graphics globale.
e esegui l'istruzione Form.Creategraphics()

poi ogni volta che lo schema di gioco viene aggiornato(spostamento,fuoco,caduta,...) ridisegni il form.

invece per le navi farei cosi

Classe Principale Nave

creerei metodi e proprietà overridable

come codice faccio questo esempio
fatto velocemente a mano
Class MustInherits Navone
       Overridable Property Lenght() As Int32 'Va bene anche byte, tanto il massimo è 5
       Overridable Sub DrawMe(byref G as graphics)
       End Sub
       Overridable Property Direction() as Dir 'Dir è un enum con Verticale e Orrizontale
'Ecc
End Class
aaa
14/12/13 21:56
Dice
Allora, due cose devo dirti:
1)io di quelle cose della grafica non le ho mai usate, e non so come funzionano :(
per la grafica pensavo di fare una semplice del tipo: metto come oggetto ad esempio una listView(o una griglia di qualche tipo) e poi faccio comparire le X quando viene colpita una nave.

2)mi daresti più dettagli per l'ereditarietà? la classe madre è Nave, che ha come attributo nome e lunghezza; le classi derivate sono: Portaerei, Incrociatori, Torpediniere, Sommergibili; ma che attributo li do a tutte queste? Li lascio sempre nome e lunghezza come la classe madre?
aaa
15/12/13 10:27
amreo
Non preoccuparti per GDI+, sono facili da usare e le trovi in System.Window.Form e System.Drawing.

ti faccio un codice d' esempio per la nave madre

''' <summary>
''' La classe Madre Navone, può essere usato solo per eredità
''' </summary>
''' <remarks>MustInherits Obbliga il Programmatore a non usarlo come tipo di dato es</remarks>
''' Es: Dim Nav As new Navone  : SBAGLIATO, Non può essere usato come tipo di dato
Public MustInherit Class Navone

    ''' <summary>
    ''' Nome della nave
    ''' </summary>
    Public Overridable Property Nome() As String

    ''' <summary>
    ''' Punto dove si trova la nave,corrisponde in alto a sinistra
    ''' </summary>
    Public Overridable Property Locazione() As Point

    ''' <summary>
    ''' Immagine della nave verticale, grande 32 e 32*Lenght, verra disegnato questo se la direzione della nave è verticale
    ''' </summary>
    ''' <remarks>Se non vuoi usare immagini già preparate, puoi disegnare tranquillamente con fill e Draw</remarks>
    Public Overridable Property DrawingBitmapVert() As Bitmap

    ''' <summary>
    ''' Immagine della nave orrizontale, grande 32*Lenght e 32, verra disegnato questo se la direzione della nave è orrizontale
    ''' </summary>
    ''' <remarks>Se non vuoi usare immagini già preparate, puoi disegnare tranquillamente con fill e Draw</remarks>
    Public Overridable Property DrawingBitmapOrr() As Bitmap

    ''' <summary>
    ''' Questa è la lunghezza della nave
    ''' </summary>
    Public Overridable Property Lenght() As Byte

    ''' <summary>
    ''' Direzione della nave, può essere Orrizontale o Verticale
    ''' </summary>
    Public Overridable Property Dir() As Direction

    ''' <summary>
    ''' Disegna la nave su G,senza spaccature
    ''' </summary>
    ''' <remarks>Ho messo Overridable anche se non è necessario</remarks>
    Public Overridable Sub DrawMe(ByRef G As Graphics)
        'In base alla direzione disegna la nave
        If Dir = Direction.Orrizontale Then
            G.DrawImage(DrawingBitmapOrr, Locazione)
        Else
            G.DrawImage(DrawingBitmapVert, Locazione)
        End If
    End Sub

    ''' <summary>
    ''' Disegna la nave su G,con spaccature
    ''' </summary>
    ''' <remarks>Ho messo Overridable anche se non è necessario</remarks>
    Public Overridable Sub DrawMeWthSp(ByRef G As Graphics)
        'In base alla direzione disegna la nave
        If Dir = Direction.Orrizontale Then
            G.DrawImage(DrawingBitmapOrr, Locazione.X * 32, Locazione.Y * 32)
        Else
            G.DrawImage(DrawingBitmapVert, Locazione.X * 32, Locazione.Y * 32)
        End If
        'Disegna le spaccature, Gira tutti gli elementi di _SP e disegna se sono spaccati
        REM questa parte di codice è un po confusionale
        For index As Byte = 0 To Lenght - 1 'Lenght meno 1 perchè gli array che contengono x elementi (es 3) vanno da 0 a x-1 (0;1;2), perciò non togliere -1 per evitare IndexOutException
            If SpaccP(index) = True Then
                If Dir = Direction.Orrizontale Then
                    'Disegna il segno che indica che la nave è spaccata, come la croce
                    'Prima linea
                    '*
                    '  *
                    '    *
                    G.DrawLine(Pens.Red, (Locazione.X * 32 + index * 32), (Locazione.Y * 32), ((Locazione.X + 1) * 32 + index * 32), ((Locazione.Y + 1) * 32))

                    'Seconda linea
                    '    *
                    '  *
                    '*    
                    G.DrawLine(Pens.Red, ((Locazione.X + 1) * 32 + index * 32), (Locazione.Y * 32), ((Locazione.X) * 32 + index * 32), ((Locazione.Y + 1) * 32))
                ElseIf Dir = Direction.Orrizontale Then
                    'Disegna il segno che indica che la nave è spaccata, come la croce
                    'Prima linea
                    '*
                    '  *
                    '    *
                    G.DrawLine(Pens.Red, (Locazione.X * 32), (Locazione.Y * 32 + index * 32), ((Locazione.X + 1) * 32), ((Locazione.Y + 1) * 32 + index * 32))

                    'Seconda linea
                    '    *
                    '  *
                    '*    
                    G.DrawLine(Pens.Red, ((Locazione.X + 1) * 32), (Locazione.Y * 32 + index * 32), (Locazione.X * 32), ((Locazione.Y + 1) + index * 32))
                End If
            End If
        Next

    End Sub

    Private _SP(Lenght - 1) As Boolean
    ''' <summary>
    ''' Indica i punti spaccati
    ''' </summary>
    ''' <remarks>True se il punto dell' indice è spaccato</remarks>
    Public Overridable Property SpaccP(Index As Byte) As Boolean
        Get
            Return _SP(Index)
        End Get
        Set(value As Boolean)
            _SP(Index) = value
        End Set
    End Property

    ''' <summary>
    ''' Crea una nuova nave
    ''' </summary>
    ''' <remarks>New non è overridable</remarks>
    Public Sub New(X As Byte, y As Byte)
        Me.Locazione = New Point(X, y)
        EliminaSpaccature()
    End Sub

    ''' <summary>
    ''' Elimina le spaccature della nave
    ''' </summary>
    Public Overridable Sub EliminaSpaccature()
        'elimina tutte le spaccature ridichiarando SP
        ReDim _SP(Lenght - 1)
    End Sub

    ''' <summary>
    ''' Controlla se la nave è stata colpita, se si modifica SpaccP
    ''' </summary>
    Public Overridable Function CheckSpaccatura(ByVal P As Point) As Boolean
        'Controlla se la nave è stata colpita
        If Dir = Direction.Orrizontale Then
            If P.Y = Locazione.Y Then
                If P.X >= Locazione.X And P.X <= Locazione.X + Lenght Then
                    Dim Index As Byte = P.X - Locazione.X
                    SpaccP(Index) = True
                    Return True
                Else
                    Return False
                End If
            Else
                Return False
            End If
        Else 'Dir = verticale
            If P.X = Locazione.X Then
                If P.Y >= Locazione.Y And P.Y <= Locazione.Y + Lenght Then
                    Dim Index As Byte = P.Y - Locazione.Y
                    SpaccP(Index) = True
                    Return True
                Else
                    Return False
                End If
            Else 'Dir = verticale
                Return False
            End If
        End If

    End Function


End Class

''' <summary>
''' Elenco di possibili direzioni
''' </summary>
Public Enum Direction
    Orrizontale = 0
    Verticale = 1
End Enum





invece qui c'è un esempio di eredità qui

''' <summary>
''' Nave Es
''' </summary>
Public Class Naves
    Inherits Navone

    Public Overrides ReadOnly Property Nome As String
        Get
            Return "NAVES"
        End Get
    End Property
    Public Overrides ReadOnly Property Lenght As Byte
        Get
            Return 5
        End Get
    End Property
    Sub New(x As Byte, y As Byte)
        MyBase.New(x, y)
    End Sub

    Public Overrides Property DrawingBitmapOrr As System.Drawing.Bitmap
        Get
            'Immagine contenuta nei resources, per aggiungere basta che clicci MyProject-->Risorse-->AggiungiRisorsa-->Aggiungi File esistente
            Return My.Resources.NavesO
        End Get
        Set(value As System.Drawing.Bitmap)
            MyBase.DrawingBitmapOrr = value
        End Set
    End Property

End Class


Modifica i valori facendo a caso tuo

Per quanto riguardi le dichiarazioni delle navi fai una funzione simile a questa
    'Liste di navi
    Public NL As List(Of Navone)
    Sub InitNL()
        NL.Add(New Naves(10, 10))
        NL.Add(New Incrociatore(4, 5))
        'ecc
        'puoi aggiungere alla lista qualsiasi oggetto che eredita da navone
    End Sub



Per la grafica fai una funzione simile a questa

    'Grafica
    Public G As Graphics

    Sub Draw()
        For y = 0 To 8 - 1 '8 è il numero di colonne e trasverse
            For x = 0 To 8 - 1
                G.FillRectangle(Brushes.CornflowerBlue, x * 32, y * 32, 32, 32)
                G.DrawRectangle(Pens.Blue, x * 32, y * 32, 32, 32)
            Next
        Next
        For Each N As Navone In NL
            N.DrawMeWthSp(G)
        Next
    End Sub


e infine all'evento load del form aggiungi
    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        InitNL()
        G = panel1.createGraphics
    End Sub



ti ho suggerito tutto, comunque l'ereditarietà è quando la classe figlia eredita tutti gli oggetti della classe madre e può aggiungere altro e sovrascrivere.


NB: puoi dichiarare una classe figlia anche usando la base della madre, cioè
Dim Nav As Navona = New Naviglia(5,6)

Però puoi usare solo gli oggetti presenti in Navona e non le funzioni aggiuntive di Naviglia, però gli Overrides si
Capit :D?


aaa
15/12/13 13:55
tuttodiMC
Dice stai commettendo un errore. Se proprio vuoi utilizzare l'ereditarietà non puoi implementare Nave come una classe perché non esistono navi standard. Dovresti implementarla come interfaccia da cui poi erediteranno i singoli tipi di navi, che si adatteranno ai metodi e alle proprietà indicate nell'interfaccia. Inoltre secondo me ti conviene creare un progetto in cui siano presenti più classi madre con le relative classi derivate, in modo da evidenziare la classificazione.
aaa
15/12/13 18:59
Dice
Allora, devo dire una cosa importante:

Amreo, io ti ringrazio un miliardo di volte per tutto l'aiuto che mi stai dando, ma c'è un però: del codice che hai scritto ci sono varie cose che non capisco e che (sfortunatamente per me :( ) non ho tempo di imparare al volo.

Quindi io direi che abbandono il progetto battaglia navale, vista la difficoltà (o per lo meno è difficile per me :( )

E vi chiederei se mi potreste aiutare a trovare un altra idea progetto: i requisiti minimi sono che sia possibile usare l'ereditarietà e il polimorfismo.

Ricordate però una cosa: io non sono un esperto :( quindi non mi proponete cose troppo complicate


Grazie mille ancora per l'aiuto a tutti quanti :)
aaa
16/12/13 13:37
amreo
a dire vero neanchio sono esperto, avrò circa la tua stessa eta.

devi perforza usare un progetto window form? o va bene anche libreria di classe
aaa
16/12/13 15:58
Dice
Io preferire fare un progetto usando le windows form (giusto per fare un pochino l'interfaccia grafica con dei semplici bottini e text box qua e la; non voglio fare la VERA grafica come per i video-giochi)
Però mi potrebbe andare bene anche fare un programma da riga di comando.


Mi era venuta in mente questa idea (anche un po banale): fare una specie di gestore aziendale, dove faccio inserire, modificare, eliminare un dipendente; e anche una specie di libro paga dove segnare entrate e uscite e cose varie. Così mi viene bene il fatto dell'ereditarietà: Persona -> Dipendente, Datore (o cose del genere).


Però c'è un piccolo dettaglio: io di ragioneria ne so poca sinceramente, e avrei quindi bisogno che mi diceste voi cosa ci andrebbe in un programma del genere (ad es. come fare i vari calcoli da ragioniere e i vari importi)
aaa