package gui;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import java.util.Vector;
import model.Block;
import model.Body;
import model.Food;
import model.Snake;
import model.Tail;
import util.Direction;
public class SnakeCanvas extends Canvas implements KeyListener {
/**
*
*/
private static final long serialVersionUID = -4989895601085448933L;
public static final int BOX_LENGTH = 10;
public static final int FOODSCOUNT = 3;
private Snake snake;
private Block[][] blocks;
private Food[] foods;
private int width;
private int height;
int count = 0;
int max = 0;
Vector<Tail> body = new Vector<Tail>();
public void setSnake(Snake snake) {
this.snake = snake;
}
public Snake getSnake() {
return snake;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width / BOX_LENGTH;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height / BOX_LENGTH;
}
private void initBlock() {
blocks = new Block[getWidth()][getHeight()];
for (int i = 0; i < getWidth(); i++) {
for (int j = 0; j < getHeight(); j++) {
blocks[i][j] = new Block();
blocks[i][j].setX(BOX_LENGTH*i);
blocks[i][j].setY(BOX_LENGTH*j);
}
}
}
private void initFood() {
foods = new Food[FOODSCOUNT];
for (int i = 0; i < FOODSCOUNT; i++) {
foods[i] = new Food();
setFood(i);
}
}
private void setFood(int index) {
int x, y;
Random r = new Random();
r.setSeed(index*r.nextLong());
x = Math.abs(r.nextInt()%getWidth());
y = Math.abs(r.nextInt()%getHeight());
if (snake != null) {
Snake s = snake;
do {
if (s.getX() == x &&
s.getY() == y) {
setFood(index);
}
s = s.getNext();
} while (s.hasNext());
}
foods[index].setX(x);
foods[index].setY(y);
}
/**
* 初始化大小
* @param x 横向px
* @param y 纵向px
*/
public SnakeCanvas(int x, int y) {
setWidth(x);
setHeight(y);
setSize(new Dimension(getWidth()*BOX_LENGTH, getHeight()*BOX_LENGTH));
setBackground(Color.BLACK);
addKeyListener(this);
initBlock();
initFood();
}
public void paint(Graphics g) {
count--;
Snake block = getSnake();
for (Food f : foods) {
if (block.getX() == f.getX() &&
block.getY() == f.getY()) {
body.add(eatFood(f));
break;
}
f.draw(g, blocks);
}
for (;;) {
block.draw(g, blocks);
if (block.hasNext()) {
block.getNext().setMoveFlag(block.getOldMoveFlag());
block.setOldMoveFlag(block.getMoveFlag());
block = block.getNext();
} else {
if (body.size() != 0 && block.getX() == body.get(0).getX() && block.getY() == body.get(0).getY()) {
if (count < 0) {
count = 0;
}
max += 2;
count += 2;
}
if (body.size() != 0 && count >= 0 && count != max && count%2 == 0) {
Body b = new Body(block.getX(), block.getY());
b.setMoveFlag(block.getMoveFlag());
b.setOldMoveFlag(block.getOldMoveFlag());
b.setNext(body.get(0));
block.getPrevious().setNext(b);
body.get(0).setPrevious(b);
body.get(0).setMoveFlag(b.getOldMoveFlag());
b.setOldMoveFlag(b.getMoveFlag());
body.get(0).draw(g, blocks);
body.get(0).setOldMoveFlag(body.get(0).getMoveFlag());
body.remove(0);
max -= 2;
break;
}
block.setOldMoveFlag(block.getMoveFlag());
break;
}
}
}
/**
* 是否可变向,上<->下,左<->右,不能直接变向
*/
private void canMove(int moveFlag) {
if (Math.abs(moveFlag - snake.getOldMoveFlag()) != 2) {
snake.setMoveFlag(moveFlag);
}
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP) {
canMove(Direction.UP);
} else if (key == KeyEvent.VK_DOWN) {
canMove(Direction.DOWN);
} else if (key == KeyEvent.VK_LEFT) {
canMove(Direction.LEFT);
} else if (key == KeyEvent.VK_RIGHT) {
canMove(Direction.RIGHT);
}
repaint();
e.consume();
}
private Tail eatFood(Food f) {
int x = f.getX(),
y = f.getY();
Tail tail = new Tail(x, y);
f.setX(-1);
f.setY(-1);
return tail;
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}