Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Tastiera gaming MSI GK600 TKL: switch hot-swap, display LCD e tre modalità wireless
Tastiera gaming MSI GK600 TKL: switch hot-swap, display LCD e tre modalità wireless
MSI FORGE GK600 TKL WIRELESS: switch lineari hot-swap, tripla connettività, display LCD e 5 strati di fonoassorbimento. Ottima in gaming, a 79,99 euro
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici
DJI porta un importante aggiornamento alla sua linea di gimbal camera tascabili con Osmo Pocket 4: sensore CMOS da 1 pollice rinnovato, gamma dinamica a 14 stop, profilo colore D-Log a 10 bit, slow motion a 4K/240fps e 107 GB di archiviazione integrata. Un prodotto pensato per i creator avanzati, ma che convince anche per l'uso quotidiano
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Il primo headset open-back della linea INZONE arriva a 200 euro con driver derivati dalle cuffie da studio MDR-MV1 e un peso record di soli 199 grammi
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 15-09-2008, 17:24   #1
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
[JAVA]Problema di ArrayList di oggetti classe

Spero che si capisca il titolo, ho buttato là una specie di pseudo descrizione del problema, visto che non so se ciò che cerco ha un nome specifico

Sto creando un'applicazione grafica pseudo-gioco e sto facendo alcuni test preliminari, in pratica creo degli oggetti Entity (nient'altro che delle palline), che è una classe da me definita così:

Codice:
/** Posizione x dell'entità */ 
	protected int x;
	/** Posizione y dell'entità */
	protected int y;
	
	/** Velocità orizzontale dell'entità */
	protected double dx = 3;
	/** Velocità verticale dell'entità */
	protected double dy = 3;
	/** Raggio della sfera */
	int radius = 8;
	
	public Entity(int x,int y)
	{
		this.x = x;
		this.y = y;
	}
public void move(int i, int j, int larg, int alt)
	{ ... }
In pratica posso inizializzare una sfera in un qualsiasi punto dello schermo ed impostarne il moto, scegliendo se muoverla in orizzontale, verticale o diagonale, in quale direzione deve muoversi ed entro quali limiti.

Funziona alla perfezione (dopotutto sono 10 righe di codice ) finchè devo inizializzarne ciascuna separatamente... il fatto è che volevo farlo in modo iterativo creando un arraylist di Entity dove inserire ciascuno che creo, qualcosa del genere:
Codice:
/** Lista entità sfera */
  	ArrayList<Entity> entityList = new ArrayList<Entity>();
for (int i = 0; i < 4; i++)
    	{
//Tanto per dire eh, così non funziona
    		entityList.add(i*50,i*50);
    		
    	}
e dentro il mainLoop qualcosa del genere
Codice:
for (int i = 0; i < 4; i++)
    	{
    		entityList.move(dirOrizzontale, dirVerticale, LarghezzaSchermo, AltezzaSchermo);
    		
    	}
Si capisce che voglio fare?
Vorrei inserire degli oggetti inizializzati ad un arraylist di tali oggetti e richiamarne le funzioni direttamente selezionandoli dall'arrayList. Possibile?
Immagino di si ma non so dove metterci le mani
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 15-09-2008, 20:44   #2
pequeno
Member
 
L'Avatar di pequeno
 
Iscritto dal: Jul 2005
Città: Potenza
Messaggi: 126
A prima vista non funziona perchè dovresti passare all'ArrayList un parametro che sia il riferimento ad un oggetto... non i due argomenti previsti dal costruttore di Entity...
__________________
Un'interfaccia per domarli, un package per trovarli tutti, un riferimento per ghermirli e nel framework incatenarli."
Il Signore degli Oggetti
pequeno è offline   Rispondi citando il messaggio o parte di esso
Old 15-09-2008, 20:55   #3
pequeno
Member
 
L'Avatar di pequeno
 
Iscritto dal: Jul 2005
Città: Potenza
Messaggi: 126
Il codice che hai postato dovrebbe diventare...
Codice:
/** Lista entità sfera */
ArrayList<Entity> entityList = new ArrayList<Entity>();
for (int i = 0; i < 4; i++) {    ;
    entityList.add(new Entity(i*50, i*50));    		
}
e nel main..

Codice:
for (Entity elemento:entityList) {   	
    elemento.move(dirOrizzontale, dirVerticale, LarghezzaSchermo, AltezzaSchermo);
}
ovviamente avendo il riferimento alla lista creata dall'altro metodo e i parametri corretti.. dirOrizzontale, dirVerticale, etc. etc.
__________________
Un'interfaccia per domarli, un package per trovarli tutti, un riferimento per ghermirli e nel framework incatenarli."
Il Signore degli Oggetti
pequeno è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 08:31   #4
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Donbabbeo, pequeno ha ragione.
Codice:
/** Lista entità sfera */
ArrayList<Entity> entityList = new ArrayList<Entity>();
for (int i = 0; i < 4; i++) {    ;
    entityList.add(new Entity(i*50, i*50));    		
}
Il fatto che tu abbia dichiarato una ArrayList<Entity> (usando così i Generics) invece della semplice ArrayList (che invece non è tipizzata e accetta quindi qualsiasi Object) non significa che basti invocare il metodo .add() per invocare implicitamente il costruttore di un nuovo oggetto di tipo Entity (e vorrei anche vedere )

