SpriteKit - Border on all sides except bottom and top - swift

I have a main player node and enemies coming down randomly, but parts of them are outside the frame, I want to make it so they (and the player) are not able to get out of frame, left and right borders. How can I achieve that?
Thank you for your time and effort :)
Here's my enemy line, not sure how this can help but here it is so I don't get reported for being 'too broad'
func launchEnemy() {
let randomX = arc4random_uniform( UInt32(screenWidth))
EnemyMissile.position = CGPoint( x: CGFloat(randomX) - (screenWidth / 2), y: screenHeight + 50)
let action = SKAction.move(by: CGVector(dx: 0, dy: -400 + speedScore), duration: 5.0)
EnemyMissile.run(SKAction.repeatForever(action))
increaseSpeed()
self.run(action, withKey:"LaunchEnemyAction")
}
Here's my EnemyClass
import Foundation
import SpriteKit
class EnemyClass: SKNode {
var EnemyNode:SKSpriteNode = SKSpriteNode()
var hitsToKill:Int = 2
var hitCount:Int = 0
var damagePoints: Int = 2
//var missileAnimation:SKAction?
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) had not been implemented")
}
override init () {
super.init()
}
func createEnemy ( _ theImage:String) {
EnemyNode = SKSpriteNode(imageNamed: theImage)
self.addChild(EnemyNode)
let body:SKPhysicsBody = SKPhysicsBody(circleOfRadius: EnemyNode.size.width / 2.25, center:CGPoint(x: 0,y: 0))
body.isDynamic = true
body.affectedByGravity = false
body.allowsRotation = false
body.categoryBitMask = BodyType.enemy.rawValue
body.contactTestBitMask = BodyType.bullet.rawValue | BodyType.player.rawValue
self.physicsBody = body
self.name = "EnemyClass"
}
func destroy() {
self.removeFromParent()
self.name = "removeNode"
}
func hit() -> Bool {
hitCount += 1
if ( hitCount == hitsToKill) {
destroy()
return true
} else {
damagePoints = 4
EnemyNode.removeAction(forKey: "animation")
return false
}
}
}

Basically you have 2 issues:
Your spawning points are messed up
You have no boundary in place
You have a few options for setting boundaries, one being a physicsBody, another being keepInBounds() method or such. Below I should a simple keep in bounds method:
class GameScene: SKScene {
func spawnEnemy() {
let offset = CGFloat(5) // pixels, so enemy will have some spacing between borders.
let enemy = SKSpriteNode(color: .blue, size: CGSize(width: 50, height: 100))
enemy.name = "enemy"
addChild(enemy)
var randomX = CGFloat(arc4random_uniform(UInt32(self.size.width))) // This is not a perfect rando algo.
// Because our random x was from 0 through screenwidth, but .position works
// on -halfWidth through +halfWidth
randomX -= (self.frame.size.width / 2)
// Because spawning on the border will mean that the enemy is HALF out of view:
/*
right border: |
enemy # frame.maxX: x
- offset: x|
- size.w/2 x |
*/
if randomX > self.frame.maxX - offset - (enemy.size.width / 2) {
randomX = self.frame.maxX - offset - (enemy.size.width / 2)
}
else if randomX < self.frame.minX + offset + (enemy.size.width / 2) {
randomX = self.frame.minX + offset + (enemy.size.width / 2)
}
enemy.position.x = randomX
}
func keepEnemyInBounds() {
// A better way to do this would be to have a dictionary of enemies:
for node in self.children {
guard node.name == "enemy" else { continue }
let enemy = node as! SKSpriteNode
if enemy.position.x > frame.maxX - (enemy.size.width / 2) {
enemy.position.x = frame.maxX - (enemy.size.width / 2)
}
else if enemy.position.x < frame.minX + (enemy.size.width / 2) {
enemy.position.x = frame.minX + (enemy.size.width / 2)
}
}
}
override func update(_ currentTime: TimeInterval) {
spawnEnemy()
}
override func didFinishUpdate() {
keepEnemyInBounds()
}
}

Related

How to fix: Calling a node by name (generated by func) won't work

