Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Hello, I am currently working on a ios game where you play as a cactus on the left and you shoot enemies on the right.

Hello, I am currently working on a ios game where you play as a cactus on the left and you shoot enemies on the right. When I tap the screen the enemies end up disappearing because of the collision but I am not sure why it is hitting all of the enemies at once. It is supposed to hit one enemy at a time. I have commented code that I was thinking would work but it is not working out well. Can you please see if you can see the problem and fix the code you think will work. Please see if you can fix it. Thank you. This is written using swift

This is what it does when it runs.

https://drive.google.com/file/d/1e5vQUIcnosfILXXEu_yCczi2sOGipB9E/view?usp=sharing

Swift Code:

import SpriteKit

import GameplayKit

import CoreGraphics

import AVFoundation

var invaderNum = 1

struct CollisionCategories{

// static let Invader : UInt32 = 0x1 << 0

// static let Player: UInt32 = 0x1 << 1

// static let InvaderBullet: UInt32 = 0x1 << 2

// static let PlayerBullet: UInt32 = 0x1 << 3

static let coinManCategory : UInt32 = 0x1 << 1

static let coinCategory : UInt32 = 0x1 << 2

static let bombCategory : UInt32 = 0x1 << 3

static let groundAndCeilCategory : UInt32 = 0x1 << 4

let playableRect = CGRect()

}

class GameScene: SKScene, SKPhysicsContactDelegate{

var cat = SKSpriteNode(imageNamed: "cat")

var enemy = SKSpriteNode(imageNamed: "enemy")

var ceil : SKSpriteNode?

var yourScoreLabel : SKLabelNode?

var finalScoreLabel : SKLabelNode?

var scoreLabel : SKLabelNode?

var score = 0

private var label : SKLabelNode?

private var spinnyNode : SKShapeNode?

var background = SKSpriteNode(imageNamed: "background1")

var backgroundMusicPlayer: AVAudioPlayer!

let texture = SKTexture(imageNamed: "apple")

let textureEnemy = SKTexture(imageNamed: "enemy")

let rowsOfInvaders = 4

var invaderSpeed = 2

let leftBounds = CGFloat(30)

var rightBounds = CGFloat(0)

var invadersWhoCanFire:[Apple] = []

let player:Player = Player()

let maxLevels = 3

var playableRect = CGRect()

var bullet = InvandarApple(imageName: "apple",bulletSound: nil)

override func didMove(to view: SKView) {

let maxAspectRatio:CGFloat = 16.0/9.0

let playableHeight = size.width / maxAspectRatio

let playableMargin = (size.height-playableHeight)/2.0

playableRect = CGRect(x: 0, y: playableMargin,

width: size.width,

height: playableHeight)

playBackgroundMusic("backgroundMusic.wav")

self.physicsWorld.gravity = CGVector(dx : 0, dy : 0)

self.physicsWorld.contactDelegate = self

background.anchorPoint = CGPoint.zero

background.position = CGPoint(x: 0, y: 0)

addChild(background)

debugDrawPlayableArea()

// setupInvaders()

setupPlayer()

invokeInvaderFire()

run(SKAction.repeatForever(

SKAction.sequence([SKAction.run(spawnEnemy),

SKAction.wait(forDuration: 1.0)])))

run(SKAction.repeatForever(

SKAction.sequence([SKAction.run(spawnCat),

SKAction.wait(forDuration: 2.0)])))

scoreLabel = childNode(withName: "scoreLabel") as? SKLabelNode

}

func debugDrawPlayableArea() {

let shape = SKShapeNode()

let path = CGMutablePath()

path.addRect(playableRect)

shape.path = path

shape.strokeColor = SKColor.red

shape.lineWidth = 4.0

addChild(shape)

}

func touchDown(atPoint pos : CGPoint) {

if let n = self.spinnyNode?.copy() as! SKShapeNode? {

n.position = pos

n.strokeColor = SKColor.green

self.addChild(n)

}

}

func touchMoved(toPoint pos : CGPoint) {

if let n = self.spinnyNode?.copy() as! SKShapeNode? {

n.position = pos

n.strokeColor = SKColor.blue

self.addChild(n)

}

}

func touchUp(atPoint pos : CGPoint) {

if let n = self.spinnyNode?.copy() as! SKShapeNode? {

n.position = pos

n.strokeColor = SKColor.red

self.addChild(n)

}

}

override func touchesBegan(_ touches: Set, with event: UIEvent?) {

if let touch = touches.first {

let position = touch.location(in: view)

print(position)

bullet.position.y = position.y

}

player.fireBullet(scene: self)

if let label = self.label {

label.run(SKAction.init(named: "Pulse")!, withKey: "fadeInOut")

}

for t in touches { self.touchDown(atPoint: t.location(in: self)) }

let touch = touches.first

if let location = touch?.location(in: self) {

let theNodes = nodes(at: location)

for node in theNodes {

if node.name == "play" {

score = 0

let myScene = GameScene(size: self.size)

myScene.scaleMode = self.scaleMode

let reveal = SKTransition.fade(with: UIColor.black, duration: 1.5)

myScene.scaleMode = .resizeFill

self.view?.presentScene(myScene, transition: reveal)

node.removeFromParent()

finalScoreLabel?.removeFromParent()

yourScoreLabel?.removeFromParent()

scene?.isPaused = false

scoreLabel?.text = "Score: \(score)"

// startTimers()

}

}

}

}

func gameOver() {

scene?.isPaused = true

// coinTimer?.invalidate()

// bombTimer?.invalidate()

yourScoreLabel = SKLabelNode(text: "Your Score:")

yourScoreLabel?.position = CGPoint(x: self.size.width/2-30, y:200)

yourScoreLabel?.fontSize = 60

yourScoreLabel?.zPosition = 1

if yourScoreLabel != nil {

addChild(yourScoreLabel!)

}

finalScoreLabel = SKLabelNode(text: "\(score)")

finalScoreLabel?.position = CGPoint(x:(yourScoreLabel?.frame.size.width)!+60 , y:200)

finalScoreLabel?.fontSize = 60

finalScoreLabel?.zPosition = 1

if finalScoreLabel != nil {

addChild(finalScoreLabel!)

}

let playButton = SKSpriteNode(imageNamed: "playButton")

playButton.position = CGPoint(x: self.size.width/2, y:self.size.height/2)

playButton.name = "play"

playButton.zPosition = 1

addChild(playButton)

}

override func touchesMoved(_ touches: Set, with event: UIEvent?) {

for t in touches { self.touchMoved(toPoint: t.location(in: self)) }

}

override func touchesEnded(_ touches: Set, with event: UIEvent?) {

for t in touches { self.touchUp(atPoint: t.location(in: self)) }

}

override func touchesCancelled(_ touches: Set, with event: UIEvent?) {

for t in touches { self.touchUp(atPoint: t.location(in: self)) }

}

override func update(_ currentTime: TimeInterval) {

moveInvaders()

}

func setupInvaders(){

var invaderRow = 1;

var invaderColumn = 1;

let numberOfInvaders = invaderNum * 2 + 1

for i in 0..

invaderRow = i

for j in 0..

invaderColumn = j

let tempInvader:Apple = Apple()

let invaderHalfWidth:CGFloat = tempInvader.size.width/2

let xPositionStart:CGFloat = size.width/2 - invaderHalfWidth - (CGFloat(invaderNum) * tempInvader.size.width) + CGFloat(10)

tempInvader.position = CGPoint(x:xPositionStart + ((tempInvader.size.width+CGFloat(10))*(CGFloat(j-1))), y:CGFloat(self.size.height - CGFloat(i) * 46))

tempInvader.invaderRow = invaderRow

tempInvader.invaderColumn = invaderColumn

addChild(tempInvader)

if(i == self.rowsOfInvaders){

invadersWhoCanFire.append(tempInvader)

}

}

}

}

