java – Codename One Animation Trouble(也在Solitaire演示中)?

Codename One动画发生了什么?我使用了很多,截至12月,我的应用程序已不再有效.当我在六月离开时,一切都很好(并且已经超过一年了).

我的应用程序是一个草稿(跳棋)游戏,自2013年起在应用程序商店中可用.在看到CN1扑克演示后,我完全重写了我的GUI,因为我想将这些动画添加到我的应用程序.现在发生的是我突然得到索引超出限制的异常.我把它缩小到以下情况:

cont.addComponent(comp);
...
...
cont.getComponent(0);  <-- index out of bound exception: 0 out of 0

我相信,我已经在6月使用了newVM = true,现在是默认值.我尝试通过添加一个来修复问题

cont.animateLayoutAndWait(100);

在addComponent调用之后.这修复了索引超出绑定的异常,但现在应用程序在短时间工作正常后随机崩溃.我试过,但一直无法找到问题的根源. CN1中的某些内容发生了变化,因此我的代码不再有效. (另请参阅旧论坛,搜索“草稿”,我在其中发布了我的基本设计的完整列表.)

我研究了新的Solitaire演示,它具有我需要的大部分动画功能.在我的所有iOS / Android设备上,Solitaire的应用商店版本运行良好.一个小错误是可以拖动一组卡片,包括一些朝下的卡片,这些卡片在拖动操作期间面朝上.另外很难准确地拿出适量的卡片.拖动一组卡片也会在屏幕上留下白色痕迹,看起来不太好看.这也发生在模拟器中.

作为一个实验,我重新设计了我的GUI布局,使其完全类似于Solitaire代码:两层按钮,唯一的区别是我使用GridLayout(10,10)Solitaire使用SolitaireLayout().这有效,除了一件事:如果棋子向下移动棋盘它会正确地移动到其他棋子上,但如果棋子向上移动棋盘,它会移动到其他棋子下面.

我的代码看起来像这样:

Button pc = (Button)piecesCnt.getComponentAt(a1);
Button to = (Button)piecesCnt.getComponentAt(a2);

piecesCnt.removeComponent(pc);
piecesCnt.addComponent(a1, createPieceButton(Piece.EMPTY_PIECE, true));
piecesCnt.removeComponent(to);
piecesCnt.addComponent(a2, pc);

piecesCnt.animateLayoutAndWait(1000);

所以似乎按钮总是按照GridLayout顺序绘制,而我希望动画(移动)按钮最后/顶部绘制,就像Solitaire中的移动卡一样.

这是处理SolitaireLayout与GridLayout中的动画之间的区别吗?如果是这样,可以在动画逻辑中更改吗?否则我必须添加额外的动画层和大量的开销.

在Android上,动画(动作)无法正常工作.因此,我决定使用当前的CN1版本(插件3.2.6,libs 2016-01-11)在我的设备上自行构建和测试Solitaire演示.我将动画更改为慢了10倍,以便更好地了解正在发生的事情.在模拟器中,布局和动画效果很好,但在我的iOS和Android设备上存在很多问题.

模拟器(Windows 7,NetBeans 8.0.2):
– 我删除了字体图标,因为它们丢失了.
– 但是如何进入汉堡包菜单?我没有看到3个点,甚至没有空间.
– 有时候可以用一些下注卡来拖动一组牌;拖着他们暂时翻转面朝上.
– 自动播放似乎并不总是有效. (并非所有动作都被播放.)

在iOS 9.2(iPad 4),iOS 8.4(iPhone 4)上:
– [?]显示在汉堡菜单复选框中.
– 启动后,画面背景卡片后退跳转到容器/屏幕的底部.
– 有时,在甲板上的动画片中,最右边的画面中的卡片暂时朝上,而面朝上的卡片面朝下翻转.然而,最终的交易状态是正确的.
– 撤消/重做:有时会在甲板0上形成面朝上的牌,在甲板1上面朝下.
– 重做有时会“跳转”到新的布局而不是动画.
仅限iPhone:
– 一系列自动播放动作留下了不稳定的基础状态:顶级牌心-J,俱乐部-10,俱乐部-K,钻石-Q;即,在不同的基础堆栈上的2张俱乐部卡.

在Android 5.1.1(Nexus 7)上存在更多问题.
– 来自甲板的交易动画不是很好看.卡片插入(滑动到)桌面堆叠的底部,因此它们可以在其他卡片下方滑动.移动的卡片应朝下,但通常朝上,始终显示第一张卡片送到画面1.最右边的画面卡片暂时朝上.最后,面朝上的卡片面朝下翻转,然后再翻转.然而,最终的交易状态是正确的.
– 连续多次移动时,自动播放也不正确.在动画期间,面朝上的几张基础卡暂时改变其卡片值(正面).此外,移动的卡片在基础卡片下面滑动(有时会超过,但这是例外).
– 完成游戏后,完成的屏幕已损坏,因为文本似乎显示未覆盖但在卡片下方(在大的白色空间中),这些仅在屏幕顶部的一小部分中部分可见.
– 开始一个新游戏经常失败,因为没有开始从甲板交易;屏幕显示一个甲板和四个国王在基础上空,画面空.当敲击牌组时,会发出一张牌并显示完成的顺序.有时重复此操作会导致成功开始新游戏.

所有这些已经花了很多时间,我仍然没有让我的应用程序再次工作,这是非常令人沮丧的.对于这个主题有这么多麻烦,即使使用下载的演示应用程序,使用Codename One构建这种类型的应用程序感觉就像在流沙上构建一样.请帮忙!

最佳答案 一旦你遇到麻烦而不是在帖子上努力工作,你可能应该问过.是的,我们确实做了一个主要的兼容性破坏性更改,作为长期动画问题的错误修复的一部分(并行运行的动画可能会发生碰撞).

这引入了一些冲突,但减少了设备/模拟器之间的不一致性,这总是一件好事.

我们在这里宣布:https://www.codenameone.com/blog/new-animation-manager.html

现在创建便携式动画实际上更简单,因为所有内容都将被同步以避免动画冲突,例如如果在动画正在进行时执行Component.removeComponent(),它将隐式添加到动画队列中,并在动画完成后执行,而不是立即执行.

要推迟你的下一个动作,直到我们有动画:

form.getAnimationManager().flushAnimation(() -> doThisAfterAnimation());

更简单,没有特殊情况全局锁定.

将代码直接“移植”到新方法有点困难,但看起来你的动画逻辑依赖于动画需要1000毫秒并且当方法返回时它完全完成,这可能并非总是如此(作为添加/删除调用或其他逻辑可能会妨碍).

在过去,保证动画完成的唯一方法是将它们分开,但现在您可以使用flushAnimation来确保所有动画都已完成.请记住,一些未明确动画的内容现在可能会偶然成为动画,例如如果在调用动画时正在进行动画,则添加/删除组件将成为动画…

点赞