我正在创建一个射击游戏,我正在尝试创建一个射击方法,但我当前的方法只在点击时生成一个子弹。我将我的子弹定义为SKnode子类,并在我的gameScene.swift中使用touches start方法调用它。这是
的方式class Bullet1: SKNode {
var Bullet1:SKSpriteNode = SKSpriteNode()
var Bullet1Animaton:SKAction?
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init () {
super.init()
}
func createBullet1s (){
let wait:SKAction = SKAction.waitForDuration( CFTimeInterval(0.25))
let block:SKAction = SKAction.runBlock(createBullet1)
let seq2:SKAction = SKAction.sequence( [block, wait])
SKAction.repeatActionForever(seq2)
self.runAction(seq2, withKey:"droneAction")
}
func createBullet1() {
Bullet1 = SKSpriteNode(imageNamed: "bullet.png")
Bullet1.xScale = 0.5
Bullet1.yScale = 0.5
Bullet1.physicsBody = SKPhysicsBody(rectangleOfSize: Bullet1.size)
Bullet1.physicsBody?.categoryBitMask = PhysicsCategory.bullet1
Bullet1.physicsBody?.contactTestBitMask = PhysicsCategory.enemy1
Bullet1.physicsBody?.affectedByGravity = false
Bullet1.physicsBody?.dynamic = true
self.addChild(Bullet1)
self.name = "Bullet1"
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
override func touchesBegan(touches: Set<UITouch>, withEvent
event:UIEvent?) {
override func touchesBegan(touches: Set<UITouch>, withEvent
event:UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
if (CGRectContainsPoint(joystick.frame, location)) {
stickActive = true
fireWeapon = true
}else{
stickActive = false
}
if stickActive == true && fireWeapon == true{ if fireWeapon == false
{}
let bulletAction = SKAction.runBlock({
let v = CGVector(dx: location.x - self.joystickBase.position.x, dy:
location.y - self.joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)
print(deg + 180) // prints degree in debugging
self.hero.zRotation = angle - 1.57079633 //rotates with angle of joy
stic
let bullet1:Bullet1 = Bullet1()
bullet1.createBullet1()
bullet1.position = CGPoint (x: self.hero.position.x , y:
self.hero.position.y) // Bullet spawn @ anchor point
let xDist:CGFloat = sin(angle - 1.5709633) * 35 //bullet spawn location
let yDist:CGFloat = cos(angle - 1.5709633) * 35 //bullet spawn location
bullet1.position = CGPointMake( self.hero.position.x - xDist,
self.hero.position.y + yDist) //spawning bullet @ defined location
let xDistMove:CGFloat = sin(angle - 1.5709633) * 700 //Bullet max x
distance
let yDistMove:CGFloat = cos(angle - 1.5709633) * 700 //Bullet max y
distance
let bulletMovementY = SKAction.moveToY(self.hero.position.y +
yDistMove, duration: 1) //Bullet y speed
let bulletMovementX = SKAction.moveToX(self.hero.position.x -
xDistMove, duration: 1) //Bullet x speed
bullet1.runAction(bulletMovementY)
bullet1.runAction(bulletMovementX)
self.addChild(bullet1)
})
let wait = SKAction.waitForDuration(0.25)
let completeSequence = SKAction.sequence([bulletAction, wait])
let repeatShootingActionForever =
SKAction.repeatActionForever(completeSequence)
self.runAction(repeatShootingActionForever, withKey: "BulletAction")
}
override func touchesMoved(touches: Set<UITouch>, withEvent event:
UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self
if (stickActive == true) {
let v = CGVector(dx: location.x - joystickBase.position.x, dy:
location.y - joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)
let length: CGFloat = joystickBase.frame.size.height / 2
print(deg + 180) // prints degree in debugging
joystick.position = location
hero.zRotation = angle - 1.57079633 //rotates with angle of joy stick
if (CGRectContainsPoint(joystickBase.frame, location)) {
}
override func touchesMoved(touches: Set<UITouch>, withEvent event:
UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
if stickActive == true && fireWeapon == true{ if fireWeapon == false
{}
let v = CGVector(dx: location.x - joystickBase.position.x, dy:
location.y - joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)//converts radains to degrees and
generates a degree when touchesmove == true
let length: CGFloat = joystickBase.frame.size.height / 2 //sets maximum
distance for joystick ball
print(deg + 180) // prints degree in debugging
joystick.position = location
self.hero.zRotation = angle - 1.57079633 //rotates with
angle of joy stick
let xDist:CGFloat = sin(angle - 1.5709633) * 35 //bullet spawn location
let yDist:CGFloat = cos(angle - 1.5709633) * 35 //bullet spawn location
bullet1.position = CGPointMake( self.hero.position.x - xDist,
self.hero.position.y + yDist) //spawning bullet @ defined location
let xDistMove:CGFloat = sin(angle - 1.5709633) * 700 //Bullet max x
distance
let yDistMove:CGFloat = cos(angle - 1.5709633) * 700 //Bullet max y
distance
let bulletMovementY = SKAction.moveToY(self.hero.position.y +
yDistMove, duration: 1) //Bullet y speed
let bulletMovemenX = SKAction.moveToX(self.hero.position.x - xDistMove,
duration: 1) //Bullet x speed
bullet1.runAction(bulletMovementY)
bullet1.runAction(bulletMovemenX)
}}
你可以看到我需要在触摸开始时调用我的子弹方法,因为子弹生成位置与操纵杆协调。当我按照我在createBullet1s方法中尝试的操纵杆按下操纵杆时,当前方法仅在点击时生成1个子弹而不是每0.25秒创建一个新子弹。如果有人能帮助我,我将非常感激!谢谢
答案 0 :(得分:1)
如果必须为每个项目符号计算新的值,那么这样的事情就是我猜的方法(在每个节点名称之前添加self.
):
if stickActive == true && fireWeapon == true{ if fireWeapon == false
{}
let shootingAction = SKAction.runBlock({
let v = CGVector(dx: location.x - joystickBase.position.x, dy:
location.y - joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)//converts radains to degrees and
generates a degree when touchesmove == true
print(deg + 180)
let bullet1:Bullet1 = Bullet1()
self.bullet1.createBullet1s()
self.bullet1.position = CGPoint (x: self.hero.position.x , y: self.hero.position.y)
let xDist:CGFloat = sin(angle - 1.5709633) * 35
let yDist:CGFloat = cos(angle - 1.5709633) * 35
self.bullet1.position = CGPointMake(self.hero.position.x - xDist,self.hero.position.y + yDist)
let xDistMove:CGFloat = sin(angle - 1.5709633) * 700
let yDistMove:CGFloat = cos(angle - 1.5709633) * 700
let bulletMovementY = SKAction.moveToY(self.hero.position.y + yDistMove,
duration: 1)
let bulletMovemenX = SKAction.moveToX(self.hero.position.x - xDistMove,
duration: 1)
let wait:SKAction = SKAction.waitForDuration(CFTimeInterval(0.25))
self.addChild(self.bullet1)
let groupMovement = SKAction.group([bulletMovementY,bulletMovementX])
let removeNode = SKAction.removeFromParent()
let sequenceMovementWithWait = SKAction.sequence([wait,groupMovement,removeNode])
self.hero.runAction(sequenceMovementWithWait)
self.hero.zRotation = angle - 1.57079633
})
let repeatShootingActionForever = SKAction.repeatActionForever(shootingAction)
self.runAction(repeatShootingActionForever, withKey: "BulletAction"))
如果每个项目的值可以保持不变,那么这样就足够了:
let bulletAction = SKAction.runBlock({
self.addChild(self.bullet1)
let groupAction = SKAction([bulletMovementY,bulletMovementX])
let removeNode = SKAction.removeFromParent()
let finalSequenceWithWait = SKAction.sequence([wait,groupAction,removeNode])
self.bullet1.runAction(finalSequenceWithWait)
})
let repeatBulletActionForever = SKAction.repeatActionForever(bulletAction)
self.runAction(repeatBulletActionForever, withKey: "BulletAction")
对于我在TouchesEnded
中所说的两种方式:
self.removeActionForKey("BulletAction")
编辑:
好的..你有一个SKNode子类,你可以将子弹(SpriteNodes)添加到SKNode。顺便说一下 - 它很复杂,因为你给了SpriteNodes和SKNode相同的名字。但是,子弹(SpriteNodes)会添加到SKNode中,而SKNode会添加到GameScene中。现在我们在gamescene中“生成”和“删除”这个SKNode,但是我们只将SpriteNodes添加到SKNode中,我们不会在那里删除它们。
你想在GameScene中同时看到多个子弹吗?如果你一次只需要1个子弹可见(但重复)我会说可能有助于从你的SKNode中删除Bullet(SpriteNode),就像我们在GameScene中那样。
想象一下:
- GameScene creates a SKNode. (your class Bullet1)
- SKNode creates Child SpriteNode
- GameScene removes the SKNode.
- GameScene creates another SKNode. (again your class Bullet1)
- SKNode wants to create Child SpriteNode
-> Error: SpriteNode already exists.
所以我们需要编辑你的课程。
//class Bullet1
func createBullet1() {
if Bullet1.parent == nil{
Bullet1 = SKSpriteNode(imageNamed: "bullet.png")
Bullet1.xScale = 0.5
Bullet1.yScale = 0.5
Bullet1.physicsBody = SKPhysicsBody(rectangleOfSize: Bullet1.size)
Bullet1.physicsBody?.categoryBitMask = PhysicsCategory.bullet1
Bullet1.physicsBody?.contactTestBitMask = PhysicsCategory.enemy1
Bullet1.physicsBody?.affectedByGravity = false
Bullet1.physicsBody?.dynamic = true
self.addChild(Bullet1)
self.name = "Bullet1"
}
else{
Bullet1.removeFromParent()
}
}
哦,我们需要等待0.25秒才能添加新的SKNode,以便动画完成。在你的GameScene编辑这部分:
let repeatShootingActionForever = SKAction.repeatActionForever(shootingAction)
self.runAction(repeatShootingActionForever, withKey: "BulletAction"))
到此:
let wait = SKAction.waitForDuration(0.25)
let runShootingAction = SKAction.runBlock(shootingAction)
let completeSequence = SKAction.sequence([wait,runShootingAction])
let repeatShootingActionForever = SKAction.repeatActionForever(completeSequence)
self.runAction(repeatShootingActionForever, withKey: "BulletAction"))
我打赌有更好的解决方案,我也不是Swift的专家。你必须测试..对不起。
另一个编辑: 你没有告诉子弹应该有哪个zRotation。
试试这个(你有bulletAction = SKAction.runBlock
):
let bulletAction = SKAction.runBlock({
let v = CGVector(dx: location.x - self.joystickBase.position.x, dy: location.y - self.joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)//converts radains to degrees and generates a degree when touchesmove == true
print(deg + 180) // prints degree in debugging
let bullet1:Bullet1 = Bullet1()
bullet1.position = CGPoint (x: self.hero.position.x , y: self.hero.position.y) // Bullet spawn @ anchor point
bullet1.zRotation = angle - 1.57079633 //rotates with angle of joy stick
let xDist:CGFloat = sin(angle - 1.5709633) * 35 //bullet spawn location
let yDist:CGFloat = cos(angle - 1.5709633) * 35 //bullet spawn location
bullet1.position = CGPointMake( self.hero.position.x - xDist, self.hero.position.y + yDist) //spawning bullet @ defined location
bullet1.createBullet1()
let xDistMove:CGFloat = sin(angle - 1.5709633) * 700 //Bullet max x distance
let yDistMove:CGFloat = cos(angle - 1.5709633) * 700 //Bullet max y distance
let bulletMovementY = SKAction.moveToY(self.hero.position.y+yDistMove, duration: 1) //Bullet y speed
let bulletMovemenX = SKAction.moveToX(self.hero.position.x -xDistMove, duration: 1) //Bullet x speed
let wait:SKAction = SKAction.waitForDuration( CFTimeInterval(0.25))
// let bulletFire = SKAction.sequence([wait,bulletMovemenX, bulletMovementY])
self.addChild(bullet1)
bullet1.runAction(wait)
bullet1.runAction(bulletMovementY)
bullet1.runAction(bulletMovemenX)
self.hero.zRotation = angle - 1.57079633 //rotates with angle of joy stick
})
上次修改: 我在你的更新方法中看不到bullet1.zRotation所以我想你只想要英雄来改变zRotation。
但是,如果zRotation仅在touchesBegan
而不在touchesMoved
中更改,我会说您应该使angle
成为可在两种方法中更改的全局变量。也许这会有所帮助,因为英雄根据angle
(我认为)的价值得到他的zRotation。
将angle
设为全局变量并添加一个变量,告诉您触摸是否被移动:
class GameScene: SKScene, SKPhysicsContactDelegate{
var angle = CGFloat() // It should be a CGFloat, right?
var touchesMovedOn = false
从touchesBegan
编辑此部分:
let bulletAction = SKAction.runBlock({
let v = CGVector(dx: location.x - self.joystickBase.position.x, dy: location.y - self.joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)
print(deg + 180) // prints degree in debugging
self.hero.zRotation = angle - 1.57079633 //rotates with angle of joystic
到此:
let bulletAction = SKAction.runBlock({
let v = CGVector(dx: location.x - self.joystickBase.position.x, dy: location.y - self.joystickBase.position.y)
if touchesMovedOn == false{
angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
}
let deg = angle * CGFloat(180 / M_PI)
print(deg + 180) // prints degree in debugging
self.hero.zRotation = angle - 1.57079633 //rotates with angle of joystic
从touchesMoved
编辑此部分:
let v = CGVector(dx: location.x - joystickBase.position.x, dy: location.y - joystickBase.position.y)
let angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)//converts radains to degrees and generates a degree when touchesmove == true
let length: CGFloat = joystickBase.frame.size.height / 2 //sets Maximum distance for joystick ball
print(deg + 180) // prints degree in Debugging to this:
到此:
touchesMovedOn = true
let v = CGVector(dx: location.x - joystickBase.position.x, dy: location.y - joystickBase.position.y)
angle = atan2(v.dy, v.dx) //where angle is defined "in radians"
let deg = angle * CGFloat(180 / M_PI)//converts radains to degrees and generates a degree when touchesmove == true
let length: CGFloat = joystickBase.frame.size.height / 2 //sets Maximum distance for joystick ball
print(deg + 180) // prints degree in Debugging to this:
在touchesEnded
touchesMovedOn = false
如果这没有帮助我真的需要项目,因为我必须自己测试问题所在。所以我希望它现在有效。好运 !正如我所说,我确信有更好的解决方案,所以在未来你应该注意使代码更好。 ; - )