Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
vivo X300 Pro rappresenta un'evoluzione misurata della serie fotografica del produttore cinese, con un sistema di fotocamere migliorato, chipset Dimensity 9500 di ultima generazione e l'arrivo dell'interfaccia OriginOS 6 anche sui modelli internazionali. La scelta di limitare la batteria a 5.440mAh nel mercato europeo, rispetto ai 6.510mAh disponibili altrove, fa storcere un po' il naso
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2 è la nuova handheld PC gaming con processore AMD Ryzen Z2 Extreme (8 core Zen 5/5c, GPU RDNA 3.5 16 CU) e schermo OLED 8,8" 1920x1200 144Hz. È dotata anche di controller rimovibili TrueStrike con joystick Hall effect e una batteria da 74Wh. Rispetto al dispositivo che l'ha preceduta, migliora ergonomia e prestazioni a basse risoluzioni, ma pesa 920g e costa 1.299€ nella configurazione con 32GB RAM/1TB SSD e Z2 Extreme
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
A re:Invent 2025, AWS mostra un’evoluzione profonda della propria strategia: l’IA diventa una piattaforma di servizi sempre più pronta all’uso, con agenti e modelli preconfigurati che accelerano lo sviluppo, mentre il cloud resta la base imprescindibile per governare dati, complessità e lock-in in uno scenario sempre più orientato all’hybrid cloud
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 28-09-2011, 00:14   #1
neutronirt
Member
 
L'Avatar di neutronirt
 
Iscritto dal: Sep 2011
Messaggi: 68
[Java]Problema animazione 2D

Ciao a tutti ragazzi, il mio problema non è prettamente dovuto al codice, ma a come l'applicazione funziona esclusivamente sul MIO pc.
Sostanzialmente da qualche giorno l'applicazione 2d su cui sto lavorando va molto più velocemente di quanto dovrebbe. Mi spiego meglio.
Quando muovo lo sprite lungo lo schermo, un pixel ogni millisecondo circa, il tutto viene fatto molto più velocemente del dovuto, ma ripeto, solo sul mio pc.
Ho pensato che questo potesse essere dovuto alla JRE, ma non ne sono sicuro e non so cosa pensare, spero qualcuno posssa aiutarmi.
Saluti
neutronirt è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 09:42   #2
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da neutronirt Guarda i messaggi
Quando muovo lo sprite lungo lo schermo, un pixel ogni millisecondo circa, il tutto viene fatto molto più velocemente del dovuto, ma ripeto, solo sul mio pc.
A livello di codice, come fai a ottenere le spostamento di 1 pixel/millisec?

Quote:
Originariamente inviato da neutronirt Guarda i messaggi
Ho pensato che questo potesse essere dovuto alla JRE, ma non ne sono sicuro e non so cosa pensare, spero qualcuno posssa aiutarmi.
Senza vedere il codice è impossibile dirti qualcosa di concreto e specifico...
__________________

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 28-09-2011, 12:10   #3
neutronirt
Member
 
L'Avatar di neutronirt
 
Iscritto dal: Sep 2011
Messaggi: 68
Per spostare di un pixel al ms uso un timer che richiama il metodo actionperformed del jpanel che implementa ActionListener.
Ogni millisecondo viene richiamato il metodo actionPerformed che sposta lo sprite. Sicuramente il problema non è dovuto al codice, lo dico perchè aprendo due volte l'eseguibile dell'applicazione(quindi con 2 app aperte) la velocità di entrambe si dimezza...
Segue il codice del jpanel:

Codice:
public class Board extends JPanel implements ActionListener {
	
    private Timer timer;
    private Sprite craft;

    public Board() {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);
        
        craft = new Sprite();
        
        //IL TIMER RICHIAMA IL METODO ACTION PERFORMED OGNI VOLTA
        timer = new Timer(1, this);
        timer.start();
    }


    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);
        
        ArrayList<Missile> ms = craft.getMissiles();

        for (int i = 0; i < ms.size(); i++ ) {
            Missile m = (Missile) ms.get(i);
            g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
        }

        
        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }


    public void actionPerformed(ActionEvent e) {
    	
    	ArrayList ms = craft.getMissiles();

        for (int i = 0; i < ms.size(); i++) {
            Missile m = (Missile) ms.get(i);
            if (m.isVisible()) 
                m.move();
            else ms.remove(i);
        }
    	craft.move(); 
    	repaint();
    }


    private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            craft.keyPressed(e);
        }
    }

}
neutronirt è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 12:36   #4
neutronirt
Member
 
L'Avatar di neutronirt
 
Iscritto dal: Sep 2011
Messaggi: 68
Credo che il problema si manifesti solo quando internet è aperto, non so perchè, ma è così, me ne sono appena accorto.
neutronirt è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 12:56   #5
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da neutronirt Guarda i messaggi
Credo che il problema si manifesti solo quando internet è aperto, non so perchè, ma è così, me ne sono appena accorto.
Puoi postare la versione del JDK che stai utilizzando?
__________________

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 28-09-2011, 13:03   #6
neutronirt
Member
 
