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)父类的指针,指向子类的对象。