Devi comunque creare ogni singolo oggetto Entity, prima di poterlo aggiungere alla tua ArrayList<Entity>.

Il vantaggio (tanto per citarne uno) di aver dichiarato la "versione a tipo parametrico":
Codice:
ArrayList<Entity> entityList;
Invece che la versione "non tipizzata":
Codice:
ArrayList entityList;
E' che quanto chiamerai una .get(index) sulla tua lista ti verrà restituito un reference all'oggetto del tipo giusto (Entity) invece di un reference a Object che dovresti quindi castare a Entity.

Inoltre con la versione Generics della tua Collection puoi utilizzare i cicli "for each" introdotti dalla versione 1.5 e scrivere così cicli for più snelli ed eleganti. Vedi qui per maggiori info.
Per i Generics c'è questo
Ciao.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)

Ultima modifica di banryu79 : 16-09-2008 alle 08:46.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 10:45   #5
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
Innanzitutto grazie ad entrambi, come penso si sia capito sono un vero caprone con queste cose...

Purtroppo non mi riesce di farlo andare
Ho provato anche ad usare un classico array, visto che so il numero di oggetti da creare fin dal principio, ma dà un errore di eccezione...

In pratica sto creando uno sfondo animato, ho una classe Space fatta così:

Codice:
package Space;

import java.awt.Graphics;
import java.awt.Color;

/** Implementa un quadrato che si muove */

public class Space extends Entity
{
	/** Velocità dell'entità in verticale */
	protected double dy = 2;
	/** Dimensione entità */
	protected int radius = 2;
	
	/** Costruttore */
	public Space(int x, int y)
	{
		super(x, y);
	}
	
	/** Muovi la stella verso il basso,
	 *  al raggiungimento del bordo inferiore
	 *  riprendi il cammino dall'alto */
	public void move(int altezza)
	{
		this.y += dy;
			
		if (this.y > altezza)
			this.y = 0;
	}
	
	/** Disegna la stella */
	public void draw(Graphics g)
	{
		int posX, posY;
    	
    	posX = this.x;
    	posY = this.y;
    	
    	g.setColor(Color.WHITE);
    	g.fillRect(posX, posY, radius, radius);
	}
}
La classe da cui deriva ha il costruttore così composto:

Codice:
public Entity(int x,int y)
	{
		this.x = x;
		this.y = y;
	}
L'errore se ho ben capito dovrebbe essere che definisco nella main l'istanza della classe Space come array così:
Codice:
/** Lista entità stelle */
  	Space space[];
che viene poi inizializzata così:
Codice:
for (int i = 0; i < 50, i++)
	space[i] = new Space(i * 2, i * 2);
Invece dovrei definire una lista di classi Space giusto? Peccato che non mi riesca
Scusate se abuso della vostra pazienza ma sono davvero niubbo
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 11:06   #6
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
L'errore nell'utilizzo dell'array è dato dal fatto che qui dichiari una reference ad un array di oggeti Space:
Codice:
/** Lista entità stelle */
  	Space space[];
Ma questa appunto è una semplice dichiarazione del fatto che la reference di nome "space" è un riferimento ad un array di dimensioni non note di oggetti Space, ma l'array di per se non viene creato/istanziato in memoria, ancora non esiste per cui quando fai:
Codice:
for (int i = 0; i < 50, i++)
	space[i] = new Space(i * 2, i * 2);
space[i] ti da un errore perchè stai usando una reference (space) che non è stata ancora inizializzata, quindi il compilatore giustamente si lamenta perchè non sa che pesci pigliare ...

Basta che inizializzi space a null per esempio.
Codice:
/** Lista entità stelle */
  	Space space[] = null;
Ciao
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 11:07   #7
pequeno
Member
 
L'Avatar di pequeno
 
Iscritto dal: Jul 2005
Città: Potenza
Messaggi: 126
Quote:
Originariamente inviato da Donbabbeo Guarda i messaggi
Invece dovrei definire una lista di classi Space giusto? Peccato che non mi riesca
Scusate se abuso della vostra pazienza ma sono davvero niubbo
Semmai una lista di riferimenti ad oggetti della classe Space...
Cmq potresti postare o inviarmi il codice delle classi che hai creato, così ti indico come fare?

P.S. Per convezione del linguaggio i nomi dei package andrebbero scritti sempre tutti in minuscolo e i nomi dei metodi secondo la notazione cammello..

