www.pudn.com > MobiCraft_src.rar > UnitAnimator.java


// style: tabs, tabsize=4, style=ANSI 
//+----------------------------------------------------------------------+ 
// Copyright (c) 2006 Company Name 
// Made by Andrew and Zahar 
//+----------------------------------------------------------------------+ 
// Filename: UnitAnimator.java 
//+----------------------------------------------------------------------+ 
// Comment: Does all job with animated sprites of units 
//+----------------------------------------------------------------------+ 
 
package battle; 
 
import java.io.*; 
import java.util.Vector; 
import javax.microedition.lcdui.*; 
import javax.microedition.lcdui.game.*; 
 
// Создается для Каждого юнита, не для типа, а именно юнита 
class UnitAnimatorState 
{ 
    public int iType;			// Тип юнита (вид) 
    public int iState;			// Какая анимация 
	public boolean bBackward;	// 20070222 Black Для того чтобы можно было проигрывать анимацию в обратном порядке (складывание/раскладывание танка, закапывание/раскапывание) 
    public long lTime;			// Временная позиция 
} 
/*class UnitAnimActions 
{ 
    public UnitAnimatorSprite Sprite; 
    public int Start; 
    public int Length; 
}*/ 
class EffectState 
{ 
	public int iType;		// Тип эффекта 
	public long lTime;		// Временная позиция 
	public int iPosX;		// Позиция эффекта 
	public int iPosY;		//  
	public int iSpeedX;		// Скорость перемещения эффекта (px/s) 
	public int iSpeedY;		//  
	public int iTargetX;	// Конечные значения позиции спрайта (eg цель патрона) 
	public int iTargetY;	// 
	public boolean bBack;	// Лежит ли эффект под юнитами 
} 
public class UnitAnimator 
{ 
	// States for Unit class 
    public final static int ANIM_IDLE=    0; 
    public final static int ANIM_A1=      1; 
    public final static int ANIM_A2=      2; 
    public final static int ANIM_A3=      3; 
    public final static int ANIM_A4=      4; 
    public final static int ANIM_DEATH=   5; 
	public final static int ANIM_IDLE2=   6;	//20070126 Black Для закопанных Зергов и Сиеж Танка 
    public final static int ANIM_TOTAL=   7; 
	 
	// Effects (Bullets, Storm, etc.) 
	public final static int EFFECT_BULLET_DRAGOON=	0; 
	public final static int EFFECT_BULLET_VULTURE=	1; 
	public final static int EFFECT_LOCKDOWN=		2; 
	public final static int EFFECT_STORM=			3; 
	public final static int EFFECT_MATRIX=			4; 
	public final static int EFFECT_EMP=				5; 
	public final static int EFFECT_PLAGUE=			6; 
	public final static int EFFECT_IRRADIATE=		7; 
	public final static int EFFECT_BULLET_REAVER=	8; 
	public final static int EFFECT_ARCHONTHIT=		9; 
	public final static int EFFECT_LURKERHIT=		10;	// Black это вообще то не эффект, а способ создать совокупность  LURKERHIT_ONE'ов, но так надо =) 
	public final static int EFFECT_ENSNARE=			11; 
	public final static int EFFECT_LURKERHIT_ONE=	12; 
	public final static int EFFECT_TOTAL=			13; 
	 
	Vector vStates; // Все юниты. Содержит UnitAnimator_State 
	Vector vEffectStates;// Все эффекты. Содержит UnitAnimator_Effect 
    //Graphics g; 
 
    // Все для анимации ( многие указатели простаивают, ничего страшного, это лучше чем Vector тут ): 
    // Список действий, если действия такого нет ( например 2, 3, 4), то null 
    // Если ==null, то значит ещё не загружен. 
    // как правило attack 
	// Это все анимации (по одной на каждый тип юнита). Тут будут созданны только те, что нужны. 
    public UnitAnimatorSprite[][] m_pUnitAnimation; 
	// Здесь хранятся все анимации эффектов 
	public UnitAnimatorSprite[] m_pEffectAnimation; 
	 
    public UnitAnimator() 
    { 
		m_pUnitAnimation = new UnitAnimatorSprite[Unit.UNIT_TOTAL_NUMBER][]; 
		m_pEffectAnimation = new UnitAnimatorSprite[UnitAnimator.EFFECT_TOTAL]; 
		vStates = new Vector(); 
		vEffectStates = new Vector(); 
    } 
 
	public static int CoordinateToUnit ( int iPosX, int iPosY) 
	{ 
		int iUnit = -1; 
		iUnit += iPosY / 40; 
		if (iPosX <= 40) 
		{ 
			iUnit += 4 * (1 - iPosX / 40); 
		} 
		else 
		{ 
			iUnit += 8 + 4 * (iPosX - 96) / 40; 
		} 
		return iUnit; 
	} 
	public static int UnitToX (int iUnit) 
	{ 
		if ( iUnit < 8 ) 
			return (40 - iUnit/4 * 40); 
		else 
			return (96 + (iUnit - 8)/4 * 40 ); 
	} 
 