L'Avatar di neutronirt
 
Iscritto dal: Sep 2011
Messaggi: 68
1.6.0, grazie mille dell'interessamento comunque
neutronirt è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 15:05   #7
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da neutronirt Guarda i messaggi
Sostanzialmente da qualche giorno l'applicazione 2d su cui sto lavorando va molto più velocemente di quanto dovrebbe.
Ciao.
Posto che il codice da te pubblicato è ok, nel senso che non fa nulla di "strambo", ci sono un paio di considerazioni da fare, relativamente a quello che vuoi ottenere.

Stai implementando una sorta di gioco 2D, appoggiandoti a Swing, almeno stando a quanto fin qui visto. Quindi vuoi fare grafica 2D performante e controllare il frame rate con il quale girerà il gioco. Roba tutto sommato normale.

Le due considerazioni, sulle quali non mi dilungo per motivi di tempo, sono le seguenti:

1) per farla breve, per le immagini da caricare, affinchè siano performanti e accellerate, non basta caricarle semplicemente con i soliti metodi, bisogna anche convertirle in un formato compatibile con il display (GraphicConfiguration del monitor in uso).

2) per la grafica acellerata in Java non basta fare l'override del metodo paint di un JComponent, è invece neccessario usare un BufferStrategy ricavato da un Canvas (AWT) o un JFrame (Swing).

3) Bisogna controllare direttamente il frame rate del rendering loop di un gioco (essendo in Java non hai nessuna garanzia circa il sistema sottostante e le sue politiche di scheduling per i thread, nonchè la granularità del timer di sistema).

Ti posto due link utili:
- tutrial per giochi 2D in Java, che tocca tutti gli aspetti qui citati e va anche oltre;
- un forum specializzato su giochi e grafica ad alte prestazioni in Java, una risorsa eccellente;

Il metodo da te usato per aggiornare la posizione delle sprite (1pixel/ms) non è deterministico perchè non hai nessuna garanzia che il timer lanci effettivamente 1 evento ogni 1 millisecondo. Intanto dipende dal sistema operativo su cui il tuo gioco si trova a girare: se sei sotto Windows, ad esempio, essendo che Timer internamente fa chiamate a System.currentTimeMillis() il risultato è che le pause da 1 millisecondo sono in realtà pause da (circa) 15-16 millisecondi perchè questa è la granularità del timer di sistema in Windows a cui si appoggia quella chiamata.
Il seguente programma lo dimostra in via sperimentale (il mio sistema è un Windows XP):
Codice:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import javax.swing.Timer;

/**
 * Class TimerOneMillisec...
 * @author Francesco Baro
 */
public class TimerOneMillisec implements ActionListener {

    public static void main(String[] args) {
        TimerOneMillisec tom = new TimerOneMillisec();
        tom.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ignored) {
            System.out.println("@" + Time.now() +
                    " (nanos)> main thread has been interrupted");
        }

        tom.stop();
        tom.printResult();
    }

    TimerOneMillisec() {
        timer = new Timer(1, this);
    }

    @Override public void actionPerformed(ActionEvent e) {
        buffer.append(Time.now()).append(" ");
    }

    void start() {
        startTime = Time.now();
        timer.start();
    }

    void stop() {
        timer.stop();
        endTime = Time.now();
    }

    Iterable<String> processResults() {
        List<String> result = new LinkedList<String>();
        long oldTime = startTime;
        String results = buffer.toString().trim();
        StringTokenizer st = new StringTokenizer(results);
        while (st.hasMoreTokens()) {
            long time = Long.parseLong(st.nextToken());
            result.add(String.valueOf(time - oldTime));
            oldTime = time;
        }
        return result;
    }

    void printResult() {
        long t1 = Time.toMillis(startTime);
        long t2 = Time.toMillis(endTime);
        System.out.println("Started at (millis): " + t1);
        System.out.println("Ended at (millis): " + t2);
        System.out.println("Total elapsed (millis): " + (t2 - t1));
        System.out.println("Partials (nanos):");

        Iterable<String> lines = processResults();
        for (String line : lines) System.out.println(line);

        
    }

    private final StringBuilder buffer = new StringBuilder();
    private final Timer timer;
    private long startTime, endTime;


    private static class Time {

        // construction forbidden
        private Time() {}

        static long now() {
            return System.nanoTime();
        }

        static long elapsedFrom(long nanos) {
            return System.nanoTime() - nanos;
        }

        static long toMillis(long nanos) {
            return nanos / 1000000;
        }
    }
}
Una sua tipica esecuzione da me ha prodotto questo risultato:
Quote:
run:
Started at (millis): 21608361
Ended at (millis): 21609362
Total elapsed (millis): 1001
Partials (nanos):
61758408
1160483
11890617
15492472
15683278
15578796
15611202
15591088
15619862
15627964
15653386
15603659
15617348
15638859
15626567
15622936
15684116
15620980
15608408
15588294
15639977
15762338
15491634
15752840
15585780
15580751
15605335
15607850
15606453
15646681
15632434
15572370
15655062
15638859
15650313
15580193
15669030
15619025
15579075
15637183
15614554
15624891
15648357
15611482
16157360
15127901
15622376
15630479
15599748
15635506
15609526
15627126
15737754
15500015
15651710
15607850
15620141
15632155
15638579
15621539
15606732
15642770
BUILD SUCCESSFUL (total time: 2 seconds)
Ma poi anche se il timer effettivamente pubblicasse un action event ogni millisecondo nella coda degli eventi awt, è possibile che più richieste di repaint() in successione vengano fuse/unite in un'unica rischiesta, e l'effetto risultante è quello di vedere un aggiornamento della posizione delle sprite "a singhiozzo", perdendo gli "step" intermedi.

