/**
* Copyright 2008 - 2011
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* @project loonframework
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
package loon.srpg.actor;
import loon.LRelease;
import loon.LTexture;
import loon.Screen;
import loon.action.sprite.AnimationHelper;
import loon.canvas.LColor;
import loon.opengl.GLEx;
import loon.srpg.SRPGType;
public class SRPGActor implements LRelease {
private int posX, posY, tileWidth, tileHeight;
private int move_direction;
private int max_frame, frame;
private int direction, animation, changeble, actionCount;
private boolean isEnd, isAttack, isAction, isAnimation, isAutoEnd;
private boolean isVisible, isExist;
private SRPGStatus status;
private LTexture[] actionImage;
private AnimationHelper move, attack;
public SRPGActor(String name, String fileName, int index, int level,
int team, int tileWidth, int tileHeight) {
this(SRPGActorFactory.makeActorStatus(name, index, level, team),
AnimationHelper.makeRMVXObject(fileName), null, tileWidth,
tileHeight);
}
public SRPGActor(String name, int index, int level, int team,
AnimationHelper animation, int tileWidth, int tileHeight) {
this(SRPGActorFactory.makeActorStatus(name, index, level, team),
animation, null, tileWidth, tileHeight);
}
public SRPGActor(SRPGStatus status, AnimationHelper animation,
int tileWidth, int tileHeight) {
this(status, animation, null, tileWidth, tileHeight);
}
public SRPGActor(SRPGStatus status, AnimationHelper mv,
AnimationHelper atk, int tileWidth, int tileHeight) {
this.max_frame = 0;
this.frame = 0;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.move = mv;
if (atk == null) {
attack = mv;
} else {
attack = atk;
}
this.direction = SRPGType.MOVE_DOWN;
this.animation = 25;
this.changeble = animation;
this.actionCount = 0;
this.isAnimation = true;
this.isVisible = true;
this.isExist = true;
if (status != null) {
this.status = status;
} else {
this.status = new SRPGStatus();
this.isVisible = false;
this.isExist = false;
}
}
SRPGActor() {
}
/**
* 获得移动图像
*
* @param direction
* @return
*/
public LTexture[] getAnimationImages(final AnimationHelper o, final int d) {
LTexture[] result = null;
switch (d) {
// 向下移动
case SRPGType.MOVE_DOWN:
result = o.downImages;
break;
// 向上移动
case SRPGType.MOVE_UP:
result = o.upImages;
break;
// 向左移动
case SRPGType.MOVE_LEFT:
result = o.leftImages;
break;
// 向右移动
case SRPGType.MOVE_RIGHT:
result = o.rightImages;
break;
default:
result = o.downImages;
}
return result;
}
/**
* 返回当前动作图像
*
* @return
*/
public LTexture getActionImage() {
if (actionImage != null) {
return actionImage[actionCount];
}
return null;
}
/**
* 返回一副静止的角色画面
*
* @return
*/
public LTexture getImage() {
LTexture[] img = getAnimationImages(move, SRPGType.MOVE_DOWN);
if (img != null) {
return img[actionImage.length / 2];
}
return null;
}
/**
* 获得当前角色是否处于活动状态
*
* @return
*/
public boolean getStatus() {
return frame < max_frame && status != null && status.action != 0;
}
/**
* 延迟当前角色的移动
*
*/
public void waitMove() {
for (; getStatus();) {
}
}
/**
* 延迟指定Screen的刷新
*
* @deprecated
* @param screen
*/
public void waitMove(final Screen screen) {
for (; getStatus();) {
try {
screen.wait();
} catch (Exception ex) {
}
}
}
/**
* 让当前角色向指定方向移动指定帧数
*
* @param d
* @param frame
*/
public void moveActorShow(int d, int frame) {
if (getStatus()) {
return;
} else {
moveActor(d, frame);
isAnimation = true;
isAutoEnd = true;
return;
}
}
/**
* 让当前角色向指定方向移动指定帧数
*
* @param d
* @param frame
*/
public void moveActor(int d, int frame) {
if (getStatus()) {
return;
} else {
moveActorOnly(d, frame);
direction = d;
return;
}
}
/**
* 让当前角色向指定方向移动指定帧数
*
* @param d
* @param f
*/
public void moveActorOnly(int d, int f) {
if (getStatus()) {
return;
}
this.frame = 0;
this.max_frame = f;
switch (d) {
case SRPGType.MOVE_LEFT:
posX--;
break;
case SRPGType.MOVE_RIGHT:
posX++;
break;
case SRPGType.MOVE_UP:
posY--;
break;
case SRPGType.MOVE_DOWN:
posY++;
break;
}
this.move_direction = d;
}
/**
* 查询指定X,Y坐标所对应的移动方向
*
* @param x
* @param y
* @return
*/
public int findDirection(int x, int y) {
int nx = x - posX;
int ny = y - posY;
int tx = nx;
int ty = ny;
if (tx < 0) {
tx *= -1;
}
if (ty < 0) {
ty *= -1;
}
if (tx > ty) {
return nx >= 0 ? SRPGType.MOVE_RIGHT : SRPGType.MOVE_LEFT;
}
if (tx < ty) {
return ny >= 0 ? SRPGType.MOVE_DOWN : SRPGType.MOVE_UP;
}
if (nx < 0 && ny < 0) {
if (direction == SRPGType.MOVE_RIGHT) {
return SRPGType.MOVE_UP;
}
if (direction == SRPGType.MOVE_DOWN) {
return SRPGType.MOVE_LEFT;
}
} else if (nx > 0 && ny < 0) {
if (direction == SRPGType.MOVE_LEFT) {
return SRPGType.MOVE_UP;
}
if (direction == SRPGType.MOVE_DOWN) {
return SRPGType.MOVE_RIGHT;
}
} else if (nx < 0 && ny > 0) {
if (direction == SRPGType.MOVE_RIGHT) {
return SRPGType.MOVE_DOWN;
}
if (direction == SRPGType.MOVE_UP) {
return SRPGType.MOVE_LEFT;
}
} else if (nx > 0 && ny > 0) {
if (direction == SRPGType.MOVE_LEFT) {
return SRPGType.MOVE_DOWN;
}
if (direction == SRPGType.MOVE_UP) {
return SRPGType.MOVE_RIGHT;
}
}
return direction;
}
/**
* 获得指定SRPG角色所对应的移动方向
*
* @param actor
* @return
*/
public int getDirectionStatus(SRPGActor actor) {
int d = actor.getDirection();
int newd = actor.findDirection(getPosX(), getPosY());
if (d == newd) {
return SRPGType.MOVE_DOWN;
}
return (d != SRPGType.MOVE_UP || newd != SRPGType.MOVE_DOWN)
&& (d != SRPGType.MOVE_DOWN || newd != SRPGType.MOVE_UP)
&& (d != SRPGType.MOVE_RIGHT || newd != SRPGType.MOVE_LEFT)
&& (d != SRPGType.MOVE_LEFT || newd != SRPGType.MOVE_RIGHT) ? SRPGType.MOVE_LEFT
: SRPGType.MOVE_RIGHT;
}
/**
* 获得受到攻击后的角色方向
*
* @param d
* @return
*/
public final static int matchDirection(final int d) {
int result = 0;
switch (d) {
case SRPGType.MOVE_UP:
result = SRPGType.MOVE_DOWN;
break;
case SRPGType.MOVE_DOWN:
result = SRPGType.MOVE_UP;
break;
case SRPGType.MOVE_LEFT:
result = SRPGType.MOVE_RIGHT;
break;
case SRPGType.MOVE_RIGHT:
result = SRPGType.MOVE_LEFT;
break;
}
return result;
}
/**
* 转换图像帧到下一个
*
*/
public void next() {
if (!isVisible()) {
return;
} else {
frame++;
return;
}
}
/**
* 绘制角色
*
* @param g
* @param x
* @param y
*/
private void drawActor(GLEx g, int x, int y) {
boolean isMoving = (this.status.action != 0);
// 攻击动画
if (isAttack) {
actionImage = getAnimationImages(attack, direction);
if (actionCount >= actionImage.length - 1) {
setAttack(false);
}
// 事件动画
} else if (isAction) {
actionImage = getAnimationImages(attack, direction);
// 移动动画
} else {
actionImage = getAnimationImages(move, direction);
}
// 变更动作
if (isAnimation && animation > 0 && isMoving) {
changeble--;
if (changeble <= 0) {
changeble = animation;
actionCount++;
if (actionCount >= actionImage.length) {
actionCount = 0;
}
}
}
if (!getStatus() && isAutoEnd) {
this.isAutoEnd = false;
this.max_frame = 0;
this.frame = 0;
}
LTexture img = actionImage[actionCount];
// 移动中(此处可能会修改加入特殊效果)
if (isMoving) {
g.draw(img, x + (tileWidth - img.getWidth()) / 2, y
+ (tileHeight - img.getHeight()) / 2);
// 角色行动完毕
} else if (isEnd) {
g.draw(img, x + (tileWidth - img.getWidth()) / 2, y
+ (tileHeight - img.getHeight()) / 2, LColor.gray);
// 其它情况
} else {
g.draw(img, x + (tileWidth - img.getWidth()) / 2, y
+ (tileHeight - img.getHeight()) / 2);
}
}
/**
* 绘制当前角色到游戏屏幕
*
* @param g
* @param x
* @param y
*/
public void draw(final GLEx g, int x, int y) {
if (isVisible()) {
drawActor(g, drawX() - x, drawY() - y);
}
}
/**
* 获得实际定位用的X坐标
*
* @return
*/
public int drawX() {
int x = posX * tileWidth;
if (getStatus()) {
int j = (frame * tileWidth) / max_frame;
switch (move_direction) {
case SRPGType.MOVE_LEFT:
x += tileWidth - j;
break;
case SRPGType.MOVE_RIGHT:
x -= tileWidth - j;
break;
}
}
return x;
}
/**
* 获得实际定位用的Y坐标
*
* @return
*/
public int drawY() {
int y = posY * tileHeight;
if (getStatus()) {
int j = (frame * tileHeight) / max_frame;
switch (move_direction) {
case SRPGType.MOVE_UP:
y += tileHeight - j;
break;
case SRPGType.MOVE_DOWN:
y -= tileHeight - j;
break;
}
}
return y;
}
public boolean isAttack() {
return isAttack;
}
public void setAttack(boolean attack) {
this.isAttack = attack;
}
public boolean isAction() {
return isAction;
}
public void setAction(boolean action) {
this.isAction = action;
}
public boolean isActionEnd() {
return isEnd;
}
public void setActionEnd(boolean e) {
isEnd = e;
}
public void setPosX(int x) {
max_frame = 0;
posX = x;
}
public void setPosY(int y) {
max_frame = 0;
posY = y;
}
public void setPos(int x, int y) {
setPosX(x);
setPosY(y);
}
public void setPos(int[] res) {
setPosX(res[0]);
setPosY(res[1]);
}
public int getPosX() {
return posX;
}
public int getPosY() {
return posY;
}
public int[] getPos() {
int[] res = new int[2];
res[0] = getPosX();
res[1] = getPosY();
return res;
}
public boolean isVisible() {
return isExist && isVisible;
}
public void setVisible(boolean flag) {
isVisible = flag;
}
public boolean isExist() {
return isExist;
}
public void setExist(boolean flag) {
isExist = flag;
}
public void setDirection(int d) {
this.direction = d;
}
public int getDirection() {
return direction;
}
public void setCount(int i) {
actionCount = i;
}
public int getCount() {
return actionCount;
}
public void setAnimation(boolean flag) {
isAnimation = flag;
}
public boolean isAnimation() {
return isAnimation;
}
public void setAnimationFrame(int i) {
animation = i;
changeble = i;
}
public int getAnimationFrame() {
return animation;
}
public void setActorStatus(SRPGStatus status) {
this.status = status;
}
public SRPGStatus getActorStatus() {
return this.status;
}
public int getTileHeight() {
return tileHeight;
}
public void setTileHeight(int tileHeight) {
this.tileHeight = tileHeight;
}
public int getTileWidth() {
return tileWidth;
}
public void setTileWidth(int tileWidth) {
this.tileWidth = tileWidth;
}
@Override
public void close() {
}
}