我正在制作一款包含Swift
和SpriteKit
的简单游戏。
我想添加一个无尽的背景(垂直),我只找到了背景与图像的答案,但我需要做到没有图像,只有背景颜色。
我考虑过检查玩家是否在frame.maxY
,如果是,将其移回起点,但我想知道是否有更好的想法。
//Does not matter which ring we chose as all ring's 'y' position is the same.
func moveBackgroundUp(){
if ((mPlayer.position.y >= self.frame.maxY) || (mRingOne.position.y >= self.frame.maxY)) {
mPlayer.position.y = 150 //mPlayers original starting point.
for ring in mRings {
ring.position.y = 350
}
}
}
提前致谢!
答案 0 :(得分:3)
不要只是在屏幕上移动背景,那就是'真的不是这样的方式。你应该做的是检测相机的位置(假设它与玩家一起移动),当它的位置即将占据你当前背景精灵的占用空间之外的空间时,添加一个新的背景精灵到最后一个离开的场景。这是一个如何使用红色精灵来做到这一点的例子:
首先向场景添加属性以跟踪关卡位置:
await Navigation.PushAsync (new ContactPage());
现在创建一个更新背景的方法:
// To track the y-position of the level
var levelPositionY: CGFloat = 0.0
现在,您要在覆盖的func updateBackground() {
let cameraPos = camera!.position
if cameraPos.y > levelPositionY - (size.height * 0.55) {
createBackground()
}
}
func createBackground() {
// Create a new sprite the size of your scene
let backgroundSprite = SKSpriteNode(color: .red, size: size)
backgroundSprite.anchorPoint = CGPoint(x: 0.5, y: 0)
backgroundSprite.position = CGPoint(x: 0, y: levelPositionY)
// Replace backgroundNode with the name of your backgroundNode to add the sprite to
backgroundNode.addChild(backgroundSprite)
levelPositionY += backgroundSprite.size.height
}
方法中调用updateBackground
:
update(_:)
此外,请确保在首次创建场景时创建初始背景:
override func update(_ currentTime: TimeInterval) {
// All your other update code
updateBackground()
}
注意! - 为背景精灵设置自定义锚点以使此代码正常工作非常重要。 (0.5,0)的锚点允许背景精灵在x轴上锚定在场景的中间,但在y轴的场景底部。这使您可以轻松地将一个堆叠在另一个之上。
编辑 - 我忘了提及保存资源并删除可见区域之外的任何背景节点并且不会再回来的好主意(即连续滚动游戏,你不能倒退)。您可以通过更新上面的override func didMove(to view: SKView) {
createBackground()
}
方法来实现这一目标:
updateBackground
因此,您只需遍历后台节点中的所有子节点,并检测它们是否在视图之外,如果是,则从父节点中删除它们。确保将我的通用func updateBackground() {
let cameraPos = camera!.position
if cameraPos.y > levelPositionY - (size.height * 0.55) {
createBackground()
}
// Make sure to change 'backgroundNode' to whatever the name of your backgroundNode is.
for bgChild in backgroundNode.children {
// This will convert the node's coordinates to scene's coordinates. See below for this function
let nodePos = fgNode.convert(fgChild.position, to: self)
if !isNodeVisible(bgChild, positionY: nodePos.y) {
// Remove from it's parent node
bgChild.removeFromParent()
}
}
}
func isNodeVisible(_ node: SKNode, positionY: CGFloat) -> Bool {
if !camera!.contains(node) {
if positionY < camera!.position.y - size.height * 2.0 {
return false
}
}
return true
}
更改为您的后台节点的名称。