Es.
// package della classe
package it.space.modello;

// metodo della classe
public void metodoEseguiQualcosa() {}
__________________
Un'interfaccia per domarli, un package per trovarli tutti, un riferimento per ghermirli e nel framework incatenarli."
Il Signore degli Oggetti
pequeno è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 13:36   #8
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
Banryu ho provato a fare come dici tu ma sebbene compili correttamente continua a segnalarmi l'errore:
Codice:
Exception in thread "main" java.lang.NullPointerException
    at Space.MainWindow.init(MainWindow.java:69)
    at Space.MainWindow.gameLoop(MainWindow.java:82)
    at Space.MainWindow.main(MainWindow.java:145)
Comunque ora posto il codice completo, è poca roba e scritta nel modo più intuitivo possibile, spero non porti via troppo tempo cercare di capirlo.
PS: Grazie mille ancora una volta

Breve descrizione:
Sto creando una specie di videogioco, qualcosa tipo space invaders o breakout o una via di mezzo tra i 2 .
PS: nel main ci sono un bordello di librerie, fate finta che siano solo le necessarie, ho ripreso un vecchio file che avevo e non le ho ancora sistemate
PSS: il package è con la maiuscola perchè senza mi da un sacco di errori

MainWindow.java
contiene la logica del programma e l'inizializzazione del frame
Codice:
package Space;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.lang.*;
import java.awt.*;
import java.text.DecimalFormat;
import java.util.ArrayList;

public class MainWindow extends Canvas
{
	/** larghezza dello schermo */
	public final static int LARGHEZZA = 800;
	/** altezza dello schermo */
	public final static int ALTEZZA = 600;
	/** numero di stelle dello sfondo */
	public final static int STELLE = 50;
  	/** double buffering */
  	Image doublebuffer;
  	/** Lista entità sfera */
  	Ball ball;
  	/** Lista entità stelle */
  	Space space[] = null;
  	//Space space;
  	
	/**
	 * Costruisce il frame ed il pannello su cui andremo a disegnare.
	 */
	public MainWindow()
	{
		// crea un frame che conterrà il nostro gioco
		JFrame container = new JFrame("TEST");
		
		// aggiunge il pannello al frame e ne imposta le dimensioni
		JPanel panel = (JPanel) container.getContentPane();
		panel.setPreferredSize(new Dimension(LARGHEZZA,ALTEZZA));
		panel.setLayout(null);
		
		// imposta la dimensione del canvas e lo inserisce nel pannello
		setBounds(0,0,LARGHEZZA,ALTEZZA);
		panel.add(this);
		
		// evita il repainting da parte di AWT
		setIgnoreRepaint(true);
		
		// imposta il frame come visibile e non ridimensionabile 
		container.pack();
		container.setResizable(false);
		container.setVisible(true);
		
		// aggiunge l'operazione in caso di chiusura del frame 
		container.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
	
		// imposta il focus sul frame
		requestFocus();
	}
	
	/** Inizializza gli elementi */
	public void init() 
  	{
		// posiziona una stella nel punto selezionato
    	for (int i = 0; i < STELLE; i++)
			space[i] = new Space(i * 2, i * 2);
		//space = new Space(getWidth()/3, getHeight()/3);
		
    	// posiziona una palla al centro dello schermo e impostane la dimensione
    	ball = new Ball(getWidth()/2, getHeight()/2);
    	ball.setRadius(20);
    	
    	// crea un double buffer della dimensione dello schermo
    	doublebuffer = createImage(getWidth(),getHeight());
  	} 

	/** Loop principale del gioco */
  	public void gameLoop() 
  	{
  		// richiama l'inizializzazione degli elementi
    	init();
    	
    	// ciclo infinito, DA MODIFICARE
    	int a = 1;
    	while (a == 1)
    	{	
    		// muovi la stella verso il basso
    		// campo di azione: tutto lo schermo
    		for (int i = 0; i < STELLE; i++)
				space[i].move(ALTEZZA);
			//space.move(ALTEZZA);
			
      		// muovi la palla verso il basso a destra
      		// campo di azione: tutto lo schermo
      		ball.move(1, 1, LARGHEZZA, ALTEZZA);
			
			// richiama il metodo update
      		repaint();
    		
    		// imposta la pausa del thread a 60 fps massimi
     		try {	Thread.sleep( 1000 / 60 );  
     		} catch ( Exception e ){}
    	}
  	}
	
	/** Metodo update, generalmente resetta gli oggetti a schermo e
	 *  richiama la funzione paint, è stato riscritto per chiamare
	 *  solo la funzione paint */
  	public void update ( Graphics screen )
  	{
		paint(screen);
  	}

