欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Java代码】贪吃蛇小游戏

程序员文章站 2024-03-18 20:12:04
...

少玩游戏,玩物丧志

       先贴上最终的成品图↓
【Java代码】贪吃蛇小游戏
【Java代码】贪吃蛇小游戏

一、文件结构

       下面来看看文件结构:greedysnake包下有四个类以及一些用到的图片(四个方向的蛇头,蛇身,banner,食物)。
【Java代码】贪吃蛇小游戏

       本项目共创建了四个类: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 );

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