我正在制作类似于“钢琴瓷砖”的游戏https://itunes.apple.com/us/app/piano-tiles-dont-tap-white/id848160327?mt=8
即使较早的动画尚未完成,您也可以点击图块。
这是我的实现
- (void)moveDown {
[UIView animateWithDuration:DURATION_MOVE_DOWN delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
for (Tile *t in self.tiles) {
if (t.y == NUM_TILES_Y - 1) {
t.y = 0;
}
else {
t.y++;
}
if (t.y == 0) {
//move down
//then place it to the top (in the completion handler)
t.frame = [Tile frameWithX:t.x y:NUM_TILES_Y];
}
else {
//move down
t.frame = [Tile frameWithX:t.x y:t.y];
}
}
} completion:^(BOOL finished) {
for (Tile *t in self.tiles) {
//if user tap while animating, just place the tile at its final position first, (then continue the new animation)
t.frame = [Tile frameWithX:t.x y:t.y];
}
[self assignTouchDontTouchWithRowY:0];
}];
}
AssignTouchDontTouchWithRowY方法是随机选择一行中的一个图块为TileTypeTouch(黑色图块),其余行作为TileTypeDontTouch(白色图块)
- (void)assignTouchDontTouchWithRowY:(int)y {
int touchX = [Helper randomIntInclusiveBetweenLow:0 High:NUM_TILES_X -1];
for (int x = 0; x < NUM_TILES_X; x++) {
Tile *t = [self tileWithX:x y:y];
if (x == touchX) {
t.type = TileTypeTouch;
}
else {
t.type = TileTypeDontTouch;
}
}
}
问题是,当我在完成较早的动画之前按一个图块时,某些代码未执行(例如,为新行着色,向下移动一行,有时底部的行会从上方翻译到顶部而不是滑动首先向下,然后放在顶部)
当我使用
UIViewAnimationOptionBeginFromCurrentState
选项时,当较早的一个动画时,用户交互将被取消。因此它也不起作用。编辑:
在屏幕截图中,(0,1)磁贴是倒数第二个,它被平移到顶部(不向下滑动并更新其颜色)
还请注意,在(y = 1)行上方,屏幕外还有另一行(y = 0)。
即有5行,其中有4行在屏幕上,而第一行(y = 0)位于屏幕外部的顶部。向下滑动时,最后一行(y = 4)首先向下滑动,然后将其放在完成处理程序的顶部(y = 0)
编辑3:
以防万一我的逻辑不清楚:
编辑4:
视频中显示了错误
https://drive.google.com/file/d/0B-iP0P7UfFj0Q01neEhaZmtBY2c/edit?usp=sharing
最佳答案
完成块是在新动画之后执行的(调用-moveDown时会立即发生
完工块什么时候执行?我们不知道!它在排队/ future !
因此,将前一个动画的清理代码移到moveDown的开头(动画之外),并且不要忘记检查(完成)是否省去了一些不必要的工作
- (void)moveDown {
Tile *t = self.tiles[0];
if (t.layer.animationKeys.count) {
for (Tile *t in self.tiles) {
t.frame = [Tile frameWithX:t.x y:t.y];
}
[self assignTouchDontTouchWithRowY:0];
}
[UIView animateWithDuration:DURATION_MOVE_DOWN delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
NSLog(@"anim");
for (Tile *t in self.tiles) {
if (t.y == NUM_TILES_Y - 1) {
t.y = 0;
}
else {
t.y++;
}
if (t.y == 0) {
//move down
//then place it to the top (in the completion handler)
t.frame = [Tile frameWithX:t.x y:NUM_TILES_Y];
}
else {
//move down
t.frame = [Tile frameWithX:t.x y:t.y];
}
}
} completion:^(BOOL finished) {
if (finished) {
for (Tile *t in self.tiles) {
if (t.y == 0) {
t.frame = [Tile frameWithX:t.x y:t.y];
}
}
[self assignTouchDontTouchWithRowY:0];
}
}];
}
关于ios - iOS View 动画允许用户交互,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23728969/