javaWeb简单的口算游戏的开发流程(springboot+jpa)附源码

记一个javaWeb写的网页速算小游戏的开发流程,前段时间找到了一个自己大学那会写的一个简单口算游戏的程序,大学那时候一直想起高中玩过的一个在塞班系统的索爱手机的口算游戏,没有找到一模一样的了,只能通过自己的记忆,重新写一个类似的游戏出来,原来在学校的写的程序架构是javaWeb项目,那时候程序架构是ssh,也没有用到maven管理jar,前两天重新整理成springboot+docker+maven的架构发出来,后面有源码

  1. 程序架构:springboot+jpa+jsp+docker
  2. 系统流程图
  3. 系统截图
    游戏的入口:http://www.xinzhihuo.top/countgame/user/toGame
    javaWeb简单的口算游戏的开发流程(springboot+jpa)附源码_第1张图片 javaWeb简单的口算游戏的开发流程(springboot+jpa)附源码_第2张图片
  4. 数据库设计
    简单的一张表,记录用户的昵称、性别、答题数目以及答对数目
    javaWeb简单的口算游戏的开发流程(springboot+jpa)附源码_第3张图片

持久层框架采用jpa的hibernate实现,程序运行的时候如果不存在数据表就会新建表,所以不需要在数据库手工新建表

  1. 后端设计
    前端只有很简单的两个页面,首页(进行口算游戏),以及用户排名页
    后端考虑的主要是根据前端的数据更新用户的游戏信息以及通过分页显示用户排名页面
@Controller
@RequestMapping("/user")
public class UserController {

	Logger logger  =  LoggerFactory.getLogger(UserController.class);


	@Resource
	private IUserService userService;

	/**
	 * 跳转到首页
	 * http://localhost:8082/countgame/user/toGame
	 * @return
	 */
	@RequestMapping("toGame")
	public String toGame(){
		logger.info("into game");
		return "countGame";
	}

	/**
	 * 跳转到显示列表页面
	 * @param model
	 * @return
	 */
	@RequestMapping("toGameList")
	public String toGameList(Model model){
		model.addAttribute("gameList",  userService.getUserByPage( 1, 5).getRecordList());
		return "gameList";
	}

	/**
	 * ajax分页
	 * @param page
	 * @return
	 */
	@ResponseBody
	@RequestMapping("loadMore")
	public List<User> loadMore(int page){
		//List gameList = userService.getUserByPage("", page, 5).getRecordList();
		return userService.getUserByPage( page, 5).getRecordList();
	}

	/**
	 * 更新用户游戏数据
	 * @param newUser
	 * @return
	 */
	@ResponseBody
	@RequestMapping("updateUser")
	public boolean updateUser(User newUser){
		//先判断是否已有数据,若有,则更新
		User preUser = userService.findUserByName(newUser.getUsername());
		if(preUser!=null&&preUser.getCorrectSum()<newUser.getCorrectSum()){
			//更新
			preUser.setSex(newUser.getSex());
			preUser.setCountSum(newUser.getCountSum());
			preUser.setCorrectSum(newUser.getCorrectSum());
			userService.updateUser(preUser);
			logger.info("game update user:{},correctSum:{}",preUser.getUsername(),preUser.getCorrectSum());
		}else if(preUser==null){
			//插入
			newUser.setUsername(EmojiFilter.EmojiFilter(newUser.getUsername()));
			userService.save(newUser);
			logger.info("game save user:{},correctSum:{}",preUser.getUsername(),preUser.getCorrectSum());
		}
		return true;
	}
}

  1. 前端设计
    移动端样式采用weui组件:https://weui.io/
  • 首页:
    核心逻辑在game.js
    首先封装一个js的算术类
    //算术类
    function Count(firNum,sedNum,countSum,correctSum,continuousCorrect)
    {
    	this.firNum=firNum;//第一个随机数
        this.sedNum=sedNum;//第二个随机数
        this.countSum=countSum;//计算题目总数(包括答题的对错数)
        this.correctSum=correctSum;//答对题目总数
        this.continuousCorrect=continuousCorrect;//连续答对次数
        this.result;//用户输入的计算结果
        this.sex;//用户性别
        this.username;//用户姓名
    }

首次进入页面初始化

    var startFlag=false;//开始标志
	var timeNum=100;//游戏时间,100秒
	var level=0;//游戏难度水平,越大游戏难度越大(计算的数越大)
	var timeTip=null;//显示提示定时器
	var count =new  Count(0,0,0,0,0);//初始化算术类
	//页面第一次初始化
	$(document).ready(function(){
		//从h5的sessionStorage本地数据库获取数据,已存在,则相当于用户已登录
		var name = sessionStorage.getItem("USERNAME");  
		var sex = sessionStorage.getItem("SEX");
		if(name!=null&&sex!=null){
			count.username=name;
			count.sex=sex;
		}
		initCountNum();//游戏数据初始化
		$("#highlevel").click(function(){
			if(document.getElementById("highlevel").checked==true){				
				level=50;//随机数上线加50
			}else{				
				level=0;//正常难度
			}
		});
	});