I'm currently working on my first test game in which the player have to jump over some randomly generated bars.
I wrote a func which should generate the bars outside of my scene.
My problem at the moment is that when I'm trying to call the created bars with "self.childNode(withName:)" xCode is telling me "Fatal error: Unexpectedly found nil while unwrapping an Optional value".
I've already read the Apple Documentation for "childNode(withName:)" and added "//" before the name of the node. In addition I used the stackoverflow search but I can't find anything that solved my problem.
//
// GameScene.swift
// PlaxerJump
//
//
import SpriteKit
import AVFoundation
class GameScene: SKScene {
let bottom1 = SKSpriteNode(imageNamed: "Bottom")
let bottom2 = SKSpriteNode(imageNamed: "Bottom")
let player = SKSpriteNode(imageNamed: "Player")
var velocity = CGFloat(0)
var onGround = true
var value = CGFloat(5)
override func didMove(to view: SKView) {
// Hintergrund
self.backgroundColor = SKColor.lightGray
bottom1.anchorPoint = CGPoint.zero
bottom1.position = CGPoint.zero
bottom1.zPosition = 1
self.addChild(bottom1)
bottom2.anchorPoint = CGPoint.zero
bottom2.position = CGPoint(x: bottom1.size.width - 1, y: 0)
bottom2.zPosition = 1
self.addChild(bottom2)
// Spieler
player.position = CGPoint(x: player.size.width / 2 + 20, y: bottom1.size.height + player.size.height / 2)
player.zPosition = 2
self.addChild(player)
//Balken
addBalken(xScale: 1.5, yScale: 1, name: "ba1", xPoint: 0)
}
func addBalken(xScale: CGFloat, yScale: CGFloat, name: String, xPoint: CGFloat) {
let balken = SKSpriteNode(imageNamed: "Balken")
balken.anchorPoint = CGPoint.zero
balken.position = CGPoint(x: self.size.width + (2 * balken.size.width) + xPoint, y: bottom1.size.height - 16)
balken.zPosition = 1
balken.xScale = xScale
balken.yScale = yScale
balken.name = name
addChild(balken)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if onGround == true {
velocity = -16
onGround = false
self.run(SKAction.playSoundFileNamed("Jump.wav", waitForCompletion: false))
}
}
override func update(_ currentTime: TimeInterval) {
//Player
player.zRotation -= CGFloat(Double.pi * 5) / 180
velocity += 0.6
player.position.y -= velocity
if player.position.y <= bottom1.size.height {
player.position.y = bottom1.size.height
velocity = 0
onGround = true
}
//Bottom
bottom1.position.x -= 4
bottom2.position.x -= 4
if bottom1.position.x < -bottom1.size.width {
bottom1.position.x = bottom2.position.x + bottom2.size.width
} else if bottom2.position.x < -bottom2.size.width {
bottom2.position.x = bottom1.position.x + bottom1.size.width
}
//Balken - ** THIS IS THE PART WHERE THE ERROR OCCURS **
let balke1 = self.childNode(withName: "//ba1") as! SKSpriteNode
balke1.position.x -= value
if balke1.position.x < self.size.width {
balke1.position.x = self.size.width + (2 * balke1.size.width)
value = CGFloat(arc4random_uniform(UInt32(value)))
}
}
}
I just want to call the node so I can use it to implement the bars in the game.
Change this line of code:
addBalken(xScale: 1.5, yScale: 1, name: "//ba1", xPoint: 0)
to:
addBalken(xScale: 1.5, yScale: 1, name: "ba1", xPoint: 0)
The // only applies when searching for the node, so keep these characters in this line:
let balke1 = self.childNode(withName: "//ba1") as! SKSpriteNode
EDIT:
I think the root cause of your problem is that you forgot to call addChild in your addBalken function. Simply creating a node isn't enough. The node must also be added to the scene as well. So this is the final code:
func addBalken(xScale: CGFloat, yScale: CGFloat, name: String, xPoint: CGFloat) {
let balken = SKSpriteNode(imageNamed: "Balken")
balken.anchorPoint = CGPoint.zero
balken.position = CGPoint(x: self.size.width + (2 * balken.size.width) + xPoint, y: bottom1.size.height - 16)
balken.zPosition = 1
balken.xScale = xScale
balken.yScale = yScale
balken.name = name
//add the node to the scene
addChild(balken)
}

Add Physics only to the sprites that are within my view

I have a tileMap and within it some tileNodes, I am looking to only give physics to the tilesNodes that are within the screen view and as the player navigates the world, the tileNodes that come into screen view get physics and the tileNodes that go out of screen view get their physics removed. Any help would be appreciated, even if it means to completely redo my code.
Thank you.
Here is how i been adding physics to my tiles...
static func addPhysicsTo(map: SKTileMapNode){
let tileSize = map.tileSize
let halfWidth = CGFloat(map.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(map.numberOfRows) / 2.0 * tileSize.height
for col in 0..<map.numberOfColumns
{
for row in 0..<map.numberOfRows
{
let tileDefinition = map.tileDefinition(atColumn: col, row: row)
let isUsedTile = tileDefinition?.userData?["Tile"] as? Bool
if (isUsedTile ?? false)
{
let x = CGFloat(col) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight
let rect = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKShapeNode(rect: rect)
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2.0, y: tileSize.height / 2.0))
tileNode.physicsBody?.isDynamic = true
tileNode.physicsBody?.allowsRotation = false
tileNode.physicsBody?.affectedByGravity = false
tileNode.physicsBody?.pinned = true
tileNode.physicsBody?.density = 200.0
tileNode.physicsBody?.categoryBitMask = GameConstants.physicsConstants.tileCategory
tileNode.physicsBody?.collisionBitMask = GameConstants.physicsConstants.playerCategory
//tileNode.physicsBody?.contactTestBitMask = GameConstants.physicsConstants.allCategory
map.addChild(tileNode)
}
}
}
}
The player adds an impulse to the Hero with this function in touchesBegun...
static func applyImpulse(sprite: SKSpriteNode, touchLocationX: CGFloat, touchLocationY: CGFloat) {
let impulseX = (sprite.position.x - touchLocationX ) / 10
let impulseY = (sprite.position.y - touchLocationY ) / 20
sprite.physicsBody?.applyImpulse(CGVector(x: impulseX , y: impulseY))
}
I created a tileNode Class that will activated and deactivate nodes, i just don't know what the rest of the code should look like...
class TileNodes: SKSpriteNode {
var isTileActivated: Bool = false
{
didSet {
physicsBody = isTileActivated ? activatedBody : nil
}
}
private var activatedBody: SKPhysicsBody?
init(with size: CGSize) {
super.init(texture: nil, color: UIColor.clear, size: size)
//I ASSUME THE CODE GOES HERE
physicsBody = isTileActivated ? activatedBody : nil
name = GameConstants.nameConstants.tileName
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Based on some of the things Ive found online, it seems like I need to use didSimulatePhysics() but i don't know how..
override func didSimulatePhysics() {
for node in tileMap[GameConstants.nameConstants.tileName] {
if let tileNode = node as? TileNodes {
}
}
}

Something's wrong with my scheduledTimer on SpriteKit

I'm experimenting a few things with Swift and SpriteKit.
I have 4 images of coins. (coin1,coin2, ...). I want to spawn a random coin at a random position on the screen and let it fade out. I want to repeat this action every 3 seconds. This is the code and it worked fine.
class GameScene: SKScene {
// creating a playable area
let gameArea: CGRect
override init(size: CGSize) {
let maxAspectRatio: CGFloat = 16.0/9.0
let playableWidth = size.height / maxAspectRatio
let gameAreaMargin = (size.width - playableWidth)/2
gameArea = CGRect(x: gameAreaMargin, y: 270, width: playableWidth, height: size.height - 270)
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max-min) + min
}
func spawnAndFadeCoins() -> SKSpriteNode{
let randNum = arc4random()%4 + 1
let coin = SKSpriteNode(imageNamed: "coin\(randNum)")
if randNum == 4 {
coin.zPosition = 10
}
else {
coin.zPosition = 5
}
coin.name = "coin\(randNum)"
let randomX = random(min: gameArea.minX + coin.size.width/2,
max: gameArea.maxX - coin.size.width/2)
let randomY = random(min: gameArea.minY + coin.size.height/2,
max: gameArea.maxY - coin.size.height/2)
coin.position = CGPoint(x: randomX, y: randomY)
let disappear = SKAction.fadeOut(withDuration: 1.0)
coin.run(SKAction.repeatForever(disappear))
self.addChild(coin)
return(coin)
}
override func didMove(to view: SKView) {
let background = SKSpriteNode(imageNamed:"bg")
background.size = self.size
background.position = CGPoint(x:self.frame.size.width/2, y: self.frame.size.height/2)
background.zPosition = 0
self.addChild(background)
var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeCoins), userInfo: nil, repeats: true)
}
}
However, when I add a label to each coin specifying its name, something weird happens: After every 3 seconds, 3 coins appear simultaneously on the screen. The label is placed on 1 of those 3 coins, and it doesn't even say the coin's name correctly. This is the new code:
class GameScene: SKScene {
// creating a playable area
let gameArea: CGRect
override init(size: CGSize) {
let maxAspectRatio: CGFloat = 16.0/9.0
let playableWidth = size.height / maxAspectRatio
let gameAreaMargin = (size.width - playableWidth)/2
gameArea = CGRect(x: gameAreaMargin, y: 270, width: playableWidth, height: size.height - 270)
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max-min) + min
}
func spawnAndFadeCoins() -> SKSpriteNode{
let randNum = arc4random()%4 + 1
let coin = SKSpriteNode(imageNamed: "coin\(randNum)")
if randNum == 4 {
coin.zPosition = 10
}
else {
coin.zPosition = 5
}
coin.name = "coin\(randNum)"
let randomX = random(min: gameArea.minX + coin.size.width/2,
max: gameArea.maxX - coin.size.width/2)
let randomY = random(min: gameArea.minY + coin.size.height/2,
max: gameArea.maxY - coin.size.height/2)
coin.position = CGPoint(x: randomX, y: randomY)
let disappear = SKAction.fadeOut(withDuration: 1.0)
coin.run(SKAction.repeatForever(disappear))
self.addChild(coin)
return(coin)
}
func spawnAndFadeLabels() -> SKLabelNode{
let label = SKLabelNode()
label.text = "\(spawnAndFadeCoins().name)"
label.zPosition = 15
label.color = SKColor.white()
label.fontSize = 60
label.position = spawnAndFadeCoins().position
let disappear2 = SKAction.fadeOut(withDuration: 1.0)
label.run(SKAction.repeatForever(disappear2))
self.addChild(label)
return(label)
}
override func didMove(to view: SKView) {
let background = SKSpriteNode(imageNamed:"bg")
background.size = self.size
background.position = CGPoint(x:self.frame.size.width/2, y: self.frame.size.height/2)
background.zPosition = 0
self.addChild(background)
var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeCoins), userInfo: nil, repeats: true)
var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeLabels), userInfo: nil, repeats: true)
}
}
Can you help me solve this mystery? Thanks in advance.
The problem is that you called spawnAndFadeCoins two more times in spawnAndFadeLabels:
func spawnAndFadeLabels() -> SKLabelNode{
let label = SKLabelNode()
label.text = "\(spawnAndFadeCoins().name)" <-- here!
label.zPosition = 15
label.color = SKColor.white()
label.fontSize = 60
label.position = spawnAndFadeCoins().position <-- and here!
let disappear2 = SKAction.fadeOut(withDuration: 1.0)
label.run(SKAction.repeatForever(disappear2))
self.addChild(label)
return(label)
}
I think one thing you can do to solve it is this:
Have only one timer:
runAction(SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration: 3), SKAction.run(spawnAndFadeCoins)])))
I used SKActions here because it is not recommended to use Timer in spritekit.
Now only spawnAndFadeCoins will be called once every three seconds. Then, change spawnAndFadeLabels to:
func spawnAndFadeLabels(of node: SKSpriteNode) -> SKLabelNode{
let label = SKLabelNode()
label.text = "\(node.name)"
label.zPosition = 15
label.color = SKColor.white()
label.fontSize = 60
label.position = node.position
let disappear2 = SKAction.fadeOut(withDuration: 1.0)
label.run(SKAction.repeatForever(disappear2))
self.addChild(label)
return(label)
}
Change spawnAndFadeCoins to:
func spawnAndFadeCoins() -> SKSpriteNode{
let randNum = arc4random()%4 + 1
let coin = SKSpriteNode(imageNamed: "coin\(randNum)")
if randNum == 4 {
coin.zPosition = 10
}
else {
coin.zPosition = 5
}
coin.name = "coin\(randNum)"
let randomX = random(min: gameArea.minX + coin.size.width/2,
max: gameArea.maxX - coin.size.width/2)
let randomY = random(min: gameArea.minY + coin.size.height/2,
max: gameArea.maxY - coin.size.height/2)
coin.position = CGPoint(x: randomX, y: randomY)
let disappear = SKAction.fadeOut(withDuration: 1.0)
coin.run(SKAction.repeatForever(disappear))
self.addChild(coin)
spawnAndFadeLabels(of: coin) <-- This line is added!
return(coin)
}
I think this is want you want.

