Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Oracle AI World 2026: in Europa prima la sovranità, poi la sicurezza e solo dopo l'IA
Oracle AI World 2026: in Europa prima la sovranità, poi la sicurezza e solo dopo l'IA
In tre giorni a Las Vegas Oracle ha presentato agenti che eseguono il lavoro, l'alleanza con OpenAI e un cloud aperto agli acceleratori di tutti. Ma i clienti europei chiedono garanzie prima ancora delle funzionalità
DS N°7 E-Tense: il SUV premium made in Melfi che punta su autonomia e comfort
DS N°7 E-Tense: il SUV premium made in Melfi che punta su autonomia e comfort
Fino a 740 km WLTP con la batteria da 97,2 kWh, sospensioni che leggono la strada con una telecamera e un abitacolo da salotto parigino. La nuova DS N°7 raccoglie l'eredità della DS 7 e la porta, per la prima volta, nel mondo 100% elettrico. Ecco come è fatta, cosa offre e quanto costa.
Recensione Samsung Galaxy Tab S12 Ultra: non chiamatelo tablet... è molto di più
Recensione Samsung Galaxy Tab S12 Ultra: non chiamatelo tablet... è molto di più
Abbiamo provato Samsung Galaxy Tab S12 Ultra nella versione 12 GB + 256 GB con tastiera, e il risultato è un tablet che in questa configurazione si comporta come un notebook con la fluidità tipica di Android. Spessore di 5,1 mm, display Dynamic AMOLED 2X da 14,6 pollici, MediaTek Dimensity 9500 e un software senza incertezze compongono un prodotto di vertice, con prezzi da 1.539 euro, frenato solo da un'autonomia nella parte bassa del confronto
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 07-04-2006, 10:21   #1
DesmoColo
Senior Member
 
L'Avatar di DesmoColo
 
Iscritto dal: Sep 2003
Città: Lucca
Messaggi: 379
[JAVA]applicazione 2d: conviene usare i thread?

In una semplice applicazione 2d, dove ho un player che si muove tramite input e 3 nemici che sonon mossi dal pc, conviene usare i thread per implementare il giocatore e i nemici?
__________________
God rides DUCATI!
DesmoColo è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 11:57   #2
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Quote:
Originariamente inviato da DesmoColo
In una semplice applicazione 2d, dove ho un player che si muove tramite input e 3 nemici che sonon mossi dal pc, conviene usare i thread per implementare il giocatore e i nemici?
Direi proprio di si. Ovviamente quando il numero di nemici si incrementa di molto, dovrai cercare altre soluzioni

High Flying
Sottovento
__________________
In God we trust; all others bring data
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 13:37   #3
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Se ti serve usare i thread allora li usi E' una risposta banale, ma nemmeno tanto
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 15:23   #4
DesmoColo
Senior Member
 
L'Avatar di DesmoColo
 
Iscritto dal: Sep 2003
Città: Lucca
Messaggi: 379
Potrei anche usare un array con dentro i nemici e le loro posizioni all'interno della finestra, ma forse usare i thread è meglio per ragioni di efficienza....
Per fare gli attori come thread avrei bisogno di un consiglio sull'architettura da seguire:

La classe attori ha un metodo
Codice HTML:
public void draw(Graphics g,Window w){
            g.drawImage(loadImage(),getX(),getY(),w);
        }
che disegna gli attori.
per far diventare gli attori thread mi serve il metodo run() che va ad eseguire la draw().
Cisi come ho strutturato la classe è un po problematica, come mi consigliate di procedere? Modifico la draw()? Come?
__________________
God rides DUCATI!
DesmoColo è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 15:42   #5
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Altra domanda...hai bisogno di efficienza ?

Se vai a vedere nella sottosezione Diamonds, abbiamo fatto tutto il gioco senza thread...

Il problema dei thread in una situazione come questa è che dovrai comunque sincronizzare il tutto e molto strettamente (farai un refresh dello schermo ogni tot milisecondi), quindi se ci arrivi senza thread, perchè usarli ?
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 16:17   #6
DesmoColo
Senior Member
 
L'Avatar di DesmoColo
 
Iscritto dal: Sep 2003
Città: Lucca
Messaggi: 379
Uso i thread....perchè il prof con faccio il progetto mi ha chiesto di usarli!!!
Se mi confermi che posso eveitarli però, mi togli un peso, perchè infatto sta riscontrando numerosi problemi di soncronizzazione, per cui forse un array è meglio. Cerco di spiegrami meglio partendo dall'inizio

