Java编写的贪吃蛇(没有线程)

上网查的资料大部分都是采用线程写的贪吃蛇,但由于线程的部分还没有学习,所以就采用了死循环的方法,实现了键盘监听并且蛇身的移动。但可能是因为死循环的原因,所以在运行过程中会出现卡顿。实在是不知道该怎么解决了。等学完线程在回来看吧。

下面是全部的代码:

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都可以^.^ 嘘!!!别声张)

发布了88 篇原创文章 · 获赞 47 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/dai_ma_dong/article/details/102458116
今日推荐