How to make sprites follow a random pattern within a circle?

I am makeing a game in which I want that the enemies move following a random pattern within a circle. I already made that the enemies spawn randomly in all the sides of the screen, but the problem is that I dont know how to make the enemies move following a random pattern within a circle just like the image.
class GameScene: SKScene, SKPhysicsContactDelegate {
var circuloPrincipal = SKSpriteNode(imageNamed: "circulo")
var enemigoTimer = NSTimer()
}
override func didMoveToView(view: SKView) {
circuloPrincipal.size = CGSize(width: 225, height: 225)
circuloPrincipal.position = CGPoint(x: frame.width / 2, y: frame.height / 2)
circuloPrincipal.color = colorAzul
circuloPrincipal.colorBlendFactor = 1.0
circuloPrincipal.name = "circuloPrincipal"
circuloPrincipal.zPosition = 1.0
self.addChild(circuloPrincipal)
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
enemigoTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("enemigos"), userInfo: nil, repeats: true)
}
func enemigos() {
let enemigo = SKSpriteNode(imageNamed: "enemigo")
enemigo.size = CGSize(width: 25, height: 25)
enemigo.zPosition = 2.0
enemigo.name = "enemigo"
let posisionRandom = arc4random() % 4
switch posisionRandom {
case 0:
enemigo.position.x = 0
let posisionY = arc4random_uniform(UInt32(frame.size.height))
enemigo.position.y = CGFloat(posisionY)
self.addChild(enemigo)
break
case 1:
enemigo.position.y = 0
let posisionX = arc4random_uniform(UInt32(frame.size.width))
enemigo.position.x = CGFloat(posisionX)
self.addChild(enemigo)
break
case 2:
enemigo.position.y = frame.size.height
let posisionX = arc4random_uniform(UInt32(frame.size.width))
enemigo.position.x = CGFloat(posisionX)
self.addChild(enemigo)
break
case 3:
enemigo.position.x = frame.size.width
let posisionY = arc4random_uniform(UInt32(frame.size.height))
enemigo.position.y = CGFloat(posisionY)
self.addChild(enemigo)
break
default:
break
}
enemigo.runAction(SKAction.moveTo(circuloPrincipal.position, duration: 1.4))
}
Try to add this code:
let randomY = CGFloat(Int.random(-Int(circuloPrincipal.frame.height/2)...Int(circuloPrincipal.frame.height/2)))
let randomX = CGFloat(Int.random(-Int(circuloPrincipal.frame.width/2)...Int(circuloPrincipal.frame.width/2)))
let slopeToCirculoPrincipal = (enemigo.position.y - circuloPrincipal.position.y + randomY ) / (enemigo.position.x - circuloPrincipal.position.x + randomX)
let constant = enemigo.position.y - slopeToCirculoPrincipal * enemigo.position.x
let finalX : CGFloat = enemigo.position.x < circuloPrincipal.position.x ? 1500.0 : -1500.0 // Set it to somewhere outside screen size
let finalY = constant + slopeToCirculoPrincipal * finalX
let distance = (enemigo.position.y - finalY) * (enemigo.position.y - finalY) + (enemigo.position.x - finalX) * (enemigo.position.x - finalX)
let enemigoSpeed : CGFloat = 100.0
let timeToCoverDistance = sqrt(distance) / enemigoSpeed
let moveAction = SKAction.moveTo(CGPointMake(finalX, finalY), duration: NSTimeInterval(timeToCoverDistance))
let removeAction = SKAction.runBlock { () -> Void in
enemigo.removeFromParent()
}
enemigo.runAction(SKAction.sequence([moveAction,removeAction]))
Instead of:
enemigo.runAction(SKAction.moveTo(circuloPrincipal.position, duration: 1.4))
Also you need to put this extension somewhere in your project:
extension Int
{
static func random(range: Range<Int> ) -> Int
{
var offset = 0
if range.startIndex < 0 // allow negative ranges
{
offset = abs(range.startIndex)
}
let mini = UInt32(range.startIndex + offset)
let maxi = UInt32(range.endIndex + offset)
return Int(mini + arc4random_uniform(maxi - mini)) - offset
}
}