Devo appunto fare una piccola applicazione grafica 2d, in cui vi è un giocatore che muovo io e tre spring che deve muovere la macchina: tanto per vedere se funziona mi basta che una figurina parta dalle coordinate (0,0) e ad ogni aggiornamento del buffer di 5 pixel, finchè le coordinate non sono (400,400).
A gestire la figurina che muovo tramite input non ho nessun problema: ogni 5 millisecondi il double buffering disegna le coordinate x,y aggiornate (se appunto sono cambiate a causa di un evento da tastiera). Il problema nasce nel disegnare e spostare gli altri spring mossi dall'intelligenza artificiale.

Il metodo render della mia finestra è fatto in queto modo:
Codice HTML:
public boolean render (Graphics g){
        g.setColor (backgroundColor) ;
        g.fillRect (0,0,getWidth(),getHeight());
            for(int i = 0; i < iterator+1;i++){
                attori[i].draw(g,this);
        }
        return true;
    }
Quindi gli attori vengono disegnati dal rendering invocando il metodo draw() di un attore.
Come faccio dunque a simulare lo spostamento degli altri 3 attori non mossi da input? Io ed il mio prof avevamo pensato di far diventare gli attori dei thread affinche tramite l'invocazione del metodo start() avvenisse lo spostamento.
Come posso fare senza starvolgere tutto il codice trasformando gli attri in thread?
__________________
God rides DUCATI!
DesmoColo è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 16:37   #7
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Sprite

Un metodo molto semplice:
Codice:
Timer timer = new Timer();

int timeStamp = timer.getTime();
while(true)
{
   if(timeStamp + 20 <= timer.getTime())
   {
      timeStamp += 20;

      giocatore.processInput();
      giocatore.doAction();

      for(int i = 0; i < numeroNemici; ++i)
         nemico[i].move();
   
      engine.render(g);

      //qui ci vuole anche un Thread.Sleep(1); per non occupare tutta la CPU
   }
}
Ti posto anche timer, giusto per farti capire:
Codice:
public class Timer
{
    private long time;

    public Timer()
    {
        time = System.nanoTime();
    }

    public long getTime()
    {
        return (System.nanoTime() - time) / 1000000;
    }
}
Con il valore 20 (che puoi mettere in una cosatante) specifichi che ogni 20 ms (50fps) venga effettuato un loop del gioco... move esegue il movimento logico dei nemici (sposta il loro valore interno di x e y)... render deve fare il rendering dei nemici e del giocatore...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 17:37   #8
DesmoColo
Senior Member
 
L'Avatar di DesmoColo
 
Iscritto dal: Sep 2003
Città: Lucca
Messaggi: 379
Purtroppo mi sa che come è strutturato il mio codice non funziona il metodo da te suggerito.
Non so come spiegarmi, così allego a questo post un file zip contenente i file java che ho scritto e che ti possono far capire meglio la situazione. Per motivi implementativi successivi, preferirei non modificare la struttura della classe Test, ovvero il main deve per forza terminare con l'invocazione del metodo gameInit();
Inoltre vedi come è strutturato il render della finestra? così com'è non so proprio come applicare quanto mi hai postato prima...
Allegati
File Type: zip codice.zip (3.7 KB, 3 visite)
__________________
God rides DUCATI!
DesmoColo è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 17:49   #9
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Il fatto che il main termini con l'invocazione di gameInit non è un problema... GameInit può benissimo contenere il codice sopra...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 07-04-2006, 21:35   #10
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Provo a darti un'idea ma concedimi le attenuanti dell'aver scritto al volo.

Hai un proiettore fatto all'incirca così:

Renderer.java

Codice:
import java.awt.*;
import java.awt.image.*;
import java.util.*;

public class Renderer {
	private BufferStrategy bs;
	private java.util.List<Attore> attori;
	private final Rectangle viewRect;
	
	public Renderer(BufferStrategy bs, Rectangle viewArea, Attore...a) {
		this.bs = bs;
		viewRect = (Rectangle)viewArea.clone();
		attori = Collections.unmodifiableList(Arrays.asList(a));
	}
	
	public boolean render() {
		Graphics g = bs.getDrawGraphics();
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, viewRect.width, viewRect.height);
		for(Attore a : attori) {
			a.draw(g);
		}
		bs.show();
		return true;
	}
}
Con un attore di questa specie:

Attore.java

Codice:
import java.awt.*;
import java.awt.image.*;

public class Attore {
	private Point location = new Point();
	private BufferedImage image;
	
	public Attore(BufferedImage image) {
		this.image = image;
	}
	
	public Point getLocation() {
		return new Point(location);
	}
	
	public void setLocation(int x, int y) {
		location.move(x, y);
	}
	
	public void move(int dx, int dy) {
		location.translate(dx, dy);
	}
	
	public void draw(Graphics g) {
		g.drawImage(image, location.x, location.y, null);
	}
}
A questo punto vuoi trasformare alcuni attori in personaggi la cui logica sia gestita attraverso dei Thread autonomi dal Thread del proiettore.

