简易贪吃蛇(JAVA版)源代码

本文介绍了一个使用Java实现的经典贪吃蛇游戏。通过继承JPanel并实现Runnable接口,游戏实现了贪吃蛇的移动、食物生成及碰撞检测等功能。此外,还通过监听键盘事件来改变贪吃蛇的方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.LinkedList;

import javax.swing.*;
class snakeModel extends JPanel implements Runnable{
	public snakeModel(){
		iniMap();
		createFood();
	}
	private int[][] map=new int[90][50];
	private LinkedList snakeBody=new LinkedList();//记录snake状态
	//private LinkedList rcrdSnake;//记录snake坐标值
	private LinkedList rcrdSnake;//记录snake坐标值
	private JButton startButton=new JButton("开始"),
					pauseButton=new JButton("暂停"),
					exitButton=new JButton("退出");
	private int foodLocationX,foodLocationY;
	private int direct=1,status=0;//1=右,2=左,5=上,6=下
	private int speedTime=100;//设置snake运动速度
	protected void iniMap(){//初始化游戏,没有实体部分全部设置为0
		for(int i=0;i<90;i++){
			for(int j=0;j<50;j++)
				map[i][j]=0;
		}
		/**初始化snake**/
		addSnakeBody(44,25);
		addSnakeBody(45,25);
		addSnakeBody(46,25);
	}
	protected void addSnakeBody(int x,int y){//记录snake状态
		rcrdSnake=new LinkedList();//记录snake坐标值
		rcrdSnake.add(x);
		rcrdSnake.addLast(y);
		map[x][y]=1;
		snakeBody.addFirst(rcrdSnake);
	}
	protected void removeSnakeBody(){
		int x,y;
		rcrdSnake=(LinkedList) snakeBody.getLast();
		x=(int)rcrdSnake.getFirst();
		y=(int)rcrdSnake.getLast();
		map[x][y]=0;
		snakeBody.removeLast();
	}
	protected boolean move(){
		int x,y;
		rcrdSnake=(LinkedList) snakeBody.getFirst();
		x=(int)rcrdSnake.getFirst();
		y=(int)rcrdSnake.getLast();
		switch(direct){
			case 1://向右运动
				x++;break;
			case 2://向左运动
				x--;break;
			case 5://向上运动
				y--;break;
			case 6://向下运动
				y++;break;
		}
		if(x>89||x<0||y<0||y>49){//碰到边界
			//drawString("Failed");
			status=1;
			return false;
		}
		else if(x==foodLocationX&&y==foodLocationY){//吃到食物
			addSnakeBody(x,y);
			createFood();
			//return true;
		}
		else {//普通移动
			if(map[x][y]==1){
				System.out.printf("\nfoodX%d foodY%d\n",foodLocationX,foodLocationY);
				System.out.printf("\nX%d Y%d\n",x,y);
				System.out.printf("\n蛇体%d\n",map[x][y]);
				return false;
			}
			else{//碰到自己
				System.out.printf("\nX%d Y%d\n",x,y);
				System.out.printf("\n蛇体%d\n",map[x][y]);
				addSnakeBody(x,y);
				//snakeBody.removeLast();
				removeSnakeBody();//移除snake最后一个点
				System.out.println(snakeBody.size());
				//return false;
			}
		}
		return true;
		
	}
	protected void changeDirect(int newDirect){
		if(Math.abs(newDirect-direct)!=1)
			direct=newDirect;
			
	}
	protected void createFood(){//生成食物
		int i,j;
		do{
			i=(int)Math.rint(Math.random()*89);
			j=(int)Math.rint(Math.random()*49);
		}while(map[i][j]==1);
		map[i][j]=1;
		foodLocationX=i;
		foodLocationY=j;
		System.out.println("createFooding....");
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(move()){
			try{
				System.out.println("running");
				repaint();
				Thread.sleep(speedTime);
			}catch(InterruptedException e){
				System.out.println(e);
			}
		}
		//move();
	}

	public void paintComponent(Graphics g){//绘制贪吃蛇并创建食物
		super.paintComponent(g);
		g.setColor(Color.RED);
		g.drawRect(10, 0, 544, 304);//绘制游戏边框
		int x,y;
		for(int i=0;i<snakeBody.size();i++){
			rcrdSnake= (LinkedList) snakeBody.get(i);
			x=(int) rcrdSnake.get(0);
			y=(int) rcrdSnake.get(1);
			g.fillRect(x*6+12, y*6+2, 6, 6);
			
		}
		Font font=new Font("",50,30);
		//System.out.println(status);
		if(status==1){
			g.setFont(font);
			g.drawString("Game over", 10, 10);
			}
		g.fillRect(foodLocationX*6+12, foodLocationY*6+2, 6, 6);
		//g.fillRect(50, 50, 6, 6);
	}
	
}
class gameWindow extends JFrame implements KeyListener{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected snakeModel panelActive=new snakeModel();
	protected JPanel panelMenu=new JPanel();
	private int newDirect;
	public gameWindow(){
		super("贪吃蛇");
		setLayout(null);
		panelActive.setBackground(Color.cyan);
		panelMenu.setBackground(Color.darkGray);
		panelMenu.setBounds(0, 325, 600, 50);
		panelActive.setBounds(10, 10, 580, 310);
		add(panelActive);
		add(panelMenu);
		addKeyListener(this);
		setSize(600,400);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Thread moveThread=new Thread(panelActive);
		moveThread.start();
		//repaint();
	}
	@Override
	public void keyPressed(KeyEvent key) {
		// TODO Auto-generated method stub
		if(key.getKeyCode()==38){//向上
			newDirect=5;
			panelActive.changeDirect(newDirect);
		}
		else if(key.getKeyCode()==40){//向下
			newDirect=6;
			panelActive.changeDirect(newDirect);
		}
		else if(key.getKeyCode()==39){//向右
			newDirect=1;
			panelActive.changeDirect(newDirect);
		}
		else if(key.getKeyCode()==37){//向左
			newDirect=2;
			panelActive.changeDirect(newDirect);
		}
	}
	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
}
public class Snake {
	public static void main(String args[]){
		new gameWindow();
		//int i=(int)(Math.random()*10);
		System.out.println("hello world");
		//System.out.println(i);
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值