-
-
Save sturdysturge/2546a098a0facf29ff79bf51e118f888 to your computer and use it in GitHub Desktop.
RevDoc GameScene
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SpriteKit | |
class GameScene: SKScene, SKPhysicsContactDelegate { | |
static let projectileSize = CGFloat(10) | |
static let playerSize = CGFloat(15) | |
static let enemySize = CGFloat(30) | |
let data = GameModel.shared | |
var playerPosition: CGPoint { | |
CGPoint(x: size.width * 0.1, y: size.height * 0.5) | |
} | |
override func didMove(to view: SKView) { | |
physicsWorld.contactDelegate = self | |
startGame() | |
} | |
func startGame() { | |
addWalls() | |
addPlayer() | |
run(SKAction.repeatForever(SKAction.sequence([SKAction.run(addEnemy), SKAction.wait(forDuration: 1.0)]))) | |
} | |
func restart() { | |
removeAllChildren() | |
self.scene?.view?.isPaused = false | |
startGame() | |
} | |
func addPlayer() { | |
let player = SKSpriteNode(color: UIColor.red, size: CGSize(width: Self.playerSize, height: Self.playerSize)) | |
player.position = playerPosition | |
addChild(player) | |
} | |
func addWalls() { | |
let wallFrames = [ | |
CGRect(x: 0, y: frame.midY, width: 10, height: size.height), | |
CGRect(x: size.width, y: frame.midY, width: 10, height: size.height), | |
CGRect(x: frame.midX, y: size.height, width: size.width, height: 10) | |
] | |
wallFrames.forEach { | |
let wall = SKSpriteNode(color: UIColor.orange, size: $0.size) | |
wall.position = CGPoint(x: $0.minX, y: $0.minY) | |
wall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: wall.size.width, height: wall.size.height)) | |
wall.zPosition = 1 | |
wall.physicsBody?.isDynamic = false | |
addChild(wall) | |
} | |
} | |
func didBegin(_ contact: SKPhysicsContact) { | |
guard let nodeA = contact.bodyA.node, let nodeB = contact.bodyB.node else { return } | |
if [nodeA.name, nodeB.name].contains("projectile") && [nodeA.name, nodeB.name].contains("enemy") { | |
[nodeA, nodeB].forEach { | |
$0.removeAllActions() | |
$0.name = "projectile" | |
$0.physicsBody?.affectedByGravity = true | |
$0.run(SKAction.sequence([SKAction.wait(forDuration: 2), SKAction.removeFromParent()]) ) | |
} | |
self.data.score += 1 | |
} | |
} | |
func random() -> CGFloat { | |
return CGFloat(Float(arc4random()) / 4294967296) | |
} | |
func random(min: CGFloat, max: CGFloat) -> CGFloat { | |
return random() * (max - min) + min | |
} | |
func addEnemy() { | |
let enemy = SKSpriteNode(color: UIColor.blue, size: CGSize(width: Self.enemySize, height: Self.enemySize)) | |
let actualY = random(min: Self.enemySize / 2, max: size.height - Self.enemySize / 2) | |
enemy.position = CGPoint(x: size.width + Self.enemySize, y: actualY) | |
enemy.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: Self.enemySize, height: Self.enemySize)) | |
guard let physicsBody = enemy.physicsBody else { | |
return | |
} | |
physicsBody.affectedByGravity = false | |
physicsBody.contactTestBitMask = physicsBody.collisionBitMask | |
enemy.name = "enemy" | |
addChild(enemy) | |
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0)) | |
let actionMove = SKAction.move(to: CGPoint(x: -enemy.size.width/2, y: actualY), | |
duration: TimeInterval(actualDuration)) | |
let actionMoveDone = SKAction.removeFromParent() | |
enemy.run(SKAction.sequence([actionMove, actionMoveDone]), completion: { | |
if self.data.lives > 0 { | |
self.data.lives -= 1 | |
} | |
if self.data.lives <= 0 { | |
self.data.gameOver = true | |
self.scene?.view?.isPaused = self.data.gameOver | |
} | |
}) | |
} | |
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { | |
guard let touchLocation = touches.first?.location(in: self) else { | |
return | |
} | |
let projectile = SKShapeNode(circleOfRadius: Self.projectileSize) | |
projectile.fillColor = UIColor.green | |
projectile.position = playerPosition | |
projectile.zPosition = 1 | |
projectile.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: Self.projectileSize, height: Self.projectileSize)) | |
projectile.name = "projectile" | |
guard let physicsBody = projectile.physicsBody else { | |
return | |
} | |
physicsBody.contactTestBitMask = physicsBody.collisionBitMask | |
addChild(projectile) | |
physicsBody.applyImpulse(CGVector(dx: (touchLocation.x - playerPosition.x) / 50, dy: (touchLocation.y - playerPosition.y) / 50)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment