package elements;
import javax.swing.*;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Random;
public class SnakeModel extends Observable implements Runnable {
LinkedList<Node> body ;
Node food;
int maxX;
int maxY;
int nodeWidth;
int nodeHeight;
Direction direction;
int timeInterval;
double changeRate;
boolean[][] exist;
int moveCount;
boolean running;
boolean pause;
int score;
class Node {
int x;
int y;
public Node(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
public SnakeModel(int maxX, int maxY, int nodeWidth, int nodeHeight) {
super();
this.maxX = maxX;
this.maxY = maxY;
this.nodeWidth = nodeWidth;
this.nodeHeight = nodeHeight;
reset();
}
public void reset() {
this.body=new LinkedList<>();
direction = Direction.RIGHT;
timeInterval = 200;
changeRate = 0.75;
moveCount = 0;
pause=false;
score=0;
// 重设初始信息
exist = new boolean[maxX][maxY];
creatSnake();
creatFood();
}
private void creatSnake() {
int x = 0;
int y = 0;
Random r = new Random();
x = r.nextInt(maxX / 2/nodeWidth);
y = r.nextInt(maxY / 2/nodeHeight);
Node n = new Node(x, y);
body.add(n);
exist[x][y] = true;
}
private Node creatFood() {
int x = 0;
int y = 0;
do {
Random r = new Random();
x = r.nextInt(maxX/nodeWidth);
y = r.nextInt(maxY/nodeHeight);
} while (exist[x][y]);
food = new Node(x, y);
exist[x][y] = true;
return food;
}
public void setDirection(Direction direction) {
if (this.direction.getNumber() % 2 != direction.getNumber()%2) {
this.direction = direction;
}
}
public void speedUp() {
timeInterval *= changeRate;
}
public void speedDqwn() {
timeInterval /= changeRate;
}
public void speedPause() {
this.pause = true;
}
public boolean moveOn() {
Node n = body.getFirst();
int x = n.x;
int y = n.y;
switch (direction) {
case UP:
y--;
break;
case DOWN:
y++;
break;
case RIGHT:
x++;
break;
case LEFT:
x--;
break;
}
if ((0 <= x && x < maxX/nodeWidth) && (0 <= y && y < maxY/nodeHeight)) {
if (exist[x][y]) {
if (food.x == x && food.y == y) {
body.addFirst(food);
food = creatFood();
score+=100;
moveCount=0;
return true;
} else {
return false;
}
} else {
body.addFirst(new Node(x, y));
exist[x][y] = true;
Node last = body.removeLast();
exist[last.x][last.y] = false;
moveCount++;
return true;
}
}
return false;
}
@Override
public void run() {
running = true;
while (running) {
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
break;
}
if (!pause) {
if (moveOn()) {
setChanged();
notifyObservers();
} else {
JOptionPane.showMessageDialog(null, "生命如此短暂", "结束", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
break;
}
}
}
}
}
package elements;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class SnakeControl implements KeyListener {
private SnakeModel sm;
public SnakeControl(SnakeModel sm) {
this.sm = sm;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int key=e.getKeyCode();
if (sm.running){
switch (key) {
case KeyEvent.VK_UP:
sm.pause=false;
sm.setDirection(Direction.UP);
break;
case KeyEvent.VK_DOWN:
sm.pause=false;
sm.setDirection(Direction.DOWN);
break;
case KeyEvent.VK_RIGHT:
sm.pause=false;
sm.setDirection(Direction.RIGHT);
break;
case KeyEvent.VK_LEFT:
sm.pause=false;
sm.setDirection(Direction.LEFT);
break;
case KeyEvent.VK_SPACE:
sm.pause=true;
break;
case KeyEvent.VK_ENTER:
sm.reset();
break;
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
/**
*
*/
package elements;
/**
* @author Administrator
*
*/
public enum Direction {
UP(1), DOWN(3), RIGHT(2), LEFT(4);
private int number;
private Direction(int num) {
this.number = num;
}
/**
* @return the number
*/
public int getNumber() {
return number;
}
/**
* @param number
* the number to set
*/
public void setNumber(int number) {
this.number = number;
}
}
package elements;
import java.awt.*;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;
import elements.SnakeModel.Node;
public class GameFrame implements Observer {
private SnakeModel sm;
private SnakeControl snakeControl;
private JFrame jFrame;
private Container container;
private Canvas paintCanvas;
private JLabel label;
private ImageIcon image;
private ImageIcon image1;
private ImageIcon image2;
private ImageIcon image3;
public GameFrame(SnakeModel sm, SnakeControl snakeControl) {
image = new ImageIcon("D:\\beijing.jpg");
image1 = new ImageIcon("d:\\qingwa.png");
image2 = new ImageIcon("d:\\shetou.png");
image3 = new ImageIcon("d:\\shenti.png");
this.snakeControl = snakeControl;
this.sm = sm;
jFrame = new JFrame("贪吃蛇");
container = jFrame.getContentPane();
paintCanvas = new Canvas();
paintCanvas.setSize(sm.maxX + 1, sm.maxY + 1);
paintCanvas.addKeyListener(snakeControl);
container.add(paintCanvas, BorderLayout.CENTER);
label = new JLabel("分数: ");
container.add(label, BorderLayout.NORTH);
jFrame.pack();
jFrame.addKeyListener(snakeControl);
jFrame.setResizable(false);
jFrame.setLocationRelativeTo(null);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}
@Override
public void update(Observable o, Object arg) {
repaint();
}
void repaint() {
Graphics g = paintCanvas.getGraphics();
// 画背景
//g.setColor(Color.WHITE);
//g.fillRect(0, 0, sm.maxX, sm.maxY);
g.drawImage(image.getImage(), 0, 0, image.getIconWidth(), image.getIconHeight(), null);
// 画食物
//g.setColor(Color.RED);
g.drawImage(image1.getImage(), sm.food.x * sm.nodeWidth, sm.food.y * sm.nodeHeight, sm.nodeWidth, sm.nodeHeight, null);
//drawNode(g, sm.food);
// 画蛇
// g.setColor(Color.BLACK);
// for (Node n : sm.body) {
// drawNode(g, n);
// }
g.drawImage(image2.getImage(), sm.body.getFirst().x * sm.nodeWidth, sm.body.getFirst().y * sm.nodeHeight, sm.nodeWidth, sm.nodeHeight, null);
for (int i = 1; i < sm.body.size(); i++) {
g.drawImage(image3.getImage(), sm.body.get(i).x * sm.nodeWidth, sm.body.get(i).y * sm.nodeHeight, sm.nodeWidth, sm.nodeHeight, null);
}
setLabel();
}
private void drawNode(Graphics g, Node n) {
g.fillRect(n.x * sm.nodeWidth, n.y * sm.nodeHeight, sm.nodeWidth - 1, sm.nodeHeight - 1);
}
private void setLabel() {
label.setText("分数: " + sm.score);
}
}
package elements;
public class GameView {
public static void main(String[] args) {
SnakeModel sModel = new SnakeModel(800, 600, 30, 30);
SnakeControl snakeControl = new SnakeControl(sModel);
GameFrame gameFrame = new GameFrame(sModel, snakeControl);
sModel.addObserver(gameFrame);
//(new Thread(sModel)).start();
sModel.run();
}
}