我使用java和swing编写了一个贪吃蛇的程序,可以顺利运行,但有两个小问题,一直不知道如何解决。第一个是当蛇吃到随机出来的点时,蛇的长度会加1,但蛇身后面会出来一个
新的点,随着蛇移动蛇身的距离而消失;第二个问题是有时候运行游戏会不能控制,希望大神费心解答一下。
package game;
import java.awt.Color;
public class SnakeNode {//定义蛇身集合中的各个元素点
private int x;
private int y;
private Color color;
public SnakeNode() {
super();
// TODO Auto-generated constructor stub
}
public SnakeNode(int x, int y, Color color) {
super();
this.x = x;
this.y = y;
this.color = color;
}
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 Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
package game;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MainGame extends JPanel{
private final int length = 20;//定义画板的长
private final int width = 30;//定义画板的宽
private final int unit = 20;//定义单位长度
private ArrayList<SnakeNode> snake = new ArrayList<>();//定义蛇身的集合
private int Direction;//定义蛇头的方向
private int Length ;//定义蛇身的长度
private SnakeNode newNode = new SnakeNode(1,1,Color.BLACK);//定义随机点
Timer time = new Timer(100,new ThingsListener());
public int getDirection() {
return Direction;
}
public void setDirection(int direction) {
Direction = direction;
}
public int getLength() {
return Length;
}
public void setLength(int length) {
Length = length;
}
public SnakeNode getNewNode() {
return newNode;
}
public void setNewNode(SnakeNode newNode) {
this.newNode = newNode;
}
public MainGame() {//初始化各项数据与方法
snake.add(new SnakeNode(width/2,length/2,Color.GREEN));
snake.add(new SnakeNode(width/2,length/2,Color.BLUE));
snake.add(new SnakeNode(width/2,length/2,Color.RED));
Direction = 1;//定义初始方向为向上
Length = 3;//蛇身长度为3
CreateNode();//产生随机点
this.addKeyListener(new KeyAdapter() {//捕捉键盘的按键事件
public void keyPressed(KeyEvent e) {
int direction = 0;//定义一个按下按钮后要去的方向
switch(e.getKeyCode()) {
case KeyEvent.VK_UP://按下向上,返回1
direction = 1;
break;
case KeyEvent.VK_DOWN://按下向下,返回-1
direction = -1;
break;
case KeyEvent.VK_LEFT://按下相左,返回2
direction = 2;
break;
case KeyEvent.VK_RIGHT://按下向右,返回-2
direction = -2;
break;
default:
break;
}
if(direction + Direction !=0) {//不能反向运动
Direction = direction;
Move(direction);
repaint();
}
}
});
time.start();
}
public void Move(int direction) {//定义蛇身移动的方法
int FirstX = snake.get(0).getX();//获取蛇第一个点
int FirstY = snake.get(0).getY();//获取蛇第二个点
switch(direction) {
case 1:
FirstY--;
break;
case -1:
FirstY++;
break;
case 2:
FirstX--;
break;
case -2:
FirstX++;
break;
default:
break;
}
if(FirstX == newNode.getX()&&FirstY == newNode.getY()) {//当碰到随机点时
getNode();
repaint();
}
for(int x = 0; x < Length; x++) {//当碰到蛇身自己时
if((FirstX==snake.get(x).getX())&&(FirstY == snake.get(x).getY())) {
Dead("你碰到自己啦~~~");
}
}
if(FirstX < 0 || FirstX > width -1 || FirstY < 0 || FirstY > length -1) {
Dead("菜鸡,你撞墙啦~~~~~");
}
for(int x = Length - 1; x > 0; x--) {
snake.get(x).setX(snake.get(x-1).getX());
snake.get(x).setY(snake.get(x-1).getY());
}
snake.get(0).setX(FirstX);
snake.get(0).setY(FirstY);
repaint();
}
public void getNode() {
SnakeNode addNode = new SnakeNode(newNode.getX(),newNode.getY(),newNode.getColor());
snake.add(addNode);
Length++;
for(int x = Length-1; x >0; x--) {
snake.get(x).setX(snake.get(x-1).getX());
snake.get(x).setY(snake.get(x-1).getY());
snake.get(x).setColor(snake.get(x-1).getColor());
}
snake.get(0).setX(addNode.getX());
snake.get(0).setY(addNode.getY());
snake.get(0).setColor(addNode.getColor());
CreateNode();
repaint();
}
public void Dead(String s) {
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat();
String str2 = sd.format(date);
String str = s +"\n" +"所以说游戏不得已将结束了";
JOptionPane.showMessageDialog(this, str2 + "\n" + str );
System.exit(0);
}
public void CreateNode() {//创造随机点的方法
int newX = 0;
int newY = 0;
Boolean flag = true;
while(flag) {
newX = new Random().nextInt(width);
newY = new Random().nextInt(length);
for(int i = 0; i < Length; i++) {
if(snake.get(i).getX()==newX && snake.get(i).getY()==newY) {
flag = true;
break;
}
flag= false;
}
}
Color color = new Color(new Random().nextInt(255),new Random().nextInt(255),new Random().nextInt(255));
newNode.setX(newX);
newNode.setY(newY);
newNode.setColor(color);
snake.get(0).setColor(newNode.getColor());
}
class ThingsListener implements ActionListener {//设置一个监听器事件
public void actionPerformed(ActionEvent e) {
Move(Direction);
repaint();
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(newNode.getColor());
g.fillOval(newNode.getX()*unit, newNode.getY()*unit, unit, unit);
g.setColor(newNode.getColor());
g.drawRect(0, 0, width*unit, length*unit);
for(int x = 0; x < Length; x++) {
g.setColor(snake.get(x).getColor());
g.fillOval(snake.get(x).getX()*unit, snake.get(x).getY()*unit, unit, unit);
}
}
}
package game;
import java.awt.Color;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("贪吃蛇————————————made by chenjiaheng");
frame.setBackground(Color.white);
frame.setBounds(0,0,800,500);
MainGame sn = new MainGame();
frame.add(sn);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
sn.requestFocus();
}
}