How can I spawn a random (CLASS SPRITENODE) enemy into my gamescene

I am new is swift programming. I want to spawn an enemies into a random positions using a Class node. I tried to search a code for a random spawning of an enemies but it seems it is irrelevant for my code.
Here is the code I searched for the random spawning.
import SpriteKit
class GameScene: SKScene {
let player = SKSpriteNode(imageNamed:"spacemonkey_fly02")
override func didMoveToView(view: SKView) {
player.position = CGPoint(x:frame.size.width * 0.1, y: frame.size.height * 0.5)
addChild(player)
backgroundColor = SKColor.blackColor()
runAction(SKAction.repeatActionForever(
SKAction.sequence([
SKAction.runBlock(spawnEnemy),
SKAction.waitForDuration(1.0)])))
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(#min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
func spawnEnemy() {
let enemy = SKSpriteNode(imageNamed: "boss_ship")
enemy.name = "enemy"
enemy.position = CGPoint(x: frame.size.width, y: frame.size.height * random(min: 0, max: 1))
addChild(enemy)
}
}
Here is the Class I made that I want to spawn randomly in my gamescene
import SpriteKit
class Meteor: SKSpriteNode, GameSprite {
var textureAtlas:SKTextureAtlas = SKTextureAtlas(named:"meteor.atlas")
var meteorAnimation = SKAction()
func spawn(parentNode: SKNode, position: CGPoint, size: CGSize = CGSize(width: 30, height: 30)) {
parentNode.addChild(self)
meteorRotation()
self.size = size
self.position = position
self.texture = textureAtlas.textureNamed("meteor-1.png")
self.physicsBody = SKPhysicsBody(texture: textureAtlas.textureNamed("meteor-1.png"), size: size)
self.physicsBody = SKPhysicsBody(circleOfRadius: size.width / 2)
self.physicsBody?.affectedByGravity = true
self.runAction(meteorAnimation)
}
func meteorRotation() {
let meteorCycle = SKAction.rotateByAngle(4, duration: 2);
meteorAnimation = SKAction.repeatActionForever(meteorCycle)
}
func onTap() {
//self.physicsBody?.affectedByGravity = false
self.physicsBody?.dynamic = false
self.physicsBody?.categoryBitMask = 0
let crashAnimation = SKAction.group([
SKAction.fadeAlphaTo(0, duration: 0.2),
SKAction.scaleTo(1.5, duration: 0.2),
SKAction.moveBy(CGVector(dx: 0, dy: 25), duration: 0.2)
])
let resetAfterCrashed = SKAction.runBlock {
self.position.y = 5000
self.alpha = 1
self.xScale = 1
self.yScale = 1
}
let crashSequence = SKAction.sequence([
crashAnimation,
resetAfterCrashed
])
self.runAction(crashSequence)
}
}
Is it possible to use the code I searched for a class node?
I tried to modify the random spawning code you found to use your meteor class. I took out any lines that didn't involve the meteors, so you'll need to add your world, earth, and field code as you sent me. Give this a shot and let me know if it works out:
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.blackColor()
runAction(SKAction.repeatActionForever(
SKAction.sequence([
SKAction.runBlock(spawnEnemy),
SKAction.waitForDuration(1.0)])))
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(#min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
func spawnEnemy() {
let newMeteor = Meteor()
let meteorPosition = CGPoint(x: frame.size.width, y: frame.size.height * random(min: 0, max: 1))
newMeteor.spawn(world, meteorPosition)
}
}