我正在使用swift和库SpriteKit创建一个Snake Game。
要控制蛇的方向,用户必须在屏幕上滑动。要检查滑动方向,请使用UISwipeGestureRecognizer
。
现在,我必须将信息(滑动方向)从GameViewController.swift
文件传递到GameScene.swift
文件。为此,我声明了一个名为movesConoller
的4项数组:
movesController[false, false, false, false]
[如果用户向上滑动,则数组的第一个元素变为true;如果向下滚动,则第二个元素变为true,而第一个元素为false ...等等。
现在,在GameScene.swift
文件中,我必须说说如果玩家上移,Snake必须做什么。因此,我使用了另外两个变量:
var playerX:CGFloat = 0
var playerY:CGFloat = 0
然后创建此代码
if movesController[0] == true {
playerY += 56
}
if movesController[1] == true {
playerY -= 56
}
if movesController[2] == true {
playerX += 56
}
if movesController[3] == true {
playerX -= 56
}
现在我创建机芯
let startPoint = CGPoint(x: player.position.x, y: player.position.y )
let endPoint = CGPoint(x: playerX + player.position.x, y: playerY + player.position.y)
let moveIt = SKAction.move(to: endPoint, duration:0.1)
player.run(moveIt)
因此,每次执行程序时,playerX
和playerY
变量等于0。然后,根据滑动方向,将其相加或相减56。要移动蛇,我只是说要在0.1秒内将其从startPoint
移至endPoint
。
我添加的另一件事是尾巴。为了创建它,我使用了两个数组snakeX
和snakeY
。向这两个空数组(CGFloat类型)添加蛇的先前位置,然后,如果分数保持不变,则删除每个数组的最后一个元素。否则,最后一个元素不会被删除,而是保留在他的数组中。
用这种方法,当蛇吃一个苹果时,我使尾巴长出来。
但是头部在0.1秒内移动56。这意味着他每次执行移动8个像素。因此,每执行7个程序,我就必须在snakeX
和snakeY
中添加X和Y值。
这是问题。如果在程序执行7次后玩家在屏幕上滑动,则尾巴的移动将是完美的。但是如果玩家在执行7之前滑动,就会出现问题。假设蛇在向右移动,并且在程序执行第4次时玩家向上滑动。
//snakeX and snakeY values before the swipe
snakeX[168, 112, 56, 0] //all this numbers are multiple of 56
snakeY[224, 224, 224, 224] //the snake is moving right, the Y value doesn't change.
//snakeX and snakeY values after the swipe
snakeX[168 ,112 ,56 , 0]
snakeY[248, 224, 224, 224] //look at the first element
248不是56的倍数。蛇在第4次执行时上移,在3次执行后其位置将添加到数组中。但是在3次执行中,他移动了24像素。因此,我将收到此错误
正如您所看到的,尾巴不是一个完美的角落。
蛇头无法完成56像素的移动。当我滑动时,它离开了他的动作并开始了另一个动作。有没有办法让我的头在完成另一个动作之前总是先完成他的动作?
您正在尝试将基于像素的方法用于基本上是基于网格的游戏,但是类似的方法可能会起作用...
使变量控制是否允许移动:
var moveAllowed = true
使用该变量保护您的移动代码:
if moveAllowed {
if movesController[0] == true {
playerY += 56
}
...
}
当您计划移动动作时,切换moveAllowed
,并添加完成处理程序以在动作完成后将其切换回原处:
...
moveAllowed = false
let moveIt = SKAction.move(to: endPoint, duration:0.1)
player.run(moveIt) { self.moveAllowed = true }
((self.moveAllowed
可能只是moveAllowed
,具体取决于您的结构如何,但我无法从片段中分辨出来。)
编辑:我刚刚意识到也许您正在基于snakeX
设置snakeY
和player.position
。还不清楚。无论如何,您将使用相同的想法,但仅当player.position
为moveAllowed
时才从true
复制。基本上,该变量会告诉您操作是否仍在运行。