A me risulta una cosa di questo tipo. Separo la definizione di "intelligenza" da quella di personaggio intelligente, giusto per non affastellare troppo nei "personaggi concorrenti":

AI.java

Codice:
public interface AI {

	void apply(Attore a);
	
	long getTick();
}
Qui getTick è il periodo del ciclo della "intelligenza artificiale".

Il Thread che gestisce un singolo personaggio non giocante applica un AI. AI può alterare gli stati da cui dipende la proiezione del personaggio e, dunque, esiste un problema di accesso condiviso agli stati del personaggio. In particolare, il proiettore (Renderer) legge alcuni valori conservati da un Attore (posizione e figura) che un AI concorrente può modificare.

Per rendere il proiettore consistente con il singolo attore concorrente direi che basti rendere atomiche e mutualmente esclusive le operazioni di lettura e scrittura degli stati di un attore. Usando il composition and forwarding possiamo creare un secondo tipo di attori che risponda a queste caratteristiche:

Codice:
import java.awt.*;
import java.util.concurrent.locks.*;

public class NPC extends Attore implements Runnable {
	private final Attore attore;
	private Lock lock = new ReentrantLock();
	private volatile boolean running;
	private long sleepTime;
	private AI ai;
	
	public NPC(Attore a, AI ai) {
		super(null);
		attore = a;
		sleepTime = ai.getTick() / 1000000;
		this.ai = ai;
	}
	
	public Point getLocation() {
		lock.lock();
		try {
			return attore.getLocation();
		} finally {
			lock.unlock();
		}
	}
	
	public void setLocation(int x, int y) {
		lock.lock();
		try {
			attore.setLocation(x, y);
		} finally {
			lock.unlock();
		}
	}
	
	public void move(int dx, int dy) {
		lock.lock();
		try {
			attore.move(dx, dy);
		} finally {
			lock.unlock();
		}
	}
	
	public void start() {
		lock.lock();
		try {
			if(!running) {
				running = true;
				new Thread(this).start();
			}
		} finally {
			lock.unlock();
		}
	}
	
	public void stop() {
		lock.lock();
		try {
			running = false;
		} finally {
			lock.unlock();
		}
	}

	public void draw(Graphics g) {
		lock.lock();
		try {
			attore.draw(g);
		} finally {
			lock.unlock();
		}
	}
	
	public void run() {
		long time0 = System.nanoTime();
		while(running) {
			long time1 = System.nanoTime();
			long dTime = time1 - time0;
			while(dTime >= ai.getTick()) {
				dTime -= ai.getTick();
				ai.apply(this);
			}
			time0 = time1 - dTime;
			try {
				Thread.sleep(sleepTime);
			} catch(InterruptedException ex) {
				running = false;
				return;
			}
		}
	}
}
A questo punto devi però modificare il ciclo di gioco in modo tale che l'avvio causi avvio anche delle entità concorrenti. La cosa più sentitica che sono riuscito a scrivere al riguardo è:

GameLoop.java

Codice:
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.imageio.*;

public class GameLoop implements Runnable {
	private long tick = 10000000;
	private volatile boolean loop;
	private Renderer renderer;
	private java.util.List<Attore> attori;

	public GameLoop(Renderer r, Attore...a) {
		attori = Collections.unmodifiableList(Arrays.asList(a));
		renderer = r;
	}
	
	public void start() {
		if(!loop) {
			loop = true;
			new Thread(this).start();
		}
	}
	
	public void stop() {
		loop = false;
		for(Attore a : attori) {
			if(a instanceof NPC) ((NPC)a).stop();
		}
	}
	
	public void run() {
		for(Attore a : attori) {
			if(a instanceof NPC) ((NPC)a).start();
		}
		long time0 = System.nanoTime();
		while(loop) {
			long time1 = System.nanoTime();
			long dTime = time1 - time0;
			while(dTime >= tick) {
				dTime -= tick;
				renderer.render();
			}
			long sleepTime = (tick - dTime) / 1000000;
			if(sleepTime > 0) {
				try {
					Thread.sleep(sleepTime);
				} catch(InterruptedException ex) {
					loop = false;
				}
			}
			time0 = time1 - dTime;
		}
	}
}
Qui l'avvio del motore di gioco causa (prima istruzione del metodo run()) l'avvio delle entità-attore che siano degli NPC. Specularmente, al termine dell'esecuzione (stop()) GameLoop si occupa anche di fermare tutti gli NPC.

Nel mucchio, Attore e Renderer sono rimasti invariati. GameLoop cambia solo per quanto riguarda l'avvio e l'arresto degli NPC.

Giusto per provare ad incollare i vari pezzi:

Main.java

Codice:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.imageio.*;