	/** Metodo paint, colora lo sfondo di nero, colora la stella
	 *  e la palla */
  	public void paint( Graphics screen )
  	{
    	// seleziona il double buffer
    	Graphics g = doublebuffer.getGraphics();
    	
    	// colora lo sfondo della canvas di nero
    	g.setColor(Color.BLACK);
    	g.fillRect(0, 0, getWidth(), getHeight());
    	
    	// disegna la stella
    	for (int i = 0; i < STELLE; i++)
			space[i].draw(g);
		//space.draw(g);    	
				
		// disegna la palla
    	ball.draw(g);
    	
    	//double buffer
    	screen.drawImage(doublebuffer,0,0,this);

    	// libera le risorse
    	g.dispose();
  	}
  	
	/** funzione main, esegue il loop principale */
	public static void main(String argv[])
	{
		MainWindow game = new MainWindow();
		game.gameLoop();
	}
}
Entity.java
contiene la classe padre da cui derivano i vari elementi
Codice:
package Space;

import java.awt.Graphics;

public class Entity
{
	/** Posizione x corrente dell'entità */ 
	protected int x;
	/** Posizione y corrente dell'entità */
	protected int y;
	/** Velocità corrente dell'entità Orizzontale e Verticale */
	protected double dx = 3;
	protected double dy = 3;
	/** Dimensione entità */
	protected int radius;
	
	/** Costruttore dell'entità
	 *  @ x: posizione orizzontale
	 *  @ y: posizione verticale */
	public Entity(int x,int y)
	{
		this.x = x;
		this.y = y;
	}
	
	/** Restituisce la posizione x dell'entità */
	public int getX()
	{
		return (int) x;
	}
	
	/** Restituisce la posizione y dell'entità */
	public int getY()
	{
		return (int) y;
	}
	
	/** Imposta la dimensione dell'entità
	 *  @ i: valore dimensione */
	public void setRadius(int i)
	{
		this.radius = i;
	}
	
	/** Muove l'entità e controlla il rimbalzamento ai bordi
	 *  @ dirX: direzione orizzontale (1: destra, -1: sinistra)
	 *			può essere usato anche per incrementare la velocità
	 *			di movimento
	 *  @ dirY: direzione verticale (1: giù, -1: su)
	 *			può essere usato anche per incrementare la velocità
	 *			di movimento
	 *  @ larghezza: dimensione orizzontale su cui calcolare il rimbalzo
	 *  @ altezza: dimensione verticale su cui calcolare il rimbalzo */
	public void move(int dirX, int dirY, int larghezza, int altezza)
	{
		// imposta direzione di movimento
		x += dirX * dx;
		y += dirY * dy;
		
		// calcola il rimbalzo sui muri laterali
		if (this.x < 0 || this.x > larghezza - radius)
			dx = -dx;
		
		// calcola il rimbalzo sui muri superiore ed inferiore
		if (this.y < 0 || this.y > altezza - radius)
			dy = -dy;
	}
}
Ball.java
figlio di entity, implementa una sfera gialla con movimento obliquo che rimbalza sui bordi del frame
Codice:
package Space;

import java.awt.Graphics;
import java.awt.Color;

/** Implementa una sfera che si muove */

public class Ball extends Entity
{
	/** Costruttore dell'entità
	 *  @ x: posizione orizzontale
	 *  @ y: posizione verticale */
	public Ball(int x,int y)
	{
		super(x, y);
	}
	
	/** Disegna l'entità */
	public void draw(Graphics g)
	{
    	// variabili locali di posizione
    	int posX, posY;
    	
    	// imposta la posizione dell'entità
    	posX = this.x;
    	posY = this.y;
    	
    	// colorala
    	g.setColor(Color.YELLOW);
    	g.fillOval(posX, posY, radius, radius);
   	}
}
Space.java
implementa un quadrato che si muove dal punto di creazione verso il basso, una volta raggiunto il bordo inferiore ricomincia dall'alto
(creandone molte in modo random volevo implementare una sorda di background animato di un cielo stellato)
Codice:
package Space;

import java.awt.Graphics;
import java.awt.Color;

/** Implementa un quadrato che si muove */

public class Space extends Entity
{
	/** Velocità corrente dell'entità Verticale */
	protected static final double dy = 2;
	/** Dimensione entità */
	protected static final int radius = 2;
	
	/** Costruttore */
	public Space(int x, int y)
	{
		super(x, y);
	}
	
	/** Muovi l'entità verso il basso
	 *  @ altezza: punto in cui viene reinizializzata l'entità
	 *			   sul bordo superiore */
	public void move(int altezza)
	{
		this.y += dy;
			
		if (this.y > altezza)
			this.y = 0;
	}
	
