【Java代码】贪吃蛇小游戏

少玩游戏,玩物丧志

       先贴上最终的成品图↓
在这里插入图片描述
在这里插入图片描述

一、文件结构

       下面来看看文件结构:greedysnake包下有四个类以及一些用到的图片(四个方向的蛇头,蛇身,banner,食物)。
在这里插入图片描述

       本项目共创建了四个类:Food用于设置食物的随机产生、Snake用于实现蛇头蛇身的初始化以及对蛇是否吃到食物、是否撞到墙和是否撞到自己的判断、SnakePanel用于绘制图形界面、SnakeFrame为总体框架,可在其中添加监听或面板等。
       可以依照以下流程完善游戏功能:编写界面面板→添加静态的蛇(蛇头和蛇身)→添加随机产生的食物→让蛇动起来→添加键盘监听让蛇可以根据按键值进行转向→让蛇可以吃食物并变长→设置规则:当蛇碰到自己身体或边界时结束游戏→添加按空格暂停或开始的功能→显示暂停/开始和游戏结束的提示文字→完成随着蛇身变长加快速度的功能→添加分数的显示。

二、实现功能的要点

①如何随机产生食物

while(flag) {
			flag=false;
			x=(int) (Math.random()*34);//850(界面宽度)//25(以25像素为一个单位)=34
			y=(int) (Math.random()*21)+3;//
			if(x==snake.head.x&&y==snake.head.y) {//判断食物是否和蛇的头重合
				flag=true;
			}
			for(Point p:snake.body) {//判断食物是否和蛇的身体重合
				if(x==p.x&&y==p.y) {
					flag=true;
				}
			}
		}

②如何构造蛇

public Snake(Point head) {//构造方法
		this.head=head;
		dir=4;
		length=5;
		size=25;
		body=new ArrayList<Point>();
		for(int i=0;i<length-1;i++) {//length是蛇的总长度,-1就是身体的长度
			Point p=new Point(head.x,head.y+1+i);//+1表示第一个身体的位置,+i即下移i个单位,最后乘上size就能扩大
			body.add(p);
		}
	}

③如何让蛇动起来

       首先保存蛇头位置,接着对行进方向进行判断,并将头的坐标进行改变,然后在原先蛇头的位置添加一个身体,最后再去掉尾部的一个身体,即可模拟蛇的运动。

public void startMove() {
		if(isStart&&!isFaild) {
			Point oxy=new Point(snake.head);//将当前头所在的位置坐标赋给oxy保存
			//下面对行进方向进行判断,并将头的坐标进行改变
			if(snake.dir==1) {
				imgName="up.png";
				snake.head.y--;
			}
			if(snake.dir==2) {
				imgName="down.png";
				snake.head.y++;
			}
			if(snake.dir==3) {
				imgName="left.png";
				snake.head.x--;
			}
			if(snake.dir==4){
				imgName="right.png";
				snake.head.x++;
			}
			snake.body.add(0, oxy);//在原先蛇头的位置处添加一个身体(0是存放身体数组的下标,oxy是原先蛇头的坐标)
			...
			else { snake.body.remove(snake.length-1);}//没吃到食物则去掉尾部的身体,保持身体总长不变
			...
		}
	}

④如何实现蛇的转向

       实现接口KeyListener,利用其方法keyPressed(KeyEvent e),在其中对按键值进行判断,根据不同的按键值,给 dir变量赋对应方向值,以改变蛇头运动方向。

@Override
	public void keyPressed(KeyEvent e) {// dir设置方向,1向上,2向下,3向左,4向右
		// TODO 自动生成的方法存根
		int key=e.getKeyCode();
		if(key==KeyEvent.VK_UP&&snake.dir!=2)
			snake.dir=1;
		if(key==KeyEvent.VK_DOWN&&snake.dir!=1)
			snake.dir=2;
		if(key==KeyEvent.VK_LEFT&&snake.dir!=4)
			snake.dir=3;
		if(key==KeyEvent.VK_RIGHT&&snake.dir!=3)
			snake.dir=4;
		if(key==KeyEvent.VK_SPACE&&!isFaild) {
			if(isStart) {
				isStart=false;
			}else isStart=true;
		}
	}

⑤如何让蛇吃食物并变长

       设置一个返回值为布尔类型的方法isEat(),若蛇头的坐标和食物坐标相同则返回True,并令蛇在移动过程中不去掉尾部的身体,由此即可模拟吃到食物变长。

public boolean isEat(Food food) {//判断是否吃到食物
		if(head.x==food.x&&head.y==food.y) {
			return true;
		}
		else {return false;}
	}

public void startMove() {
...
if(snake.isEat(food)) {//吃到食物则为true,让身体加长(即不去掉尾部的身体)
				snake.length++;
				flag++;
				score+=100;
				food=new Food(snake);//随机产生的新的食物位置}

⑥如何判断是否撞到自己或撞到墙

       循环判断比较头部的坐标是否和每个身体坐标相同,若有相同则撞到自己;若蛇头范围超出界面范围,则可说明撞到墙。

public boolean isOut() {//判断是否碰撞边界
		if(head.x<0||head.x>33||head.y<3||head.y>23) {
			return true;
		}else {return false;}
	}
	
	public boolean isPitch() {//判断是否撞到自己
		for(Point p:body) {
			if(head.x==p.x&&head.y==p.y) {
				return true;
			}
		}
		return false;
	}
public void startMove() {
...
	if(snake.isOut()) {//如果碰到边界,则令isFaild标志变为true,让游戏结束
		isFaild=true;
	}
	if(snake.isPitch()) {//如果碰到自己的身体,则令isFaild标志变为true,让游戏结束
		isFaild=true;
	}
}

⑦如何实现暂停和开始

       同样在keyPressed(KeyEvent e)方法中实现,若得到的按键值为空格键且游戏没结束,当目前状态为运行时,则让isStart标志变为false暂停;当目前状态为暂停时,则让isStart标志变为true运行。

		if(!isStart) {//当游戏没开始或暂停时,显示“Press space to start/pause”
			g.setColor(Color.white);
			g.setFont(new Font("方正小标宋简体",Font.BOLD,28));
			g.drawString("Press space to start/pause", 250, 350);
		}
		if(isFaild) {//游戏结束时,显示“Game Over”
			g.setColor(Color.white);
			g.setFont(new Font("方正小标宋简体",Font.BOLD,28));
			g.drawString("Game Over!",350, 350);
		}

⑧加速&分数

@Override
	public void run() {
		while(true) {
			startMove();
			try {
				Thread.sleep(speed);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			repaint();
		}
	}
public void startMove() {
...
	if(flag==4&&speed>50) {//每吃到四个食物让蛇移动速度变快,当移动时间间隔减为50毫秒时不再加快
		speed-=25;
		flag=0;
	}
...
}

g.setColor(Color.white);
		g.setFont(new Font("方正小标宋简体",Font.BOLD,20));
		g.drawString("Score:"+score, 700,40 );

代码文件已经上传,戳这里下载源码

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值