package org.test;
import java.io.IOException;
import loon.Stage;
import loon.action.ActionBind;
import loon.action.ActionListener;
import loon.action.MoveTo;
import loon.action.map.Config;
import loon.action.map.Field2D;
import loon.action.map.TileMap;
import loon.action.sprite.AnimatedEntity;
import loon.action.sprite.MoveControl;
import loon.action.sprite.effect.RippleEffect;
import loon.canvas.LColor;
import loon.component.LClickButton;
import loon.component.LPad;
import loon.event.ActionKey;
import loon.event.SysKey;
import loon.event.Touched;
import loon.event.Updateable;
import loon.opengl.LTexturePackClip;
import loon.utils.TArray;
public class MapTest extends Stage {
//此示例演示了三种角色的地图移动方式,分别是触屏移动,键盘移动,以及虚拟按钮移动
@Override
public void create() {
try {
// 点击处波纹效果
RippleEffect ripple = new RippleEffect();
// 红色
ripple.setColor(LColor.red);
// 设置一个高的z值,避免被精灵遮挡
ripple.setZ(100);
add(ripple);
// 构建数组地图精灵
final TileMap map = new TileMap("assets/rpg/map.txt", 32, 32);
// 设置切图方式
TArray<LTexturePackClip> clips = new TArray<LTexturePackClip>(10);
// 索引,名称,开始切图的x,y位置,以及切下来多少
clips.add(new LTexturePackClip(0, "1", 0, 0, 32, 32));
clips.add(new LTexturePackClip(1, "2", 32, 0, 32, 32));
clips.add(new LTexturePackClip(2, "3", 64, 0, 32, 32));
clips.add(new LTexturePackClip(3, "4", 96, 0, 32, 32));
clips.add(new LTexturePackClip(4, "5", 128, 0, 32, 32));
clips.add(new LTexturePackClip(5, "6", 160, 0, 32, 32));
// 注入切图用地图,以及切图方式(也可以直接注入xml配置文件)
map.setImagePack("assets/rpg/map.png", clips);
// 执行切图
map.pack();
// 设置数组瓦片索引id和切图id的绑定关系(不设置时按照setImagePack中注入的切图id自动和地图id匹配)
/*map.putTile(0, 0);
map.putTile(1, 1);
map.putTile(2, 2);
map.putTile(3, 3);
map.putTile(4, 4);
map.putTile(5, 5);*/
// 注入地图到窗体
add(map);
// 制作动画角色,切分大小32x32每帧,显示位置到坐标3,4(换算为数组地图位置),显示大小32x32
final AnimatedEntity hero = new AnimatedEntity("assets/rpg/hero.gif", 32, 32, map.tilesToPixelsX(3),
map.tilesToPixelsY(4), 32, 32);
// 播放动画,速度每帧220
final long[] frames = {220, 220, 220 };
// 左右下上四方向的帧播放顺序(也可以理解为具体播放的帧)
final int[] leftIds = { 3, 4, 5 };
final int[] rightIds = { 6, 7, 8 };
final int[] downIds = { 0, 1, 2 };
final int[] upIds = { 9, 10, 11 };
// 播放动画,速度每帧220,播放顺序为第0,1,2帧
// hero.animate(new long[]{220, 220, 220 }, new int[]{0, 1, 2});
hero.animate(frames, downIds);
// 限制精灵到索引1,2,3,5位置的移动
map.setLimit(new int[] { 1, 2, 3, 5 });
// 设置一个高的z值,避免被精灵遮挡
hero.setZ(100);
// 让地图追随hero
map.followAction(hero);
// 矫正hero的显示位置
hero.setOffset(map.getOffset());
// 添加hero到地图上
add(hero);
// ----触屏移动---
// 监听窗体down事件
down(new Touched() {
@Override
public void on(final float x, final float y) {
// 角色缓动动画移动,以map中二维数组为基础,4方走法,每次移动增加8个像素(并且矫正地图的偏移位置,否则直接获得屏幕触点肯定错误)
final MoveTo move = new MoveTo(map.getField(), map.offsetXPixel(hero.x()),
map.offsetYPixel(hero.y()), map.offsetXPixel(x), map.offsetYPixel(y), false, 8);
// 监听MoveTo
move.setActionListener(new ActionListener() {
private int lastDirection = -1;
@Override
public void stop(ActionBind o) {
}
@Override
public void start(ActionBind o) {
}
@Override
public void process(ActionBind o) {
// 存储上一个移动方向,避免反复刷新动画事件
if (lastDirection != move.getDirection() && o.getX() != x && o.getY() != y) {
switch (move.getDirection()) {
case Field2D.TUP:
hero.animate(frames, upIds);
break;
default:
case Field2D.TDOWN:
hero.animate(frames, downIds);
break;
case Field2D.TLEFT:
hero.animate(frames, leftIds);
break;
case Field2D.TRIGHT:
hero.animate(frames, rightIds);
break;
}
lastDirection = move.getDirection();
}
}
});
// 开始缓动动画
hero.selfAction().event(move).start();
}
});
//构架移动控制器,注入控制的角色和二维数组
final MoveControl mc = new MoveControl(hero,map.getField());
mc.start();
// 注销窗体时关闭移动控制器
putRelease(mc);
// ----按键移动---
//构建键盘监听
ActionKey left = new ActionKey();
left.setFunction(new Updateable() {
@Override
public void action(Object a) {
if(!mc.isTLeft()){
hero.animate(frames, leftIds);
}
mc.setDirection(Config.TLEFT);
}
});
addActionKey(SysKey.LEFT, left);
ActionKey right = new ActionKey();
right.setFunction(new Updateable() {
@Override
public void action(Object a) {
if(!mc.isTRight()){
hero.animate(frames, rightIds);
}
mc.setDirection(Config.TRIGHT);
}
});
addActionKey(SysKey.RIGHT, right);
ActionKey up = new ActionKey();
up.setFunction(new Updateable() {
@Override
public void action(Object a) {
if(!mc.isTUp()){
hero.animate(frames, upIds);
}
mc.setDirection(Config.TUP);
}
});
addActionKey(SysKey.UP, up);
ActionKey down = new ActionKey();
down.setFunction(new Updateable() {
@Override
public void action(Object a) {
if(!mc.isTDown()){
hero.animate(frames, downIds);
}
mc.setDirection(Config.TDOWN);
}
});
addActionKey(SysKey.DOWN, down);
// ----虚拟按键移动---
// 创建控制按钮
final LPad pad = new LPad(25, 150);
// 禁止窗体触屏区域包含pad
addTouchLimit(pad);
// 监听事件
pad.setListener(new LPad.ClickListener() {
@Override
public void up() {
// 只有上一次操作不是同方向时,才执行动画切换,以下同(否则会重复刷新动画状态到初始,也就是老在每次设置的第一帧跑)
if (!pad.isLastUp()) {
hero.animate(frames, upIds);
}
mc.setDirection(Config.TUP);
}
@Override
public void right() {
if (!pad.isLastRight()) {
hero.animate(frames, rightIds);
}
mc.setDirection(Config.TRIGHT);
}
@Override
public void other() {
}
@Override
public void left() {
if (!pad.isLastLeft()) {
hero.animate(frames, leftIds);
}
mc.setDirection(Config.TLEFT);
}
@Override
public void down() {
if (!pad.isLastDown()) {
hero.animate(frames, downIds);
}
mc.setDirection(Config.TDOWN);
}
});
add(pad);
} catch (IOException e) {
error(e.getMessage());
}
LClickButton click = MultiScreenTest.getBackButton(this, 1);
//禁止触屏点击到click位置,也就是防止点击back时自动寻径
addTouchLimit(click);
add(click);
}
}