每次答题前的口算题目随机生成的初始化

   /**
     * 初始化计算的题目数据
    */
	function initCountNum(){
		
		var operations= Math.floor(Math.random()*3);//随机的题目操作符,加减乘
		count.firNum = getRandomNum(73+level);//左边第一个随机数,0到73+level的随机数
		count.sedNum = getRandomNum(67+level);//第二个随机数,0到67+level的随机数
		switch(operations)
		{
		case 0:
			$("#operate").html('+');//加
			count.result=count.firNum + count.sedNum;
		    break;
		case 1:
			$("#operate").html('-');//减
			if(count.sedNum>count.firNum){
				count.firNum=count.firNum + count.sedNum;
				count.sedNum=count.firNum-count.sedNum;
				count.firNum=count.firNum-count.sedNum;
			}
			count.result=count.firNum - count.sedNum;
		    break;
		case 2:
			$("#operate").html('x');//乘
			count.firNum = getRandomNum(15+level);		
			count.sedNum = getRandomNum(12+level);
			count.result=count.firNum * count.sedNum;
			  break;
		default:
		  //n 与 case 1 和 case 2 不同时执行的代码
		}
		$("#firNum").html(count.firNum);
        $("#sedNum").html(count.sedNum);
		//alert('result='+count.result);
	}

计算用户的计算结果是否正确,并记录用户口算分数

    //计算速算结果
	function countResult(flag){
		if(count.username!=null&&count.sex!=null){
			if(!startFlag){
				startFlag=true;
				//开始计时
				timeNum=100;
				var time=setInterval("refresh();",1000);
				 setTimeout("endTimer("+time+");",100000);
			}
			if($("#userResult").val() == count.result){
				$("#tip").html("恭喜,答对了");
				if(timeTip!=null)
				clearInterval(timeTip);
				time =setTimeout("$('#tip').html('');",2000);
				$("#userResult").val('');
				count.correctSum++;
				count.countSum++;
				count.continuousCorrect++;
				initCountNum();
			}else if($("#userResult").val()>=10&&count.result<100||flag||$("#userResult").val()>100){
				$("#tip").html("答错了喔");
				if(timeTip!=null)
				clearInterval(timeTip);
				time =setTimeout("$('#tip').html('');",2000);
				$("#userResult").val('');
				count.countSum++;
				count.continuousCorrect=0;
				initCountNum();
			}
			if(count.continuousCorrect==10){
				count.continuousCorrect=0;
				//连续答对10道题,增加时间
				timeNum+=5;
				$("#tip").html("不错喔,再接再厉!");
			}
		}else{
			$("#dialog2").show();
			$("#username").focus();
		}
		
	}

游戏结束函数

    //游戏结束
	function endTimer(obj){
		$("#userResult").attr("disabled",true);
		 clearInterval(obj);
		 $("#loadingToast").show();
		 //$("#percenr").html('100%');
		 
		 //弹出结束对话框
		 if(count.correctSum<40){
			 $("#endContent").html("一共答了"+count.countSum+"道题,答对了"+count.correctSum+"道题,不要灰心,还有很大进步空间呢");
		 }else if(count.correctSum<55){
			 $("#endContent").html("一共答了"+count.countSum+"道题,答对了"+count.correctSum+"道题,还不错哟,继续加油喔");
		 }else if(count.correctSum<70){
			 $("#endContent").html("一共答了"+count.countSum+"道题,答对了"+count.correctSum+"道题,已经很厉害啦,再接再厉!");
		 }else{
			 $("#endContent").html("一共答了"+count.countSum+"道题,答对了"+count.correctSum+"道题,哇,你是天才吗,接受我的膜拜吧!");
		 }

		 //向服务器反馈
         $.ajax({
         url:"user/updateUser",
         data:{
            username:count.username,
            sex:count.sex,
            countSum:count.countSum,
            correctSum:count.correctSum
         },
         type:"post",
         success:function(data){
             if(data){
                 
            	//重置数据
        		 initCountNum();
        		 $("#userResult").val("");
        		 $("#timeProgress").width('100%');
        		 startFlag=false;
        		 $("#userResult").attr("disabled",false);
        		 count.countSum=0;
        		 count.correctSum=0;
        		 count.continuousCorrect=0;    		 
                 setTimeout("$('#loadingToast').hide();$('#dialog1').show();$('#share').focus();",400);
             }
         },
         fail:function(data){
         }
         });
		 
	}

登录函数

    //登录
	function login(){

		if(!$.trim($("#username").val())){
			$("#username").focus();
			$("#username").attr("placeholder","昵称不能为空");
		}else{
			//成功
			count.sex=$("#sex").val();
			count.username=$("#username").val();
			sessionStorage.setItem("USERNAME", count.username);
			sessionStorage.setItem("SEX", count.sex);
			//alert(count.sex+":"+count.username);
			$("#dialog2").hide();
			countResult(false);
            $("#userResult").blur();//先失去焦点,保证触发数字键盘
			$("#userResult").focus();
		}
	}

其他函数

    //分享按钮
	function share(){
		$('#dialog1').hide();
		document.getElementById('hdsm').style.display='block';
		document.getElementById('fx').style.display='block';
		setTimeout("$('#hdsm').hide();$('#fx').hide()",3000);
	}
	//游戏重新开始
	function rePlay(){					
		$('#dialog1').hide();
	}

	//得到随机数
	function getRandomNum(num){
		return Math.round(Math.random()*num);
	}
	
	//更新时间进度条
	function refresh(){
		timeNum--;
		//$("#percenr").html(timeNum+'%');
		$("#timeProgress").width(timeNum+'%');
	}
  • 排名列表页
    通过ajax进行分页,每次加载10条,底部显示加载更多按钮,点击加载更多的按钮,则通过ajax无刷新加载10条排名数据
  1. 编译docker镜像到远程的docker服务器并启动docker容器
    具体流程这篇文章有详细说明
    推送springboot编译的镜像到远程的docker服务器: https://blog.csdn.net/qq_21187515/article/details/90302026
    具体操作
    1)上传docker镜像到服务器
    2)启动容器 docker run --name countgame -d -p 8082:8082 6f0d
    3)查看容器日志 docker logs --tail 300 -f countgame

  2. 源码
    码云: https://gitee.com/zhangxinlin/countgame

你可能感兴趣的:(java)