public class GameView extends JFrame implements KeyListener {
private GameMap map;
JPanel mainPanel = new JPanel();
MyPanel drawPanel = new MyPanel();
boolean isOver=false;
int speed=1;
public GameView(int size,int speed) {
this.speed=(speed==0?1:speed);
map = new GameMap(size);
drawPanel.setBounds(0, 0, 7*size, 7*size);
this.add(drawPanel);
this.addKeyListener(this);
this.setTitle("贪吃蛇小游戏");
this.setSize(7*size+19, 7*size+43);
// this.pack();
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
Thread thread = new Thread(new MyRunnable());
thread.start();
if(isOver){
thread.stop();
}
}
@Override
public void keyPressed(KeyEvent e) {
// System.out.println("press " +e.getKeyCode());
map.changeDire(e.getKeyCode());
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// System.out.println(e.getKeyCode());
// map.move(e.getKeyCode());
}
class MyRunnable implements Runnable {
@Override
public void run() {
while (true) {
isOver=map.move();
if(!isOver){
JOptionPane.showMessageDialog(null, "Game Over !");
return;
}
repaint();
try {
Thread.sleep(1000/speed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) {
int[][] mapArray = map.getValMap();
for (int i = 0; i < map.getN(); i++) {
for (int j = 0; j < map.getN(); j++) {
switch (mapArray[i][j]) {
case 0:
g.setColor(Color.WHITE);
break;
case 1:
g.setColor(Color.BLACK);
break;
case 2:
g.setColor(Color.RED);
break;
default:
break;
}
g.fillRect(7 * i, 7 * j, 7, 7);
}
}
}
}
public static void main(String[] args) {
new GameView(40,10);
}
}
public class GameMap {
private static int[][] valMap;
private int n;
private int max_length;
private Snake snake;
public GameMap(int n){
this.n=n;
valMap=new int[n][n];
max_length=n*n/2;
snake=new Snake(valMap,max_length);
this.creatFood();
}
public void creatFood(){
int x=this.getRandom();
int y=this.getRandom();
while(valMap[x][y]!=0){
x=this.getRandom();
y=this.getRandom();
}
valMap[x][y]=2;
}
public void changeDire(int i){
switch (i) {
case KeyEvent.VK_UP:
snake.setDire(Direction.UP);
break;
case KeyEvent.VK_DOWN:
snake.setDire(Direction.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.setDire(Direction.LEFT);
break;
case KeyEvent.VK_RIGHT:
snake.setDire(Direction.RIGHT);
break;
default:
break;
}
}
public boolean move(){
this.valMap=snake.move();
if(null==valMap){
return false;
}
if(snake.isEat()){
this.creatFood();
snake.setEat(false);
}
return true;
}
private int getRandom(){
return (int)(Math.random()*n);
}
public static int[][] getValMap() {
return valMap;
}
public static void setValMap(int[][] valMap) {
GameMap.valMap = valMap;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public int getMax_length() {
return max_length;
}
public void setMax_length(int max_length) {
this.max_length = max_length;
}
public Snake getSnake() {
return snake;
}
public void setSnake(Snake snake) {
this.snake = snake;
}
}
public class Snake {
private Direction dire;
private LinkedList<Point> body;
private int[][] valMap;
private int max_length;
private boolean isEat=false;
// private Point food;
public Snake(int[][] valMap, int max_length) {
dire = Direction.RIGHT;
body = new LinkedList<>();
this.valMap = valMap;
// body.add(new Point(0, 0));
this.addPoint(new Point(0, 0));
this.addPoint(new Point(1, 0));
this.addPoint(new Point(2, 0));
this.addPoint(new Point(3, 0));
this.addPoint(new Point(4, 0));
this.max_length = max_length;
}
public int[][] move() {
int x = body.getFirst().getX();
int y = body.getFirst().getY();
Point add;
switch (dire) {
case UP:
add = new Point(x, y - 1);
break;
case DOWN:
add = new Point(x, y + 1);
break;
case RIGHT:
add = new Point(x + 1, y);
break;
case LEFT:
add = new Point(x - 1, y);
break;
default:
add = null;
break;
}
int tmp = isVal(add);
if (tmp != -1) {
// body.addFirst(add);
this.addPoint(add);
if (tmp == 0) {
this.removePoint();
}
return valMap;
}
return null;
}
private void addPoint(Point p) {
body.addFirst(p);
valMap[p.getX()][p.getY()] = 1;
}
private void removePoint() {
Point p = body.getLast();
body.removeLast();
valMap[p.getX()][p.getY()] = 0;
}
private int isVal(Point add) {
if (null == add) {
return -1;
}
int x = add.getX();
int y = add.getY();
int n = valMap.length;
boolean val=x >= 0 && x < n && y >= 0 && y < n;
if(!val||valMap[x][y] == 1){
return -1;// 不合法移动
}
if (valMap[x][y] == 2 ) {
isEat=true;// 吃到食物
if(body.size() < max_length){
return 1;//增长
}
}
return 0;//不增长
}
public Direction getDire() {
return dire;
}
public void setDire(Direction dire) {
Direction opp = null;
switch (this.dire) {
case UP:
opp = Direction.DOWN;
break;
case DOWN:
opp = Direction.UP;
break;
case RIGHT:
opp = Direction.LEFT;
break;
case LEFT:
opp = Direction.RIGHT;
break;
default:
break;
}
if (dire != opp) {
this.dire = dire;
}
}
public boolean isEat() {
return isEat;
}
public void setEat(boolean isEat) {
this.isEat = isEat;
}
public LinkedList<Point> getBody() {
return body;
}
public void setBody(LinkedList<Point> body) {
this.body = body;
}
}
public class Point {
private int x,y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
public Point(){
x=0;
y=0;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public boolean equals(Point p){
return (p.getX()==x)&&(p.getY()==y);
}
}
public enum Direction {
UP,DOWN,LEFT,RIGHT;
}