简单版贪吃蛇小游戏

新人任务二:基于Java Swing 的吃食蛇小游戏

自己设计的蛇和食物,有些丑,请勿见怪,哈哈!


前言

这是我的第二个小项目,原本想继续用VS的MFC实现的,奈何自己太菜,MFC不太会用,于是“转移战场”改用Java Swing去做了!


前期准备

我用的是Eclipse ,为了使用Swing,使游戏最终可以窗口的形式运行,在开始做小项目之前,需要去Elipse Marketplace 安装一下 WindowBuilder!

1、Java Swing的基本介绍
Swing 是一个为Java设计的GUI工具包,是JAVA基础类的一部分。

Swing包括了图形用户界面(GUI)器件如:文本框,按钮,分隔窗格和表。
转载JavaSwing的一些介绍

2、需求分析:

实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子,上下左右控制“蛇”的移动,吃到“豆子”以后“蛇”的身体加长一点,得分增加,“蛇”碰到边界或,蛇头与蛇身相撞,蛇死亡,游戏结束。为游戏设计初始欢迎界面,游戏界面,游戏结束界面。

程序流程图

设计思路

1.窗口设计

(1)设计思路:
利用Java swing 中的JFrame 窗口创建一个Snake Class,可以运行后弹出的窗口,之后创建一个SnakePenal Class ,并添加到窗口上画布,我们后面所有的操作在SnakePenal(画布)上进行
在这里插入图片描述

(2)参数设置:

		frame.setBounds(200, 150, 600, 510);
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		SnakePanel panel = new SnakePanel();
		frame.add(panel);
		frame.setVisible(true);
	}
}

2.蛇模块

(1)设计蛇的身体、头、标题以及整个活动范围等元素并导入Snake Class所在的项目路径下

蛇头

身体

标题

活动范围

	//加载图片
	ImageIcon up = new ImageIcon("up.png");
	ImageIcon down = new ImageIcon("down.png");
	ImageIcon left = new ImageIcon("left.png");
	ImageIcon right = new ImageIcon("right.png");
	ImageIcon title = new ImageIcon("title.png");
	ImageIcon food = new ImageIcon("food.png");
	ImageIcon body = new ImageIcon("body.png");
	

(2)蛇的数据结构设计

//蛇的数据结构
	int[] snakex = new int[400];
	int[] snakey = new int[400];
	int len = 3;
	String direction = "R";

(3)初始化蛇

//初始化蛇
	public void initSnake() {
		isOver = false;
		isStarted = true;
		len = 3;
		direction = "R";
		snakex[0]=100;
		snakey[0]=100;
		snakex[1]=75;
		snakey[1]=100;
		snakex[2]=50;
		snakey[2]=100;
	}

3.食物模块

(1)食物的设计
食物

(2)食物的数据结构

	//食物的数据结构
	Random random = new Random();
	int foodx = random.nextInt(22)*25+25;
	int foody = random.nextInt(16)*25+75;
	

(3)初始化食物

随机生成,无需初始化

具体实现

(1)画布部分

package xch.snake;

import javax.swing.JFrame;

public class Snake {
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setBounds(200, 150, 600, 510);
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		SnakePanel panel = new SnakePanel();
		frame.add(panel);
		
		frame.setVisible(true);
	}
}
...

(2)蛇部分

1)初始化蛇
	//初始化蛇
	public void initSnake() {
		isOver = false;
		isStarted = true;
		len = 3;
		direction = "R";
		snakex[0]=100;
		snakey[0]=100;
		snakex[1]=75;
		snakey[1]=100;
		snakex[2]=50;
		snakey[2]=100;
	}
2)画蛇头的蛇身体
//画蛇头
		if(direction.equals("R")) {
			right.paintIcon(this, g, snakex[0], snakey[0]);
		}
		else if(direction.equals("L")) {
			left.paintIcon(this, g, snakex[0], snakey[0]);
		}
		else if(direction.equals("U")) {
			up.paintIcon(this, g, snakex[0], snakey[0]);
		}
		else if(direction.equals("D")) {
			down.paintIcon(this, g, snakex[0], snakey[0]);
		}
		//画蛇的身体
		for(int i=1;i<len;i++) {
			body.paintIcon(this, g, snakex[i], snakey[i]);
		}
