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
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
}
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() {
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
physics engine will not control the card
enemy.physicsBody?.categoryBitMask = PhysicsCategory.enemy
Set the category bit mask to be the main category defined earlier
enemy.physicsBody?.contactTestBitMask =
PhysicsCategory.projectile
categories this object notify the contact listener when they intersect.
You choose projectiles here
enemy.physicsBody?.collisionBitMask = PhysicsCategory.none
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.
let actualY = random(min: enemy.size.width/2, max: size.width -
enemy.size.width/2)
above
enemy.position = CGPoint(x: actualY, y: size.width +
enemy.size.width/2)
addChild(enemy)
let actualDuration = random(min: CGFloat(2.0), max:
CGFloat(6.0))
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")
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?) {
guard let touch = touches.first else {
return
}
let touchLocation = touch.location(in: self)
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
let offset = touchLocation - projectile.position
if offset.x < 0 { return }
addChild(projectile)
let direction = offset.normalized()
let shootAmount = direction * 1000
let realDest = shootAmount + projectile.position
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) {
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
}
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 )
}
}
}
}
What I have tried:
I have tried to change the positioning of certain elements but no matter what i try, the projectile will not show. I'm honestly not sure what else to try.