Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1

    Interazione tra logica e gui

    Ciao ragazzi
    Sono incappato in un problema informatico (mi succede troppo spesso )
    Mi serve un consiglio/dritta/informazione. Mettiamola in termini generali:
    Sto creando un gioco completo di grafica dove sto separando la logica dalla gui come giusto
    che sia, ma come faccio a farli interagire? Mi spiego meglio. Ho la classe A che
    contiene tutta la logica del gioco, il suo svolgimento, l'intelligenza del pc. Lo svolgimento
    in generale effettua side-effect sulle proprietà di altre classi (tramite metodi get/set) senza
    andare a toccare minimamente la grafica. Ho la classe B che rappresenta la finestra principale
    di gioco e che deve andare a rappresentare tutte quelle proprietà su cui la classe A di volta
    in volta va a fare side-effect. Questa finestra principale è "statica" per così dire, quindi come fa
    ad essere aggiornata (dal punto di vista grafico, ad esempio le immagini dei pulsanti) in
    corrispondenza di quello che accade nella classe A? Non so se sono stato chiaro..

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    non molto a dire il vero.
    HO visto la parola statica e già mi sono venuti i brividi...spero che tu NON abbia dichiarato la finestra statica, ma usato quel termine per indicare appunto che prevedi che quella parte sia fissa.

    Ci sono dei wrapper che offrono servizi. Mi spiego.
    Supponi che tu hai una calcolatrice, avrai una interfaccia che indica quali operazioni puoi fare.
    Supponi che tu hai fatto una interfaccia grafica per la calcolatrice.
    A questo punto succede che la tua interfaccia grafica si porti dietro una istanza di Calcolatrice, quando chiedi somma ad esempio su questa chiami il metodo somma e ne prendi il risultato.
    Il metodo è implementato in un'altra classe (quella che implementa la tua interfaccia).
    Hai separato la logica di business da quella di GUI.

    Poi se hai altre proprietà da aggiornare, la cosa migliore (almeno per me) è gestirle come eventi, viste le loro caratteristiche resta la soluzione più sicura per evitare casini.

    Poi se non intendevi questo, cerca di spiegarti meglio.

    RTFM Read That F*** Manual!!!

  3. #3
    No no non l'ho dichiarata statica tranquillo
    L'esempio della calcolatrice è molto chiaro però nel mio caso la situazione è molto più complessa.
    Per la precisione ho la classe GuiPartita (grafica) e la classe Partita (logica). Sto creando
    un gioco di carte (per me è una sfida, non ho mai programmato una cosa così "complessa").
    La classe GuiPartita prende Partita come argomento nel costruttore come te giustamente dici.
    Il problema è che la Partita si svolge appunto in Partita modificando gli attributi delle classi
    Giocatore, Computer e Tavolo (carte che hanno in mano, carte giocate ecc..) e non so come
    "ripercuotere" questo sulle carte della gui! Ora come ora se il computer gioca una carta avviene
    solo dal punto di vista logico, nella gui non succede nulla. Nella gui riesco ad impostare
    solo le carte iniziali attingendo ai dati iniziali della classe Partita. Una volta che il computer
    ha giocato una carta il programma si mette in attesa della mossa del giocatore, quindi dovrei
    associare anche degli actionListener alla gui che in un qualche modo vadano a comunicare
    con Partita. Comunque se può servire, lo schema principale di gioco presente in Partita è questo:

    codice:
    private void start() {
    		
    		/* Controlla turno e stato del gioco dell'utente
             * e si ramifica in 4 possibili situazioni
             */
    
            /* turno PC */
            if(isTurnoPc()) {
            	System.out.println("E' il turno del pc.");
                /* user non ha giocato (inizio della mano) */
                if(!userHavePlayed) {
                    giocoPcScarta();
                }
                
                /*user ha già risposto al gioco pc: calcolo punti e vincitore*/
                else {
                    fineMano();
                }
            }
            
            /* turno user */
            else {
            	System.out.println("E' il turno del giocatore.");
                /* user non ha giocato (inizio della mano) */
                if(!userHavePlayed) {
                    /* non accade nulla
                     * serve il gioco dell'utente --> qui il programma si ferma, dovrei sbloccarlo
                     * da un'altra classe utilizzando probabilmente qualche variabile di stato
                     * di questa classe.
                     */        
                	System.out.println("Il computer sta attendendo la mossa del giocatore...");
                }
                
                /* user ha giocato e attende risposta pc */
                else {
                	System.out.println("Il giocatore ha giocato, il computer sta rispondendo...");
                    giocoPcRisposta();   /* risposta pc */
                    fineMano();          /* punti e vincitore */
                }            
            }
        }

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    non trovi comodo che ci sia un "gestore" della partita che solleciti le varie parti? non conosco bene la tua architettura, sono idee le mie
    RTFM Read That F*** Manual!!!

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Secondo me ti mancano, oppure non li hai mostrati, dei metodi in Partita attraverso cui si possa risalire allo stato della partita in ogni momento. Userai questi valori ritornati (da dei metodi getter, o come valore di ritorno da metodi di azione) per visualizzare a video, tramite la GUI, lo stato della partita.

    Questi getter ovvimente possono anche stare in classi annidate in Partita tipo:
    partita.getGiocatore(1).getPunteggio()

    In caso di una partita a carte, il gioco avanzerà solo quando comanderai tu a Partita di avanzare, quindi conosci i momenti in cui dovrai andare a richiamare i vari getter per rinfrescare la GUI.

    Nel caso di un gioco in cui la partita avanzi da sola senza un tuo input allora dovresti prevedere un meccanismo di callback della Partita, in modo che la Partita possa segnalare ai suoi "osservatori" che qualcosa è cambiato.

    Nulla ti vieta comunque di prevedere un sistema di callback anche per la tua partita di carte. Sostanzialmente passeresti a Partita una classe (che implementa una interfaccia) con tanti metodi (oppure anche solo uno con diversi argomenti) a seconda di quello che vuoi essere notificato (e.g. punteggioCambiato(), partitaVinta(), ...) Quando si verificano questi eventi, Partita chiamerà quei metodi sull'interfaccia, notificando così chi ha implementato e passato quell'interfaccia a Partita.

  6. #6
    Nella classe Partita ho vari metodi get:

    codice:
            //Verifica di chi è il turno
    	public boolean isTurnoPc() {
    		if(turno < 0) return true;
    		else return false;
    	}
    	
            /*Verifica se la partita è in corso.
             * La variabile partita viene settata 
             * a false quando la partita è finita */
    	public boolean inPartita() {
    		return partita == true;
    	}
    	
            //Ritorna il punteggio attuale del giocatore
    	public int getPuntiUser() {
    		return puntiUser;
    	}
    	
            //Ritorna il punteggio attuale del computer
    	public int getPuntiComputer() {
    		return puntiComputer;
    	}
    	
            //Questi sono abbastanza autoesplicativi..
    
    	public Giocatore getGiocatore() {
    		return user;
    	}
    	
    	public GiocatoreElettronico getComputer() {
    		return computer;
    	}
    	
    	public Mazzo getMazzo() {
    		return mazzo;
    	}
    Poi ho buttato giu una cosa del genere:

    codice:
    /*
    	 * Metodo di interfacciamento con la grafica per capire quale carta
    	 * ha scelto il giocatore.
    	 */
    public boolean interfacciamentoUtente(int scelta) {
    		
    		if(scelta == 1) {
    			if(user.getPrimaCarta().isCarta()) {
    				tavolo.setCartaUser(user.getPrimaCarta());
    				user.setPrimaCarta(new Carta(0,null));
    			}
    		}
    		
    		if(scelta == 2) {
    			if(user.getSecondaCarta().isCarta()) {
    				tavolo.setCartaUser(user.getSecondaCarta());
    				user.setSecondaCarta(new Carta(0,null));
    			}
    		}
    		
    		if(scelta == 3) {
    			if(user.getTerzaCarta().isCarta()) {
    				tavolo.setCartaUser(user.getTerzaCarta());
    				user.setTerzaCarta(new Carta(0,null));
    			}
    		}
    		
    		userHavePlayed = true;
    		
    		start();
    		
    		return true;
    	}
    Non penso che serva qualcos'altro.. il problema è che non so come sfruttarli nella
    GuiPartita xD Poi giustamente dici:

    "In caso di una partita a carte, il gioco avanzerà solo quando comanderai tu a Partita di avanzare, quindi conosci i momenti in cui dovrai andare a richiamare i vari getter per rinfrescare la GUI."

    Ma è la GUI che deve comunicare alla Partita di avanzare tramite qualche azione
    svolta da un ActionListener.. solo che non so come.

    Grazie del supporto comunque

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Originariamente inviato da Javino89
    Non penso che serva qualcos'altro.. il problema è che non so come sfruttarli nella
    GuiPartita xD Poi giustamente dici:

    "In caso di una partita a carte, il gioco avanzerà solo quando comanderai tu a Partita di avanzare, quindi conosci i momenti in cui dovrai andare a richiamare i vari getter per rinfrescare la GUI."

    Ma è la GUI che deve comunicare alla Partita di avanzare tramite qualche azione
    svolta da un ActionListener.. solo che non so come.

    Grazie del supporto comunque
    devi avere anche un manager del gioco:

    la tua gui interagisce col manager, il manager sollecita i vari partecipanti.
    ricorda che i vari componenti diranno tramite eventi al manager che sono pronti, il manager richiamerà un metodo sui componenti (in funzione dell'evento che ha ricevuto).
    RTFM Read That F*** Manual!!!

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Ma è la GUI che deve comunicare alla Partita di avanzare tramite qualche azione svolta da un ActionListener.. solo che non so come.
    Non so perché parli di ActionListener. L'avanzare della Partita, non sapendo nulla del tuo programma, può avvenire (per dire) perché l'utente ha fatto una mossa o il computer deve fare una mossa.
    Allora immagino che Partita abbia dei metodi come:
    void userPlay(PlayerAction action) // mi invento PlayerAction non sapendo cosa può fare un player
    void computerPlay()

    La GUI chiamerà userPlay() e computerPlay() quando l'utente muoverà una carta e quando avrà finito il suo turno.

  9. #9
    Per c0der:

    Parlo di ActionListener poiché nella gui le 3 carte del giocatore (è una briscola in particolare) sono dei JButton che devono essere cliccati. Al loro click il computer deve capire che il giocatore
    ha giocato e fare la sua mossa (oddio forse mi sta venendo un'idea...) quindi per forza di cose a questi JButton devo associare un ActionListener (da disattivare quando è il turno del computer).
    L'idea (molto generale) che mi sta venendo giusto ora mentre scrivo è che l'ActionListener
    deve settare una variabile di stato della classe Partita, in particolare una che ho già creato:
    "boolean userHavePlayed" che è true se l'utente ha giocato, false altrimenti. Oltre a questo
    la classe Partita deve anche capire quale carta delle 3 l'utente ha giocato ovviamente. Devo
    combinare il metodo che ho scritto sopra con un ActionListener sicuramente.
    Comunque non credo che sia corretto chiamare dei metodi di Partita dalla Gui, non ci sarebbe più separazione tra logica e gui.

    Per Valia:

    Conosco la tecnica di cui parli. O meglio, la studiai 2 anni fa al corso di progettazione del software e ora non la ricordo quasi per niente (nonostante presi 28 all'esame.. ma ingegneria non ti abitua a programmare). Se non sbaglio una tecnica simile implicherebbe un restyling completo del codice che ho scritto e la cosa mi scoraggia veramente tanto T_T Hai per caso del materiale sulla programmazione ad eventi? Sarebbe comunque roba utile da visionare.

    Comunque ragazzi non c'è un modo per allegare la mia classe Partita? Sono più di 1100 righe
    e non mi pare il caso di postarla ehehe

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Ok, ho capito che ActionListener parlavi.

    IMHO però anche se la posti non è che ti si può riscrivere il design di tutta la tua classe.

    Se cerchi su internet ci saranno millemila esempi di giochi di carte, dagli una occhiata.

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.