Swift - Space Invaders (Aliens Display Loop Not Working) - swift

I'm currently trying to make a space invaders game, I've got my ship movement working and am currently working on my Alien Display loop.
I'm close but for some reason my screen keeps coming up blank, no aliens are being displayed. Can anyone help? Here's what I have so far.
//Add and display given amount of aliens...
while displayAliens == true {
aliens.append(SKSpriteNode(texture: SKTexture(imageNamed: "ClassicAlien")))
self.addChild(aliens[displayLoopCounter])
//Location
aliens[displayLoopCounter].position.x = 0
aliens[displayLoopCounter].position.y = 0
aliens[displayLoopCounter].position.x = CGFloat(displayLoopCounter + 25)
displayLoopCounter += 1
//Have we run out of aliens yet?
if displayLoopCounter > alienAmount {
displayAliens = false
}
}
}

Not %100 sure where the issue is, but your loop would be cleaner as :
//Add and display given amount of aliens...
while (alienAmount >= displayLoopCounter) {
aliens.append(SKSpriteNode(texture: SKTexture(imageNamed: "ClassicAlien")))
self.addChild(aliens[displayLoopCounter])
//Location
aliens[displayLoopCounter].position.y = 0
aliens[displayLoopCounter].position.x = CGFloat(displayLoopCounter + 25)
displayLoopCounter += 1
}

Related

russian roulette odd way to count that confuses me

so i'm making this game about russian roullette
it starts wit 5 bullets out of 6 chamber
then whenever the person lives
one bullet is removed
is my way of doing it mathematicly accurate
the bullet count is based on the amount of characther on my button
heres my code
#objc func clickedTrigger(){
attempts += 1
if GKRandomDistribution.d6().nextInt() > gunTrigger.title.count{
if gunTrigger.title.count == 1{
gunTrigger.title = "⁍⁍⁍⁍⁍"
NSSound(named: NSSound.Name(rawValue: "Glass"))?.play()
attempts = 0
appWindow.title = "you won the game"
}
else{
gunTrigger.title = String(gunTrigger.title.dropLast())
appWindow.title = "the person dodged a bullet."
}
}
else{
gunTrigger.title = "⁍⁍⁍⁍⁍"
appWindow.title = "the person saddly died."
}
}

"Attemped to add a SKNode which already has a parent:" in Repeat Loop. Any simple work around?

I am pretty Newbie to programming. And I am trying to pile up the random blocks dynamically till it hits the upper frame. But it seems that Swift doesn't let me to do so. Did I miss anything please? Any input are appreciated.
let blocks =[block1,block2,block3,block4,block5,block6,block7,block8,block9,block10,block11,block12]
var block:SKSpriteNode!
let blockX:Double = 0.0
var blockY:Double = -(self.size.height/2)
repeat{
block = blocks.randomBlock()
block.zPosition = 2
block.position = CGPoint(x:blockX, y:blockY)
block.size.height = 50
block.size.width = 50
self.addChild(block)
blockY += 50
} while( block.position.y < self.size.height)
extension Array {
func randomBlock()-> Element {
let randint = Int(arc4random_uniform(UInt32(self.count)))
return self[randint]
}
}
you need to have someway of tracking which blocks have been selected and ensure that they don't get selected again. The method below uses an array to store the indexes of selected blocks and then uses recursion to find a cycle through until an unused match is found.
private var usedBlocks = [Int]()
func randomBlock() -> Int {
guard usedBlocks.count != blocks.count else { return -1 }
let random = Int(arc4random_uniform(UInt32(blocks.count)))
if usedBlocks.contains(random) {
return randomBlock()
}
usedBlocks.append(random)
return random
}
in your loop change your initializer to
let index = randomBlock()
if index > -1 {
block = blocks[index]
block.zPosition = 2
block.position = CGPoint(x:blockX, y:blockY)
}
remember that if you restart the game or start a new level, etc. you must clear all of the objects from usedBlocks
usedBlocks.removeAll()

Index Out of Range Error in Swift

var numberOfPeople = 1 //get from host
var numberAtCounter = 0
func showNames() {
if peopleInMatch[numberAtCounter] == yourPeerID { //change to peopleinmatcheveryone
if numberOfPeople == 0 {
print("hoho")
personName.isHidden = true
connect.isHidden = false
connect.setTitle("PRESS READY", for: UIControlState.normal)
//change label to ready
} else {
numberAtCounter += 1
numberOfPeople -= 1 // buggy?
print("\(numberAtCounter)")
showNames()
}
} else {
personName.text = "TAKE PHOTO OF \(peopleInMatch[numberAtCounter])'s COLOR"
numberAtCounter += 1
if numberOfPeople <= 0 {
personName.isHidden = true
connect.isHidden = false
connect.setTitle("PRESS READY", for: UIControlState.normal)
//change label to ready
}
numberOfPeople -= 1 //buggy maybe fixed
}
}
I'm getting a Thread 1: EXC_BREAKPOINT error on the if peopleInMatch[numberAtCounter] == yourPeerID line. I'm not entirely sure what out of index means or what is potentially wrong. The code will be run through once then the function calls itself and on the second time through it breaks down on the line I mentioned above. I've checked all the variables and none of them are nill. Any ideas?
Here I made a short example for you to understand where your problem actually is.
ScreenShot 1:
Everything works fine when function is called for first time value at numberAtCounter is printed.
Here in first call either you are decrementing the value as numberAtCounter-=1 which take value from 0 to -1. Thus in second call when the function is called in line at:
if peopleInMatch[numberAtCounter] == yourPeerID // here you need to check value of `numberAtCounter`
make sure it's not getting a negative value or value more than your peopleInMatch array.
Thus if it becomes negative or more than count, result you will get as follows:

