- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当节点层次结构被编码时,就像在应用程序状态保存或“游戏保存”期间常见的那样,运行带有代码块的 SKAction
Action 的节点必须被特殊处理,因为代码块不能被编码.
在这里,一个兽人被杀死了。它动画淡出,然后从节点层次结构中删除自身:
SKAction *fadeAction = [SKAction fadeOutWithDuration:3.0];
SKAction *removeAction = [SKAction removeFromParent];
[orcNode runAction:[SKAction sequence:@[ fadeAction, removeAction ]]];
如果对 orc 节点进行编码然后解码,动画将正确恢复并按预期完成。
但是现在示例被修改为使用在淡入淡出之后运行的代码块。一旦兽人(最终)死了,代码可能会清理一些游戏状态。
SKAction *fadeAction = [SKAction fadeOutWithDuration:3.0];
SKAction *removeAction = [SKAction removeFromParent];
SKAction *cleanupAction = [SKAction runBlock:^{
[self orcDidFinishDying:orcNode];
}];
[orcNode runAction:[SKAction sequence:@[ fadeAction, removeAction, cleanupAction ]]];
不幸的是,代码块不会编码。在应用程序状态保存(或游戏保存)期间,如果此序列正在运行,将发出警告:
SKAction: Run block actions can not be properly encoded, Objective-C blocks do not support NSCoding.
解码后,orc 会淡出并从父对象中移除,但清理方法orcDidFinishDying:
不会被调用。
解决此限制的最佳方法是什么?
SKAction
customActionWithDuration:actionBlock:
似乎非常适合补间。我对这种事情的样板代码是这样的:
SKAction *slideInAction = [SKAction customActionWithDuration:2.0 actionBlock:^(SKNode *node, CGFloat elapsedTime){
CGFloat normalTime = (CGFloat)(elapsedTime / 2.0);
CGFloat normalValue = BackStandardEaseInOut(normalTime);
node.position = CGPointMake(node.position.x, slideStartPositionY * (1.0f - normalValue) + slideFinalPositionY * normalValue);
}];
不幸的是,customActionWithDuration:actionBlock:
无法编码。如果游戏在动画期间保存,则在游戏加载时将无法正确恢复。
同样,解决此限制的最佳方法是什么?
以下是我考虑过但不喜欢的解决方案。 (也就是说,我很乐意阅读成功支持其中一个的答案。)
不完美的解决方案:在动画中使用 performSelector:onTarget:
而不是 runBlock:
。这个解决方案是不完美的,因为不能将参数传递给被调用的选择器;调用的上下文只能由目标和选择器的名称来表达。不太好。
不完美的解决方案:在编码期间,从所有相关节点中删除 SKAction
序列,并推进程序状态,就好像该序列已完成一样。在第一个示例中,这意味着立即将节点 alpha
设置为 0.0
,从父节点中删除 orc 节点,并调用 orcDidFinishDying:
。这是一个不幸的解决方案,至少有两个原因:1)它在编码期间需要特殊的处理代码; 2) 在视觉上,节点不会有机会完成它的动画。
不完美的解决方案:在编码期间,从任何相关节点中删除 SKAction
代码块,并在解码期间重新创建它们。这很重要。
不完美的解决方案:永远不要使用 SKAction
代码块,尤其是在延迟之后。永远不要依赖动画的完成来恢复良好的应用程序状态。 (如果您需要以可编码的方式安排 future 事件,请构建您自己的事件队列而不是使用代码块。)此解决方案是不完美的,因为 runBlock
和 customActionWithDuration:actionBlock:
它们实在是太有用了,认为它们是邪恶的将是一种耻辱(对于新手来说也是一个反复出现的陷阱)。
最佳答案
可编码的轻量级对象可以模拟我们想要使用(但不能)的各种SKAction
代码块。
以下想法的代码是 here .
runBlock
第一个可编码的轻量级对象取代了 runBlock
。它可以使用一个或两个参数进行任意回调。
调用者实例化轻量级对象并设置其属性:目标、选择器和参数。
轻量级对象由标准无参数 [SKAction performSelector:onTarget:]
在 runAction
动画中触发。对于这个触发 Action ,目标是轻量级对象,选择器是指定的“执行”方法。
轻量级对象符合NSCoding
。
作为奖励,触发 SKAction
保留了对轻量级对象的强引用,因此两者都将与运行操作的节点一起编码。
这个轻量级对象的一个版本可以弱保留目标,这可能是好的和/或必要的。
这是一个可能的界面草稿:
@interface HLPerformSelector : NSObject <NSCoding>
- (instancetype)initWithTarget:(id)target selector:(SEL)selector argument:(id)argument;
@property (nonatomic, strong) id target;
@property (nonatomic, assign) SEL selector;
@property (nonatomic, strong) id argument;
- (void)execute;
@end
以及伴随的实现:
@implementation HLPerformSelector
- (instancetype)initWithTarget:(id)target selector:(SEL)selector argument:(id)argument
{
self = [super init];
if (self) {
_target = target;
_selector = selector;
_argument = argument;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
_target = [aDecoder decodeObjectForKey:@"target"];
_selector = NSSelectorFromString([aDecoder decodeObjectForKey:@"selector"]);
_argument = [aDecoder decodeObjectForKey:@"argument"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_target forKey:@"target"];
[aCoder encodeObject:NSStringFromSelector(_selector) forKey:@"selector"];
[aCoder encodeObject:_argument forKey:@"argument"];
}
- (void)execute
{
if (!_target) {
return;
}
IMP imp = [_target methodForSelector:_selector];
void (*func)(id, SEL, id) = (void (*)(id, SEL, id))imp;
func(_target, _selector, _argument);
}
@end
以及使用它的例子:
SKAction *fadeAction = [SKAction fadeOutWithDuration:3.0];
SKAction *removeAction = [SKAction removeFromParent];
HLPerformSelector *cleanupCaller = [[HLPerformSelector alloc] initWithTarget:self selector:@selector(orcDidFinishDying:) argument:orcNode];
SKAction *cleanupAction = [SKAction performSelector:@selector(execute) onTarget:cleanupCaller];
[orcNode runAction:[SKAction sequence:@[ fadeAction, removeAction, cleanupAction ]]];
customActionWithDuration:actionBlock:
第二个可编码的轻量级对象替换了 customActionWithDuration:actionBlock:
。然而,这并不是那么简单。
同样,它由无参数 [SKAction performSelector:onTarget:]
触发,调用指定的 execute
方法。
customActionWithDuration:actionBlock:
有持续时间。但是触发 performSelector:onTarget:
不会。调用者必须在她的序列中插入伴随的 waitForDuration:
操作(如果它取决于持续时间)。
轻量级对象使用目标、选择器、节点和持续时间进行初始化。
当它被触发时,轻量级对象会跟踪自己的耗时并定期调用目标上的选择器,将节点和耗时传递给它。
轻量级对象符合NSCoding
。在解码时,如果已被触发,它将在其配置的剩余时间内继续调用选择器。
我已经实现了 a version of these proposed classes .通过轻度使用,我已经发现了一个重要的限制:Nodes encoded with a running SKAction
sequence restart the sequence from the beginning upon decoding .
关于ios - 在应用程序状态保存期间解决 SKAction 代码块编码限制的好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35249269/
我对自定义 CSS 或在将图像作为 Logo 上传到页面时使用编码 block 有疑问。我正在为我的网站使用 squarespace,我需要帮助编码我的 Logo 以使其适合每个页面。一个选项是使用自
如 encoding/json 包文档中所述, Marshal traverses the value v recursively. If an encountered value implement
我必须做一些相当于Java中的iconv -f utf8 -t sjisMS $INPUT_FILE的事情。该命令在 Unix 中 我在java中没有找到任何带有sjisMS的编码。 Java中有Sh
从 PHP 5.3 迁移到 PHP 5.6 后,我遇到了编码问题。我的 MySQL 数据库是 latin1,我的 PHP 文件是 windows-1251。现在一切都显示为“ñëåäíèòå àäðå
我有一个 RScript文件(我们称之为 main.r ),它引用了另一个文件,使用以下代码: source("functions.R") 但是,当我运行 RScript 文件时,它提示以下错误:
我无法设法从 WSDL 创建 RPC/编码风格的代码 - 有谁知道哪个框架可以做到这一点? 带有 adb 和 xmlbeans 映射的 Axis2 无法正常工作(无法处理响应中的肥皂编码)直接使用 X
安装了最新版本的Node.Js()和npm包**(1.2.10)**当我运行 Express 命令来生成项目时,它向我抛出以下错误 buffer.js:240 switch (encoding &
JavaScript中有JSON编码/解码base64编码/解码函数吗? 最佳答案 是的,btoa() 和 atob() 在某些浏览器中可以工作: var enc = btoa("this is so
>>> unicode('восстановление информации', 'utf-16') Traceback (most recent call last): File "", line
我当然熟悉 java.net.URLEncoder 和 java.net.URLDecoder 类。但是,我只需要 HTML 样式的编码。 (我不想将 ' ' 替换为 '+' 等)。我不知道任何只做
有一个非常简单的 SSIS 包: OLE DB Source 通过 View 获取数据(数据库表 nvarchar 或 nchar 中的所有字符串列)。 派生列,用于格式化现有日期并将其添加到数据集(
我正在使用一个在 Node 中进行base64编码的软件,如下所示: const enc = new Buffer('test', 'base64') console.log(enc) 显示: 我正
前言 下文介绍的自定义协议仅作为学习示例,纯粹是玩具项目,没有实际可用性。无需过度关注和讨论其合理性 进行通信的双方是谁? 常见的模型 客户端-服务器,例如HTTP协议,浏览器<=>
我试图将带有日语字符的数据插入到 oracle 数据库中。事情是保存在数据库中的是一堆倒置的问号。我该如何解决这个问题 最佳答案 见 http://www.errcode.net/blogs/?p=6
当我在 java 中解压 zip 文件时,我发现文件名中出现了带有重音字符的奇怪行为。 西索: Add File user : L'equipe Technique -- Folder : spec
在网上冲浪我找到了 ExtJS 的 Ext.Gantt 插件,该扩展有一个特殊的编码。任何人都知道如何编码那样或其他复杂的形式。 Encoded Gantt Chart 最佳答案 它似乎被 Dean
我正在用C语言做一个编码任务,我进展顺利,直到读取符号并根据表格分配相应的代码的部分。我必须连接几个代码,直到它们的长度达到 32 位,为此我必须将它们写入一个文件中。这种写入文件的方法给我带来了很多
我有一个外部链接的 javascript 文件。在那个 javascript 里面,我有这个功能: function getMonthNumber(monthName){ monthName = mo
使用mechanize,我检索到一个网页的源页面,其中包含一些非ASCII字符,比如汉字。 代码如下: #using python2.6 from mechanize import Browser b
我有一个包含字母 ø 的文件。当我用这段代码 File.ReadLines(filePath) 读取它时,我得到了一个问号而不是它。 当我像这样添加编码时 File.ReadLines(filePat
我是一名优秀的程序员,十分优秀!