func setupPlayer(){

player.zPosition = 1

player.position = CGPoint(x:(self.frame.size.width/4)-50, y:player.size.height+50)

addChild(player)

}

func moveInvaders(){

var changeDirection = false

enumerateChildNodes(withName: "apple") { node, stop in

let invader = node as! SKSpriteNode

let invaderHalfWidth = invader.size.width/2

invader.position.x -= CGFloat(self.invaderSpeed)

if(invader.position.x > self.rightBounds - invaderHalfWidth || invader.position.x < self.leftBounds + invaderHalfWidth){

changeDirection = true

}

}

if(changeDirection == true){

self.invaderSpeed *= -1

self.enumerateChildNodes(withName: "apple") { node, stop in

let invader = node as! SKSpriteNode

invader.position.y -= CGFloat(46)

}

changeDirection = false

}

}

func fireBullet(scene: SKScene){

bullet = InvandarApple(imageName: "apple",bulletSound: nil)

bullet.position.y = self.position.x

bullet.position.x = self.position.x - self.size.width/2

scene.addChild(bullet)

let moveBulletAction = SKAction.move(to: CGPoint(x:self.position.x,y:bullet.position.y), duration: 2.0)

let removeBulletAction = SKAction.removeFromParent()

bullet.run(SKAction.sequence([moveBulletAction,removeBulletAction]))

}

func invokeInvaderFire(){

let fireBullet = SKAction.run(){

self.fireInvaderBullet()

}

let waitToFireInvaderBullet = SKAction.wait(forDuration: 1.5)

let invaderFire = SKAction.sequence([fireBullet,waitToFireInvaderBullet])

let repeatForeverAction = SKAction.repeatForever(invaderFire)

run(repeatForeverAction)

}

