Swift 从斯普瑞泰诺德发射子弹

Swift 从斯普瑞泰诺德发射子弹,swift,sprite-kit,skspritenode,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 = s

我尝试建立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))
}
但是,我不知道如何正确设置位置。。。 我试着做这样的东西
(绿点-这是一个项目符号)。谁能帮帮我吗

假设您的播放器是一个由
SKShapeNode
SKSpriteNode
组成的圆圈

它们都具有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

假设您的播放器是一个由
SKShapeNode
SKSpriteNode
组成的圆圈

它们都具有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

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

可以通过以下方式计算子弹在场景中的初始位置:

let point = node.convertPoint(weapon.position, toNode: 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)
    }
}
struct武器{
var位置:CGPoint
}
类游戏场景:SKScene{
让sprite=SKSpriteNode(图像名为:“太空船”)
让双枪=[武器(位置:CGPoint(x:15,y:15)),武器(位置:CGPoint(x:15,y:15))]
让单枪=[武器(位置:CGPoint(x:0,y:15))]
设numGuns=1
//如果角色面朝上,其中zRotation==0,则偏移pi
设旋转偏移=CGFloat(M_PI_2)
覆盖func didMoveToView(视图:SKView){
scaleMode=.ResizeFill
sprite.position=view.center
sprite.size=CGSizeMake(25,25)
self.addChild(精灵)
}
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
如果让u=先接触{
let action=SKAction.rotateByAngle(CGFloat(M_PI_4/2),持续时间:1)
sprite.runAction(动作){
[虚弱的自我]在
如果让场景=自我{
开关(scene.numGuns){
案例1:
场景中的武器。单枪{
场景。拍摄(武器:武器,来源:场景。精灵)
}
案例2:
现场的武器,双枪{
场景。拍摄(武器:武器,来源:场景。精灵)
}
违约:
打破
}
}
}
}
}
func射击(武器:武器,来自节点:SKNode){
//将角色坐标系中的位置转换为场景坐标系
let converted=node.convertPoint(武器位置,音调:self)
//根据角色的旋转确定子弹的方向
让向量=旋转(CGVector(dx:0.25,dy:0),角度:node.zRotation+旋转偏移)
//创建具有物理实体的子弹
让bullet=SKSpriteNode(颜色:SKColor.blueColor(),大小:CGSizeMake(4,4))
bullet.physicsBody=SKPhysicsBody(圆圈半径:2)
bullet.physicsBody?重力影响=假
bullet.position=CGPointMake(转换为.x,转换为.y)
addChild(项目符号)
bullet.physicsBody?.applyImpulse(矢量)
}
//围绕z轴旋转点(或向量)
func旋转(矢量:CGVector,角度:CGFloat)->CGVector{
设rotatedX=vector.dx*cos(角度)-vector.dy*sin(角度)
旋转y=vector.dx*sin(角度)+vector.dy*cos(角度)
返回CGVector(dx:rotatedX,dy:rotatedY)
}
}

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

可以通过以下方式计算子弹在场景中的初始位置:

let point = node.convertPoint(weapon.position, toNode: 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)
    }
}
struct武器{
var位置:CGPoint
}
类游戏场景:SKScene{
让sprite=SKSpriteNode(图像名为:“太空船”)
让双枪=[武器(位置:CGPoint(x:15,y:15)),武器(位置:CGPoint(x:15,y:15))]
让单枪=[武器(位置:CGPoint(x:0,y:15))]
设numGuns=1
//如果角色面朝上,其中zRotation==0,则偏移pi
设旋转偏移=CGFloat(M_PI_2)
覆盖func didMoveToView(视图:SKView){
scaleMode=.ResizeFill
sprite.position=view.center
sprite.size=CGSizeMake(25,25)
self.addChild(精灵)
}
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
如果让u=先接触{
let action=SKAction.rotateByAngle(CGFloat(M_PI_4/2),持续时间:1)
sprite.runAction(动作){
[虚弱的自我]在
如果让场景=自我{
开关(scene.numGuns){