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新增分数数据出现问题了!");
}
}
}