Thread

Animating objects using a thread is the most effective way of animation


Star.java
package star3;

import javax.swing.JFrame;

public class Star extends JFrame {

public Star() {

add(new Board());

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(280, 240);
setLocationRelativeTo(null);
setTitle("Star");
setResizable(false);
setVisible(true);
}

public static void main(String[] args) {
new Star();
}
}

This is the main class.

Board.java
package star2;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.ImageIcon;
import javax.swing.JPanel;


public class Board extends JPanel implements Runnable {

private Image star;
private Thread animator;
private int x, y;

private final int DELAY = 50;


public Board() {
setBackground(Color.BLACK);
setDoubleBuffered(true);

ImageIcon ii = new ImageIcon(this.getClass().getResource("star.png"));
star = ii.getImage();

x = y = 10;
}

public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}

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

Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(star, x, y, this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}


public void cycle() {

x += 1;
y += 1;

if (y > 240) {
y = -45;
x = -45;
}
}

public void run() {

long beforeTime, timeDiff, sleep;

beforeTime = System.currentTimeMillis();

while (true) {

cycle();
repaint();

timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;

if (sleep < 0)
sleep = 2;
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("interrupted");
}

beforeTime = System.currentTimeMillis();
}
}
}

In the previous examples, we executed a task at specific intervals. In this examle, the animation will take place inside a thread. The run() method is called only once. That's why we have a while loop in the method. From this method, we call the cycle() and the repaint() methods.

public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}

The addNotify() method is called after our JPanel has been added to the JFrame component. This method is often used for various initialization tasks.

We want our game run smoothly. At constant speed. Therefore we compute the system time.

timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;

The cycle() and the repaint() methods might take different time at various while cycles. We calculate the time both methods run and substract it from the DELAY constant. This way we want to ensure that each while cycle runs a constant time. In our case, 50ms each cycle.

Niciun comentariu:

Trimiteți un comentariu