Non so se questo meccanismo sia la causa che produce gli effetti che hai verificato quando lanci due istanze del tuo gioco (che girano sì in due istanze diverse della jvm, ma la scheda grafica, le risorse video e il window manager del so sono sempre singoli)...

Il primo post (quello con i tutorial), può aiutarti davvero molto, è una lettura che ti consiglio caldamente.
__________________

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 : 28-09-2011 alle 15:27.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 15:34   #8
neutronirt
Member
 
L'Avatar di neutronirt
 
Iscritto dal: Sep 2011
Messaggi: 68
Caro banryu, ti ringrazio infinitamente per l'immenso aiuto che mi hai dato. Sto iniziando ora, infatti, con la programmazione 2d in java e questa è la primissima applicazione con grafica accelerata che implemento (per quanto riguarda le swing sono piuttosto ferrato, ma non per ciò che concerne la grafica accelerata).
Credo proprio che il problema dell'app sia dovuto a questa mancanza di controllo del tempo.
Comunque sia ora leggerò accuratamente le guide che mi hai sottoposto, da tempo ne cercavo di valide e finalmente posso appoggiarmi a qualcosa di utile!
neutronirt è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 15:52   #9
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Sì, ho visto che nel codice esegui una chiamata a Toolkit.synch(), il che *in teoria* dovrebbe scongiurare l'accumulo di eventi grafici nella coda degli eventi. Dico in teoria, perchè leggendo in giro pare che, come sempre, dipenda dall'implementazione sottostante.

@EDIT: ti segnalo anche un vecchio thread su questo forum, si sa mai che possa contenere info & link utili (ad esempio se cerchi sprite e asset grafici vari da usare nei tuoi giochi, butta un occhio): http://www.hwupgrade.it/forum/showthread.php?t=1817420
__________________

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 : 28-09-2011 alle 15:57.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 28-09-2011, 19:39   #10
MEMon
Senior Member
 
Iscritto dal: Dec 2002
Messaggi: 3359
Un timer di 1 ms ha poco senso, non è che da te va più veloce, è probabile che in altri pc vada più piano.
Comunque, se vuoi abbozzare un motore di rendering 2d, non servono timer, detta molto alla buona ti basta un ciclo infinito, calcolare il tempo(delta t) che intercorre tra due esecuzioni del ciclo e in base a quello spostare la roba.
Quello è l'unico modo che ti assicura che gli oggetti si spostino tutti alla stessa velocità in tutti i pc che eseguono il programma.
MEMon è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria Recensione vivo X300 Pro: è ancora lui il...
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'...
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti AWS re:Invent 2025: inizia l'era dell'AI-as-a-Se...
Cos'è la bolla dell'IA e perché se ne parla Cos'è la bolla dell'IA e perché se...
BOOX Palma 2 Pro in prova: l'e-reader diventa a colori, e davvero tascabile BOOX Palma 2 Pro in prova: l'e-reader diventa a ...
Dreame H15 Mix: la soluzione 7-in-1 per ...
AirPods Pro 3 in forte sconto su Amazon:...
36 offerte Amazon, molte appena partite:...
2 caricatori multipli eccezionali: da 28...
OLED e 360 Hz a un prezzo senza preceden...
Roborock Q10 S5+ a un prezzo molto conve...
Upgrade PC a prezzo ridotto: le migliori...
Sono i 6 smartphone migliori su Amazon: ...
Google Pixel 9a a 361€, mai così ...
Super sconti sugli spazzolini Oral-B, an...
Aspira a 6000Pa, lava bene, costa 139€: ...
Nuove scorte: torna il portatile tuttofa...
Toyota usa giochi e premi per spingere i...
HarmonyOS ha raggiunto la soglia di sopr...
Le offerte Amazon più convenienti...
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: 10:34.


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