1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
| import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.Timer;
import javax.swing.plaf.basic.BasicArrowButton;
public class AnimationDemo extends JPanel {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 30;
private static final int HEIGHT = WIDTH;
private int x; // abscisse du mobile
private int y; // ordonnée du mobile
private int dx; // sens de déplacement du mobile sur l'axe horizontal
private int dy; // sens de déplacement du mobile sur l'axe vertical
private int v=1; // vitesse de déplacement (en pixel/frame)
private Timer timer = new Timer(33, e->animate()); // timer pour l'animation (toutes les 33 ms, donc 30 images par secondes) : on appelle donc la méthode animate() toutes les 33 ms
public void setVitesse(int v) {
this.v=Math.min(8, Math.max(1, v)); // on borne la vittesse : 1<=v<=8
}
public void setDeplacement(int dx, int dy) {
this.dx=(int)Math.signum(dx); // on prend le signe pour que dx soit soit -1, soit 0, soit 1
this.dy=(int)Math.signum(dy);
}
public void setDeplacementX(int dx) {
this.dx=(int)Math.signum(dx);
}
public void setDeplacementY(int dy) {
this.dy=(int)Math.signum(dy);
}
public boolean isAnimated() {
return timer.isRunning();
}
// lance l'animation si elle est arrêtée, arrête l'animation si elle est lancée
public boolean toggleAnimation() {
if ( timer.isRunning() ) {
timer.stop();
}
else {
timer.start();
}
return timer.isRunning();
}
public void startAnimation() {
if ( !timer.isRunning() ) {
timer.start();
}
}
public void stopAnimation() {
if ( timer.isRunning() ) {
timer.stop();
}
}
// méthode qui déplace le mobile
private void animate() {
final int width=getWidth();
final int height=getHeight();
boolean move=false;
if ( dx!=0 ) { // si on déplace sur l'axe horizontal
move=true;
int ddx=dx*v; // calcul du déplacement effectif (sens déplacement fois vitesse)
if ( x+ddx+WIDTH>=width ) { // si on sort (on dépasse le bord droit ici)
x=width-WIDTH; // on plaque contre le bord
dx=-dx; // on inverse le sens de déplacement
}
else if ( x+ddx<0 ) { // idem bord gauche
x=0;
dx=-dx;
}
else { // si on sort pas, on déplace
x+=ddx;
}
}
if ( dy!=0 ) { // idem pour axe vertical
move=true;
int ddy=dy*v;
if ( y+ddy+HEIGHT>=height) {
y=height-HEIGHT;
dy=-dy;
}
else if ( y+ddy<0 ) {
y=0;
dy=-dy;
}
else {
y+=ddy;
}
}
if ( move ) { // si on a déplacé, alors on redessine
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getForeground());
g.fillOval(x, y, WIDTH, HEIGHT);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Démo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AnimationDemo anim = new AnimationDemo();
anim.setBackground(Color.BLACK);
anim.setForeground(Color.ORANGE);
frame.add(anim);
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton startStopButton = new JButton("Start");
startStopButton.addActionListener(e->{
if ( anim.toggleAnimation() ) {
startStopButton.setText("Stop");
}
else {
startStopButton.setText("Start");
}
});
buttonPanel.add(startStopButton);
JPanel padPanel = new JPanel(new GridBagLayout());
int[] arrowButtons = {BasicArrowButton.NORTH_WEST,
BasicArrowButton.NORTH,
BasicArrowButton.NORTH_EAST,
BasicArrowButton.WEST,
BasicArrowButton.CENTER,
BasicArrowButton.EAST,
BasicArrowButton.SOUTH_WEST,
BasicArrowButton.SOUTH,
BasicArrowButton.SOUTH_EAST};
int indexButton=0;
for(int j=-1; j<2; j++) {
for(int i=-1; i<2; i++) {
final JButton button = new BasicArrowButton(arrowButtons[indexButton++]);
final int dx=i;
final int dy=j;
button.addActionListener(e-> anim.setDeplacement(dx,dy));
padPanel.add(button,new GridBagConstraints(i+1, j+1, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0));
}
}
buttonPanel.add(padPanel);
JSpinner vitesseSpinner = new JSpinner(new SpinnerNumberModel(4, 1, 8, 1));
vitesseSpinner.addChangeListener(e-> anim.setVitesse((Integer)vitesseSpinner.getValue()));
anim.setVitesse((Integer)vitesseSpinner.getValue());
buttonPanel.add(vitesseSpinner);
frame.add(buttonPanel,BorderLayout.SOUTH);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(e-> {
if ( e.getID()==KeyEvent.KEY_PRESSED ) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
anim.setDeplacementX(-1);
break;
case KeyEvent.VK_RIGHT:
anim.setDeplacementX(1);
break;
case KeyEvent.VK_UP:
anim.setDeplacementY(-1);
break;
case KeyEvent.VK_DOWN:
anim.setDeplacementY(1);
break;
case KeyEvent.VK_ESCAPE:
anim.setDeplacement(0,0);
break;
}
}
return false;
});
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
} |
Partager