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

📄 actor.java

📁 一个j2me游戏代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package pop2;

import javax.microedition.lcdui.*;
import java.io.*;

/**
 * <p>Title: POP2</p>
 * <p>Description: Prince of Persia 2</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: UBI soft (Beijing)</p>
 * @author Cao Heng
 * @version 1.0
 */
public class Actor
{
	final static int FLAG_FLIPX = 0x01;
	final static int FLAG_FLIPY = 0x02;
	final static int FLAG_IGNORE = 0x04;
	final static int FLAG_ACTIVE = 0x08;
	// class
	Animation m_anim;
	int m_animID;
	// these varibles have low 8 bits as fraction
	int m_posX; // X position
	int m_posY; // Y position
	int m_vX; // X velocity
	int m_vY; // Y velocity
	int m_aX; // X acceleration
	int m_aY; // Y acceleration

	int m_grabPosX; // X position of grab tile point
	int m_grabPosY; // Y position of grab tile point

    //boolean m_inActiveZone; // actor is in active zone
    //short[] m_activeZone = new short[4]; // left, top, right, bottom

	boolean m_flag[] = new boolean[4]; // flipX, flipY, ignore active zone, active
	byte[] m_parameters; // parameters

	byte m_phbLeft; // left phb of player
	byte m_phbTop; // top phb of player
	byte m_phbRight; // right phb of player
	byte m_phbBottom; // bottom phb of player

	int m_frameIndex;
	int m_actionIDNow;
	int m_frameIDNow;
	byte m_durNow;
	boolean m_actionNoCycle;
	boolean m_actionOver;
	byte[] m_colBoxNow;

	Actor m_relativeMisc;

	// parameter
	int m_hp, m_maxhp;
	int m_start1/*bornx*/, m_start2/*borny*/;
	int m_counter; // HM: 0-strike 1-trust BM: 0-fire1 1-fire2 PRINCE:invincible
	final int RECOVER_TIME = 45;
	//static Random rand = new Random(System.currentTimeMillis());

	public Actor()
	{
	}

	public void loadActor(byte[] data, int offset)
	{
		offset += 2; // actor data size
		m_animID = data[offset++];
		m_anim = Player.m_anims[m_animID];
		m_actionIDNow = data[offset++];
		int flag = data[offset++];
		m_flag[0] = (flag & FLAG_FLIPX) != 0;
		m_flag[1] = (flag & FLAG_FLIPY) != 0;
		m_flag[2] = (flag & FLAG_IGNORE) != 0;
		m_flag[3] = (flag & FLAG_ACTIVE) != 0;
        int nPara = data[offset++];
		m_posX = GE.readUnsignedShort(data, offset) << 8;
		offset+=2;
		m_posY = GE.readUnsignedShort(data, offset) << 8;
		offset+=2;
		offset+=8; // activeZone
		if (nPara > 0)
		{
			m_parameters = new byte[nPara];
			System.arraycopy(data, offset, m_parameters, 0, nPara);
		}
		setAction(m_actionIDNow, 1);
		initAI();
	}
	public void packActor(byte[] data, int offset)
	{
		offset+=3; // actor data size & actor anim ID
		if (m_animID != Def.ID_SAW && m_animID != Def.ID_NAIL)
        {
            if (m_animID == Def.ID_SANDMAN)
            {
                if (m_actionIDNow == Def.SANDMAN_BM_DEAD)
                {
                    if (m_start1 != 0 && m_start2 != 0)
                        m_actionIDNow = Def.SANDMAN_HM_GUARD;
                    else
                        m_actionIDNow = Def.SANDMAN_HM_WALK;
                }
                else if(m_actionIDNow == Def.SANDMAN_HM_DEAD)
                    m_actionIDNow = Def.SANDMAN_BM_GUARD;
                else if(m_actionIDNow == Def.SANDMAN_SMOKE)
                    m_flag[3] = false;

                data[offset] = (byte)m_actionIDNow;
            }
            else if(m_animID == Def.ID_GHOST)
                data[offset] = Def.GHOST_SLEEP;
            else
                data[offset] = (byte)m_actionIDNow;
        }
		offset++;
		byte flag = 0;
		if (m_flag[0]) flag += FLAG_FLIPX;
		if (m_flag[1]) flag += FLAG_FLIPY;
		if (m_flag[2]) flag += FLAG_IGNORE;
		if (m_flag[3]) flag += FLAG_ACTIVE;
		data[offset++] = flag;

		if (m_animID == Def.ID_SAW || m_animID == Def.ID_NAIL || m_animID == Def.ID_GHOST)
			return;
		offset++; // npara
		int temp = m_posX >> 8;
		data[offset++] = (byte)(temp >> 8);
		data[offset++] = (byte)temp;
		temp = m_posY >> 8;
		data[offset++] = (byte)(temp >> 8);
		data[offset++] = (byte)temp;
	}