3)蛇的移动判断和实现
		//判断蛇的移动按键
		}else if(keyCode == KeyEvent.VK_UP && !direction.equals("D")) {
			direction="U";
		}else if(keyCode == KeyEvent.VK_DOWN && !direction.equals("U")) {
			direction="D";
		}else if(keyCode == KeyEvent.VK_LEFT && !direction.equals("R")) {
			direction="L";
		}else if(keyCode == KeyEvent.VK_RIGHT && !direction.equals("L")) {
			direction="R";
}
	}
		//蛇的移动
		timer.start();
		if(isStarted && !isOver) {
			for(int i=len;i>.0;i--) {
				snakex[i] = snakex[i-1];
				snakey[i] = snakey[i-1];
			}
			if(direction.equals("R")) {
				snakex[0] = snakex[0] + 25;
				if(snakex[0] >550) {
					snakex[0] = 25;
				}
			}else if(direction.equals("L")) {
				snakex[0] = snakex[0] - 25;
				if(snakex[0] <25) {
					snakex[0] = 550;
				}
			}else if(direction.equals("U")) {
				snakey[0] = snakey[0] - 25;
				if(snakey[0] <75) {
					snakey[0] = 400;
				}
			}else if(direction.equals("D")) {
				snakey[0] = snakey[0] + 25;	
				if(snakey[0] >400) {
					snakey[0] = 75;
				}
			}
4)蛇吃食物
/蛇吃食物的逻辑
			if(snakex[0] == foodx && snakey[0] == foody) {
				len++;
				foodx = random.nextInt(22)*25+25;
				foody = random.nextInt(16)*25+75;
5)蛇的死亡游戏结束
//游戏结束逻辑(碰到身体)
			for(int i=1;i<len;i++) {
				if(snakex[0] == snakex[i] && snakey[0] == snakey[i]) {
					isOver=true;
				}

(3)食物部分

//画食物
		food.paintIcon(this, g, foodx, foody);

(4)判断键盘输入部分

1)定义判断键盘输入部分KeyListener
public class SnakePanel extends JPanel implements KeyListener{
}
2)实现
@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		//判断游戏开始按键
		int keyCode = e.getKeyCode();
		if(keyCode == KeyEvent.VK_SPACE) {
			if(isOver) {
				initSnake();
			}else
			isStarted = !isStarted;
			//repaint();
		//判断蛇的移动按键
		}else if(keyCode == KeyEvent.VK_UP && !direction.equals("D")) {
			direction="U";
		}else if(keyCode == KeyEvent.VK_DOWN && !direction.equals("U")) {
			direction="D";
		}else if(keyCode == KeyEvent.VK_LEFT && !direction.equals("R")) {
			direction="L";
		}else if(keyCode == KeyEvent.VK_RIGHT && !direction.equals("L")) {
			direction="R";
}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

(5)执行ActionListener部分
1)定义
public class SnakePanel extends JPanel implements KeyListener, ActionListener{
}
2)实现
@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		//蛇的移动
		timer.start();
		if(isStarted && !isOver) {
			for(int i=len;i>.0;i--) {
				snakex[i] = snakex[i-1];
				snakey[i] = snakey[i-1];
			}
			if(direction.equals("R")) {
				snakex[0] = snakex[0] + 25;
				if(snakex[0] >550) {
					snakex[0] = 25;
				}
			}else if(direction.equals("L")) {
				snakex[0] = snakex[0] - 25;
				if(snakex[0] <25) {
					snakex[0] = 550;
				}
			}else if(direction.equals("U")) {
				snakey[0] = snakey[0] - 25;
				if(snakey[0] <75) {
					snakey[0] = 400;
				}
			}else if(direction.equals("D")) {
				snakey[0] = snakey[0] + 25;	
				if(snakey[0] >400) {
					snakey[0] = 75;
				}
			}
			//蛇吃食物的逻辑
			if(snakex[0] == foodx && snakey[0] == foody) {
				len++;
				foodx = random.nextInt(22)*25+25;
				foody = random.nextInt(16)*25+75;
			}
			//游戏结束逻辑(碰到身体)
			for(int i=1;i<len;i++) {
				if(snakex[0] == snakex[i] && snakey[0] == snakey[i]) {
					isOver=true;
				}
			}
			
		}
		repaint();
	}
	
}

(6)游戏开始与结束
1)定义开始与结束
	//游戏开始
	boolean isStarted=false;
	//游戏结束
	boolean isOver=false;
	Timer timer = new Timer(150,this);
	
	
	public SnakePanel() {
		this.setFocusable(true);
		initSnake();
		this.addKeyListener(this);
		timer.start();
	}
2)实现
//画游戏开始提示语
		if(!isStarted) {
			g.setColor(Color.WHITE);
			g.setFont(new Font("arial",Font.BOLD,20));
			g.drawString("Press Space to Start or Pause", 150, 250);
		}
		//画游戏结束提示语
		if(isOver) {
			g.setColor(Color.WHITE);
			g.setFont(new Font("arial",Font.BOLD,20));
			g.drawString("Game Over,Press Space to Restart", 150, 250);
			
		}

总结

1、结果展示
实现
总的来说,相对一一次写项目思路会更清晰一点,虽然说还是有很多BUG,但好在自己坚持下来了,继续努力吧,新人!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值