贪吃蛇小游戏小Demo

一、前序 

最近用java写了一个贪吃蛇游戏的Demo,感觉还不错,在这上面整理一下。

(1)游戏的运行图:

游戏规则很简单:

1.按空格启动开始游戏,再次按空格可以切换暂停和开始游戏,死亡之后按空格可以重新开始游戏

2.监听键盘空格键和上、下、左、右 键,使小蛇可以按规定方向行走

(2)游戏工程图:

(3)游戏所需要素材

 

二、核心代码:

1.Images.java 作用:封装所用到的图像地址

package cm.msb.gane;
/**
 * 
 * @author 16574
 *这个类专门获取游戏中所需要的图片
 */

import java.net.URL;

import javax.swing.ImageIcon;

public class Images {
	public static URL bodyUrl=Images.class.getResource("/images/body.png");
	public static ImageIcon bodyIcon = new ImageIcon(bodyUrl);
	
	public static URL downUrl=Images.class.getResource("/images/down.png");
	public static ImageIcon downIcon = new ImageIcon(downUrl);

	public static URL foodUrl=Images.class.getResource("/images/food.png");
	public static ImageIcon foodIcon = new ImageIcon(foodUrl);

	public static URL headerUrl=Images.class.getResource("/images/header.png");
	public static ImageIcon headerIcon = new ImageIcon(headerUrl);

	public static URL leftUrl=Images.class.getResource("/images/left.png");
	public static ImageIcon leftIcon = new ImageIcon(leftUrl);
	
	public static URL rightUrl=Images.class.getResource("/images/right.png");
	public static ImageIcon rightIcon = new ImageIcon(rightUrl);

	public static URL upUrl=Images.class.getResource("/images/up.png");
	public static ImageIcon upIcon = new ImageIcon(upUrl);

}

2.StartGame.java 

主要功能:主程序入口,设置窗口属性

package cm.msb.gane;

import java.awt.Toolkit;

import javax.swing.*;


public class StartGame {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame jf =new JFrame();
		jf.setTitle("小游戏 大逻辑   by王振");
		int width = Toolkit.getDefaultToolkit().getScreenSize().width;
		int height = Toolkit.getDefaultToolkit().getScreenSize().height;
		int x = (width-800)/2;
		int y = (height-800)/2;
		jf.setBounds(x, y, 800, 800);
		//关闭窗口的同时,程序停止运行
		jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		//设置窗体大小不可调节
		GamePanel gPanel = new GamePanel();
		jf.add(gPanel);
		jf.setResizable(false);
		
		
		jf.setVisible(true);

	}

}

3、GamePanel.java

主要功能:实现游戏运行逻辑

package cm.msb.gane;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

import javax.swing.JPanel;
import javax.swing.Timer;


public class GamePanel extends JPanel{
	//初始化蛇的长度
	int length;
	//定两个数组
	
