/** * 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 loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.1 */ package loon.action.avg; import loon.LObject; import loon.LSystem; import loon.LTexture; import loon.LTextures; import loon.LTransition; import loon.Screen; import loon.action.ActionBind; import loon.action.ActionListener; import loon.action.avg.drama.Command; import loon.action.avg.drama.CommandType; import loon.action.avg.drama.Conversion; import loon.action.sprite.Entity; import loon.action.sprite.ISprite; import loon.action.sprite.Sprites; import loon.action.sprite.effect.FadeEffect; import loon.action.sprite.effect.NaturalEffect; import loon.action.sprite.effect.NaturalEffect.NaturalType; import loon.canvas.Canvas; import loon.canvas.Image; import loon.canvas.LColor; import loon.component.Desktop; import loon.component.LButton; import loon.component.LClickButton; import loon.component.LComponent; import loon.component.LMessage; import loon.component.LSelect; import loon.component.LToast; import loon.component.LToast.Style; import loon.event.ClickListener; import loon.event.GameKey; import loon.event.GameTouch; import loon.event.Updateable; import loon.font.FontSet; import loon.font.IFont; import loon.font.LFont; import loon.opengl.GLEx; import loon.opengl.LSTRDictionary; import loon.utils.Array; import loon.utils.ListMap; import loon.utils.MathUtils; import loon.utils.StringUtils; import loon.utils.TArray; import loon.utils.processes.GameProcess; import loon.utils.processes.RealtimeProcess; import loon.utils.processes.RealtimeProcessManager; import loon.utils.timer.LTimer; import loon.utils.timer.LTimerContext; /** * Loon默认提供的AVG模板,在此Screen中可以直接实现一些简单的AVG游戏操作,并且更容易扩展出自己的AVG游戏系统。 * * @see CommandType */ public abstract class AVGScreen extends Screen implements FontSet<AVGScreen> { // 文字显示速度 private SpeedMode _speedMode = SpeedMode.Normal; // 屏幕点击计数(为了手机环境选择时防止误点的计数器) private int _clickcount = 0; // 手机屏幕手机遇到选择框时,需要点击的次数(归0则无限制,此参数的作用在于防止触屏误点选项) private int _mobile_select_valid_limit = 1; // 当前任务集合 private Array<Task> _currentTasks = new Array<AVGScreen.Task>(); // 任务集合 private ListMap<String, AVGScreen.Task> _tasks = new ListMap<String, AVGScreen.Task>(20); private boolean isSelectMessage, scrFlag, isRunning, running; private IFont _font; private int delay; private String _scriptName; private String selectMessage; private String dialogFileName; // 若需要任意处点击皆可继续脚本,此标记应为true private boolean screenClick = false; // 若需要点击触发脚本继续的功能暂时失效,此处应为true private boolean limitClick = false; // 自动播放的延迟时间 private LTimer autoTimer = new LTimer(LSystem.SECOND); private int clickButtonLayer = 200; private LColor color; protected Command command; protected LTexture dialog; protected AVGCG scrCG; protected LSelect select; protected LMessage message; protected Desktop messageDesktop; protected Sprites effectSprites; private RealtimeProcess avgProcess; private boolean autoPlay; /** * 此为AVG中特定任务接口,此接口需要实现使用,共有三个API,一个用来从脚本注入参数, * 一个调用具体任务,一个返回是否完成的状态,只有任务完成后才能继续脚本。 * * PS : 再次强调,Task不执行完,是不能继续触发脚本的 * */ public interface Task { void parameters(String[] pars); /** * 此处传参与执行并未设定在一起,方便用户异步调用. */ void call(); boolean completed(); } // AVG文字显示速度 public enum SpeedMode { SuperSlow, // 超级慢 Slow, // 慢 FewSlow, // 慢一点点 Normal, // 普通 Fast, // 快 Quickly, // 很快 Flash, // 神速 } private class SelectClick implements ClickListener { private TArray<String> _items; public SelectClick(TArray<String> items) { _items = items; } @Override public void DoClick(LComponent comp) { } @Override public void DownClick(LComponent comp, float x, float y) { } @Override public void UpClick(LComponent comp, float x, float y) { if (tasking()) { return; } if (_items != null && command != null && select != null) { if ((LSystem.base() != null && (LSystem.base().isMobile() || LSystem.base().setting.emulateTouch)) ? _clickcount++ >= _mobile_select_valid_limit : _clickcount > -1) { int idx = select.getResultIndex(); if (idx != -1) { String gotoFlag = _items.get(idx); if (MathUtils.isNan(gotoFlag)) { command.gotoIndex((int) Double.parseDouble(gotoFlag)); } else { command.gotoIndex(gotoFlag); } select.SetClick(null); select.setVisible(false); limitClick = false; scrFlag = false; isSelectMessage = false; _clickcount = 0; nextScript(); } } } } @Override public void DragClick(LComponent comp, float x, float y) { } } /** * 默认任务(同时也是任务接口实现示例,Task主要就是给用户自行扩展的) */ private void defTask() { /** * 展示一个简易消息框 * * 使用方式,脚本中调用: task toast 字符串 * * @example task toast 你获得了500万 */ putTask("toast", new Task() { private String parameter; private LToast toast; @Override public boolean completed() { boolean stop = toast.isStop() && (toast.getOpacity() <= 0.1f || !toast.isVisible()); if (stop) { getDesktop().remove(toast); } return stop; } @Override public void call() { toast = LToast.makeText(parameter, Style.ERROR); getDesktop().add(toast); } @Override public void parameters(String[] pars) { parameter = StringUtils.replace(pars[0], "\"", ""); } }); /** * 添加一个指定的过渡效果. * * 使用方式,脚本中调用: task trans 渐变效果名 颜色 * * @example task trans fadein black * @see LTransition */ putTask("trans", new Task() { private String transStr, colorStr; private LTransition transition; @Override public boolean completed() { boolean stop = transition.getTransitionListener().completed(); if (stop) { getSprites().remove(transition.getTransitionListener().getSprite()); } return stop; } @Override public void call() { transition = LTransition.newTransition(transStr, colorStr); getSprites().add(transition.getTransitionListener().getSprite()); } @Override public void parameters(String[] pars) { if (pars.length >= 2) { transStr = pars[0]; colorStr = pars[1]; } else if (pars.length == 1) { transStr = pars[0]; if (transStr.indexOf(',') != -1) { String[] list = StringUtils.split(transStr, ','); transStr = list[0]; colorStr = list[1]; } else { colorStr = null; } } else { // 字符串为null时,loon会调用默认特效设置FadeIn transStr = null; colorStr = null; } } }); /** * 添加一个精灵 (精灵可以用[clear 精灵名]或者[del 精灵名]方式删除) * * 使用方式,脚本中调用(不必全部填写): task sprite {图像来源,精灵名称,x坐标,y坐标} {loon的action脚本命令} * * @example task sprite {assets/c.png,55,55} * {move(155,155,true,16)->delay(3f)->move(25,125,true)} */ putTask("sprite", new Task() { private float x, y; private String _scriptName, scriptSource, scripteContext; private boolean isCompleted; @Override public boolean completed() { return isCompleted; } @Override public void call() { Entity entity = Entity.make(scriptSource, x, y); if (_scriptName != null) { entity.setName(_scriptName); } else { entity.setName(scriptSource); } if (scripteContext != null) { act(entity, scripteContext).start().setActionListener(new ActionListener() { @Override public void stop(ActionBind o) { isCompleted = true; } @Override public void start(ActionBind o) { } @Override public void process(ActionBind o) { } }); } else { isCompleted = true; } scrCG.actionRole.add(entity); } @Override public void parameters(String[] pars) { String scriptInfo = pars[0].trim(); int start = scriptInfo.indexOf('{'); int end = scriptInfo.lastIndexOf('}'); if (start != -1 && end != -1 && end > start) { scriptInfo = scriptInfo.substring(start + 1, end); } String[] list = StringUtils.split(scriptInfo, ','); if (list.length == 1) { scriptSource = list[0]; } else if (list.length == 2) { scriptSource = list[0]; if (MathUtils.isNan(list[1])) { x = y = Float.parseFloat(list[1]); } } else if (list.length == 3) { scriptSource = list[0]; if (MathUtils.isNan(list[1])) { x = Float.parseFloat(list[1]); } if (MathUtils.isNan(list[2])) { y = Float.parseFloat(list[2]); } } else if (list.length == 4) { scriptSource = list[0]; _scriptName = list[1]; if (MathUtils.isNan(list[2])) { x = Float.parseFloat(list[2]); } if (MathUtils.isNan(list[3])) { y = Float.parseFloat(list[3]); } } if (pars.length > 1) { scriptInfo = pars[1].trim(); start = scriptInfo.indexOf('{'); end = scriptInfo.lastIndexOf('}'); if (start != -1 && end != -1 && end > start) { scriptInfo = scriptInfo.substring(start + 1, end); } scripteContext = scriptInfo; } } }); } /** * 以键值对方式添加任务(主要是方便脚本调用) * * @param key * @param value */ public void putTask(String key, Task value) { _tasks.put(key, value); } /** * 返回指定键值对应的具体任务 * * @param key * @return */ public Task getTask(String key) { return _tasks.get(key); } /** * 删除指定任务 * * @param key * @return */ public Task removeTask(String key) { return _tasks.removeKey(key); } /** * 清空任务 */ public void clearTask() { _tasks.clear(); } /** * 返回当前字符串的文字显示速度模式 * * @param name * @return */ public SpeedMode toSpeedMode(String name) { String key = name.trim().toLowerCase(); if ("superslow".equals(key)) { return SpeedMode.SuperSlow; } else if ("slow".equals(key)) { return SpeedMode.Slow; } else if ("fewslow".equals(key)) { return SpeedMode.FewSlow; } else if ("normal".equals(key)) { return SpeedMode.Normal; } else if ("fast".equals(key)) { return SpeedMode.Fast; } else if ("quickly".equals(key)) { return SpeedMode.Quickly; } else if ("flash".equals(key)) { return SpeedMode.Flash; } else { return SpeedMode.Normal; } } public AVGScreen(final String initscript, final String initdialog) { this(initscript, LTextures.loadTexture(initdialog)); } public AVGScreen(final String initscript, final LTexture img) { this._font = LSystem.getSystemGameFont(); this._scriptName = initscript; if (initscript == null) { return; } if (img != null) { this.dialogFileName = img.getSource(); this.dialog = img; } } public AVGScreen(final String initscript) { this._font = LSystem.getSystemGameFont(); this._scriptName = initscript; if (initscript == null) { return; } } private class OptClick implements ClickListener { private String label; public OptClick(String gotoFlag) { label = gotoFlag; } @Override public void UpClick(LComponent comp, float x, float y) { if (command != null && label != null) { command.gotoIndex(label); nextScript(); } } @Override public void DragClick(LComponent comp, float x, float y) { } @Override public void DownClick(LComponent comp, float x, float y) { } @Override public void DoClick(LComponent comp) { } } /** * 添加选项按钮到游戏中 * * @param click */ private void addOpt(final LClickButton click) { if (command != null) { GameProcess process = new RealtimeProcess() { @Override public void run(LTimerContext time) { click.Tag = CommandType.L_OPTION + (click.getText() == null ? command.getIndex() : click.getText()); click.setLayer(clickButtonLayer); getDesktop().add(click); kill(); } }; addProcess(process); } } /** * 设置选项按钮为脚本中参数 * * @param click * @param order */ private final void setOpt(LClickButton click, String order) { int startFlag = order.indexOf('{'); int endFlag = order.lastIndexOf('}'); if (startFlag != -1 && endFlag != -1 && endFlag > startFlag) { String gotoMes = order.substring(startFlag + 1, endFlag).trim(); final String[] result = StringUtils.split(gotoMes, ','); if (result.length > 1) { // 只有单图时,全部按钮为一张图片(索引0存放跳转点,非按钮图) if (result.length == 2) { click.setTexture(LTextures.loadTexture(result[1])); click.setGrayButton(true); } else if (result.length == 3) { // 有两张图时 LTexture texIdle = LTextures.loadTexture(result[1]); LTexture texClick = LTextures.loadTexture(result[2]); // 空闲时 click.setIdleClick(texIdle); // 鼠标徘徊 click.setHoverClick(texClick); // 鼠标按下 click.setClickedClick(texClick); } else if (result.length == 4) { // 有三张图时 LTexture texIdle = LTextures.loadTexture(result[1]); LTexture texHover = LTextures.loadTexture(result[2]); LTexture texClick = LTextures.loadTexture(result[3]); // 空闲时 click.setIdleClick(texIdle); // 鼠标徘徊 click.setHoverClick(texHover); // 鼠标按下 click.setClickedClick(texClick); } } click.SetClick(new OptClick(result[0])); } else { click.setTexture(LTextures.loadTexture(order)); click.setGrayButton(true); } } @Override public final void onLoad() { this.setRepaintMode(Screen.SCREEN_NOT_REPAINT); this.delay = 60; if (dialog == null && dialogFileName != null) { this.dialog = LTextures.loadTexture(dialogFileName); } this.running = true; } @Override public final void onLoaded() { // 不同场合需要不同的渲染策略,此处将用户渲染置于底层 // 最先绘制用户画面 setFristOrder(DRAW_USER_PAINT()); // 其次绘制精灵 setSecondOrder(DRAW_SPRITE_PAINT()); // 最后绘制桌面 setLastOrder(DRAW_DESKTOP_PAINT()); LSystem.load(new Updateable() { @Override public void action(Object a) { defTask(); initAVG(); onLoading(); } }); this.avgProcess = new RealtimeProcess() { @Override public void run(LTimerContext time) { if (running) { if (messageDesktop != null) { switch (_speedMode) { default: case Normal: messageDesktop.update(LSystem.SECOND / 2); break; case SuperSlow: messageDesktop.update(LSystem.MSEC * 20); break; case Slow: messageDesktop.update(LSystem.MSEC * 40); break; case FewSlow: messageDesktop.update(LSystem.MSEC * 60); break; case Fast: messageDesktop.update(LSystem.SECOND); break; case Quickly: for (int i = 0; i < 2; i++) { messageDesktop.update(LSystem.SECOND); } break; case Flash: for (int i = 0; i < 3; i++) { messageDesktop.update(LSystem.SECOND); } break; } } if (effectSprites != null) { effectSprites.update(time.timeSinceLastUpdate); } if (autoPlay) { playAutoNext(); } } } }; setSpeedMode(_speedMode); avgProcess.setDelay(delay); RealtimeProcessManager.get().addProcess(avgProcess); } private synchronized void initDesktop() { if (messageDesktop != null && effectSprites != null) { return; } this.messageDesktop = new Desktop(this, getWidth(), getHeight()); this.effectSprites = new Sprites(this, getWidth(), getHeight()); if (dialog == null) { Image tmp = Image.createImage(getWidth() - 20, getHeight() / 2 - 20); Canvas g = tmp.getCanvas(); g.setColor(0, 0, 0, 125); g.fillRect(0, 0, tmp.getWidth(), tmp.getHeight()); g = null; dialog = tmp.texture(); if (tmp != null) { tmp.close(); tmp = null; } } this.message = new LMessage(_font, dialog, 0, 0); this.message.setFontColor(LColor.white); int size = (int) (message.getWidth() / (message.getMessageFont().getSize())); if (size % 2 != 0) { size = size - 3; } else { size = size - 4; } this.message.setMessageLength(size); this.message.setLocation((getWidth() - message.getWidth()) / 2, getHeight() - message.getHeight() - 10); this.message.setTopOffset(-5); this.message.setVisible(false); this.select = new LSelect(_font, dialog, message.x(), message.y()); this.select.setTopOffset(5); this.scrCG = new AVGCG(this); this.messageDesktop.add(message); this.messageDesktop.add(select); this.select.setVisible(false); } /** * 设置一个实现了IFont的字体到AVG系统中(一般使用LFont或BMFont) * * @param font */ public AVGScreen setFont(final IFont font) { this._font = font; if (message != null) { message.setMessageFont(font); } if (select != null) { select.setMessageFont(font); } return this; } public IFont getFont() { if (message != null) { return message.getMessageFont(); } return this._font; } public abstract boolean nextScript(String message); public abstract void onSelect(String message, int type); public abstract void initMessageConfig(final LMessage message); public abstract void initSelectConfig(final LSelect select); public abstract void initCommandConfig(final Command command); final public void select(int type) { if (command != null) { command.select(type); isSelectMessage = false; } } final public String getSelect() { if (command != null) { return command.getSelect(); } return null; } @Override public Screen add(LComponent c) { if (messageDesktop == null) { initDesktop(); } if ((c instanceof LClickButton) || (c instanceof LButton)) { c.setLayer(clickButtonLayer); } messageDesktop.add(c); return this; } @Override public Screen addTouchLimit(LObject<?> c) { if (messageDesktop == null) { initDesktop(); } if (!(c instanceof LClickButton)) { super.addTouchLimit(c); } return this; } @Override public Screen add(ISprite s) { if (effectSprites == null) { initDesktop(); } effectSprites.add(s); return this; } @Override public Screen remove(ISprite sprite) { effectSprites.remove(sprite); return this; } @Override public Screen remove(LComponent comp) { messageDesktop.remove(comp); return this; } @Override public Screen removeAll() { super.removeAll(); effectSprites.removeAll(); messageDesktop.clear(); _currentTasks.clear(); return this; } @Override final public void draw(GLEx g) { if (!running || !isOnLoadComplete() || isClose()) { return; } if (scrCG == null) { return; } if (scrCG.sleep == 0) { scrCG.paint(g); drawScreen(g); if (messageDesktop != null) { messageDesktop.createUI(g); } if (effectSprites != null) { effectSprites.createUI(g); } } else { scrCG.sleep--; if (color != null) { float alpha = (float) (scrCG.sleepMax - scrCG.sleep) / scrCG.sleepMax; if (alpha > 0.1f && alpha < 1.0f) { if (scrCG.getBackgroundCG() != null) { g.draw(scrCG.getBackgroundCG(), 0, 0); } LColor c = g.getColor(); g.setColor(color.r, color.g, color.b, alpha); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(c); } else { LColor c = g.getColor(); g.setColor(color); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(c); } } if (scrCG.sleep <= 0) { scrCG.sleep = 0; color = null; } g.setAlpha(1.0f); } } public abstract void drawScreen(GLEx g); public void nextScript() { if (command != null && !isClose() && running) { for (; isRunning = command.next();) { if (isSelectMessage) { continue; } String result = command.doExecute(); if (result == null) { continue; } if (!nextScript(result)) { break; } TArray<String> commands = Conversion.splitToList(result, ' '); int size = commands.size; String cmdFlag = (String) commands.get(0); String mesFlag = null, orderFlag = null, lastFlag = null; if (size == 2) { mesFlag = (String) commands.get(1); } else if (size == 3) { mesFlag = (String) commands.get(1); orderFlag = (String) commands.get(2); } else if (size == 4) { mesFlag = (String) commands.get(1); orderFlag = (String) commands.get(2); lastFlag = (String) commands.get(3); } if (cmdFlag.equalsIgnoreCase(CommandType.L_CLEAR) || cmdFlag.equalsIgnoreCase(CommandType.L_DEL)) { if (orderFlag == null) { if (messageDesktop != null) { message.setVisible(false); select.setVisible(false); effectSprites.clear(); scrCG.clear(); getSprites().removeAll(); getDesktop().removeAll(); _currentTasks.clear(); } } else { effectSprites.removeName(orderFlag); messageDesktop.removeName(orderFlag); scrCG.remove(orderFlag); } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_TASK)) { if (mesFlag != null) { mesFlag = mesFlag.trim(); // 如果是clear或del则清除任务 if (CommandType.L_CLEAR.equalsIgnoreCase(mesFlag) || CommandType.L_DEL.equalsIgnoreCase(mesFlag)) { _currentTasks.clear(); } else { Task task = getTask(mesFlag); if (task != null) { // 注入参数 int len = commands.size - 2; String[] args = new String[len]; for (int i = 0; i < len; i++) { args[i] = commands.get(i + 2); } // 注入参数 task.parameters(args); // 执行任务 task.call(); // 添加到当前任务集合中 _currentTasks.add(task); } } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SPEED)) { if (mesFlag != null) { setSpeedMode(mesFlag); } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_LOCK)) { setLimitClick(true); continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_UNLOCK)) { setLimitClick(false); continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_OPTION)) { if (mesFlag != null) { if (CommandType.L_CLEAR.equalsIgnoreCase(mesFlag) || CommandType.L_DEL.equalsIgnoreCase(mesFlag)) { if (orderFlag == null) { super.getDesktop().removeUIName("ClickButton"); } else { super.getDesktop().removeTag(CommandType.L_OPTION + orderFlag); } } else { String text = null; LClickButton click = null; if (mesFlag.indexOf(',') != -1) { String[] optSize = StringUtils.split(mesFlag, ','); if (optSize.length == 4) { click = new LClickButton(text, (int) Float.parseFloat(optSize[0].trim()), (int) Float.parseFloat(optSize[1].trim()), (int) Float.parseFloat(optSize[2].trim()), (int) Float.parseFloat(optSize[3].trim())); // 载入跳转地址与图片 if (orderFlag != null) { setOpt(click, orderFlag); } } } else { text = StringUtils.replace(mesFlag, "\"", ""); if (orderFlag != null) { String[] optSize = StringUtils.split(orderFlag, ','); if (optSize.length == 4) { click = new LClickButton(text, (int) Float.parseFloat(optSize[0].trim()), (int) Float.parseFloat(optSize[1].trim()), (int) Float.parseFloat(optSize[2].trim()), (int) Float.parseFloat(optSize[3].trim())); // 载入图片 if (lastFlag != null) { setOpt(click, lastFlag); } } } } if (click != null) { addOpt(click); } } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MESMOVE)) { // 空值时复位 if (mesFlag == null) { int mesSize = (int) (message.getWidth() / (message.getMessageFont().getSize())); if (mesSize % 2 != 0) { mesSize = mesSize - 3; } else { mesSize = mesSize - 4; } this.message.setMessageLength(mesSize); this.message.setLocation((getWidth() - message.getWidth()) / 2, getHeight() - message.getHeight() - 10); this.message.setTopOffset(-5); this.select.setTopOffset(5); } else if (mesFlag != null) { if (orderFlag != null) { if (MathUtils.isNan(mesFlag) && (MathUtils.isNan(orderFlag))) { float x = Float.parseFloat(mesFlag); float y = Float.parseFloat(orderFlag); message.setLocation(x, y); select.setLocation(x, y); } } else { if (mesFlag.indexOf(',') == -1 && MathUtils.isNan(mesFlag)) { float v = Float.parseFloat(mesFlag); message.setX(v); select.setX(v); } else { String[] res = StringUtils.split(mesFlag, ','); String v1 = res[0].trim(); String v2 = res[1].trim(); if (res.length == 1 && MathUtils.isNan(v1)) { float v = Float.parseFloat(v1); message.setX(v); select.setX(v); } else if (res.length == 2 && MathUtils.isNan(v1) && MathUtils.isNan(v2)) { float x = Float.parseFloat(v1); float y = Float.parseFloat(v2); message.setLocation(x, y); select.setLocation(x, y); } } } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_APLAY)) { autoPlay = true; continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_ASTOP)) { autoPlay = false; continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_ADELAY)) { if (mesFlag != null) { if (MathUtils.isNan(mesFlag)) { autoTimer.setDelay(Integer.parseInt(mesFlag)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_WAIT)) { scrFlag = true; break; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SNOW) || cmdFlag.equalsIgnoreCase(CommandType.L_RAIN) || cmdFlag.equalsIgnoreCase(CommandType.L_PETAL)) { if (effectSprites != null) { boolean flag = false; ISprite[] ss = effectSprites.getSprites(); for (int i = 0; i < ss.length; i++) { ISprite s = ss[i]; if (s instanceof NaturalEffect) { flag = true; break; } } if (!flag) { if (cmdFlag.equalsIgnoreCase(CommandType.L_SNOW)) { effectSprites.add(NaturalEffect.getSnowEffect()); } else if (cmdFlag.equalsIgnoreCase(CommandType.L_RAIN)) { effectSprites.add(NaturalEffect.getRainEffect()); } else if (cmdFlag.equalsIgnoreCase(CommandType.L_PETAL)) { effectSprites.add(NaturalEffect.getPetalEffect()); } else if (cmdFlag.equalsIgnoreCase(CommandType.L_THUNDER)) { effectSprites.add(NaturalEffect.getThunderEffect()); } } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SNOWSTOP) || cmdFlag.equalsIgnoreCase(CommandType.L_RAINSTOP) || cmdFlag.equalsIgnoreCase(CommandType.L_PETALSTOP)) { if (effectSprites != null) { ISprite[] ss = effectSprites.getSprites(); for (int i = 0; i < ss.length; i++) { ISprite s = ss[i]; if (s instanceof NaturalEffect) { NaturalType naturalType = ((NaturalEffect) s).getNaturalType(); if (cmdFlag.equalsIgnoreCase(CommandType.L_SNOWSTOP)) { if (naturalType == NaturalType.Snow) { effectSprites.remove(s); } } else if (cmdFlag.equalsIgnoreCase(CommandType.L_RAINSTOP)) { if (naturalType == NaturalType.Rain) { effectSprites.remove(s); } } else if (cmdFlag.equalsIgnoreCase(CommandType.L_PETALSTOP)) { if (naturalType == NaturalType.Petal) { effectSprites.remove(s); } } else if (cmdFlag.equalsIgnoreCase(CommandType.L_THUNDER)) { if (naturalType == NaturalType.Thunder) { effectSprites.remove(s); } } } } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_PLAY)) { playSound(mesFlag, false); continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_PLAYLOOP)) { playSound(mesFlag, true); continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_PLAYSTOP)) { if (mesFlag != null && mesFlag.length() > 0) { stopSound(mesFlag); } else { stopSound(); } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_FADEOUT) || cmdFlag.equalsIgnoreCase(CommandType.L_FADEIN)) { this.scrFlag = true; this.color = new LColor(mesFlag); if (effectSprites != null) { effectSprites.removeAll(); if (cmdFlag.equalsIgnoreCase(CommandType.L_FADEIN)) { effectSprites.add(FadeEffect.getInstance(ISprite.TYPE_FADE_IN, 30, color)); } else { effectSprites.add(FadeEffect.getInstance(ISprite.TYPE_FADE_OUT, 30, color)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SELLEN)) { if (mesFlag != null) { if (MathUtils.isNan(mesFlag)) { select.setLeftOffset(Integer.parseInt(mesFlag)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SELTOP)) { if (mesFlag != null) { if (MathUtils.isNan(mesFlag)) { select.setTopOffset(Integer.parseInt(mesFlag)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MESLEN)) { if (mesFlag != null) { if (MathUtils.isNan(mesFlag)) { message.setMessageLength(Integer.parseInt(mesFlag)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MESTOP)) { if (mesFlag != null) { if (MathUtils.isNan(mesFlag)) { message.setTopOffset(Integer.parseInt(mesFlag)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MESLEFT)) { if (mesFlag != null) { if (MathUtils.isNan(mesFlag)) { message.setLeftOffset(Integer.parseInt(mesFlag)); } } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MESCOLOR)) { if (mesFlag != null) { message.setFontColor(new LColor(mesFlag)); } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MES)) { if (select.isVisible()) { select.setVisible(false); } scrFlag = true; String nMessage = mesFlag; message.setMessage(StringUtils.replace(nMessage, "&", " ")); message.setVisible(true); break; } if (cmdFlag.equalsIgnoreCase(CommandType.L_MESSTOP)) { scrFlag = true; message.setVisible(false); select.setVisible(false); continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SELECT)) { if (mesFlag != null) { mesFlag = mesFlag.trim(); int selectStart = mesFlag.indexOf("{"); int selectEnd = mesFlag.lastIndexOf("}"); if (selectStart != -1 && selectEnd != -1) { String messageInfo = null; if (mesFlag.startsWith("\"")) { int startFlag = mesFlag.indexOf('"'); int endFlag = mesFlag.lastIndexOf('"'); if (startFlag != -1 && endFlag != -1 && endFlag > startFlag) { messageInfo = mesFlag.substring(startFlag + 1, endFlag); } } final String selectList = mesFlag.substring(selectStart + 1, selectEnd).trim(); if (message.isVisible()) { message.setVisible(false); } select.setVisible(true); scrFlag = true; isSelectMessage = true; limitClick = true; String[] list = StringUtils.split(selectList, ','); final int selectLength = list.length; final int len = selectLength / 2; final TArray<String> selects = new TArray<String>(len); final TArray<String> items = new TArray<String>(len); for (int i = 0; i < selectLength; i++) { if (i % 2 == 0) { selects.add(list[i]); } else { items.add(list[i]); } } select.setMessage(messageInfo, selects); addProcess(new RealtimeProcess() { @Override public void run(LTimerContext time) { select.SetClick(new SelectClick(items)); kill(); } }); break; } else { selectMessage = mesFlag; } } else { selectMessage = mesFlag; } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SELECTS)) { if (message.isVisible()) { message.setVisible(false); } select.SetClick(null); select.setVisible(true); scrFlag = true; isSelectMessage = true; String[] selects = command.getReads(); select.setMessage(selectMessage, selects); break; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SHAKE)) { scrCG.shakeNumber = Integer.valueOf(mesFlag).intValue(); continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_CGWAIT)) { scrFlag = false; break; } if (cmdFlag.equalsIgnoreCase(CommandType.L_SLEEP)) { scrCG.sleep = Integer.valueOf(mesFlag).intValue(); scrCG.sleepMax = Integer.valueOf(mesFlag).intValue(); scrFlag = false; break; } if (cmdFlag.equalsIgnoreCase(CommandType.L_FLASH)) { scrFlag = true; String[] colors = null; if (mesFlag != null) { colors = mesFlag.split(","); } else { colors = new String[] { "0", "0", "0" }; } if (color == null && colors != null && colors.length == 3) { color = new LColor(Integer.valueOf(colors[0]).intValue(), Integer.valueOf(colors[1]).intValue(), Integer.valueOf(colors[2]).intValue()); scrCG.sleep = 20; scrCG.sleepMax = scrCG.sleep; scrFlag = false; } else { color = null; } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_GB)) { if (mesFlag == null) { return; } if (mesFlag.equalsIgnoreCase("none")) { scrCG.noneBackgroundCG(); } else { scrCG.setBackgroundCG(mesFlag); } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_CG)) { if (mesFlag == null) { return; } if (scrCG != null && scrCG.count() > LSystem.DEFAULT_MAX_CACHE_SIZE) { scrCG.close(); } if (mesFlag.equalsIgnoreCase(CommandType.L_DEL)) { if (orderFlag != null) { scrCG.remove(orderFlag); } else { scrCG.close(); } } else if (lastFlag != null && CommandType.L_TO.equalsIgnoreCase(orderFlag)) { scrCG.replace(mesFlag, lastFlag); } else { int x = 0, y = 0; if (orderFlag != null) { x = Integer.parseInt(orderFlag); } if (size >= 4) { y = Integer.parseInt((String) commands.get(3)); } final int tx = x; final int ty = y; final String name = mesFlag; scrCG.add(name, tx, ty, getWidth(), getHeight()); } continue; } if (cmdFlag.equalsIgnoreCase(CommandType.L_EXIT)) { scrFlag = true; running = false; onExit(); break; } } } } public abstract void onExit(); private void playAutoNext() { if (tasking()) { return; } if (!autoTimer.action(elapsedTime)) { return; } if (scrCG.sleep != 0) { return; } if (isSelectMessage) { return; } if (message.isVisible() && !message.isComplete()) { return; } nextScript(); } private boolean tasking() { return _currentTasks.size() > 0; } public void click() { // 如果存在未完成任务,则不允许继续脚本 if (tasking()) { return; } if (limitClick) { return; } if (!running) { return; } if (message.isVisible() && !message.isComplete()) { return; } boolean isNext = false; if (!isSelectMessage && scrCG.sleep <= 0) { if (!scrFlag) { scrFlag = true; } if (!screenClick && message.isVisible()) { isNext = message.intersects(getTouchX(), getTouchY()); } else { isNext = true; } } else if (scrFlag && select.getResultIndex() != -1) { onSelect(selectMessage, select.getResultIndex()); isNext = select.intersects(getTouchX(), getTouchY()); if ((LSystem.base() != null && LSystem.base().isMobile() || LSystem.base().setting.emulateTouch) ? _clickcount++ >= _mobile_select_valid_limit : _clickcount > -1) { message.setVisible(false); select.setVisible(false); isSelectMessage = false; selectMessage = null; _clickcount = 0; } } if (isNext && !isSelectMessage) { nextScript(); } } public void initCommandConfig(String fileName) { if (fileName == null) { return; } Command.resetCache(); if (command == null) { command = new Command(fileName); } else { command.formatCommand(fileName); } if (message.getFont() instanceof LFont) { LSTRDictionary.get().bind((LFont) message.getFont(), command.getCommands()); } initCommandConfig(command); nextScript(); } public boolean isScrFlag() { return scrFlag; } public String getSelectMessage() { return selectMessage; } private void initAVG() { this.initDesktop(); this.initMessageConfig(message); this.initSelectConfig(select); this.initCommandConfig(_scriptName); } public abstract void onLoading(); public boolean isCommandGo() { return isRunning; } public LMessage messageConfig() { return message; } public void setDialogImage(LTexture dialog) { this.dialog = dialog; } public LTexture getDialogImage() { return dialog; } public int getPause() { return delay; } public void setPause(int pause) { setDelay(pause); } public int getDelay() { return delay; } public void setDelay(int d) { this.delay = d; if (_speedMode == SpeedMode.Flash || _speedMode == SpeedMode.Quickly || _speedMode == SpeedMode.Fast) { delay = 0; } if (avgProcess != null) { avgProcess.setDelay(delay); } } public Desktop getAvgDesktop() { return messageDesktop; } public LTexture getDialog() { return dialog; } public void setDialog(LTexture dialog) { this.dialog = dialog; } public LMessage getMessage() { return message; } public void setMessage(LMessage message) { this.message = message; } public boolean isRunning() { return running; } public void setRunning(boolean running) { this.running = running; } public AVGCG getScrCG() { return scrCG; } public void setScrCG(AVGCG scrCG) { this.scrCG = scrCG; } public String getScriptName() { return _scriptName; } public void setScriptName(String name) { this._scriptName = name; } public Command getCommand() { return command; } public void setCommand(Command command) { this.command = command; } public boolean isSelectMessage() { return isSelectMessage; } public LSelect getLSelect() { return select; } public int getSleep() { return scrCG.sleep; } public void setSleep(int sleep) { scrCG.sleep = sleep; } public int getSleepMax() { return scrCG.sleepMax; } public void setSleepMax(int sleepMax) { scrCG.sleepMax = sleepMax; } public Sprites getAvgSprites() { return effectSprites; } public void setCommandGo(boolean isRunning) { this.isRunning = isRunning; } public void setScrFlag(boolean scrFlag) { this.scrFlag = scrFlag; } public boolean isLocked() { return limitClick; } public void setLocked(boolean locked) { this.limitClick = locked; } @Override public void alter(LTimerContext timer) { if (_currentTasks.size() > 0) { for (; _currentTasks.hashNext();) { Task task = _currentTasks.next(); if (task.completed()) { _currentTasks.remove(task); } } _currentTasks.stopNext(); } if (scrCG != null) { scrCG.update(timer); } } @Override public void onKeyDown(GameKey e) { } @Override public void onKeyUp(GameKey e) { } @Override public void touchDown(GameTouch touch) { if (messageDesktop != null) { messageDesktop.processEvents(); } click(); } @Override public void touchMove(GameTouch e) { if (messageDesktop != null) { messageDesktop.processEvents(); } } @Override public void touchUp(GameTouch e) { if (messageDesktop != null) { messageDesktop.processEvents(); } } @Override public void touchDrag(GameTouch e) { if (messageDesktop != null) { messageDesktop.processEvents(); } } public boolean isAutoPlay() { return autoPlay; } public void setAutoPlay(boolean autoPlay) { this.autoPlay = autoPlay; } public void setAutoDelay(long d) { autoTimer.setDelay(d); } public long getAutoDelay() { return autoTimer.getDelay(); } public LTimer getAutoTimer() { return autoTimer; } public void setAutoTimer(LTimer autoTimer) { this.autoTimer = autoTimer; } public boolean isLimitClick() { return limitClick; } /** * 档次参数为true时,将无法点击消息框或画面触发脚本继续 * * @param limitClick */ public void setLimitClick(boolean lc) { this.limitClick = lc; } public boolean isScreenClick() { return screenClick; } /** * 此标记用于判断是否next仅在点击message时继续(true不是,false是) * * @param screenClick */ public void setScreenClick(boolean screenClick) { this.screenClick = screenClick; } public SpeedMode getSpeedMode() { return _speedMode; } /** * 设置当前AVG的文字显示速度默认 * * @param m */ public void setSpeedMode(SpeedMode m) { this._speedMode = m; if (_speedMode == SpeedMode.Flash || _speedMode == SpeedMode.Quickly || _speedMode == SpeedMode.Fast) { delay = 0; } } /** * 设置当前AVG的文字显示速度默认 * * @param speedName */ public void setSpeedMode(String speedName) { setSpeedMode(toSpeedMode(speedName)); } public int getClickcount() { return _clickcount; } public int getMobileSelectValidLimit() { return _mobile_select_valid_limit; } /** * 此处限制移动环境时,遇到选择时需要点击的次数 * * @param v */ public void setMobileSelectValidLimit(int v) { this._mobile_select_valid_limit = v; } /** * 清空当前任务 */ public void clearCurrentTasks() { _currentTasks.clear(); } public Array<Task> getCurrentTasks() { return _currentTasks; } public ListMap<String, AVGScreen.Task> getTasks() { return _tasks; } public int getClickButtonLayer() { return clickButtonLayer; } public void setClickButtonLayer(int clickButtonLayer) { this.clickButtonLayer = clickButtonLayer; } @Override public void close() { running = false; if (avgProcess != null) { avgProcess.kill(); avgProcess = null; } if (messageDesktop != null) { messageDesktop.close(); messageDesktop = null; } if (effectSprites != null) { effectSprites.close(); effectSprites = null; } if (command != null) { command = null; } if (message != null) { message.close(); message = null; } if (scrCG != null) { scrCG.close(); scrCG = null; } if (dialog != null) { if (dialog.getSource() != null) { dialog.close(); dialog = null; } } _currentTasks.clear(); _tasks.clear(); } }