卡牌,技能(2)

接下来是技能了,技能其实是一个主要业务逻辑组成部分,游戏的推动就是依靠技能的使用来实现的。技能的调用实质是调用卡牌的被攻击方法。

技能分单体,群体技能。所以我们需要建立一个虚基类,将必须实现的业务的方法设成虚函数,由子类去实现;

以下是具体代码,在这个类中,我们保存了全部的技能组,同样因为后期可能会对技能进行扩充,可能会有修改技能的方法,所以获取的技能亦然是副本。

副本的获取有两种。第一如我下面写的,使用覆盖clon方法来实现,优点是相当简单,只要它的子类实现这个方法即可,缺点是每个子类都要实现。

第二种,使用反射,当子类相当多的时候,可以使用反射获取构造函数来创建,优点是一次实现,子类就不需要管了。确点是构造函数要求参数相同。一种弥补措施是只使用一个构造函数。

注意:两个具体实现类的构造函数本应该使用protected(利于继续派生)或者private,这时使用反射生成对象方法应该修改(原本的只能获取public的)。

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import config.Config;
import config.SkillConfig;

public abstract class Skill extends GameUni {
	/** 构造函数 **/
	public Skill(int id, String name, int att) {
		super(id, name, att);
	}

	/** 最大技能数 **/
	private final static int MAX_SKILLS;
	/**所有的技能**/
	private final static Skill[] SKILL_ALL;
	/**用于根据名字查找id,预留**/
	private final static Map<String, Integer> SKILL_MAP;

	static {
		/**这一段同样可以先不看,可以先建立固定的数组,测试通过以后再反射使用**/
		// 使用反射创建新实例
		Map<String, ArrayList<String[]>> skillMap = Config.SKILLS.getSkillMap();
		SKILL_ALL = new Skill[Config.SKILLS.getSkillCoutn()];
		MAX_SKILLS = SKILL_ALL.length;
		SKILL_MAP = new HashMap<String, Integer>();
		Set<String> classes = skillMap.keySet();
		int id = 0;
		for (String className : classes) {
			ArrayList<String[]> primers = skillMap.get(className);
			try {
				Class clazz = Class.forName(className);
				Constructor<Skill> cons = clazz.getConstructor(int.class,
						String.class, int.class);
				for (String[] primer : primers) {
					assert primer.length == SkillConfig.Primer_COUNT;
					SKILL_ALL[id] = cons.newInstance(id++, primer[0],
							Integer.parseInt(primer[1]));
					SKILL_MAP.put(SKILL_ALL[id-1].getName(), SKILL_ALL[id-1].getId());
				}
			} catch (ClassNotFoundException e) {
				System.err.println("找不到类:" + className);
				continue;
			} catch (NoSuchMethodException e) {
				System.err.println("找不到此构造函数:" + e.getMessage());
				continue;
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
	}
	/**这是攻击某一张卡牌的方法,只提供给子类使用和复写**/
	protected void attact(Card card) {
		// TODO
		card.attacked(getAtt());
		System.out.println("card:" + getName() + "攻击了" + card.getName());
	}
	/**唯一获取实例的方法,通过各自的clone()来实现**/
	public static Skill getSkill(int id) {
		return (Skill) SKILL_ALL[id].clone();
	}
	/**通过名字查找Id的方法,这是提供给card根据配置文件实例化时调用的**/
	public static int getSkillIdFromName(String name) {
		return SKILL_MAP.get(name);
	}
	/**为了创建新实例而用的**/
	@Override
	abstract protected Object clone();
	/**外部调用的方法**/
	abstract public void attack(List<Card> cards);
}

以下是两种不同的技能的实现,单体和群体。以后的技能类都可以在这些类上进行继承,群体技能类也可以不继承基类,直接基础单体攻击的类

import java.util.List;

public class SingleSkill extends Skill{
	/**构造**/
	public SingleSkill(int id,String name, int act) {
		super(id, name, act);
	}
	
	/**特定的实现,供外部调用**/
	@Override
	public void attack(List<Card> cards) {
		//TODO 确定攻击目标
		assert cards!=null;
		for(Card card:cards) {
			if(!card.isDaeth()) {
				card.attacked(getAtt());
				break;
			}
		}
	}
	/**供建立此对象的副本时使用**/
	@Override
	protected Object clone() {
		return new SingleSkill(getId(), getName(), getAtt());
	}
	
	/**这是控制台界面时的显示用**/
	@Override
	public String toString() {
		return "SingleSkill [=" + super.toString() + "]";
	}
}


public class GroupSkill extends Skill{
	public GroupSkill(int id, String name, int act) {
		super(id, name, act);
	}
	@Override
	public void attack(List<Card> cards) {
		for(Card card:cards) {
			if(!card.isDaeth()) {
				card.attacked(this.getAtt());
			}
		}
	}
	@Override
	public String toString() {
		return "GroupSkill [" + super.toString() + "]";
	}
	@Override
	protected Object clone() {
		return new GroupSkill(getId(), getName(), getAtt());
	}
}
以上,技能就写完了。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值