文章目录
项目分析
QuickHit 游戏考验你键盘输入的速度和准确性。
根据输入速度和正确率将玩家分为不同级别,级别越高,一次显示的字符数就越多,玩家
正确输入一次的得分也越高。如果玩家在规定时间内完成规定次数的输入,正确率达到
规定要求,则玩家升级(为了简单起见,规定用户错误输入一次,游戏结束)。
玩家最高级别为六级,初始级别一律为一级
QuickHit游戏的设计主要是面向对象的程序设计,用到了抽象,封装,继承和多态。
在做这道题的时候,首先你得理清楚它的思路,比如说它涉及到了对象,对象的属性,实现的方法等等。
代码实现
玩家类
package cn.kgc.kb03.quickhit; /** * @作者:BeiisBei * @时间:2019/9/3 * @目的: */ import java.util.Scanner; //玩家类 public class Player { private int levelNo; //玩家当前级别 private int currScore; //玩家当前积分 private long startTime; //玩家当前开始时间 private int elapsedTime; //当前级别已用时间 public int getLevelNo() { return levelNo; } public void setLevelNo(int levelNo) { this.levelNo = levelNo; } public int getCurrScore() { return currScore; } public void setCurrScore(int currScore) { this.currScore = currScore; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } public int getElapsedTime() { return elapsedTime; } public void setElapsedTime(int elapsedTime) { this.elapsedTime = elapsedTime; } /** * 玩家类的方法play() * 玩家玩游戏 */ public void play() { Scanner input=new Scanner(System.in); Game game=new Game(this); //this--->指当前对象的引用,传入的值是当前Player类(现在没创建对象)以后创建对象的引用。 //外层循环一次,等级加1 for(int i = 0; i<LevelParam.levels.length; i++) { //等级加1 this.levelNo+=1; //积分清0 this.currScore=0; //计时清0 this.startTime=System.currentTimeMillis(); //获得每个级别对应的字符串输入字数 int strLength=LevelParam.levels[levelNo-1].getStrTime(); //内层循环一次,判断玩家输入的字符串 for(int k=0;k<strLength;k++) { //游戏输出字符串 String out=game.printStr(); //玩家输入 String in=input.next(); //判断玩家输入的字符串,并输出相应结果 game.printResult(out, in); } } } }
游戏类
package cn.kgc.kb03.quickhit; /** * @作者: * @时间:2019/9/3 * @目的: */ import java.util.*; //游戏类 public class Game { public Player play; //玩家 /*** * 构造方法 */ public Game(Player play) { this.play = play; } /*** * 生成字符串,输出字符串,返回字符串用于和玩家的输入进行比较 * @return */ public String printStr() { StringBuffer sbu=new StringBuffer(); //StringBuffer类,字符串缓冲区,添加字符串 Random rand=new Random(); //产生随机数类 //根据相应的等级,来获得相应的输入次数 int strLength=LevelParam.levels[play.getLevelNo()-1].getStrLength(); for(int i=0;i<strLength;i++) { int randNum=rand.nextInt(strLength); //产生随机数 switch(randNum) { case 0: sbu.append(">"); //append方法的作用是在一个StringBuffer对象后面追加字符串 break; case 1: sbu.append("<"); break; case 2: sbu.append("!"); break; case 3: sbu.append("#"); break; case 4: sbu.append("@"); break; case 5: sbu.append("%"); break; case 6: sbu.append("&"); break; case 7: sbu.append("*"); break; case 8: sbu.append("~"); break; case 9: sbu.append("?"); break; } } System.out.println(sbu); //输出字符串 return sbu.toString(); //返回字符串 } /** * 比较游戏输出out,和玩家输入in,根据比较结果输出相应信息 * */ public void printResult(String out, String in) { //输入正确 if(out.equals(in)) { //system.currentTimeMillis()的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。 long currentTime=System.currentTimeMillis(); //如果超时 if((currentTime-play.getStartTime())/1000>LevelParam.levels[play.getLevelNo()-1].getTimeLimit()) { System.out.println("你输入的太慢了,已经超时,退出!"); System.exit(1); } //如果没有超时 //计算玩家当前的积分 play.setCurrScore(play.getCurrScore()+LevelParam.levels[play.getLevelNo()-1].getPerScore()); //计算已用时间 play.setElapsedTime((int)(currentTime-play.getStartTime())/1000); //输出玩家当前级别,当前积分,已用时间 System.out.println("输入正确,你的级别是:"+play.getLevelNo()+",你的积分是:"+play.getCurrScore()+",已用时间:"+play.getElapsedTime()+"秒!"); //判断用户是否已经闯过最后一关:等级为6,玩家获得的积分==通过所需要的分数(次数*每次的分数) if(play.getLevelNo()==6) { //获得通关所需要的分数 int score=LevelParam.levels[play.getLevelNo()-1].getPerScore()*LevelParam.levels[play.getLevelNo()-1].getStrTime(); if(score==play.getCurrScore()) { System.out.println("恭喜你,通关了~"); System.exit(0); } } }else { //输入错误 System.out.println("输入错误,退出!"); System.exit(1); } } }
级别类
package cn.kgc.kb03.quickhit; /** * @作者: * @时间:2019/9/3 * @目的: */ //级别类 public class Level { private int levleNo; //各级别编号 private int strLength; //各级别一次输出字符串长度 private int strTime; //各级别输出字符串的次数 private int timeLimit; //各级别闯关时间限制 private int perScore; //各级别输入正确一次的得分 public int getLevleNo() { return levleNo; } public void setLevleNo(int levleNo) { this.levleNo = levleNo; } public int getStrLength() { return strLength; } public void setStrLength(int strLength) { this.strLength = strLength; } public int getStrTime() { return strTime; } public void setStrTime(int strTime) { this.strTime = strTime; } public int getTimeLimit() { return timeLimit; } public void setTimeLimit(int timeLimit) { this.timeLimit = timeLimit; } public int getPerScore() { return perScore; } public void setPerScore(int perScore) { this.perScore = perScore; } public Level(int levleNo, int strLength, int strTime, int timeLimit, int perScore) { super(); this.levleNo = levleNo; this.strLength = strLength; this.strTime = strTime; this.timeLimit = timeLimit; this.perScore = perScore; } }
玩家级别参数类
package cn.kgc.kb03.quickhit; /** * @作者: * @时间:2019/9/3 * @目的: */ //玩家级别参数类 public class LevelParam { //对应玩游戏的6个级别 public final static Level levels[]=new Level[6]; //static属性属于该类所有,既由该类创建的所有对象共用同一个static属性。 //static代码块的用法:当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。 static { levels[0]=new Level(1,2,6,56,1); levels[1]=new Level(2,3,5,56,2); levels[2]=new Level(3,4,4,46,5); levels[3]=new Level(4,5,3,36,8); levels[4]=new Level(5,6,2,26,10); levels[5]=new Level(6,7,1,16,15); } }
测试类
package cn.kgc.kb03.quickhit; /** * @作者: * @时间:2019/9/3 * @目的: */ //测试类 public class Test { public static void main(String[] args) { Player p = new Player(); p.play(); } }
项目总结
1.类继承的注意点:类的构造方法是不可以被继承的;虽然不能继承构造方法,但是我们可以 在子类的构造方法中 通过关键字 super 来调用到 父类的构造方法
2.构造方法一旦程序员自己给定了,那么jvm不再提供默认的 无参构造方法;
3.abstract关键字的注意点:
(1)不可以和final关键字一起使用,因为abstract关键字 是要求子类一定要重写父类的方法,但是final是不允许重写的;
(2)不可以和private关键字一起使用,因为private是私有的,不能被继承的内容,代表根本不存在方法重写,因此不能一起使用;
(3)不可以和static一起使用,因为static是静态修饰符,代表不需要实例化对象,直接用类名就可以调用方法, 那么如果是抽象方法,没有方法实现调用方法会出错,所以编译 器禁止 abstract和static一起使用
4.多态的三要素:
(1)一定要有继承
(2)一定要重写
(3)父类的指针,指向子类的对象。