	/** Disegna l'entità */
	public void draw(Graphics g)
	{
		// variabili locali di posizione
		int posX, posY;
    	
    	// imposta la posizione dell'entità
    	posX = this.x;
    	posY = this.y;
    	
    	// colorala
    	g.setColor(Color.WHITE);
    	g.fillRect(posX, posY, radius, radius);
	}
}
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 13:58   #9
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Banryu ho provato a fare come dici tu ma sebbene compili correttamente continua a segnalarmi l'errore: NullPointerException... [cut]
Sì scusami, facendo puntare l'array a null per forza... me misero
Perdonami, devi inizializzare il tuo array di Space così, per esempio:
Codice:
Space space[] = new Space[50]; //alloca un array con dimensione pari a 50 elementi di tipo Space
Comunque considera che puoi usare le Collection invece degli array.
Codice:
ArrayList<Space> spaceList = new ArrayList<Space>();
aggiungi elementi con:
Codice:
Space aSpace = new Space(x,y);
spaceList.add(aSpace);

//equivalente
spaceList.add(new Space(x,y));
itera
Codice:
Iterator<Space> itSpace = spaceList.iterator();
while(itSpace.hasNext())
{
    Space aSpace = itSpace.next();
}
o col cliclo for
Codice:
void methodDoSomenthing(Collection<Space> c)
{
    for(Space s : c)
    {
        s.doSomenthing();
    }
}
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 14:21   #10
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
grazie!!!!

Finalmente funziona, ho seguito il tuo consiglio ed ho usato l'arraylist, ho un cielo stellato fantastico ora

Se a qualcuno interessasse:

Codice:
package Space;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.lang.*;
import java.awt.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class MainWindow extends Canvas
{
	/** larghezza dello schermo */
	public final static int LARGHEZZA = 800;
	/** altezza dello schermo */
	public final static int ALTEZZA = 600;
	/** numero di stelle dello sfondo */
	public final static int STELLE = 200;
  	/** double buffering */
  	Image doublebuffer;
  	/** Lista entità sfera */
  	Ball ball;
  	/** Lista entità stelle */
  	ArrayList<Space> spaceList = new ArrayList<Space>();
  	//Space space;
  	
	/**
	 * Costruisce il frame ed il pannello su cui andremo a disegnare.
	 */
	public MainWindow()
	{
		// crea un frame che conterrà il nostro gioco
		JFrame container = new JFrame("TEST");
		
		// aggiunge il pannello al frame e ne imposta le dimensioni
		JPanel panel = (JPanel) container.getContentPane();
		panel.setPreferredSize(new Dimension(LARGHEZZA,ALTEZZA));
		panel.setLayout(null);
		
		// imposta la dimensione del canvas e lo inserisce nel pannello
		setBounds(0,0,LARGHEZZA,ALTEZZA);
		panel.add(this);
		
		// evita il repainting da parte di AWT
		setIgnoreRepaint(true);
		
		// imposta il frame come visibile e non ridimensionabile 
		container.pack();
		container.setResizable(false);
		container.setVisible(true);
		
		// aggiunge l'operazione in caso di chiusura del frame 
		container.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
	
		// imposta il focus sul frame
		requestFocus();
	}
	
	/** Inizializza gli elementi */
	public void init() 
  	{
		// posiziona una stella nel punto selezionato
    	for (int i = 0; i < STELLE; i++)
    	{
    		spaceList.add(new Space((int)(Math.random() * LARGHEZZA), (int)(Math.random() * ALTEZZA)));
    	}
		//space = new Space(getWidth()/3, getHeight()/3);
		
    	// posiziona una palla al centro dello schermo e impostane la dimensione
    	ball = new Ball(getWidth()/2, getHeight()/2);
    	ball.setRadius(20);
    	
    	// crea un double buffer della dimensione dello schermo
    	doublebuffer = createImage(getWidth(),getHeight());
  	} 

	/** Loop principale del gioco */
  	public void gameLoop() 
  	{
  		// richiama l'inizializzazione degli elementi
    	init();
    	
    	// ciclo infinito, DA MODIFICARE
    	int a = 1;
    	while (a == 1)
    	{	
    		// muovi la stella verso il basso
    		// campo di azione: tutto lo schermo
    		Iterator<Space> itSpace = spaceList.iterator();
			while(itSpace.hasNext())
			{
    			Space element = itSpace.next();
    			element.move(ALTEZZA);
			}
			//space.move(ALTEZZA);
			
      		// muovi la palla verso il basso a destra
      		// campo di azione: tutto lo schermo
      		ball.move(1, 1, LARGHEZZA, ALTEZZA);
			
			// richiama il metodo update
      		repaint();
    		
    		// imposta la pausa del thread a 60 fps massimi
     		try {	Thread.sleep( 1000 / 60 );  
     		} catch ( Exception e ){}
    	}
  	}
	
	/** Metodo update, generalmente resetta gli oggetti a schermo e
	 *  richiama la funzione paint, è stato riscritto per chiamare
	 *  solo la funzione paint */
  	public void update ( Graphics screen )
  	{
		paint(screen);
  	}

	/** Metodo paint, colora lo sfondo di nero, colora la stella
	 *  e la palla */
  	public void paint( Graphics screen )
  	{
    	// seleziona il double buffer
    	Graphics g = doublebuffer.getGraphics();
    	
    	// colora lo sfondo della canvas di nero
    	g.setColor(Color.BLACK);
    	g.fillRect(0, 0, getWidth(), getHeight());
    	
    	// disegna la stella
    	Iterator<Space> itSpace = spaceList.iterator();
		while(itSpace.hasNext())
		{
    		Space element = itSpace.next();
    		element.draw(g);
		}
		//space.draw(g);    	
				
		// disegna la palla
    	ball.draw(g);
    	
    	//double buffer
    	screen.drawImage(doublebuffer,0,0,this);

    	// libera le risorse
    	g.dispose();
  	}
  	
	/** funzione main, esegue il loop principale */
	public static void main(String argv[])
	{
		MainWindow game = new MainWindow();
		game.gameLoop();
	}
}
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 14:48   #11
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Scusa la curiosità ma:
Codice:
public MainWindow()
	{
		// crea un frame che conterrà il nostro gioco
		JFrame container = new JFrame("TEST");
		
		// aggiunge il pannello al frame e ne imposta le dimensioni
		JPanel panel = (JPanel) container.getContentPane();
		panel.setPreferredSize(new Dimension(LARGHEZZA,ALTEZZA));
		panel.setLayout(null);
		
		// imposta la dimensione del canvas e lo inserisce nel pannello
		setBounds(0,0,LARGHEZZA,ALTEZZA);
		panel.add(this);
		
		// evita il repainting da parte di AWT
		setIgnoreRepaint(true);
considerando che la tua Window non è full-screen non hai nessun side-effect a fare quella chiamata (in grassetto)?
Ho visto che ci pensi tu a chiamare un "repaint()" della Window circa ogni "Thread.sleep( 1000 / 60 )" ma se ridimensiono al volo la finestra del gioco oppure ci sovvrappongo parzialmente un'altra finestra di un'altra applicazione aperta, va tutto bene?
Lo chiedo per curiosità, leggendo le Javadoc su setIgnoreRepaint mi ero fatto una prima idea, forse parziale, della questione:
(quotazione dalla javadoc Sun del JDK 1.6)
Quote:
setIgnoreRepaint

public void setIgnoreRepaint(boolean ignoreRepaint)

Sets whether or not paint messages received from the operating system should be ignored. This does not affect paint events generated in software by the AWT, unless they are an immediate response to an OS-level paint message.

This is useful, for example, if running under full-screen mode and better performance is desired, or if page-flipping is used as the buffer strategy.

Since:
1.4
See Also:
getIgnoreRepaint(), Canvas.createBufferStrategy(int), Window.createBufferStrategy(int), BufferStrategy, GraphicsDevice.setFullScreenWindow(java.awt.Window)
P.S.:
Visto che ti piace cimentarti con Java2D ti linko questo thread dove potresti trovare altri stimoli, ciao
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 15:01   #12
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
Il link che hai postato l'avevo già letto tempo addietro, purtroppo ciò che sto facendo non è solo per passione, ho l'obbligo di usare solo librerie standard...

RETTIFICA SULL'IGNORE REPAINT:

Ho appena aggiunto un'ulteriore classe figlia di Entity che invece di essere disegnata a schermo è formata da un'immagine. In questo caso senza il comando ignoreRepaint vengono fuori i seguenti messaggi di errore (sebbene si compili e continui ad eseguirsi senza alcun errore):

Codice:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Space.MainWindow.paint(MainWindow.java:141)
    at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
    at sun.awt.RepaintArea.paint(RepaintArea.java:224)
    at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
    at java.awt.Component.dispatchEventImpl(Component.java:4489)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Ultima modifica di Donbabbeo : 16-09-2008 alle 16:04.
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 16:42   #13
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da Donbabbeo Guarda i messaggi

RETTIFICA SULL'IGNORE REPAINT:

Ho appena aggiunto un'ulteriore classe figlia di Entity che invece di essere disegnata a schermo è formata da un'immagine. In questo caso senza il comando ignoreRepaint vengono fuori i seguenti messaggi di errore (sebbene si compili e continui ad eseguirsi senza alcun errore):
Ehm, sì ok, ma io non intendevo suggerire che tu dovessi toglierlo stavo solo chiedendo se con quella chiamata presente non avessi problemi della serie "artefatti grafici" o altre "anomalie" quando sovrapponi e muovi un'altra finestra davanti a quella della tua applicazione che sta girando o provi a ridimensionare la tua finestra mediante trascinamento dei bordi.

La mia era semplice curiosità.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-09-2008, 19:33   #14
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
ahhhh

no no a parte qualche warning durante l'esecuzione funziona bene in entrambi i modi
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 17-09-2008, 08:21   #15
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Ok, grazie.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 17-09-2008, 13:43   #16
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
Aggiungo qua che non è il caso di aprire un nuovo topic:

Sto cercando di modificare l'entità in modo che sia possibile caricare sprites al posto di disegnare oggetti. Funziona bene, il problema è che carico ad ogni costruttore della flotta tante immagini quanti sono gli oggetti, mentre io mi accontenterei di caricarlo UNA volta e riutilizzarlo.

Questo è il costruttore della flotta, come si può vedere per ogni entità richiama il caricamento della funzione loadSprite che gli incolla un'immagine.
Codice:
/** Costruttore della flotta
  	 *  @ colonne: numero delle colonne della flotta
  	 *			   (numero alieni per riga)
  	 *  @ righe: numero di righe della flotta */
	public Flotta(int righe, int colonne)
	{
		int indice = 0;
		
		// posizione alcuni alieni in formazione
    	for (int i = 0; i < righe; i++)
    	{
    		for (int j = 0; j < colonne; j++)
    		{
    			alienoList.add(new Alieno((40 * j), (25 * i)));
    			alienoList.get(indice).loadSprite("alien10A");
    			alienoList.get(indice).setVel(1, 2);
    			indice++;
    		}
    	} 
	}
Questa è la funzione all'interno dell'entità, come vedete è stata già "pensata" per controllare se esiste già un'immagine caricata con quel nome, solo che manca tutta la parte che lo fa
Codice:
/** Carica l'immagine in base al suo indirizzo
	 *  @ nome: indirizzo completo dell'immagine*/
	private BufferedImage loadImmagine(String nome)
	{
		URL url=null;
		try {	url = getClass().getClassLoader().getResource(nome);
				return ImageIO.read(url);
		} catch (Exception e) {	System.out.println("Impossibile caricare l'immagine " + nome);
								System.exit(0);
								return null;}
	}
	
	/** Ottiene l'indirizzo completo dell'immagine
	 *  e richiama la funzione di caricamento
	 *  @ nome: nome dell'immagine */
	public BufferedImage loadSprite(String nome)
	{
		immagine = loadImmagine("res/images/" + nome + ".bmp");
		return immagine;
	}
So che dovrebbe essere fatto dentro loadSprite, precisamente un qualcosa tipo

Controlla se esiste immagine con nome nella struttura, se non esiste richiama la funzione loadImmagine con il nome dell'immagine e aggiungi l'immagine alla struttura.
Il problema è su cosa controllo? Dovrei creare un arraylist di immagini? Un array di stringhe e uno di immagini grandi uguali?
Consigli?
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 17-09-2008, 16:20   #17
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Potresti usare una HashMap, e mappare le coppie: nomefileImmagine(come chiave) - bufferedImage(come valore).

Quando devi caricare una nuova immagine prima controlli se quel nomeFileImmagine è già presente nella HashMap, e in quel caso passi il relativo reference, oppure se devi proprio caricarlo, e in quel caso poi lo inserisci nella HashMap.

@EDIT:
visto che ti stai tuffando nelle bellezze della grafica 2D con uso di immagini in ambito Java2D, ti segnalo questa pagina che contiene tre link ad altrettanti articoli presenti nel blog di Chet Haase; leggili (quando avrai tempo per farlo con calma), ti assicuro che non te ne pentirai
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)