	public static int UnitToY (int iUnit) 
	{ 
		return (iUnit%4 * 40); 
	} 
 
	public int AddUnit( int iType ) throws IOException 
    { 
		UnitAnimatorState tmp = new UnitAnimatorState(); 
		tmp.iType = iType; 
		tmp.iState = ANIM_IDLE; 
		tmp.lTime = 0; 
		vStates.addElement(tmp); 
		tmp = null; 
		return (vStates.size()-1); // Number of added unit 
    } 
	 
	public int AddEffect ( int itype, int iposX, int iposY, int ispeedX, int ispeedY, int itargetX, int itargetY, boolean bback ) 
	{ 
		EffectState tmp = new EffectState(); 
		tmp.iSpeedX = ispeedX; 
		tmp.iSpeedY = ispeedY; 
		tmp.iPosX = iposX; 
		tmp.iPosY = iposY; 
		tmp.iType = itype; 
		tmp.lTime = 0; 
		tmp.iTargetX = itargetX; 
		tmp.iTargetY = itargetY; 
		tmp.bBack = bback; 
		vEffectStates.addElement(tmp); 
		tmp = null; 
		return 0; 
	} 
	 
    public void LoadAnim( int iType, int anim) throws IOException // iType - тип юнита, anim - тип анимации 
    { 
		if (iType <0 ) 
			return; // UNIT_NONE == -1; 
		 
		if (m_pUnitAnimation[iType] == null ) 
		{ 
			m_pUnitAnimation[iType] = new UnitAnimatorSprite[ANIM_TOTAL]; 
			for (int i=0; i= act.mLength ) 
		{ 
			if ( ( ( tmp.iType == Unit.UNIT_T_TANK ) && ( tmp.iState == ANIM_A2 ) ) || ( ( tmp.iType == Unit.UNIT_Z_LURKER ) && ( tmp.iState == ANIM_A1 ) ) ) //20070126 Black При альтернативной стрельбе танк возвращается обратно в сиеж. Люр возвращается в закопанность 
			{ 
				SetState( i, ANIM_IDLE2 ); 
			} 
			else 
				SetState( i, ANIM_IDLE ); 
		} 
    } 
 
    // Change state of sprite by some seconds 
    public void Draw(int i, Graphics g, int x, int y, boolean bmirror) 
    { 
		if ( (i<0) || (vStates.size() <= i) ) 
			return; 
		UnitAnimatorState tmp = (UnitAnimatorState)vStates.elementAt(i); 
		 
		if ( m_pUnitAnimation[tmp.iType][tmp.iState] == null) 
			return; // Error 
		UnitAnimatorSprite act = m_pUnitAnimation[tmp.iType][tmp.iState]; 
		//20070222 Black 
		if (tmp.bBackward) 
			act.setFrame( act.mLength - 1 - (int)( tmp.lTime/act.mDelay) ); 
		else 
			act.setFrame( (int)( tmp.lTime/act.mDelay) ); 
		act.Draw(g, x, y, bmirror); 
		act = null; 
		tmp = null; 
    } 
	 
	public void EffectsDoTimeStep (long dt) 
	{ 
		for ( int i = 0; i < vEffectStates.size(); i++ ) 
		{ 
			EffectState tmp = (EffectState)vEffectStates.elementAt(i); 
			tmp.lTime += dt;			 
			if ( Math.abs((int)(tmp.iSpeedX * tmp.lTime / 1000)) > Math.abs(tmp.iTargetX - tmp.iPosX) ) 
			{ 
				vEffectStates.removeElementAt(i); 
				return; 
			} 
			if (tmp.iType == UnitAnimator.EFFECT_LURKERHIT_ONE && (tmp.lTime>=600)) 
			{ 
				vEffectStates.removeElementAt(i); 
				return; 
			}				 
		} 
	} 
	 
	public void EffectsDraw (Graphics g, boolean bBack) 
	{ 
		for ( int i = 0; i < vEffectStates.size(); i++ ) 
		{ 
			EffectState tmp = (EffectState)vEffectStates.elementAt(i); 
			if (bBack == tmp.bBack) 
			{ 
				UnitAnimatorSprite act = m_pEffectAnimation[tmp.iType]; 
				act.setFrame( (int)( (tmp.lTime % (m_pEffectAnimation[tmp.iType].mLength * m_pEffectAnimation[tmp.iType].mDelay) )/act.mDelay) ); 
				act.Draw(g, (int)(tmp.iPosX + tmp.iSpeedX * tmp.lTime / 1000), (int)(tmp.iPosY + tmp.iSpeedY * tmp.lTime / 1000), (tmp.iSpeedX < 0) ); 
			} 
		} 
	} 
}