Swift: If SKNode color matches background color

I'm currently learning swift and i'm having some difficulty.
In my game a random background color changes every time to a random color between Red Green and Blue.
let colorgen = arc4random_uniform(3)+1
if colorgen == 1{
Col = UIColor.redColor()
}
else if colorgen == 2{
Col = UIColor.greenColor()
}
else if colorgen == 3{
Col = UIColor.blueColor()
}
It works pretty well but I know its not the best way to do things.
The game is pretty straight forward, a object can pass through either 3 walls. One green, one red, one blue. However the object can only pass through one wall at a time and that walls color MUST match the background color.
Here is what I tried to do:
override func update(currentTime: CFTimeInterval) {
if segment.color == self.backgroundColor{
segment.physicsBody?.collisionBitMask = 0
}
}
The code above is in the gamescene swift class
The effect is supposed to knock the walls out of place (only when the object hits the wrong color wall, making it fly away with its enabled collision bit mask) indicating a game over.
I only want the walls to have the ability to be knocked out physically when hit if the background color and wall being hit does NOT match (Basically wrong wall getting hit/touched by object). Thus that is why im using collision bit mask so that the current matching correct wall can still register the contact but the object goes right through it (setting it to 0). Exactly how I want it to be.
However collisionBitMask = 0 seems to have no effect on ALL the walls at all times.
My segment code is in another class called MovingGround and was made like this:
for i in 0 ..< NumberSeg {
//NumberSeg = 3 So that means 3 walls on screen
if i == 1{
segmentColor = colorone
//ColorX is just UIColors of Red Green and Blue
}
else if i == 2{
segmentColor = colortwo
}
else{
segmentColor = colorthree
}
segment = SKSpriteNode(color: segmentColor, size: CGSizeMake(self.size.width / CGFloat(NumberSeg), self.size.height))
segment.anchorPoint = CGPointMake(0.5, 0.5)
segment.position = CGPointMake(CGFloat(i)*segment.size.width+50, 0.5)
addChild(segment)
segment.physicsBody = SKPhysicsBody(rectangleOfSize:CGSizeMake(self.size.width/3,
15))
segment.physicsBody?.categoryBitMask = heroCategory
segment.physicsBody?.contactTestBitMask = wallCategory
segment.physicsBody?.affectedByGravity = false
segment.physicsBody?.velocity = CGVectorMake(0, 0)
segment.physicsBody?.usesPreciseCollisionDetection = true
It's weird, when I try:
if segment.color == UIColor.blueColor(){
segment.physicsBody?.collisionBitMask = 0
}
or
if self.backgroundColor == UIColor.blueColor(){
segment.physicsBody?.collisionBitMask = 0
}
To test if they work individually, they do!
I just don't understand why if I try to put them together with either a nested if statement or a single if with the && operator it won't work!
I should also mention I made the segment variable global (At least I think that's what its supposed to do) by putting it outside of Constants (Which is another separate file) swift class by:
var segment: SKSpriteNode!
I'm 14 & pretty new to Swift with not much programming knowledge except for a little bit of Python. So if anyone could help me figure this out that would be great!

Swift - Array of AVplayers?

I am putting together an app that plays drum beats based on hard-coded arrays as such:
var beatArray = [[String]]()
var beat01 = [["kick"], ["snare"], ["kick"], ["snare"]]
var beat02 = [["kick"], ["kick", "snare"], ["kick"], ["kick","snare"]]
Based on a set of parameters, beat01 or beat02 is chosen and when a button is pressed, an NSTimer is started with this following Selector:
// THIS IS WHAT HAPPENS EVERY BEAT
func increaseCounter() {
beatCounter++
if beatCounter >= beatArray.count {
beatCounter = 0
}
print(beatCounter)
if beatArray[beatCounter].contains("kick") {
kickPlayer.currentTime = 0
kickPlayer.play()
}
if beatArray[beatCounter].contains("snare") {
snarePlayer.currentTime = 0
snarePlayer.play()
}
}
kickPlayer and snarePlayer are AVAudioPlayers.
Since there are only two instruments, separately declaring each IF statement is fine, but as I add more and more instruments, this will soon be chaotic.
Is there a way to streamline this process? I'm looking for something along the lines of:
if beatArray[beatCounter].contains("INSTRUMENT") {
INSTRUMENTPlayer.currentTime = 0
INSTRUMENTPlayer.play()
}
put your players in a map
let players = ["kick": kickPlayer, "snare": snarePlayer, ...]
then
for beat in beatArray[beatCounter] {
if let player = players[beat] {
player.currentTime = 0
player.play()
}
}