Java改良贪吃蛇小游戏

Java贪吃蛇小游戏改良版

前段时间学完Java的一些基础知识,就自己写了一个贪吃蛇,相对于传统的贪吃蛇游戏进行了玩法和界面的优化。现在整理出来当个留念吧。

需求分析: 注册账号并登陆后进入贪吃蛇小游戏,按键盘WASD控制贪吃蛇的移动方向,贪吃蛇吃到不同的buff可以产生不同的效果,当贪吃蛇撞墙或咬到自己的身体时,游戏结束,弹出游戏结果和分数,将结果提交到数据库。
增添特色:
1、对贪吃蛇皮肤进行优化,增加换装buff
2、游戏面板里所有buff随机出现,不定时出现不同buff。
3、增加保护罩功能,当蛇身上存在保护罩时,贪吃蛇变为无敌状态,所有伤害值降为零。
4、增加音乐线程
部分游戏界面:
1、登陆
登陆
2、游戏界面展示
粽子
(保护罩效果展示)
保护罩

3、游戏结束界面
在这里插入图片描述
以及提交分数等界面,在此不做一一展示了。

运用技术: GUI,mysql,DBUtil,以及反射技术创建对象等。
设计模式: 仿照MVC模式分包书写,使用策略模式等设计模式。
基本思路:
0、登录注册就不啰嗦了。
1、贪吃蛇身体移动借助两个一维数组存储蛇头和蛇身的坐标,移动过程中后面一节身体的坐标等于前面一节身体的坐标,由于蛇头要比蛇身大,需要对蛇头坐标进行适当修正。
2、绘制保护罩时利用Timer定时器对象,写一个继承TimerTask的匿名内部类,重写run()方法,在里面写好几秒后要执行的代码(也就是停止绘制保护罩的代码),在保护罩方法内使用Timer类的schedule()方法实现定时多少秒后保护罩消失的功能。

//保护罩
	public static void testRound(GameObject o1, GameObject o2) {
		class task extends TimerTask{
			//必须实现方法run()
			        public void run(){
			         //里面写你要在5秒后执行的代码。
			        	MainController.getCon().getSnake().setHaveRound(false);
			        }
			}
			if (o1 instanceof Snake && o2 instanceof point3) {
				if (o1.getRect().intersects(o2.getRect())) {
					//和相应的buff撞了以后 产生保护罩
				MainController.getCon().getSnake().setHaveRound(true);
					//五秒后将保护罩关掉 PERFECT!
				Timer t=new Timer();
				task tt=new task();
				t.schedule(tt,8000);//5000单位是毫秒=5秒
			}
		}
	}

3、书写配置文件,利用反射技术实现buff的不定时随机出现。

package com.ls.Thread;
/**
 * 游戏中贪吃蛇食物分发线程 根据每一关的配置文件 在制定的时间内创建出一个指定的游戏物体
 * @author 不点
 *
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import com.ls.controller.MainController;
import com.ls.util.Helper;
public class DispatcherThread extends Thread{
	private List<String> config = new ArrayList<>();
	Boolean isRun = true;
	int times = 0;
	public DispatcherThread() {
		//source folder 里的文件没有方法使用newfile直接获取,可以使用类加载器读文件读成流的方式
		//类加载器是用来加载类的字节码文件 进内存的对象 可以读取到类路径里的资源(文件)
		InputStream is = DispatcherThread.class.getClassLoader().getResourceAsStream(Helper.LEVEL+".e65");
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line = null;
		try {
			while((line = br.readLine())!=null) {
				config.add(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void run() {
		while(isRun) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				times++;
				for(int i=0;i<config.size();i++) {
					String[]datas = config.get(i).split("=");
					int t = Integer.parseInt(datas[0]);
					if (times==t) {
						int count = Integer.parseInt(datas[2]);
						for(int j = 1;j<=count;j++) {
							//使用反射技术用字符串形式的类名的到这个类名创建的一个对象
							try {
								Class.forName(datas[1]).newInstance();
							} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
								e.printStackTrace();
							}
						}
					}
				}
		}
	}
	@Override
	public void interrupt() {
		isRun = false;
	}
}

❤配置文件:

5=com.ls.model.food.point=2
10=com.ls.model.food.point2=30
15=com.ls.model.food.point4=3
20=com.ls.model.food.point2=6
25=com.ls.model.food.point3=4
30=com.ls.model.food.point5=3
40=com.ls.model.food.point2=6
45=com.ls.model.food.point1=3
50=com.ls.model.food.point=2
55=com.ls.model.food.point4=4
60=com.ls.model.food.point2=10
65=com.ls.model.food.point5=2
70=com.ls.model.food.point2=30
75=com.ls.model.food.point=5
80=com.ls.model.food.point1=5

4、书写dao层代码用来专门处理与数据库交互的代码,便于日后的检查。

package com.ls.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.ls.bean.Player;
import com.ls.bean.Result;
import com.ls.controller.MainController;
import pool.PoolUtil;

public class playDao {
	public Player login(Player p) {
		//1:qr
		QueryRunner qr = new QueryRunner(PoolUtil.getDatasource());
		//2:sql
		String sql = "select * from player where pname = ? and ppass = ?";
		//3:?
		Object[]params = {p.getPname(),p.getPass()};
		//4:执行查询 封装结果返回
		try {
			Player player = qr.query(sql, new BeanHandler<Player>(Player.class),params);
			return player;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("playerDao"+p+"出现问题");
		}
	}

	public int register(Player player) {
		QueryRunner qr = new QueryRunner(PoolUtil.getDatasource());
		String sql = "insert into player (pname,ppass,pnick)values(?,?,?)";
		Object []params = {player.getPname(),player.getPass(),player.getPnick()};
		try {
			int rows = qr.execute(sql, params);
			return rows;
		} catch (SQLException e) {
		//	e.printStackTrace();
			int error = 1045;
			return error;
		}
	}

	public Player searchID(Player p) {
		QueryRunner qr = new QueryRunner(PoolUtil.getDatasource());
		String sql = "select * from player where pname =  ?";
		Object[]params = {p.getPname()};
		try {
			Player player = qr.query(sql, new BeanHandler<Player>(Player.class),params);
			return player;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("playerDao查询出现问题了!!!");
		}
	}
	
	public int addPoint(Result result) {
		QueryRunner qr = new QueryRunner(PoolUtil.getDatasource());
		String sql = "insert into record(rscore,rtime,pid)values(?,?,?)";
		String date = MainController.getCon().getNowDay();
		String score = (MainController.getCon().getSnake().getLen()*3)+"";
		Object params[] = {score,date,result.getPid()};
		try {
			int rows = qr.execute(sql, params);
			return rows;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException("playerDao新增分数数据出现问题了!");
		}
	}
}
	小白一枚,如果大家有什么好的意见,欢迎大家批评指正。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值