|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
[JAVA]Animazioni
Ragazzi non ho ben chiaro come vengono effettuate le animazioni in java(ho appena iniziato), cioè bisogna per forza cancellare quello che si è appena disegnato e ridisegnarlo "di poco" spostato?
Ditemi che non è così... |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Ho letto qualcosa tipo doppio buffer, c'è nessuno che mi da qualche info in più? in rete non sono riuscito a trovare quclsa di veramente chiaro...
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Dai raga help!!!!!!!
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
L'alternativa allo spostare di poco per volta qualcosa sta nel proiettare l'immagine a video, afferrare il monitor e correre su e giù per la stanza. Inspiegabilmente è pratica poco comune.
Il doppio buffer è una tecnica usata per impacchettare le operazioni di disegno in un solo comando (quello che invia una richiesta di sostituzione del buffer correntemente proiettato a video). Si fa semplicemente eseguendo le singole operazioni di disegno in una regione di memoria non proiettata per poi ordinare la proiezione del risultato globale delle singole operazioni. Altrimenti detto, disegni tutto su un'immagine fuori schermo e poi disegni quell'immagine sullo schermo. L'AWT Java offre un gradevole precotto, BufferStrategy, che incorpora l'accelerazione hardware delle superfici (se disponibile), buffer multipli e il meccanismo di sincronizzazione per la sostituzione degli stessi. La documentazione Java è loquace al riguardo: in sintesi si tratta di disegnare usando il contesto grafico (Graphics) restituito da un BufferStrategy anzichè sovrascrivere il metodo paintComponent usando il suo argomento Graphics. Circa l'animazione, in ogni caso animi mutando ciclicamente un qualche stato (non necessariamente la posizione pur sembrandomi questa la via più intuitiva). Con un minimo d'ordine al sistema che vuoi realizzare il fatto che per muovere qualcosa sposti un poco per volta delle coordinate passa praticamente subito in sordina. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Io vorrei utlizzare lo swing non l'awt e il doppio buffer, hai mica un pezzo di codice che mi mostri come fare una semplice animazione con questa tecnica?
Che non sia un'applet xò. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Se preferisci usare Swing allora sei a cavallo. E' "double buffered, hw accelerated, page flipped e chi più ne ha più ne metted" di suo. Idealmente è meno performante perchè oltre al pacco "performance" ti becchi anche il raffinato ma non certo leggero meccanismo per la gestione di bordi, contenimento, decorazioni e via dicendo.
Ho romanzato il codice per cui mi limito ad incollarlo. Naturalmente per qualsiasi curiosità son qui. Drawable.java Codice:
package it.tukano.anisample;
/** Un che di disegnabile */
public interface Drawable {
void draw(java.awt.Graphics2D g);
}
Codice:
package it.tukano.anisample;
/** Un che di aggiornabile */
public interface Updatable {
void update();
}
Codice:
package it.tukano.anisample;
/** Sprite è qualcosa che ha un aspetto e un'animazione (in questo caso
solo animazione per spostamento) */
public interface Sprite extends Drawable {
void move(float dx, float dy);
void setLocation(float x, float y);
}
Codice:
package it.tukano.anisample;
import java.awt.*;
import java.awt.geom.*;
/** Quando il nome dice tutto */
public class HorribleSprite implements Sprite {
private Point2D.Float location = new Point2D.Float();
private Rectangle2D.Float shape = new Rectangle2D.Float(0, 0, 20, 20);
public void move(float dx, float dy) {
shape.setRect(
shape.getX() + dx, shape.getY() + dy,
shape.getWidth(), shape.getHeight());
}
public void setLocation(float x, float y) {
shape.setRect(
x, y,
shape.getWidth(), shape.getHeight());
}
public void draw(Graphics2D g) {
g.setColor(Color.RED);
g.fill(shape);
}
}
Codice:
package it.tukano.anisample;
import java.awt.*;
/** Definizione di un comportamento applicabile ad uno Sprite */
public class Behavior implements Updatable {
private float speed = 0.1f; //pixel per millisecondo
private long time0, time1, dTime;
private Sprite sprite;
public Behavior(Sprite s) {
sprite = s;
}
/** Applica allo sprite uno spostamento calcolato in base al tempo
trascorso dall'ultima invocazione di questo metodo. */
public void update() {
if(time0 == 0) {
time0 = time1 = System.currentTimeMillis();
} else {
time1 = System.currentTimeMillis();
}
dTime = time1 - time0;
time0 = time1;
float dx = speed * dTime;
sprite.move(dx, 0);
}
}
Codice:
package it.tukano.anisample;
import java.awt.event.*;
import java.util.*;
/** Qualcosa che aggiorna periodicamente qualcos'altro */
public class Updater {
/** Controlla l'inizio e la fine del ciclo di aggiornamento */
private volatile boolean doUpdate;
/** Periodo di attesa tra un passaggio e l'altro nel ciclo di
aggiornamento */
private int updateDelay;
/** Elenco degli oggetti aggiornabili da questo oggetto */
private ArrayList<Updatable> updatables = new ArrayList<Updatable>();
private Runnable updateTask = new Runnable() {
public void run() {
while(doUpdate) {
updateAll();
waitForDelay();
}
}
};
/** @param delay ritardo del ciclo di aggiornamento */
public Updater(int delay) {
updateDelay = delay;
}
/** definizione del compito periodico */
private void updateAll() {
for(Updatable u : updatables) {
u.update();
}
}
/** definizione dell'attesa per il ritardo periodico */
private void waitForDelay() {
try {
Thread.sleep(updateDelay);
} catch(InterruptedException ex) {
System.err.println("Threadus interruptus!");
doUpdate = false;
}
}
/** Aggiunge un elenco di updatable alla lista di aggiornamento */
public void appendUpdatables(Updatable...u) {
updatables.addAll(Arrays.asList(u));
}
/** Aggiunge un updatable alla lista degli aggiornabili in posizione
position (0 = prima del primo elemento della lista)*/
public void addUpdatable(Updatable u, int position) {
updatables.add(position, u);
}
/** Avvia il ciclo di aggiornamento */
public void start() {
if(!doUpdate) {
doUpdate = true;
new Thread(updateTask).start();
} else {
System.out.println("Updater on line...");
}
}
/** Ferma il ciclo di aggiornamento */
public void stop() {
if(doUpdate) {
doUpdate = false;
} else {
System.out.println("Updater offline");
}
}
}
Codice:
package it.tukano.anisample;
import java.awt.*;
import java.util.*;
import javax.swing.*;
/** Lo schermo è un oggetto che proietta dei drawable ed è aggiornabile */
public class Screen implements Updatable {
private ArrayList<Drawable> drawables = new ArrayList<Drawable>();
/** Questo è il componente Swing che concretamente proietterà i
Drawable sullo schermo...
@see #draw*/
private JComponent component = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
draw((Graphics2D)g);
}
};
public void addDrawable(Drawable...d) {
drawables.addAll(Arrays.asList(d));
}
public void update() {
component.repaint();
}
public JComponent getComponent() {
return component;
}
/** ... e questo è il metodo in cui è disegnato ciò che il componente
Swing proietta. */
private void draw(Graphics2D g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, component.getWidth(), component.getHeight());
for(Drawable d : drawables) {
d.draw(g);
}
}
}
Codice:
package it.tukano.anisample;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main {
/** C.d. punto d'entrata dell'applicazione. */
public static void main(String...args) {
new Main().startAndShow();
}
/** Un vezzo personale :D */
private Main() {}
/** Nell'ordine, crea uno HorribleSprite, crea un Behavior (horrible
pure quello), crea uno Screen, assegna una dimensione allo screen
(400x400 px), aggiunge lo sprite come "oggetto che sarà disegnato sullo
schermo", crea un Updater con un periodo ideale di 24ms, aggiunge
allo updater lo schermo e il behavior come "oggetti che saranno
aggiornati dall'aggiornatore", crea una finestra, collega alla finestra
qualcosa che reagirà quanto questa sarà chiusa (per chiudere effettivamente
la finestra e fermare l'aggiornatore), aggiunge il componente dello schermo
alla finestra, impacchetta tutto e lo spara sullo schermo. */
private void startAndShow() {
HorribleSprite sprite = new HorribleSprite();
Behavior simpleBehavior = new Behavior(sprite);
Screen screen = new Screen();
screen.getComponent().setPreferredSize(new Dimension(400, 400));
screen.addDrawable(sprite);
Updater updater = new Updater(24);
updater.appendUpdatables(simpleBehavior, screen);
JFrame window = new JFrame("AniSample");
bindWindowListener(window, updater);
window.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
window.getContentPane().add(screen.getComponent());
packAndShow(window, updater);
}
/** Assegna una dimensione al frame in base al suo contenuto, mostra
la finestra sullo schermo e avvia lo updater */
private void packAndShow(final JFrame frame, final Updater updater) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.pack();
frame.setVisible(true);
updater.start();
}
});
}
/** Aggiunge un ascolatore alla chiusura della finestra frame. */
private void bindWindowListener(final JFrame frame, final Updater updater) {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
shutdownApp(frame, updater);
}
});
}
/** Invocato alla chiusura della finestra.la distrugge
e ferma lo updater. Può comportare spegnimento
dolce della JVM (anzi, l'idea è proprio quella) */
private void shutdownApp(JFrame frame, Updater upd) {
upd.stop();
frame.dispose();
}
}
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Intanto ti ringrazio tantissimo per il codice! Vorrei sapere, ma questo è lo stretto necessario per fare un'animazione del genere? O hai aggiunte delle piccole finezze tue?
Io sono proprio alle primi armi con il java e quindi mi sarebbe utile visionare un codice il pìù asciutto possibile, e senza metodi di programazzione troppo avanzati. Vedo che hai fatto largo uso delle interfaccie, le quali ancora non mi sono chiarissime ma che sto cmq cercando di capire. Se riesci a ridurlo ulteriormente mi saresti di grande aiuto! |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Sul significato di "stretto necessario" potremmo iniziare qui una diatriba da concludersi a barbe bianche
Il codice precedente non si avvicina neanche ad un che di orientato agli oggetti. E' facile osservare come l'oggetto Main sia in verità indistinto da HorribleSprite, Screen, Updater e Behavior. Abbi cuore, l'ho scritto in fretta Si può fare di meno (sul peggio avrei dei dubbi ScreenWithAnimation.java Codice:
package it.tukano.simpleranimation;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
public class ScreenWithAnimation extends JPanel {
/** Periodo del ciclo di animazione */
private final long TIMER_PERIOD = 24;
/** Velocità dello sprite in pixel per millisecondo */
private final float SPEED = 0.1f;
/** "Sprite" */
private Rectangle2D.Float fakeSprite =
new Rectangle2D.Float(0, 0, 20, 20);
/** Variabili per il calcolo del tempo intercorso tra due passaggi nel
ciclo di aggiornamento */
private long time0, time1;
/** Compito affidato al timer */
private TimerTask updateTask = new TimerTask() {
public void run() {
long dTime = updateTime();
updateSprite(dTime);
repaint();
}
};
/** Una specie di Thread che esegue (anche) compiti periodici */
private java.util.Timer timer;
/** Avvia l'animazione */
public void start() {
if(timer == null) {
timer = new java.util.Timer();
timer.scheduleAtFixedRate(updateTask, 0, TIMER_PERIOD);
}
}
/** Ferma l'animazione */
public void stop() {
if(timer != null) {
timer.cancel();
timer = null;
}
}
/** Restituisce il dT dall'ultima invocazione di updateTime */
private long updateTime() {
time1 = System.currentTimeMillis();
if(time0 == 0) {
time0 = time1;
}
long dTime = time1 - time0;
time0 = time1;
return dTime;
}
/** Aggiorna la posizione dello sprite */
private void updateSprite(long dTime) {
fakeSprite.setRect(
fakeSprite.getX() + dTime * SPEED,
fakeSprite.getY(),
fakeSprite.getWidth(),
fakeSprite.getHeight());
}
/** Disegna il componente e lo sprite */
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
((Graphics2D)g).fill(fakeSprite);
}
}
Codice:
package it.tukano.simpleranimation;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main {
public static void main(String...args) {
new Main().setupAndShow();
}
private Main() {}
private void setupAndShow() {
JFrame frame = new JFrame("Simpler Animation");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ScreenWithAnimation screen = new ScreenWithAnimation();
screen.setPreferredSize(new Dimension(400, 400));
screen.setBackground(Color.BLACK);
frame.getContentPane().add(screen, BorderLayout.CENTER);
bindWindowListener(frame, screen);
packAndShow(frame, screen);
}
private void bindWindowListener(final JFrame f,
final ScreenWithAnimation s)
{
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
s.stop(); //<<-- qui si ferma l'animazione
f.dispose();
}
});
}
private void packAndShow(final JFrame f, final ScreenWithAnimation s) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.pack();
f.setVisible(true);
s.start(); //<<-- qui parte l'animazione
}
});
}
}
java.util.Timer è un Thread che può eseguire un particolare Runnable (TimerTask) periodicamente. Nota che nel nostro caso non è necessario appoggiarsi esplicitamente al Thread AWT Event Dispatcher (quello che deve occuparsi di aggiornare l'aspetto di componenti AWT/Swing visibili) poichè ridisegnamo il componente (ScreenWithAnimation qui e Screen là) usando il metodo repaint(). repaint() in realtà non repaint un bel nulla: quello che fa è premere nella coda degli eventi AWT (consumata dall'Event Dispatcher Thread) una richiesta di aggiornamento del componente. Io credo che dalla seconda versione, pur più breve, non si evinca il fatto che l'animazione sia un procedimento in senso proprio (cioè la composizione di più atti distinti e collegati): è più un bel minestrone. Che sia più o meno facile da comprendere dipende poi dai punti di vista di chi guardi. Insomma, vedi tu |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Questo mi sembra già meglio
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Ah ecco mi è venuta in mente subito una cosa, come mai nel main fai questo:
Codice:
public class Main {
public static void main(String...args) {
new Main().setupAndShow();
}
private Main() {}
private void setupAndShow(){...}
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Si tratta di una questione "tecnica" ma non di tecnica del linguaggio: in questo secondo caso, lo stesso metodo "main" è solo un suggerimento.
Solitamente la prima cosa che faccio nel metodo main di un programma Java è saltar fuori dal contesto statico in cui il main mi costringe. Lo faccio perchè metodi e campi statici in Java sono in grado di infarfugliare anche le menti più arzille, soprattutto se mescolati a membri di istanza definiti nella stessa unità di compilazione: lì è l'apoteosi della confusione. Il modificatore private applicato all'unico costruttore grida "questa classe non è la definizione di un oggetto". E' una collezione di procedure. Lo dico perchè tentare di assorbire nell'orientamento agli oggetti (che pure abbonda in creatività) qualcosa a cui nessuno salvo lui stesso può rivolgersi è da mal di testa. Molto semplicemente, Main è quell'insieme di operazioni che devono essere fatte affinchè l'applicazione parta. Il fatto, imposto col costruttore private, che non possano essere create istanze di Main al di fuori dell'unità di compilazione Main.java è una specie di pugno sul tavolo: non si può e basta! Esiste la possibilità di applicare meccanismi più confacenti alle due O ma l'argomento era "come muovere qualcosa sullo schermo" e non "Elementi della prospettiva orientata agli oggetti: identità, ambiente, comunicazione". Ecco, questa è la bella copia di quello a cui ho pensato quando ho scritto Main.java |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Si può costruire un rattangolo o in generale un poligono conoscendone le coordinate dei vertici? Perchè mi servirebbe poi spostare separatemente questi vertici, non tutta la figura insieme.
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Yes.
Puoi usare un GeneralPath come definizione di un poligono generico. Questo dovrebbe essere un rettangolo in posizione (x0, y0) di larghezza (width, height): Codice:
GeneralPath path = new GeneralPath(); path.moveTo(x0, y0); path.lineTo(x0 + width, y0); path.lineTo(x0 + width, y0 + height); path.lineTo(x0, y0 + height); path.closePath(); graphics2d.fill(path) oppure graphics2d.draw(path) Per manipolare i punti devi creare un tuo AffineTransform. Ridefinisci il metodo "transform(float[], int, float[], int, int)" del tuo AffineTransform in modo tale che intacchi i punti che ti interessano. Applichi la trasformazione con un: path.transform(myAffineTransform); |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Ehm mi sa che l'ultima parte me la devi rispiegare
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Supponiamo che, dato lo Shape di tipo GeneralPath su definito, tu voglia spostare solo il primo punto. Per farlo devi trasformare la geometria di quel GeneralPath. Non ci sono AffineTransform pronti per fare un'operazione di questo tipo ragion per cui devi crearne uno da zero:
Codice:
public class FirstPointTranslator extends AffineTransform {
public void transform(float[] src, int srcOff, float[] dst, int dstOff,
int numPts)
{
if(srcOff == 0 && src.length > 1) {
float x = src[0];
float y = src[1];
dst[dstOff] = x + 5;
dst[dstOff + 1] = y + 5;
}
}
}
FirstPointTranslator fpt = new FirstPointTranslator(); shape.transform(fpt); //hop, primo punto +5,+5 shape.transform(fpt); //hop, primo punto +5,+5 E' un approccio un po' crudo ma è l'unico se si vogliano sfruttare i "precotti" di Sun in materia di grafica vettoriale. In alternativa puoi definire un tuo oggetto Poligono e lì la strada si apre ai più biechi desideri. |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Grazie mille credo di aver capito.
Cosa intendi con "puoi definire un tuo oggetto Poligono"? |
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Ho cambiato la classe ScreenwhitAniamtion.java così
Codice:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
public class ScreenWithAnimation extends JPanel {
/** Periodo del ciclo di animazione */
private final long TIMER_PERIOD = 24;
/** Velocità dello sprite in pixel per millisecondo */
private final float SPEED = 0.1f;
/** "Sprite" */
int[] xPoints={100,150,150,100};
int[] yPoints={1,1,80,80};
private GeneralPath fakeSprite = new GeneralPath(GeneralPath.WIND_EVEN_ODD,xPoints.length);
fakeSprite.moveTo(xPoints[0],yPoints[0]);
for (int index = 1;index < xPoints.length;index++) {
fakeSprite.lineTo(xPoints[index],yPoints[index]);
};
fakeSprite.closePath();
/** Variabili per il calcolo del tempo intercorso tra due passaggi nel
ciclo di aggiornamento */
private long time0, time1;
/** Compito affidato al timer */
private TimerTask updateTask = new TimerTask() {
public void run() {
long dTime = updateTime();
updateSprite(dTime);
repaint();
}
};
/** Una specie di Thread che esegue (anche) compiti periodici */
private java.util.Timer timer;
/** Avvia l'animazione */
public void start() {
if(timer == null) {
timer = new java.util.Timer();
timer.scheduleAtFixedRate(updateTask, 0, TIMER_PERIOD);
}
}
/** Ferma l'animazione */
public void stop() {
if(timer != null) {
timer.cancel();
timer = null;
}
}
/** Restituisce il dT dall'ultima invocazione di updateTime */
private long updateTime() {
time1 = System.currentTimeMillis();
if(time0 == 0) {
time0 = time1;
}
long dTime = time1 - time0;
time0 = time1;
return dTime;
}
/** Aggiorna la posizione dello sprite */
private void updateSprite(long dTime) {
FirstPointTranslator fpt = new FirstPointTranslator();
fakeSprite.transform(fpt);
}
/** Disegna il componente e lo sprite */
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
((Graphics2D)g).fill(fakeSprite);
}
}
fakeSprite.moveTo(xPoints[0],yPoints[0]); for (int index = 1;index < xPoints.length;index++) { fakeSprite.lineTo(xPoints[index],yPoints[index]); }; fakeSprite.closePath();" e illegal start of type in corrpisondenza del ciclo for... Dove sbaglio? |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Il corpo di una classe Java può contenere solo dichiarazioni oppure blocchi.
Codice:
class Bingo {
int x = 30; //ok, dichiarazione con assegnamento contestuale
GeneralPath x; //ok, dichiarazione
x = new GeneralPath(...) //Niet!!! l'assegnamento non è dichiarazione
for(int i = 0; i < 40; i++) { //Nain!!! il ciclo for non è una dichiarazione
{ //Blocco
for(int i = 0; i <... //Ok, un blocco può contenere l'istruzione for
}
public void doSomenthing() { //Ok, dichiarazione di metodo
}
Codice:
public class ScreenWithAnimation extends JPanel {
GeneralPath fakeSprite = new GeneralPath(...omissis);
public ScreenWithAnimation() {
fakeSprite.moveTo(xPoints[0],yPoints[0]);
for (int index = 1;index < xPoints.length;index++) {
fakeSprite.lineTo(xPoints[index],yPoints[index]);
};
fakeSprite.closePath();
}
}
|
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Grazie mille chiarissimo!
Ma nell'esempio che mi hai fatto tu, inserisci il codice per spostare il quadrato qui: Codice:
/** Aggiorna la posizione dello sprite */
private void updateSprite(long dTime) {
fakeSprite.setRect(
fakeSprite.getX() + dTime * SPEED,
fakeSprite.getY(),
fakeSprite.getWidth(),
fakeSprite.getHeight());
}
E' quindi plausibile che pure io devo inserire qui il mio codice per spostare ruotare ecc ecc le mie figure? Poi un altra cosa, diciamo che ora ho materiale a sufficicenza per cominciare a fare qualcosa di semplice, mi potresti spiegare cosa intendevi con crearti un oggetto Poligono? magari potrebbe semplificarmi la vita o comunque farmi capire meglio Sempre se non ti è troppo disturbo Grazie ancora |
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Ho fatto le modifiche che mi hai suggerito, ora compila ma quando esegue sulla console mi esce questo...
Codice:
Exception in thread "Timer-0" java.lang.NullPointerException
at ScreenWithAnimation.updateSprite(ScreenWithAnimation.java:74)
at ScreenWithAnimation.access$100(ScreenWithAnimation.java:6)
at ScreenWithAnimation$1.run(ScreenWithAnimation.java:36)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sun.awt.windows.Win32Renderer.doShape(Win32Renderer.java:217)
at sun.awt.windows.Win32Renderer.fill(Win32Renderer.java:260)
at sun.java2d.pipe.ValidatePipe.fill(ValidatePipe.java:142)
at sun.java2d.SunGraphics2D.fill(SunGraphics2D.java:2258)
at ScreenWithAnimation.paintComponent(ScreenWithAnimation.java:81)
at javax.swing.JComponent.paint(JComponent.java:1005)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paint(JComponent.java:1014)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintChildren(JComponent.java:842)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4970)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4916)
at javax.swing.JComponent.paint(JComponent.java:995)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
at java.awt.Container.paint(Container.java:1709)
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
at sun.awt.RepaintArea.paint(RepaintArea.java:224)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:254)
at java.awt.Component.dispatchEventImpl(Component.java:4031)
at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Window.dispatchEventImpl(Window.java:1774)
at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Questo è il codice per aggiornare la posizione dello sprite: Codice:
/** Aggiorna la posizione dello sprite */
private void updateSprite(long dTime) {
FirstPointTranslator fpt = new FirstPointTranslator();
fakeSprite.transform(fpt);
}
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:33.



