Ultima modifica di banryu79 : 17-09-2008 alle 17:31.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 17-09-2008, 20:16   #18
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
Indovina un pò? ho bisogno di un aiutino

Ho implementato un'intera nuova classe che carica le sprite:

Codice:
package Space;

/** Inclusione librerie */
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.net.URL;
import javax.imageio.ImageIO;

/** Classe che raccoglie tutti gli sprites */
public class SpriteCache
{
	// variabili locali
	private HashMap sprites;
	
	/** Costruttore */
	public SpriteCache()
	{
		sprites = new HashMap();
	}
	
	/** Carica l'immagine in base al suo indirizzo
	 *  @ nome: indirizzo completo dell'immagine*/
	private BufferedImage loadImmagine(String nome)
	{
		URL url=null;
		try {	url = getClass().getClassLoader().getResource(nome);
				return ImageIO.read(url);
		} catch (Exception e) {	System.out.println("Impossibile caricare l'immagine " + nome);
								System.exit(0);
								return null;}
	}
	
	/** Ottiene l'indirizzo completo dell'immagine
	 *  e richiama la funzione di caricamento
	 *  @ nome: nome dell'immagine */
	public BufferedImage loadSprite(String nome)
	{	
		BufferedImage immagine = (BufferedImage)sprites.get(nome);
		if (immagine == null)
		{
			immagine = loadImmagine("res/images/" + nome + ".bmp");
			sprites.put(nome, immagine);
		}
		return immagine;
	}
}
Carica l'immagine, la mette nell'HashMap e ogni volta che viene richiamata, controlla che non sia già presente.
Il problema viene quando cerco di utilizzare questa classe...