// func didBeginContact(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 & CollisionCategories.Invader != 0) &&

// (secondBody.categoryBitMask & CollisionCategories.PlayerBullet != 0)){

// NSLog("Invader and Player Bullet Conatact")

// }

//

// if ((firstBody.categoryBitMask & CollisionCategories.Player != 0) &&

// (secondBody.categoryBitMask & CollisionCategories.InvaderBullet != 0)) {

// NSLog("Player and Invader Bullet Contact")

// }

//

// if ((firstBody.categoryBitMask & CollisionCategories.Invader != 0) &&

// (secondBody.categoryBitMask & CollisionCategories.Player != 0)) {

// NSLog("Invader and Player Collision Contact")

//

// }

// if ((firstBody.categoryBitMask & CollisionCategories.Player != 0) &&

// (secondBody.categoryBitMask & CollisionCategories.InvaderBullet != 0)) {

// player.die()

// }

//

// if ((firstBody.categoryBitMask & CollisionCategories.Invader != 0) &&

// (secondBody.categoryBitMask & CollisionCategories.Player != 0)) {

// player.kill()

// }

//

// }

func didBegin(_ contact: SKPhysicsContact) {

if contact.bodyA.categoryBitMask == CollisionCategories.coinCategory {

contact.bodyA.node?.removeFromParent()

score += 1

scoreLabel?.text = "Score: \(score)"

}

if contact.bodyB.categoryBitMask == CollisionCategories.coinCategory {

contact.bodyB.node?.removeFromParent()

score += 1

scoreLabel?.text = "Score: \(score)"

}

if contact.bodyA.categoryBitMask > contact.bodyB.categoryBitMask{

if cat.position.x == 167.0 {

gameOver()

}

}

//if contact.bodyB.categoryBitMask == CollisionCategories.bombCategory {

// }

}

func fireInvaderBullet(){

if(invadersWhoCanFire.isEmpty){

invaderNum += 1

}else{

let randomInvader = invadersWhoCanFire.randomElement()

randomInvader.fireBullet(scene: self)

}

}

func spawnCat() {

cat = SKSpriteNode(imageNamed: "cat")

cat.name = "cat"

let catScenePos = CGPoint(

// x: CGFloat.random(min: playableRect.minX,

// max: playableRect.maxX)

x: self.size.width,

// y: CGFloat.random(min: playableRect.minY,

// max: playableRect.maxY))

y: cat.size.height/2+200)

cat.position = self.convert(catScenePos, from: self)

cat.physicsBody = SKPhysicsBody(rectangleOf: cat.size)

cat.physicsBody?.affectedByGravity = true

cat.physicsBody?.categoryBitMask = CollisionCategories.coinCategory

cat.physicsBody?.contactTestBitMask = CollisionCategories.coinManCategory

cat.physicsBody?.collisionBitMask = 0

addChild(cat)

let actionMove = SKAction.moveBy(x: -size.width-cat.size.width, y: 0, duration: 2.0)

let actionRemove = SKAction.removeFromParent()

cat.run(SKAction.sequence([actionMove, actionRemove]))

}

func spawnEnemy() {

enemy = SKSpriteNode(imageNamed: "enemy")

enemy.name = "enemy"

let enemyScenePos = CGPoint(

x: self.size.width,

// y: CGFloat.random(

// min: playableRect.minY + enemy.size.height/2,

// max: playableRect.maxY - enemy.size.height/2))

y: enemy.size.height/2+175)

enemy.physicsBody = SKPhysicsBody(rectangleOf:

enemy.frame.size)

enemy.physicsBody?.usesPreciseCollisionDetection = true

enemy.position = self.convert(enemyScenePos, from: self)

enemy.physicsBody = SKPhysicsBody(rectangleOf: enemy.size)

enemy.physicsBody?.affectedByGravity = true

enemy.physicsBody?.categoryBitMask = CollisionCategories.coinCategory

enemy.physicsBody?.contactTestBitMask = CollisionCategories.coinManCategory

enemy.physicsBody?.collisionBitMask = 0

enemy.position = self.convert(enemyScenePos, from: self)

addChild(enemy)

let actionMove = SKAction.moveBy(x: -size.width-enemy.size.width, y: 0, duration: 2.0)

let actionRemove = SKAction.removeFromParent()

enemy.run(SKAction.sequence([actionMove, actionRemove]))

}

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Advances In Database Technology Edbt 88 International Conference On Extending Database Technology Venice Italy March 14 18 1988 Proceedings Lncs 303

Authors: Joachim W. Schmidt ,Stefano Ceri ,Michele Missikoff

1988th Edition

3540190740, 978-3540190745

More Books

Students also viewed these Databases questions

Question

Explain in detail how poor data quality can lead to bad decisions.

Answered: 1 week ago