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) );
}
}
}
}