	//一个数组专门储存蛇的x轴坐标
	int snakex[] = new int[200];
	//第二个储存蛇的y轴数组
	int snakey[] = new int[200];
	//定时器
	Timer timer;
	//游戏只有两个状态,开始或者暂停
	boolean isStart = false;
	//定义蛇的行走方向
	String direction;
	//定义食物的x轴和y轴坐标
	int foodx;
	int foody;
	//定义一个积分
	int score;
	//加入一个小蛇生死状态
	boolean isDie = false;
	//小蛇初始化方法
	public void inite() {
		length = 3;
		snakex[0] = 250;
		snakey[0] = 275;
		
		snakex[1] = 200;
		snakey[1] = 275;
		 
		snakex[2] = 225;
		snakey[2] = 275;
		
		direction = "R";
		foodx = 300;
		foody = 150;
		score = 0;
		
	}
	//面板类的初始化
	public GamePanel() {
		// TODO Auto-generated constructor stub
		inite();
		//将焦点定位在当前面板
		this.setFocusable(true);
		//加入监听
		this.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				super.keyPressed(e);
				int keyCode = e.getKeyCode();
				if(keyCode == KeyEvent.VK_SPACE) {
					if(isDie) {
						//全部恢复到初始状态
						inite();
						isDie = false;
					}
					else {
						isStart = !isStart;
					repaint();
					}
					
				}
				//监听向上箭头
				if(keyCode == KeyEvent.VK_UP) {
					direction = "U";
				
			    }
				if(keyCode == KeyEvent.VK_DOWN) {
					direction = "D";
					
				}
				if(keyCode == KeyEvent.VK_LEFT) {
					direction = "L";
				}
				if(keyCode == KeyEvent.VK_RIGHT) {
					direction = "R";
				}
			}
		});
		//
		timer = new Timer(100, new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// 游戏是开始状态的时候蛇才动
				if(isStart&&isDie==false) {
					for(int i=length-1;i>0;i--) {
						snakex[i] = snakex[i-1];
						snakey[i] = snakey[i-1];
					}
					//动头
					if(direction.equals("U")) {
						snakey[0] -= 25;
					}
					if(direction.equals("D")) {
						snakey[0] += 25;
					}
					if(direction.equals("L")) {
						snakex[0] -= 25;
					}
					if(direction.equals("R")) {
						snakex[0] += 25;
					}
					
					//防止蛇超出边界
					if(snakex[0] > 775) {
						snakex[0] = 25;
					}
					if(snakex[0] < 25) {
						snakex[0] = 775;
					}
					if(snakey[0] < 75) {
						snakey[0] = 725;
					}
					if(snakey[0] > 725) {
						snakey[0] = 75;
					}
					//检测碰撞的动作
					//食物的坐标和蛇的坐标一致
					if(snakex[0]==foodx&&snakey[0]==foody) {
						length++;
						//食物坐标改变,随机生成坐标**必须是25的倍数
						/*
						 * [25,775] -> [1,31]*25
						 * Math.random() ->[0.0,1.0)
						 * (int)Math.random()*31 ->[0,30]
						 * (int)Math.random()*31+1 ->[1,31]
						 */
						foodx = ((int)(Math.random()*31)+1)*25;//[25,775]
						/*
						 * [75,725] ->[3,28]*25 
						 * [3,28] ->[0,25]+3
						 * [0,25]
						 * new random().nextInt(26) ->[0,26) ->[0,25]
						 */
						foody = (new Random().nextInt(26)+3)*25;//[75,725]
						//吃上食物之后,积分加10
						score = score+10;
					}
					//死亡判定:
					for(int i=1;i<length;i++) {
						if (snakex[0]==snakex[i]&&snakey[0]==snakey[i]) {
							//将死亡状态改为true
							isDie = true;
						}
					}
					repaint();
				}
				
			}
		});
		timer.start();
	}
	@Override
	protected void paintComponent(Graphics g) {
		// TODO Auto-generated method stub
		super.paintComponent(g);
		//填充背景色
		this.setBackground(new Color(226,224,217));
		Images.headerIcon.paintIcon(this, g, 10, 0);
		g.setColor(new Color(219,226,219));
		g.fillRect(10, 70, 775, 685);
		//画小蛇
		//画蛇头
		if(direction.equals("R"))
		    Images.rightIcon.paintIcon(this, g, snakex[0], snakey[0]);
		if(direction.equals("U"))
			Images.upIcon.paintIcon(this, g, snakex[0], snakey[0]);
		if(direction.equals("L"))
			Images.leftIcon.paintIcon(this, g, snakex[0], snakey[0]);
		if(direction.equals("D"))
			Images.downIcon.paintIcon(this, g, snakex[0], snakey[0]);
		
//		Images.bodyIcon.paintIcon(this, g, snakex[1], snakey[1]);
//		Images.bodyIcon.paintIcon(this, g, snakex[2], snakey[2]);
		for (int i = 1; i <length; i++) {
			Images.bodyIcon.paintIcon(this, g, snakex[i], snakey[i]);
			
		}
		//如果有游戏是暂停的,界面中间有一句提示语
		if(isStart == false) {
			g.setColor(new Color(114,98,255));
			//字体,加粗,字号
			g.setFont(new Font("微软雅黑",Font.BOLD,40));
			//参数内容,x轴坐标,y轴坐标
			g.drawString("点击空格开始游戏", 250, 330);
		}
		//画食物
		Images.foodIcon.paintIcon(this, g, foodx, foody);
		//画积分
		g.setColor(new Color(255,248,248));
		g.setFont(new Font("微软雅黑",Font.BOLD,20));
		g.drawString("积分"+score, 680, 42);
		//画死亡状态
		if(isDie) {
		g.setColor(new Color(255,82,68));
		g.setFont(new Font("微软雅黑",Font.BOLD,20));
		g.drawString("小蛇死亡,游戏停止,按下空格重新开始游戏", 200, 330);
		}
	}

}

三、结束

这样一个简单的小游戏就做好啦!

建议:可以根据需要自行改变图中的代码,小蛇移动的快慢,改变小蛇的头和身体及各种参数

可以为面板边缘增加墙壁,使得小蛇实现撞墙死的效果,还可以改善UI使得观看更美观。

  建议就先写到这了,有什么好的建议可以通过评论区和我交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值