#ios #swift #sprite-kit
#iOS #swift #sprite-kit
Вопрос:
Я работаю над игрой, в которой у меня есть основной узел прокрутки, кто-нибудь знает, как я мог бы изменить размер основного узла в зависимости от того, на каком устройстве он запущен? У меня есть способ определить, на каком устройстве запущена игра, и изменение размера всех других узлов в моей игре отлично работает, кроме основного узла. Я пытался это сделать, но безуспешно.
Заранее благодарю вас.
Способ определить, на каком устройстве запущена игра:
func determineDevice() {
if view!.bounds.width == 480.0 { //IP4
isIphone4 = true
isIphone5 = false
isIphone6 = false
isIphone6Plus = false
}
if view!.bounds.width == 568.0 { //IP5
isIphone4 = false
isIphone5 = true
isIphone6 = false
isIphone6Plus = false
}
if view!.bounds.width == 667.0 { //IP6
isIphone4 = false
isIphone5 = false
isIphone6 = true
isIphone6Plus = false
}
if view!.bounds.width == 736.0 { //IP6
isIphone4 = false
isIphone5 = false
isIphone6 = false
isIphone6Plus = true
}
}
Вот пример, как я устанавливаю размер всех других узлов в моей игре в зависимости от размера экрана:
class GameScene: SKScene, SKPhysicsContactDelegate {
var screenWidth:CGFloat = 0
var screenHeight:CGFloat = 0
override func didMoveToView(view: SKView) {
screenWidth = self.view!.bounds.width
screenHeight = self.view!.bounds.height
node.size = CGSizeMake(screenWidth / 5.5, screenHeight / 6)
}
}
И последнее, но не менее важное: основной код:
func initializingScrollingGround() {
for var index = 0; index < 2; index = 1 {
ground = SKSpriteNode(imageNamed:"Ground_Layer")
ground.size = CGSize(width: frame.width, height: frame.height / 6)
ground.position = CGPoint(x: index * Int(ground.size.width), y: Int(screenHeight - 37))
ground.zPosition = 10
ground.anchorPoint = CGPointZero
ground.name = "Ground"
let offsetX = ground.size.width * ground.anchorPoint.x
let offsetY = ground.size.height * ground.anchorPoint.y
let path = CGPathCreateMutable()
CGPathMoveToPoint(path, nil, 0 - offsetX, 48 - offsetY)
CGPathAddLineToPoint(path, nil, 0 - offsetX, 0 - offsetY)
CGPathAddLineToPoint(path, nil, 665 - offsetX, 0 - offsetY)
CGPathAddLineToPoint(path, nil, 668 - offsetX, 48 - offsetY)
CGPathCloseSubpath(path)
ground.physicsBody = SKPhysicsBody(polygonFromPath: path)
ground.physicsBody?.categoryBitMask = PhysicsCatagory.ground
ground.physicsBody?.collisionBitMask = PhysicsCatagory.dragon
ground.physicsBody?.contactTestBitMask = PhysicsCatagory.dragon
ground.physicsBody?.affectedByGravity = false
ground.physicsBody?.dynamic = false
ground.physicsBody?.restitution = 0
self.worldNode.addChild(ground)
}
}
В методе обновления:
func moveGround() {
self.worldNode.enumerateChildNodesWithName("Ground", usingBlock: { (node, stop) -> Void in
if let Ground = node as? SKSpriteNode {
Ground.position = CGPoint(x: Ground.position.x - self.groundVelocity, y: Ground.position.y)
// Checks if ground node is completely scrolled off the screen, if yes, then puts it at the end of the other node.
if Ground.position.x <= -Ground.size.width {
Ground.position = CGPointMake(Ground.position.x Ground.size.width * 2, Ground.position.y)
}
}
})
}
Кто-нибудь знает, как я мог бы решить мою проблему?
Комментарии:
1. вы работаете в режиме масштабирования изменения размера?
2. @Knight0fDragon нет, с AspectFill
3. хорошо, тогда ваш подход неверен. Цель scaleMode (за исключением изменения размера) — иметь размер сцены 1, который масштабируется по любому аспекту и размеру. По сути, ваш «размер экрана» — это размер вашей сцены, а длина и высота отдельного пикселя будут определяться разницей в масштабе вашего размера сцены и вашего фактического размера экрана, если это имеет для вас какой-либо смысл
4. чтобы упростить цифры, предположим, что на реальном устройстве 1 пиксель равен 1 дюйму, а в строке 10 пикселей. Вы создаете сцену размером 5 пикселей подряд. При масштабировании 1 пиксель будет иметь длину 2 дюйма, так что мы можем поместить 5 пикселей в длину 10 пикселей. Если мы перейдем к устройству с 15 пикселями, то сцена будет иметь 1 пиксель длиной 3 дюйма.
5. @Knight0fDragon хорошо, я никогда раньше не работал с представлениями, я собираюсь погуглить, как это работает. скоро вернусь. Спасибо
Ответ №1:
Можно попробовать один из подходов SKCameraNode
, тогда все ваши узлы будут меняться вместе. В этом примере используется расширение на SKCameraNode
и различается только между iPad и iPhone;
// SKCameraNode Extensions.swift
extension SKCameraNode {
func updateScaleFor(userInterfaceIdiom: UIUserInterfaceIdiom, isLandscape: Bool) {
switch userInterfaceIdiom {
case .phone:
self.setScale(isLandscape ? 0.75 : 1.0)
case .pad:
self.setScale(isLandscape ? 1.0 : 1.25)
default:
break
}
}
}
Затем, когда ваша сцена загружается;
camera.updateScaleFor(userInterfaceIdiom: UIDevice.current.userInterfaceIdiom, isLandscape: true)