	// update actor state for each frame ---------------------------------------
	// if the actor is not been update, return false.
	boolean updateAI(int camX, int camY)
	{
		if (m_flag[3] == false)
			return false;
		if (m_frameIndex == -1)
			return false;
		switch (m_animID)
		{
		case Def.ID_SAW:
			m_posX += m_vX;
			m_posY += m_vY;
			break;
		case Def.ID_NAIL:
		case Def.ID_PRINCE:
	    case Def.ID_SANDMAN:
		case Def.ID_BOX:
			// position & velocity, these must have some limitions.
			checkEnvironment(false);
			break;
		}
		m_vX += m_aX;
		m_vY += m_aY;
		if (m_vY > 0x1000) m_vY = 0x1000;  // 16 pixel per frame
		// Enemy AI
		switch(m_animID)
		{
		case Def.ID_NAIL:		aiNail();		break;
		case Def.ID_GHOST:		aiGhost();		break;
		case Def.ID_SANDMAN:	aiSandman();	break;
		case Def.ID_SAW:		aiSaw();		break;
		case Def.ID_BOX:		aiBox();		break;
		case Def.ID_RSWORD:     aiRSword();     break;
		case Def.ID_TREADLE:    aiTreadle();	break;
		case Def.ID_BONUS:		aiBonus();		break;
		}
		return true;
	}
	// set the next action ---------------------------------
	void setAction(int actionID, int init)
	{
		m_actionOver = false;
		m_actionIDNow = actionID;//m_anim.getAction(actionID);
		if (m_actionIDNow == -1)
		{
			m_frameIndex = -1;
			m_frameIDNow = -1;
			getNewColBox();
		}
		else
		{
			m_frameIDNow = 0;
			m_durNow = 0;
			m_frameIndex = m_anim.getFrame(m_actionIDNow, m_frameIDNow);
			m_actionNoCycle = false;
			getNewColBox();
			if ((init & 0x01) > 0)
			{
				byte mechModelID = m_anim.mechModelID[m_actionIDNow];
				if ((mechModelID & 0x01) != 0)
				{
					m_vX = m_anim.mechModel[m_actionIDNow*4+0];
					if (m_flag[0]) m_vX = -m_vX;
				}
				if ((mechModelID & 0x02) != 0)
				{
					m_vY = m_anim.mechModel[m_actionIDNow*4+1];
					if (m_flag[1]) m_vY = -m_vY;
				}
				if ((mechModelID & 0x04) != 0)
				{
					m_aX = m_anim.mechModel[m_actionIDNow*4+2];
					if (m_flag[0]) m_aX = -m_aX;
				}
				if ((mechModelID & 0x08) != 0)
				{
					m_aY = m_anim.mechModel[m_actionIDNow*4+3];
					if (m_flag[1]) m_aY = -m_aY;
				}
			}
		}
		//return m_actionIDNow;
	}
	//------------------------------------------------------
	// now : true  for stop immediately
	//       false for stop when action is over
	void stopAction(boolean now)
	{
		if (now)
			m_durNow = -1;
		else
			m_actionNoCycle = true;
	}
	// calculate which frame is drawing ----------------------------------------
	int nextFrame(boolean pass)
	{
		if (m_frameIndex == -1)
			return -1;
		if (m_durNow < 0)
			return -1;
		if (pass == false)
		{
			m_durNow++;
			if (m_durNow < m_anim.getDuration(m_actionIDNow, m_frameIDNow))
				return m_frameIndex;
		}
		m_frameIDNow++;
		if (m_frameIDNow >= m_anim.nFrame[m_actionIDNow])
		{
			if (m_actionNoCycle)
	            m_frameIDNow--;
			else
	            m_frameIDNow = 0;
			m_actionOver = true;
		}
		m_frameIndex = m_anim.getFrame(m_actionIDNow, m_frameIDNow);
		getNewColBox();
		m_durNow = 0;
		return m_frameIndex;
	}
	//------------------------------------------------------
	public void draw(int camX, int camY)
	{
		camX = (m_posX >> 8) - camX;
		camY = (m_posY >> 8) - camY;
	    m_anim.draw(camX, camY, m_flag[0], m_flag[1], m_frameIndex);
		/* Lyman DEBUG, show col box & att box
		if (GE.m_Debug2 == 1)
		{
			GE.m_g.setClip(0, 0, Def.PF_WIDTH, Def.PF_HEIGHT);
			byte[] box = getColBox();
			GE.m_g.setColor(0xFFFF00);
			GE.m_g.drawRect(camX + box[0], camY + box[1], box[2] - box[0], box[3] - box[1]);
			box = getAttBox();
			if (box[0] != box[2])
			{
				GE.m_g.setColor(0xFF0000);
				GE.m_g.drawRect(camX + box[0], camY + box[1], box[2] - box[0], box[3] - box[1]);
			}
		}
		*/
		if (GE.m_msgIndex < 0 && GE.m_gameState == Def.STATE_RUN) // stop action when draw message
			nextFrame(false);
	}
	byte[] getNewColBox()
	{
		m_colBoxNow = new byte[4];
		byte[] colBox = m_anim.frameData;
		if (m_frameIndex != -1 && colBox != null)
		{
			m_colBoxNow[1] = colBox[m_frameIndex*8+1];
			m_colBoxNow[3] = colBox[m_frameIndex*8+3];
			if (m_flag[0]) // flipX
			{
				m_colBoxNow[0] = (byte)-colBox[m_frameIndex*8+2];
				m_colBoxNow[2] = (byte)-colBox[m_frameIndex*8+0];
			}
			else
			{
				m_colBoxNow[0] = colBox[m_frameIndex*8+0];
				m_colBoxNow[2] = colBox[m_frameIndex*8+2];
			}
		}
		return m_colBoxNow;
	}
	byte[] getColBox()
	{
		if (m_colBoxNow == null)
			 getNewColBox();
		return m_colBoxNow;
	}
	byte[] getAttBox()
	{
		byte[] attBox = m_anim.frameData;
		byte[] box = new byte[4];
		if (m_frameIndex != -1 && attBox != null)
		{
            box[1] = (byte)(attBox[m_frameIndex*8+4+1]);
            box[3] = (byte)(attBox[m_frameIndex*8+4+3]);
            if (m_flag[0]) // flipX
            {
                box[0] = (byte)-(attBox[m_frameIndex*8+4+2]);
                box[2] = (byte)-(attBox[m_frameIndex*8+4+0]);
            }
            else
            {
                box[0] = (byte)(attBox[m_frameIndex*8+4+0]);
                box[2] = (byte)(attBox[m_frameIndex*8+4+2]);
            }
            if (m_animID != Def.ID_PRINCE && m_animID != Def.ID_SANDMAN)
            {
                box[0] <<= 1;
                box[1] <<= 1;
                box[2] <<= 1;
                box[3] <<= 1;
            }
		}
		return box;
	}
	void setFlipX(boolean flipX)
	{
		if (m_flag[0] == flipX)
		    return;
		m_flag[0] = flipX;
		m_vX = -m_vX;
		m_aX = -m_aX;
		getNewColBox();
	}
	/*
	void activeActor(boolean active)
	{
		m_flag[3] = active;
	}//*/
	// judge if the box is intersect with this actor's attack box
	boolean intersectAttackBox(Actor actor)
	{
		return intersectBox(actor.m_posX, actor.m_posY, actor.getAttBox(), 0);
	}
	// judge if the box is intersect with this actor's box
	boolean intersectColBox(Actor actor)
	{
		return intersectBox(actor.m_posX, actor.m_posY, actor.getColBox(), 0);
	}
	// judge if the box is intersect with this actor's box
	boolean intersectBox(int x, int y, byte[] box, int extra)
	{
		if (box[0] == box[2]) return false;
		byte[] colBox = getColBox();
		//if (colBox == null) return false;
		x = (x - m_posX) >> 8;
		y = (y - m_posY) >> 8;
		if (x + box[0] > colBox[2] + extra || y + box[1] > colBox[3] + extra)
			return false;
		if (x + box[2] < colBox[0] - extra || y + box[3] < colBox[1] - extra)
			return false;
		return true;
	}

