上网查的资料大部分都是采用线程写的贪吃蛇,但由于线程的部分还没有学习,所以就采用了死循环的方法,实现了键盘监听并且蛇身的移动。但可能是因为死循环的原因,所以在运行过程中会出现卡顿。实在是不知道该怎么解决了。等学完线程在回来看吧。
下面是全部的代码:
package game_JM;
import java.awt.Color;
import java.awt.Label;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JM1 extends JFrame{
JFrame J=new JFrame("贪吃蛇");//创建窗口
JPanel P=new JPanel();//创建画板
Label she1,she2,she3;//出事状态有三截蛇身
Label sfood=new Label("@");//用@来表示蛇
private int x=400,y=400;//蛇的初始位置
int foodx,foody;//食物的位置
char F='R';//初始方向是向右
List list=new ArrayList();//使用集合来存储蛇身
public JM1() throws InterruptedException {
//初始化界面
J.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
P.setLayout(null);
J.setBounds(700, 50, 1000, 800);
J.add(P);
//设置界面是否可见
J.setVisible(true);
//初始化蛇身
she1=new Label("@");
she1.setBounds(x, y, 20, 20);
she1.setForeground(Color.RED);
P.add(she1);
she2=new Label("@");
she2.setBounds(x-20, y, 20, 20);
P.add(she2);
she3=new Label("@");
she3.setBounds(x-40, y, 20, 20);
P.add(she3);
//把蛇身放入集合
list.add(she1);
list.add(she2);
list.add(she3);
J.setResizable(false);
//产生第一个食物
food();
//键盘监听
init();
}
//键盘监听
public void init() {
J.addKeyListener(new KeyAdapter() {
//有按钮按下
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
//不能向相反的方向移动
if(F!='R') {
F='L';}
break;
case KeyEvent.VK_RIGHT:
//不能向相反的方向移动
if(F!='L') {
F='R';}
break;
case KeyEvent.VK_DOWN:
//不能向相反的方向移动
if(F!='U') {
F='D';}
break;
case KeyEvent.VK_UP:
//不能向相反的方向移动
if(F!='D') {
F='U';}
break;
//没有按钮按下就按方向不变
default:
F=F;
break;
}
}
});
//蛇移动
Move();
}
//实现蛇的移动
public void Move() {
//总的来说蛇的移动其实就是除了蛇头以外,每一节蛇身都是移动到了上一节蛇身的位置,所以,按照这个思想,实现蛇身的移动
for(int i=list.size()-1;i>0;i--) {
Label she0=(Label)list.get(i-1);
Label she=(Label)list.get(i);
she.setBounds((int)she0.getX(), (int)she0.getY(), 20, 20);
P.add(she);
list.set(i, she);
}
//取出蛇头
Label she=(Label)list.get(0);
//根据当前方向,实现蛇头的移动,设置的每次移动为20
switch (F) {
case 'R':
x+=20;
she.setBounds(x, y, 20, 20);
P.add(she);
list.set(0, she);
P.repaint();
break;
case 'L':
x-=20;
she.setBounds(x, y, 20, 20);
P.add(she);
list.set(0, she);
P.repaint();
break;
case 'D':
y+=20;
she.setBounds(x, y, 20, 20);
P.add(she);
list.set(0, she);
P.repaint();
break;
case 'U':
y-=20;
she.setBounds(x, y, 20, 20);
P.add(she);
list.set(0, she);
P.repaint();
break;
}
//设置睡眠时间
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//判断是否吃到食物
if(x==foodx&&y==foody) {
food();
Label shew=new Label("@");
list.add(shew);
}
//判断蛇头是否撞到蛇身
for(int i=list.size()-1;i>0;i--) {
Label sheS=(Label)list.get(i);
int shex=sheS.getX();
int shey=sheS.getY();
if(x==shex&&y==shey)
System.exit(-1);
}
//判断蛇头是否撞到墙
if(x>980||x<0||y>760||y<0)
System.exit(-1);
init();
}
public void food() {
//产生随机数,作为食物的位置
Random random=new Random();
int foodX=random.nextInt(980)+1;
int foodY=random.nextInt(760)+1;
//把产生的随机数改成20的倍数,这样食物才可以和蛇身重合
foodx=(foodX/20)*20;
foody=(foodY/20)*20;
//实现食物
sfood.setBounds(foodx, foody, 20, 20);
P.add(sfood);
}
}
这个贪吃蛇实现了吃食物和死亡判定。关于食物不能出现在当前蛇身所在位置的限定还没有写,不想写了,如果想加上的话,按照我的思路,其实就跟判断蛇头是否撞到蛇身是差不多的,挨个的获取每一节蛇身所在位置,如果随机数与这些位置重合了,就舍弃掉,再重新生成一个。大概就是这个意思吧,具体的实现可以自己试一试,如果有什么不明白的可以留言。我们一起探讨^.^ (悄悄地说一句,如果有需要代写课程设计的可以在留言区留下联系方式,有偿代写,Java和c都可以^.^ 嘘!!!别声张)