Otóż robię grę Snake. I problem na jaki się natknąłem, to problem z animacją, ponieważ chciałem aby była płynna, bez widocznego "przeskakiwania" węża. Wąż ma się poruszać z zadaną zmienną prędkością (int speed). Nie mam pomysłu co zrobić, aby uzyskać płynną animację, a już się trochę nakombinowałem. Proszę więc o pomoc, może ktoś będzie miał jakiś pomysł co mógłbym poprawić.
Poniżej zamieszczam 2 klasy które przede wszystkim odpowiadają za rysowanie węża:
Player.class
package snake;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Player
{
private int headSizeX;
private int headSizeY;
private int tailSizeX;
private int tailSizeY;
private int x;
private int y;
private int speed = 5;
private int snakeSize = 40;
private Image[] snake = new Image[5];
private ArrayList<Integer> X,Y;
private static int imageNr = 0;
private int tmp;
private boolean death = false;
static int player;
private static boolean inverse = false;
private boolean left = false;
private boolean right = false;
private boolean up = true;
private boolean down = false;
public Player()
{
initPlayer();
headSizeX = snake[0].getWidth(null);
headSizeY = snake[0].getHeight(null)-2;
tailSizeX = snake[4].getWidth(null);
tailSizeY = snake[4].getHeight(null);
System.out.println("tail: "+tailSizeX+" "+tailSizeY);
x = MainGamePanel.getSizeX()/2;
y= MainGamePanel.getSizeY()-130;
}
public void initPlayer()
{
int imgNr = 5;
X = new ArrayList<Integer>();
Y = new ArrayList<Integer>();
String name = "green";
switch (player)
{
case 1:
name = "green"; break;
case 2:
name = "red"; break;
case 3:
name = "blue"; break;
}
for (int nr = 1; nr <= imgNr; nr++)
{
snake[nr-1] = new ImageIcon("img/" +name+"/snake" +nr+".png").getImage();
}
X.add(MainGamePanel.getSizeX()/2);
Y.add( MainGamePanel.getSizeY()-200);
X.add( MainGamePanel.getSizeX()/2);
Y.add( MainGamePanel.getSizeX()/2+33);
for (int i = 2; i < snakeSize; i++) {
X.add( MainGamePanel.getSizeX()/2);
Y.add( MainGamePanel.getSizeX()/2 + i*20+13);
}
}
public void paint(Graphics g)
{
//g.drawImage(snake[imageNr], x,y,headSizeX,headSizeY,null);
for (int i = 0; i < snakeSize; i++) {
if (i == 0)
g.drawImage(snake[imageNr], X.get(i), Y.get(i), null);
else
g.drawImage(snake[4], X.get(i), Y.get(i), null);
}
}
public void update()
{
y = MainGamePanel.getSizeY()-headSizeY - 35;
for (int i = snakeSize-1; i > 0; i--) {
X.set(i, X.get(i-1));
Y.set(i, Y.get(i-1));
}
if (left) {
tmp = X.get(0);
X.set(0, tmp-20);
imageNr = 3;
}
if (right) {
tmp = X.get(0);
X.set(0, tmp+20);
imageNr = 1;
}
if (up) {
tmp = Y.get(0);
Y.set(0, tmp-20);
imageNr = 0;
}
if (down) {
tmp = Y.get(0);
Y.set(0, tmp+20);
imageNr = 2;
}
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!right)) {
left = true;
up = false;
down = false;
}
if ((key == KeyEvent.VK_RIGHT) && (!left)) {
right = true;
up = false;
down = false;
}
if ((key == KeyEvent.VK_UP) && (!down)) {
up = true;
right = false;
left = false;
}
if ((key == KeyEvent.VK_DOWN) && (!up)) {
down = true;
right = false;
left = false;
}
}
public void collision()
{
death = true;
}
public void reset()
{
imageNr = 0;
death = false;
}
public void setInverse(boolean set)
{
inverse = set;
}
public void increaseSpeed(int inc)
{
speed += inc;
}
public void decreaseSpeed(int dec)
{
speed -=dec;
}
public int getSnakeSize()
{
return snakeSize;
}
public void increaseSnakeSize()
{
snakeSize += 1;
}
public void decreaseSnakeSize(int dec)
{
snakeSize -= dec;
}
}
MainGamePanel.class
package snake;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class MainGamePanel extends JPanel implements KeyListener{
private Image bounds;
private Player player;
public static int sizex;
private Image tail;
private Image background;
private int lives;
private int speed;
private int levels;
private int counter = 0;
private int appleCounter = 0;
private static int level = 1;
public static int sizeX = 784;
public static int sizeY = 617;
public static int applesNumber;
private boolean gameover = false;
private boolean gameend = false;
private boolean death = false;
private boolean levelCompleted = false;
private Graphics buffer;
private BufferedImage img;
public MainGamePanel(int[] settings)
{
lives = settings[0];
speed = settings[1];
levels = settings[2];
bounds = new ImageIcon("img/bounds.jpg").getImage();
setFocusable(true);
addKeyListener(this);
//new Apple();
}
public void init()
{
player = new Player();
img = new BufferedImage(sizeX, sizeY, 2);
Levels.getLevel(1);
this.applesNumber = Levels.getApplesNumber();
this.background = new ImageIcon("img/bg/" + Levels.getBackground()).getImage();
}
public void addNotify()
{
super.addNotify();
init();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
buffer = img.getGraphics();
buffer.drawImage(background, 0,0, sizeX, sizeY, null);
player.paint(buffer);
for (int i = 0; i <= getWidth(); i += 12) {
buffer.drawImage(bounds, i, 0, this);
buffer.drawImage(bounds, i, getHeight()-12, this);
}
for (int i = 12; i < getHeight(); i += 12) {
buffer.drawImage(bounds, 0, i, this);
buffer.drawImage(bounds, getWidth()-12, i, this);
}
g.drawImage(this.img, 0, 0, getWidth(), getHeight(), null);
buffer.clearRect(12, 12, sizeX, sizeY);
}
public void play()
{
if (level == this.levels) gameend = true;
this.player.reset();
this.counter = 0;
this.appleCounter = 0;
long StartTime = System.currentTimeMillis();
player.update();
repaint();
/*do
{
Thread.yield();
}
while (System.currentTimeMillis() - StartTime < this.speed);*/
}
public void gameLoop()
{
while(true)
{
play();
try
{
Thread.sleep(150);
}
catch (InterruptedException ex)
{
}
if (death)
{
lives -= 1;
death = false; continue;
}
levelCompleted = false;
level+=1;
Levels.getLevel(level);
applesNumber = Levels.getApplesNumber();
}
}
public static int getApp()
{
return applesNumber;
}
public static int getSizeX()
{
return sizeX;
}
public static int getSizeY()
{
return sizeY;
}
public void setGameOver()
{
gameover = true;
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) System.exit(0);
player.keyPressed(e);
}
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
}