	// check the left, top , right, bottom of player, give the right position and speed
	boolean checkEnvironment(boolean v)
	{
		if (!v && m_vX == 0 && m_vY == 0)
		    return false;
        boolean checkX = (m_vX == 0);
		boolean checkY = (m_vY == 0);

		// get deltaX & deltaY
		int times = Math.max(Math.abs(m_vX / GE.m_tileWidth) >> 8, Math.abs(m_vY / GE.m_tileHeight) >> 8) + 1;
		int deltaX = m_vX / times, deltaY = m_vY / times;
		// init phb
		m_phbLeft = Def.PHB_NONE;
		m_phbRight = Def.PHB_NONE;
		m_phbTop = Def.PHB_NONE;
		m_phbBottom = Def.PHB_NONE;
		// check tile by tile
		if (checkY)
	        checkLeftRight(CHECK_CENTER, false);
        if (m_flag[0]) // prince face left, then check left first
        {
            if (checkLeftRight(CHECK_LEFT, false))
                if (deltaX < 0) deltaX = 0;
            if (checkLeftRight(CHECK_RIGHT, false))
                if (deltaX > 0) deltaX = 0;
        }
        else
        {
            if (checkLeftRight(CHECK_RIGHT, false))
                if (deltaX > 0) deltaX = 0;
            if (checkLeftRight(CHECK_LEFT, false))
                if (deltaX < 0) deltaX = 0;
        }

⌨️ 快捷键说明

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