我制作的游戏类似于钢琴拼花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
答案 0 :(得分:1)
在新动画之后执行完成块(当你调用-moveDown
时会立即执行)何时执行完成块?我们不知道!它在队列/未来!
所以将上一个动画的清理代码移到moveDown的开头(在animiation之外,不要忘记检查是否(完成)以保存一些不必要的工作
- (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];
}
}];
}
答案 1 :(得分:0)
试试这个:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
if ([[movingView.layer presentationLayer] hitTest:touchPoint])
{
//Do stuff here
}
}
我是从here
得到的