Nella classe padre Entità ho aggiunto 2 variabili

Codice:
protected String spriteName;
	
	protected SpriteCache spriteCache;
e 2 funzioni che impostano il nome dell'entità e lo restituiscono
Codice:
/** Imposta il nome della sprite */
	public void setSpriteName(String nome)
	{ 
		spriteName = nome;
		BufferedImage immagine = spriteCache.getSprite(spriteName);
	}     
	
	/** Restituisce il nome della sprite usata dall'entità */
	public String getSpriteName()
	{ 
		return spriteName;
	}
A questo punto ho modificato anche il costruttore delle varie classi figlie, per cui al momento della creazione, viene caricata automaticamente l'immagine

Codice:
public class Astronave extends Entità
{
	/** Costruttore dell'entità
	 *  @ x: posizione orizzontale
	 *  @ y: posizione verticale */
	public Astronave(int x,int y)
	{
		super(x, y);
		setSpriteName("laserX");
	}//Eccetera eccetera...
         
        // disegna l'entità   	    		
    	g.drawImage(spriteCache.getSprite(spriteName), posX, posY, null);
A questo punto quando nella main richiamo l'aggiunta di un nuovo elemento agli arrayList di entità, l'oggetto è già inizializzato, senza alcun bisogno di impostare nulla, se non il disegno.
Sulla carta direi che è corretto e anche sensato, peccato che non lo sia nella pratica visto che mi dice che SpriteCache non esiste bla bla bla:

Codice:
C:\Users\Josh\Desktop\MainWindow\src\Entità.java:25: cannot find symbol
symbol  : class SpriteCache
location: class Space.Entità
    protected SpriteCache spriteCache;
              ^
C:\Users\Josh\Desktop\MainWindow\src\MainWindow.java:41: cannot find symbol
symbol  : class SpriteCache
location: class Space.MainWindow
    SpriteCache spriteCache;
    ^
C:\Users\Josh\Desktop\MainWindow\src\MainWindow.java:77: cannot find symbol
symbol  : class SpriteCache
location: class Space.MainWindow
        spriteCache = new SpriteCache();
                          ^
Note: C:\Users\Josh\Desktop\MainWindow\src\SpriteCache.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
3 errors

Process completed.
eppure lo inizializzo lo spritecache, sia nell'entità che nella main, (come si può vedere dai messaggi di errore). Soluzioni?
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
Old 18-09-2008, 08:56   #19
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
nei vari file .java dove hai definito la classe Entità e le altre classi che la estendono hai fatto l'import di Space.SpriteCache?

Perchè se hai definito la classe SpiteCache in un suo package diverso da quello dove sono definite Entità e le sue sottoclassi, allora devi fare l'import.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 18-09-2008, 10:01   #20
Donbabbeo
Senior Member
 
L'Avatar di Donbabbeo
 
Iscritto dal: Jul 2006
Messaggi: 8152
Ste cose le lascio fare all'editor ma a volte è meglio farle a mano
Com'è logico il problema era quello, facendo build project l'editor non mi caricava la class di SpriteCache

Caricando ciascun file a mano ora funziona perfettamente!!!

E' normale che usando SpriteCache mi segnali questo?

Codice:
Note: C:\Users\Josh\Desktop\MainWindow\src\SpriteCache.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Process completed.
Donbabbeo è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Tastiera gaming MSI GK600 TKL: switch hot-swap, display LCD e tre modalità wireless Tastiera gaming MSI GK600 TKL: switch hot-swap, ...
DJI Osmo Pocket 4: la gimbal camera tascabile cresce e ha nuovi controlli fisici DJI Osmo Pocket 4: la gimbal camera tascabile cr...
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori Sony INZONE H6 Air: il primo headset open-back d...
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA Nutanix cambia pelle: dall’iperconvergenza alla ...
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta Recensione Xiaomi Pad 8 Pro: potenza bruta e Hyp...
Alcune varianti dei futuri Samsung Galax...
Il ridimensionamento di OnePlus in Europ...
Il cofondatore di Netflix ha lasciato l'...
ASUS porta in Italia il nuovo Zenbook Du...
Assassin's Creed: Black Flag Resynced, s...
Xbox Game Pass cambierà: tra le n...
I nuovi Surface Pro e Laptop sono vicini...
OnePlus ci riprova con la fascia bassa: ...
La Top 10 delle offerte Amazon del weeke...
XGIMI MoGo 2 Pro a 339€: Google TV con N...
Forum IT & Intelligence 2026: dall'A...
iPhone 16e per la prima volta a meno di ...
Stop Killing Games: Ross Scott convince ...
Annunciata la tuta di volo di Vast che s...
Vast presenta il nuovo Large Docking Ada...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 19:30.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v