package loon.action.sprite;
import loon.LRelease;
import loon.action.ActionBind;
import loon.action.map.Config;
import loon.action.map.Field2D;
import loon.action.map.TileMap;
import loon.utils.processes.RealtimeProcess;
import loon.utils.processes.RealtimeProcessManager;
import loon.utils.timer.LTimerContext;
/**
* 一个四方向(八方向)运动的控制器,主要用来键盘或虚拟摇杆控制角色移动
*/
public class MoveControl implements LRelease {
private int _speed = 8;
private int _px = 0, _py = 0, _direction = -1, _lastDirection = -1;
private int _moveX = 0, _moveY = 0, _movingLength = 0;
private boolean _isMoving = false, _running = false, _freeDir = true;
private ActionBind _bind;
private Field2D _map;
public MoveControl(ActionBind bind, TileMap map) {
this(bind, map.getField());
}
public MoveControl(ActionBind bind, int[][] map) {
this(bind, new Field2D(map));
}
public MoveControl(ActionBind bind, Field2D field2d) {
this._bind = bind;
this._map = field2d;
}
public void setDirection(int d) {
this._direction = d;
}
public void resetDirection() {
setDirection(-1);
}
public int getDirection() {
return this._direction;
}
public final void call() {
move(_bind, _map, _direction);
}
public MoveControl start() {
if (!_running) {
RealtimeProcess process = new RealtimeProcess() {
@Override
public void run(LTimerContext time) {
if (_running) {
call();
if (_freeDir) {
resetDirection();
}
} else {
kill();
}
}
};
process.setDelay(30);
_running = true;
RealtimeProcessManager.get().addProcess(process);
}
return this;
}
public MoveControl stop() {
this._running = false;
return this;
}
public final boolean move(ActionBind bind, Field2D field2d, int direction) {
boolean notMove = false;
this._movingLength = 0;
float posX = bind.getX();
float posY = bind.getY();
posX = posX / field2d.getTileWidth();
posY = posY / field2d.getTileHeight();
if (posX - (int) posX > 0.4) {
posX = field2d.pixelsToTilesWidth(bind.getX()) + 1;
} else {
posX = field2d.pixelsToTilesWidth(bind.getX());
}
if (posY - (int) posY > 0.4) {
posY = field2d.pixelsToTilesHeight(bind.getY()) + 1;
} else {
posY = field2d.pixelsToTilesHeight(bind.getY());
}
this._px = bind.x();
this._py = bind.y();
this._moveX = (int) posX;
this._moveY = (int) posY;
switch (direction) {
case Config.TLEFT:
if (moveTLeft(field2d)) {
notMove = true;
}
break;
case Config.LEFT:
if (moveLeft(field2d)) {
notMove = true;
}
break;
case Config.TRIGHT:
if (moveTRight(field2d)) {
notMove = true;
}
break;
case Config.RIGHT:
if (moveRight(field2d)) {
notMove = true;
}
break;
case Config.TUP:
if (moveTUp(field2d)) {
notMove = true;
}
break;
case Config.UP:
if (moveUp(field2d)) {
notMove = true;
}
break;
case Config.TDOWN:
if (moveTDown(field2d)) {
notMove = true;
}
break;
case Config.DOWN:
if (moveDown(field2d)) {
notMove = true;
}
break;
}
if (!notMove) {
bind.setX(_px);
bind.setY(_py);
_lastDirection = _direction;
}
return notMove;
}
private boolean moveLeft(Field2D field2d) {
int nextX = _moveX - 1;
int nextY = _moveY - 1;
if (nextX < 0) {
nextX = 0;
}
if (nextY < 0) {
nextY = 0;
}
if (field2d.isHit(nextX, nextY)) {
_px -= _speed;
if (_px < 0) {
_px = 0;
}
_py -= _speed;
if (_py < 0) {
_py = 0;
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileWidth()) {
_moveX--;
_px = _moveX * field2d.getTileWidth();
_isMoving = false;
return true;
}
if (_movingLength >= field2d.getTileHeight()) {
_moveY--;
_py = _moveY * field2d.getTileHeight();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveTLeft(Field2D field2d) {
int nextX = _moveX - 1;
int nextY = _moveY;
if (nextX < 0) {
nextX = 0;
}
if (field2d.isHit(nextX, nextY)) {
_px -= _speed;
if (_px < 0) {
_px = 0;
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileWidth()) {
_moveX--;
_px = _moveX * field2d.getTileWidth();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveRight(Field2D field2d) {
int nextX = _moveX + 1;
int nextY = _moveY + 1;
if (nextX > field2d.getWidth() - 1) {
nextX = field2d.getWidth() - 1;
}
if (nextY > field2d.getHeight() - 1) {
nextY = field2d.getHeight() - 1;
}
if (field2d.isHit(nextX, nextY)) {
_px += _speed;
if (_px > field2d.getViewWidth() - field2d.getTileWidth()) {
_px = field2d.getViewWidth() - field2d.getTileWidth();
}
_py += _speed;
if (_py > field2d.getViewHeight() - field2d.getTileHeight()) {
_py = field2d.getViewHeight() - field2d.getTileHeight();
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileWidth()) {
_moveX++;
_px = _moveX * field2d.getTileWidth();
_isMoving = false;
return true;
}
if (_movingLength >= field2d.getTileHeight()) {
_moveY++;
_py = _moveY * field2d.getTileHeight();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveTRight(Field2D field2d) {
int nextX = _moveX + 1;
int nextY = _moveY;
if (nextX > field2d.getWidth() - 1) {
nextX = field2d.getWidth() - 1;
}
if (field2d.isHit(nextX, nextY)) {
_px += _speed;
if (_px > field2d.getViewWidth() - field2d.getTileWidth()) {
_px = field2d.getViewWidth() - field2d.getTileWidth();
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileWidth()) {
_moveX++;
_px = _moveX * field2d.getTileWidth();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveUp(Field2D field2d) {
int nextX = _moveX + 1;
int nextY = _moveY - 1;
if (nextX > field2d.getWidth() - 1) {
nextX = field2d.getWidth() - 1;
}
if (nextY < 0) {
nextY = 0;
}
if (field2d.isHit(nextX, nextY)) {
_px += _speed;
if (_px > field2d.getViewWidth() - field2d.getTileWidth()) {
_px = field2d.getViewWidth() - field2d.getTileWidth();
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileWidth()) {
_moveX++;
_px = _moveX * field2d.getTileWidth();
_isMoving = false;
return true;
}
_py -= _speed;
if (_py < 0) {
_py = 0;
}
if (_movingLength >= field2d.getTileHeight()) {
_moveY--;
_py = _moveY * field2d.getTileHeight();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveTUp(Field2D field2d) {
int nextX = _moveX;
int nextY = _moveY - 1;
if (nextY < 0) {
nextY = 0;
}
if (field2d.isHit(nextX, nextY)) {
_py -= _speed;
if (_py < 0) {
_py = 0;
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileHeight()) {
_moveY--;
_py = _moveY * field2d.getTileHeight();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveDown(Field2D field2d) {
int nextX = _moveX - 1;
int nextY = _moveY + 1;
if (nextX < 0) {
nextX = 0;
}
if (nextY > field2d.getHeight() - 1) {
nextY = field2d.getHeight() - 1;
}
if (field2d.isHit(nextX, nextY)) {
_px -= _speed;
if (_px < 0) {
_px = 0;
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileWidth()) {
_moveX--;
_px = _moveX * field2d.getTileWidth();
_isMoving = false;
return true;
}
_py += _speed;
if (_py > field2d.getViewHeight() - field2d.getTileHeight()) {
_py = field2d.getViewHeight() - field2d.getTileHeight();
}
if (_movingLength >= field2d.getTileHeight()) {
_moveY++;
_py = _moveY * field2d.getTileHeight();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
private boolean moveTDown(Field2D field2d) {
int nextX = _moveX;
int nextY = _moveY + 1;
if (nextY > field2d.getHeight() - 1) {
nextY = field2d.getHeight() - 1;
}
if (field2d.isHit(nextX, nextY)) {
_py += _speed;
if (_py > field2d.getViewHeight() - field2d.getTileHeight()) {
_py = field2d.getViewHeight() - field2d.getTileHeight();
}
_movingLength += _speed;
if (_movingLength >= field2d.getTileHeight()) {
_moveY++;
_py = _moveY * field2d.getTileHeight();
_isMoving = false;
return true;
}
} else {
_isMoving = false;
_px = _moveX * field2d.getTileWidth();
_py = _moveY * field2d.getTileHeight();
}
return false;
}
public boolean isMoving() {
return _isMoving;
}
public int getSpeed() {
return _speed;
}
public void setSpeed(int s) {
this._speed = s;
}
public boolean isRunning() {
return _running;
}
public boolean isFreeDir() {
return _freeDir;
}
public void setFreeDir(boolean d) {
this._freeDir = d;
}
public boolean isLeft() {
return _lastDirection == Config.LEFT;
}
public boolean isRight() {
return _lastDirection == Config.RIGHT;
}
public boolean isDown() {
return _lastDirection == Config.DOWN;
}
public boolean isUp() {
return _lastDirection == Config.UP;
}
public boolean isTLeft() {
return _lastDirection == Config.TLEFT;
}
public boolean isTRight() {
return _lastDirection == Config.TRIGHT;
}
public boolean isTDown() {
return _lastDirection == Config.TDOWN;
}
public boolean isTUp() {
return _lastDirection == Config.TUP;
}
@Override
public void close() {
_running = false;
}
}