从SKSpriteNode射击子弹

时间:2016-07-04 10:07:12

标签: swift sprite-kit skspritenode

我尝试构建2D - 自上而下的游戏,我有玩家(SKSpriteNode)他可以移动和旋转,我想从他身上射出两颗子弹。 我用这段代码拍摄:

func setBullet(player: Player, bullet: Int)
{
    let weaponPosition = scene!.convertPoint(player.weapon.position, fromNode: player)
    var xPos, yPos: CGFloat!

    let sinus = sin(player.zRotation)
    let cosinus = cos(player.zRotation)

    if bullet == 1
    {
        xPos = converted.x - sinus * player.size.height / 2
        yPos = converted.y + cosinus * player.size.height / 2
    }
    else if bullet == 2
    {
        xPos = weaponPosition.x - sinus * player.size.height / 2
        yPos = weaponPosition.y + cosinus * player.size.height / 2
    }

    position = CGPoint(x: xPos, y: yPos)
    physicsBody!.applyImpulse(CGVector(dx: -sinus * normalSpeed, dy: cosinus * normalSpeed))
}

但是,我不知道如何正确设置位置...... 我试着做这样的事情this (绿点 - 这是子弹)。任何人都可以帮助我!

2 个答案:

答案 0 :(得分:1)

假设您的播放器是由SKShapeNodeSKSpriteNode制作的圈子。

它们都具有frame属性:

let f = player.frame

所以,第一颗子弹可以处于这个位置:

let firstBullet.position = CGPointMake(player.position.x-(f.width/2),player.position.y)
let secondBullet.position = CGPointMake(player.position.x+(f.width/2),player.position.y)

在旋转期间知道它:

let firstBulletXPos = firstBullet.position.x - sinus * bullet.size.height / 2
let firstBulletYPos = firstBullet.position.y + cosinus * bullet.size.height / 2

let secondBulletXPos = secondBullet.position.x - sinus * bullet.size.height / 2
let secondBulletYPos = secondBullet.position.y + cosinus * bullet.size.height / 2

答案 1 :(得分:1)

朝同一方向射击多发子弹相当简单。关键是确定子弹'旋转角色时的初始位置和方向向量。

你可以通过

计算一个子弹在场景中的初始位置
let point = node.convertPoint(weapon.position, toNode: self)

其中node是角色,weapon.position是枪的非旋转位置,self是场景。

通常,当角色未旋转时,子弹向右移动CGVector(dx:1, dy:0)或向上移动CGVector (dx:0, dy:1)。您可以通过字符“zRotation

旋转矢量来计算应用于子弹物理体的脉冲方向
func rotate(vector:CGVector, angle:CGFloat) -> CGVector {
    let rotatedX = vector.dx * cos(angle) - vector.dy * sin(angle)
    let rotatedY = vector.dx * sin(angle) + vector.dy * cos(angle)
    return CGVector(dx: rotatedX, dy: rotatedY)
}

这是一个如何从旋转的角色射出两颗子弹的例子:

struct Weapon {
    var position:CGPoint
}

class GameScene: SKScene {
    let sprite = SKSpriteNode(imageNamed:"Spaceship")
    let dualGuns = [Weapon(position: CGPoint(x: -15, y: 15)), Weapon(position: CGPoint(x: 15, y: 15))]
    let singleGun = [Weapon(position: CGPoint(x: 0, y: 15))]
    let numGuns = 1
    // If your character faces up where zRotation == 0, offset by pi
    let rotationOffset = CGFloat(M_PI_2)
    override func didMoveToView(view: SKView) {
        scaleMode = .ResizeFill
        sprite.position = view.center
        sprite.size = CGSizeMake(25, 25)
        self.addChild(sprite)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let _ = touches.first {
            let action = SKAction.rotateByAngle(CGFloat(M_PI_4/2), duration:1)
            sprite.runAction(action) {
                [weak self] in
                if let scene = self {
                    switch (scene.numGuns) {
                    case 1:
                        for weapon in scene.singleGun {
                            scene.shoot(weapon: weapon, from: scene.sprite)
                        }
                    case 2:
                        for weapon in scene.dualGuns {
                            scene.shoot(weapon: weapon, from: scene.sprite)
                        }
                    default:
                        break
                    }
                }
            }
        }
    }

    func shoot(weapon weapon:Weapon, from node:SKNode) {
        // Convert the position from the character's coordinate system to scene coodinates
        let converted = node.convertPoint(weapon.position, toNode: self)

        // Determine the direction of the bullet based on the character's rotation
        let vector = rotate(CGVector(dx: 0.25, dy: 0), angle:node.zRotation+rotationOffset)

        // Create a bullet with a physics body
        let bullet = SKSpriteNode(color: SKColor.blueColor(), size: CGSizeMake(4,4))
        bullet.physicsBody = SKPhysicsBody(circleOfRadius: 2)
        bullet.physicsBody?.affectedByGravity = false
        bullet.position = CGPointMake(converted.x, converted.y)
        addChild(bullet)
        bullet.physicsBody?.applyImpulse(vector)
    }

    // Rotates a point (or vector) about the z-axis
    func rotate(vector:CGVector, angle:CGFloat) -> CGVector {
        let rotatedX = vector.dx * cos(angle) - vector.dy * sin(angle)
        let rotatedY = vector.dx * sin(angle) + vector.dy * cos(angle)
        return CGVector(dx: rotatedX, dy: rotatedY)
    }
}