⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit.java

📁 用java开发的一个实施策略游戏源码 值得学习一下
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		}
	}
	
	//The remaining methods are intended to be over-rided by sub-classes of Unit.
	//The default version of think() may suffice for many (all?) units.
	/** Returns the number of frames needed to move forward one hex.
	 * @return How many frames it takes to move one hex.
	 */
	protected abstract int framesToMove();
	/** Returns the number of frames needed to rotate one hex-side.
	 * @return How many frames it takes to rotate sixty degrees.
	 */
	protected abstract int framesToRotate();

	/** Do the processing for a frame of animation while moving forward. */
	protected abstract void animateMove();
	/** Do the processing for a frame of animation while rotating left. */
	protected abstract void animateRotateLeft();
	/** Do the processing for a frame of animation while rotating right. */
	protected abstract void animateRotateRight();

	/** Think about what to do. Called by Update() when the Unit is sitting around, or just finished doing something (such as moving one hex or rotating one hex-side).
	 * Default version scans for enemies if in Guard Mode (changing to Pursuit Mode if one is detected),
	 * then figures out a direction to move if it has a destination.
	 */
	protected void think() {
		//Decide where to go next. Reserve an adjacent hex if plausible.
		
		//First, if a target is chosen, untarget it if it is dead
		if(target != null && target.isDead()) {
			target = null;
			targetSSMDS = null;
			if(mode == 2)
				mode = 0;
		}
		
		int fChg = 0;
		Hex next = null;
		if(mode == 0) {
			target = scan();
			if(target == null) {
				resX = x; resY = y;
				action = 0;
				return; //don't go anywhere
			}else{
				mode = 2;
				targetSSMDS = firstSSMDS.getTarget(this, target);
			}
		}
		if(mode == 1) // Go toward destination
			resF = bestDirection(goalX,goalY); //Change arguments to control destination
		if(mode == 2) // Pursue target
		{
			int fol = followRange();
			goalX = target.x;
			goalY = target.y;
			confirmSubPlan(goalX,goalY);
			resF = bestDirection(goalX,goalY);
			if((fol >= goalX - x) &&
			   (fol >= x - goalX) &&
			   (fol >= goalY - y) &&
			   (fol >= y - goalY) &&
			   (fol >= goalX - x - goalY + y) &&
			   (fol >= x - goalX - y + goalY)) {
				if(resF == f) {
					action = 0;
				}else{
					if((resF - f > 0 && resF - f < 3) || resF - f < -3){
						//rotate left
						action = 1; frame = framesToRotate();
					}else{
						//rotate right
						action = 2; frame = framesToRotate();
					}
				}
				resX = x; resY = y;
				return;
			}
		}
		switch(traceMode)
		{
			case 0:
				while(true){
					switch(resF){
						case 0: resX = x + 1;	resY = y + 1;	break;
						case 1: resX = x;	resY = y + 1;	break;
						case 2:	resX = x - 1;	resY = y;	break;
						case 3: resX = x - 1;	resY = y - 1;	break;
						case 4:	resX = x;	resY = y - 1;	break;
						case 5:	resX = x + 1;	resY = y;	break;
					}
					next = Hex.getHex(resX, resY);
					if(next != null && next.reserve())
						break;
					if(resX == goalX && resY == goalY)
					{
					    mode = 0;
					    return;
					}
					//Change resF. This causes resF to try
					//one hex-side to the left, then one to the right,
					//then two to the left, etc.
					fChg *= -1;
					fChg += (fChg == 0)?(subPlanBias):((fChg < 0)?(-1):(1));
					resF += fChg;
					if(resF < 0) resF += 6;
					else if(resF > 5) resF -= 6;

					if(fChg == 6 || fChg == -6) {//nowhere to go. Already checked all six sides.
						action = 0;
						resX = x; resY = y;
						return;
					}
				}
				fChg = resF - f;
				if(fChg == 2 || fChg == 3 || fChg == -4)
					traceMode = 1;
				else if(fChg == -2 || fChg == -3 || fChg == 4)
					traceMode = -1;
				reserved = true;
				Hex.getHex(x, y).unreserve();
			break;
			case 1:
				resF = f - 1;
				if(resF < 0) resF = 5;
				while(true){
					switch(resF){
						case 0: resX = x + 1;	resY = y + 1;	break;
						case 1: resX = x;	resY = y + 1;	break;
						case 2:	resX = x - 1;	resY = y;	break;
						case 3: resX = x - 1;	resY = y - 1;	break;
						case 4:	resX = x;	resY = y - 1;	break;
						case 5:	resX = x + 1;	resY = y;	break;
					}
					next = Hex.getHex(resX, resY);
					if(next != null && next.reserve())
						break;
					if(resX == goalX && resY == goalY)
					{
					    mode = 0;
					    return;
					}
					//Change resF. Try starting from 60 degrees right leftward.
					resF += 1;
					if(resF > 5) resF -= 6;

					if(resF == f - 1 || resF == f + 5) {//nowhere to go. Already checked all six sides.
						action = 0;
						resX = x; resY = y;
						return;
					}
				}
				confirmSubPlan(goalX,goalY);
				if(resF == bestDirection(goalX,goalY));
					traceMode = 0;
				reserved = true;
				Hex.getHex(x, y).unreserve();
			break;
			case -1:
				resF = f + 1;
				if(resF > 5) resF = 0;
				while(true){
					switch(resF){
						case 0: resX = x + 1;	resY = y + 1;	break;
						case 1: resX = x;	resY = y + 1;	break;
						case 2:	resX = x - 1;	resY = y;	break;
						case 3: resX = x - 1;	resY = y - 1;	break;
						case 4:	resX = x;	resY = y - 1;	break;
						case 5:	resX = x + 1;	resY = y;	break;
					}
					next = Hex.getHex(resX, resY);
					if(next != null && next.reserve())
						break;
					if(resX == goalX && resY == goalY)
					{
					    mode = 0;
					    return;
					}
					//Change resF. Try starting from 60 degrees left rightward.
					resF -= 1;
					if(resF < 0) resF += 6;

					if(resF == f + 1 || resF == f - 5) {//nowhere to go. Already checked all six sides.
						action = 0;
						resX = x; resY = y;
						return;
					}
				}
				confirmSubPlan(goalX,goalY);
				if(resF == bestDirection(goalX,goalY));
					traceMode = 0;
				reserved = true;
				Hex.getHex(x, y).unreserve();
			break;
		}
	}
	
	/** Returns the number of Hexes to get within if in Pursuit Mode.
	 * As long as the Unit is this close to its target, it will remain stationary and fire.
	 * This allows long range Units to abuse their range advantage by staying back while firing.
	 * @return The range to approach to, in hexes.
	 */
	public abstract int followRange();

	/** Returns The maximum value of health for this Unit, which is the initial value for health.
	 * @return The amount of damage that must be taken to destroy the Unit.
	 */
	protected abstract int maxHealth();
	/** Returns the number of damage points to be ignored from each hit.
	 * Under standard health/armor rules, a unit cannot take less than 1 damage per hit.
	 * @return The armor value of the unit.
	 */
	protected abstract int armor();
		
	/** Applies damage to this Unit, possibly destroying it.
	 * This version uses the standard health/armor rules:
	 * <BR> A unit starts with a fixed amount of health and cannot exceed that amount.
	 * <BR> A unit has a (fixed ?) amount of armor.
	 * <BR> When a unit is hit by an attack, it loses health equal to the damage minus the armor, but a minimum of one.
	 * <BR> The unit is destroyed if it drops below 1 health.
	 */
	public void recieveDamage(int dam) {
		if(dam > 0) //Presume possibility of healing 'weapons'
		{
			dam -= armor();
			if(dam <= 0) dam = 1;
		}
		health -= dam;
		if(health > maxHealth()) health = maxHealth();
		if(health <= 0) {
			action = 5;
			frame = framesToDie();
                        ((netwar.gui.NetwarPanel)netwar.Netwar.netwar.getDataViewer()).unitKilled(myPlayer.getNumber());
		}
                if (((netwar.gui.NetwarPanel)netwar.Netwar.netwar.getDataViewer()).selectedUnitIDMatch(getID()))
                        ((netwar.gui.NetwarPanel)netwar.Netwar.netwar.getDataViewer()).updateUnitHealth(health);
	}
	
	/** Make applicable adjustments, then return true if the target is within the firing arc.
	 * The default version assumes that the Unit has a 120-degree firing arc, centered at the
	 * last hex-side it was facing, and the Unit does not have an independant turret.
	 * If the unit has an independant turret, it should override aim, and use aim to
	 * rotate the turret.
	 * @return True if the target is in the firing arc.
	 */
	protected boolean aim(){
		if(target == null) return false;
		if(target.myPlayer == myPlayer)
			return false; //Don't shoot at own units, just follow them.
		if(target.isDead()) {
			target = null;
			targetSSMDS = null;
			if(mode == 2)
				mode = 0;
			return false;
		}
		int gx = target.x;
		int gy = target.y;
		int dxy;
		gx -= x;
		gy -= y;
		dxy = gx - gy;
		switch(f) {
			case 0:
				if(gx <= 0 || gy <= 0) return false;
			break;
			case 1:
				if(gy <= 0 || dxy >= 0) return false;
			break;
			case 2:
				if(dxy >= 0 || gx >= 0) return false;
			break;
			case 3:
				if(gx >= 0 || gy >= 0) return false;
			break;
			case 4:
				if(gy >= 0 || dxy <= 0) return false;
			break;
			case 5:
				if(dxy <= 0 || gx <= 0) return false;
			break;
		}
		return true;
	}
	
	/** Return True iff the Unit is already destroyed.
	 * Destuction occurs when health drops below 1.
	 * @return True if healt <= 0.
	 */
	public boolean isDead() {
		return (health <= 0);
	}
	
	/** Return True if the Unit can be damaged.
	 * The Unit can be damaged if it is not yet destroyed.
	 * @return True if health > 0.
	 */
	public boolean damageable() {
		return (health > 0);
	}
	
	public boolean repairable() {
		return (health > 0 && health < maxHealth());
	}

	public boolean paralyzable() {
		return (health > 0 && stun == 0);
	}
	public void recieveParalysis(int level) 
	{
		if(stun == 0)
			stun = level;
	}


	
        static final String[] PROPERTIES = {"Name", "Health", "Max Health", "Armor", "Following Range", "Moving Speed", "Rotating Speed"};
        protected String[] PROPERTIES() {
            return PROPERTIES;
        }
        protected String getProperty(int p) {
            switch(p) {
                case 0:
                    String name = getClass().getName();
                    return name.substring(name.lastIndexOf(".")+1);
                case 1:
                    return Integer.toString(health);
                case 2:
                    return Integer.toString(maxHealth());
                case 3:
                    return Integer.toString(armor());
                case 4:
                    return Integer.toString(followRange());
                case 5:
                    return Integer.toString(framesToMove());
                case 6:
                    return Integer.toString(framesToRotate());
                default:
                    Assert.notFalse(false, "getProperty(int) error.");
            }
            return null;
        }
        public float getStatusFraction() {
                return (float) health / maxHealth();
        }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -