《英雄对决》这个游戏是课堂示例的一个扩展版本,因为写这个游戏的时候刚学到对象、继承等,所以这个游戏其实是一个文字游戏。编程方面现在学的不多,但是没有想到的是我居然可以把我想要的效果都可以做出来。
如果你想要多了解这个游戏,可以看以下的视频。
游戏简介:
《英雄对决》是一个可以选择英雄,购买装备,购买技能的英雄PK型文字游戏。游戏开始时提示现有英雄有哪些,并且输出英雄属性。玩家选择英雄。选择英雄后,每个玩家有一定的金币数量可以购买装备和技能。装备永久的为英雄增加属性,技能每回合英雄可以使用。技能使用会消耗技能点,每个技能消耗的技能点数不同。英雄第一回合只有1点技能点,随着回合数的增加,英雄每回合增加1点技能点。
攻击阶段,英雄使用技能,使用技能后自动进入攻击阶段。
游戏难点总结:
游戏编写过程中遇到的一个问题就是,如何让玩家选择英雄。如何才能够根据玩家的输入定向的new一个新的英雄出来,而且这种方法可以根据英雄数量的增加随时的增添英雄。
由于是第一次制作游戏,我选择了一种及其笨重的方法让用户选择英雄。
首先我新建了一个类,这个类只有一个英雄数组的成员,他只有一个功能就是创建一个数组用来存放不同的英雄。我给这个类取名叫做Heros,就好像是一个英雄的酒店一样,里面住满了不同的英雄。我只需要玩家的输入,将玩家指向该英雄酒店【Heros】的某一个房间就可以了。
代码:Heros
package Hero;
public class Heros {
private Hero[] heros;
public Hero[] getHeros() {
return heros;
}
public void setHeros(Hero[] heros) {
this.heros = heros;
}
public Heros(){
this.setHeros(new Hero[3]);
this.getHeros()[0] = new Berserker();
this.getHeros()[1] = new Saber();
this.getHeros()[2] = new Lancer();
}
}
虽然这种方法可以解决选择英雄的问题,但是当我真正的选择英雄的时候我又发现了另外的一个问题,而且是一个非常严重的问题。我发现我必须为每一个玩家都要建造一个英雄酒店【Heros】。而且每个英雄酒店【Heros】必须包含现有的所有英雄。
为什么必须建造两个英雄酒店【Heros】呢?因为如果我不建造两个英雄酒店【Heros】,那么我就不能让不同的玩家选择相同的英雄。因为我的做法其实就是让玩家在英雄酒店【Heros】中为一个英雄翻牌,如果不同的玩家为同一个英雄翻牌了其实就是为同一个英雄翻牌,就是不同的玩家选择了同一个在实际内存中的同一个对象。这不就变成了两个玩家操纵同一个角色在玩游戏吗?
所以我只有选择再建造一个英雄酒店【Heros】,这样不同的玩家即便选择都是Saber,那么他们都不是实际内存中的同一个对象。这看起来解决了选择英雄的难题。但是在这个背后有一个实际的难题就是,内存浪费。每一个玩家实际都是只需要一个英雄进行游戏,但是每一个玩家实际拥有所有的英雄的内容。我现在只有3个英雄,两个玩家就浪费了4个英雄对象所占的内存。要是我有100个英雄呢?或者要是我有1000个英雄呢?这很显然是一个不经济的解决方法。
解决方案
其实解决方法很简单,就是不要创建英雄酒店【Heros】,直接写方法,根据用户的的输入创建【new】英雄。但是背后的思想是值得深入思考的,就是尽量少用对象去解决问题,多思考如何使用方法。
/**
* 選擇一個英雄
*
* @param num
* 英雄编号
* @return 对应编号的英雄
*/
public Hero chooseAHero(String num) {
switch (num) {
case "1":
return new Berserker();
case "2":
return new Lancer();
default:
return null;
}
}
比如我发现在游戏中引入【控制器】的概念后,为我自己节省了很多的思考。
1.【控制器】让编写更专注
【控制器】其实就是指挥英雄们做出一定行为【方法】的指挥官。让一个英雄做出一定的行为【方法】,其实可以在英雄的方法中编写的。但是【控制器】的好处就是,它让我在思考英雄应该是怎么样的时候不用去思考英雄应该做什么,让我在思考游戏流程是怎么样的时候不用思考英雄已经自己可以做什么了。写英雄就单纯的写英雄的属性,写游戏流程就单纯的写游戏流程。
2.【控制器】减少方法数量,使相同功能的方法更集中
如果我想要写一个输出游戏对象信息的函数,如果不使用控制器,那么我可能要在Hero类里面编写一个print方法,又要在Equipment类中再写一个print方法,最后还要在Skill类中写一个方法。这样print方法的分布就很分散。
但是如果我在控制器中编写print方法的话,我就可以写很多的重载,根据参数列表的不同输出不同的信息。
/**
* 输出所有英雄的信息
*/
public void printHeros() {
System.out.println("編號:1");
this.print(this.chooseAHero("1"));
System.out.println("編號:2");
this.print(this.chooseAHero("2"));
}
/**
* 输出技能的信息
*
* @param skill
*/
public void print(Skill skill) {
System.out.println(skill.getName() + "\t" + "价格" + skill.getPrice() + "\t" + "消耗:" + skill.getUseNumOfPoint());
System.out.println("攻击力加成:" + skill.getAddDamagePower() + "\t" + "防御力加成:" + skill.getAddDefence() + "\t"
+ "血量值加成:" + skill.getAddHp());
System.out.println("暴击力加成:" + skill.getAddCritDamage() + "\t" + "暴击率加成:" + skill.getAddCritOdds() + "\t"
+ "闪避率加成:" + skill.getAddDodgeOdds());
this.print_();
}
《英雄对决》这个文字游戏现在还有很多的问题,今天也只是简单的总结了一下。我会继续修改《英雄对决》,每一次的修改都会将源代码发布,有兴趣的同学可以去下载。