0
\$\begingroup\$

i am having a lot of troublefiguring out why my projectile will not shoot the image of luke. I have tried many different methods to try and counteract this but none of the strategies have seem to worked. I would really love some guidance and apologies in advance for the amount of code.

import SpriteKit
import GameplayKit
import AVFoundation
import CoreMotion



func +(left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)
}

func -(left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x - right.x, y: left.y - right.y)
}

func *(point: CGPoint, scalar: CGFloat) -> CGPoint {
return CGPoint(x: point.x * scalar, y: point.y * scalar)
}

func /(point: CGPoint, scalar: CGFloat) -> CGPoint {
return CGPoint(x: point.x / scalar, y: point.y / scalar)
}

#if !(arch(x86_64) || arch(arm64))
func sqrt(a: CGFloat) -> CGFloat {
return CGFloat(sqrtf(Float(a)))
}
#endif

extension CGPoint {
func length() -> CGFloat {
    return sqrt(x*x + y*y)
}

func normalized() -> CGPoint {
    return self / length()
}
}


class GameScene: SKScene {

struct PhysicsCategory {
    static let none      : UInt32 = 0
    static let all       : UInt32 = UInt32.max
    static let enemy   : UInt32 = 0b1       // 1 This is a way of 
saying each of the 32-bits in the integer represents a single category 
(and hence you can have 32 categories max).
    static let projectile: UInt32 = 0b10      // 2 Same as 1
}




//  let Interaction:UInt32 = 0x1 << 1
// let CollisionCategory:UInt32 = 0x1 << 0
var boxlabel:SKShapeNode!
var starfield:SKEmitterNode!
var player: SKSpriteNode!
var player2 : SKSpriteNode!
var ScoreLabel: SKLabelNode!
var score: Int = 0 {
    didSet {
        ScoreLabel.text = "Score: \(score)"
    }
}
var seconds = 120

@objc   var timer: Timer?





override func didMove(to view: SKView) { 

func main() {

        // Create sprite
        let enemy = SKSpriteNode(imageNamed: "luke")
        enemy.physicsBody = SKPhysicsBody(rectangleOf: enemy.size) // 
This allows the card size to be equal to a rectangle
        enemy.physicsBody?.isDynamic = true // This says that the 
physics engine will not control the card
        enemy.physicsBody?.categoryBitMask = PhysicsCategory.enemy// 3 
Set the category bit mask to be the main category defined earlier
        enemy.physicsBody?.contactTestBitMask = 
PhysicsCategory.projectile // 4 contactTestBitMask indicates when 
categories this object notify the contact listener when they intersect. 
You choose projectiles here
        enemy.physicsBody?.collisionBitMask = PhysicsCategory.none // 5 
collisionBitMask indicates what categories of objects this object that 
the physics engine handle contact responses to (i.e. bounce off of). 
You don't want the monster and projectile to bounce off each other — 
it's OK for them to go right through each other in this game — so you 
set this to .none.


        // Determine where to spawn the card along the Y axis
        let actualY = random(min: enemy.size.width/2, max: size.width - 
enemy.size.width/2)

        // Position the card slightly off-screen along the right edge,
        // and along a random position along the Y axis as calculated 
above
        enemy.position = CGPoint(x: actualY, y: size.width + 
enemy.size.width/2)

        // Add the card to the scene
        addChild(enemy)

        // Determine speed of the card
        let actualDuration = random(min: CGFloat(2.0), max: 
CGFloat(6.0))

        // Create the actions
        let actionMove = SKAction.move(to: CGPoint(x: actualY, y: - 
enemy.size.width/10),
                                       duration: 
TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        enemy.run(SKAction.sequence([actionMove, actionMoveDone]))


    }
    player = SKSpriteNode(imageNamed: "spaceship-modified")
    // The line below with the numbers 45, 25 and 540 are also stubs

    player.position = CGPoint(x: self.frame.size.width/45, y:
        player.frame.size.height/25 - 410)

        addChild(player)

        physicsWorld.gravity = .zero
        physicsWorld.contactDelegate = self
   run(SKAction.repeatForever(
       SKAction.sequence([
           SKAction.run(main),
            SKAction.wait(forDuration: 1.0)
            ])
    ))


    func random() -> CGFloat {
        return CGFloat(Float(arc4random()) / 4294967295)
    }

    func random(min: CGFloat, max: CGFloat) -> CGFloat {
        return random() * (max - min) + min
    }



        func touchesEnded(_ touches: Set<UITouch>, with event: 
    UIEvent?) {
        // 1 - Choose one of the touches to work with
        guard let touch = touches.first else {
            return
        }
        let touchLocation = touch.location(in: self)


        // 2 - Set up initial location of projectile
        let projectile = SKSpriteNode(imageNamed: "projectile")
        projectile.position = player.position

        projectile.physicsBody = SKPhysicsBody(circleOfRadius: 
   projectile.size.width/2)
        projectile.physicsBody?.isDynamic = true
        projectile.physicsBody?.categoryBitMask = 
   PhysicsCategory.projectile
        projectile.physicsBody?.contactTestBitMask = 
   PhysicsCategory.enemy
        projectile.physicsBody?.collisionBitMask = PhysicsCategory.none
        projectile.physicsBody?.usesPreciseCollisionDetection = true


        // 3 - Determine offset of location to projectile
        let offset = touchLocation - projectile.position

        // 4 - Bail out if you are shooting down or backwards
        if offset.x < 0 { return }

        // 5 - OK to add now - you've double checked position
        addChild(projectile)

        // 6 - Get the direction of where to shoot
        let direction = offset.normalized()

        // 7 - Make it shoot far enough to be guaranteed off screen
        let shootAmount = direction * 1000

        // 8 - Add the shoot amount to the current position
        let realDest = shootAmount + projectile.position

        // 9 - Create the actions
        let actionMove = SKAction.move(to: realDest, duration: 4.0)
        let actionMoveDone = SKAction.removeFromParent()
        projectile.run(SKAction.sequence([actionMove, actionMoveDone]))
    }
    }

    }

    func projectileDidCollideWithMonster(projectile: SKSpriteNode, 
    enemy: SKSpriteNode) {
    print("Hit")
    projectile.removeFromParent()
    enemy.removeFromParent()

  }

 extension GameScene: SKPhysicsContactDelegate {
 func didBegin(_ contact: SKPhysicsContact) {
  // 1
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
    firstBody = contact.bodyA
    secondBody = contact.bodyB
} else {
    firstBody = contact.bodyB
    secondBody = contact.bodyA
}

// 2
if ((firstBody.categoryBitMask & PhysicsCategory.enemy != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.projectile != 0)) {
    if let enemy = firstBody.node as? SKSpriteNode,
        let projectile = secondBody.node as? SKSpriteNode {
        projectileDidCollideWithMonster(projectile: projectile, enemy: 
 enemy )
    }
  }
}

}

Also all of the other players and timers work perfectly but if that code is required then let me know. I really appreciate everyone's help!!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.