public class Main {
	/** Movimento orizzontale a badalucco */
	private AI horizontalMove = new AI() {
		public long getTick() {
			return 100000000; //100 ms
		}
		
		public void apply(Attore a) {
			a.move(1, 0);
		}
	};
	
	/** Movimento verticale a badalucco */
	private AI verticalMove = new AI() {
		public long getTick() {
			return 50000000; //50 ms
		}
		
		public void apply(Attore a) {
			a.move(0, 1);
		}
	};
	private Renderer renderer;
	private GameLoop gameLoop;
	
	private void startApp() {
		BufferedImage white, blue;
		try {
			white = ImageIO.read(Main.class.getResource("/white.png"));
			blue = ImageIO.read(Main.class.getResource("/blue.png"));
		} catch(Exception ex) {
			throw new RuntimeException("cannot load images");
		}
		final NPC whiteNPC = new NPC(new Attore(white), horizontalMove);
		final NPC blueNPC = new NPC(new Attore(blue), verticalMove);
		final JFrame window = new JFrame("Sample") {
			{ enableEvents(AWTEvent.KEY_EVENT_MASK); }
			protected void processKeyEvent(KeyEvent e) {
				manageKey(e);
			}
		};
		window.setSize(640, 480);
		window.setIgnoreRepaint(true);
		window.setUndecorated(true);
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				window.setVisible(true);
				window.createBufferStrategy(2);
				GraphicsConfiguration cfg = window.getGraphicsConfiguration();
				GraphicsDevice device = cfg.getDevice();
				if(device.isFullScreenSupported()) {
					device.setFullScreenWindow(window);
				} else {
					Rectangle bounds = cfg.getBounds();
					window.setSize(bounds.width, bounds.height);
				}
				BufferStrategy bs = window.getBufferStrategy();
				renderer = new Renderer(bs, 
					new Rectangle(0, 0, window.getWidth(), window.getHeight()),
					whiteNPC, blueNPC);
				gameLoop = new GameLoop(renderer, whiteNPC, blueNPC);
				gameLoop.start();
			}
		});
	}
	
	private void manageKey(KeyEvent e) {
		gameLoop.stop();
		Window w = JOptionPane.getFrameForComponent((Component)e.getSource());
		GraphicsConfiguration cfg = w.getGraphicsConfiguration();
		GraphicsDevice dev = cfg.getDevice();
		if(dev.isFullScreenSupported()) {
			dev.setFullScreenWindow(null);
		}
		w.dispose();
	}

	public static void main(String...args) {
		new Main().startApp();
	}
}
Diciamo che questo è un paio di maniche a cui occorre attaccare il resto della camicia. Manca, infatti, la gestione delle collisioni: qui hai un milione di entità di cui non puoi predire l'ordine di movimento. In particolare, Pippo potrebbe rilevare che la posizione (x,y) sia libera e trovarsi, nonostante ciò, accavallato a Mario. Occorre fare in modo che la lettura di una posizione ai fini del rilevamento di collisioni impedisca il movimento fintantochè non sia terminato il computo delle restrizioni allo spostamento. Il che va un po' oltre la semplice sincronizzazione della lettura/scrittura degli stati.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Oracle AI World 2026: in Europa prima la sovranità, poi la sicurezza e solo dopo l'IA Oracle AI World 2026: in Europa prima la sovrani...
DS N°7 E-Tense: il SUV premium made in Melfi che punta su autonomia e comfort DS N°7 E-Tense: il SUV premium made in Melfi...
Recensione Samsung Galaxy Tab S12 Ultra: non chiamatelo tablet... è molto di più Recensione Samsung Galaxy Tab S12 Ultra: non chi...
Hyundai IONIQ 5 N, l'elettrica che finge di essere termica (e ci riesce da paura) Hyundai IONIQ 5 N, l'elettrica che finge di esse...
CES Unveiled Milan, l'IA diventa tecnologia fondativa e il commercio torna centrale CES Unveiled Milan, l'IA diventa tecnologia fond...
Google accende il primo satellite con ch...
Azioni Intel, il peggior crollo degli ul...
Toyota bZ4X diventerà un robotaxi...
Sam Altman vuole tutta la RAM nei datace...
L’ex CEO di Intel Gelsinger punta su una...
Techly, quattro nuovi supporti TV fra mo...
Mass Effect sacrificato per Star Wars: i...
Gemini, addio al copia e incolla per cor...
13 miliardi per un colpo di stato? NVIDI...
L'agente AI Wabi crea mini-app su misura...
Edge è il primo browser a supportare Acc...
L'IA di Firefox ora compila i moduli da ...
Tracking pixel nelle email: cosa cambia ...
La GeForce RTX 5080 da 24 GB potrebbe ar...
Apple mette alle strette OpenAI, la caus...
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: 01:08.


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