Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import SpriteKit
- 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 fly : UInt32 = 0b1
- static let net: UInt32 = 0b10
- }
- let net = SKSpriteNode(imageNamed: "net")
- var fliesAdded = 0
- var fliesCaught = 0
- let maxFlies = 10
- var level = CGFloat(1.0)
- var gameKey: String?
- var lives = 3
- var levelCounter = 0
- override func didMove(to view: SKView) {
- backgroundColor = SKColor.white
- // Set up the properties of the net
- net.scale(to: CGSize.init(width: net.size.width/10, height: net.size.height/10))
- net.physicsBody = SKPhysicsBody(rectangleOf: net.size)
- net.physicsBody?.isDynamic = false
- net.physicsBody?.categoryBitMask = PhysicsCategory.net
- net.physicsBody?.contactTestBitMask = PhysicsCategory.fly
- net.physicsBody?.collisionBitMask = PhysicsCategory.none
- net.position = CGPoint(x: size.width * 0.5, y: size.height * 0.1)
- // 4
- addChild(net)
- physicsWorld.gravity = .zero
- physicsWorld.contactDelegate = self
- self.isPaused = false
- run(SKAction.run(addFly))
- let backgroundMusic = SKAudioNode(fileNamed: "background-music-aac.caf")
- backgroundMusic.autoplayLooped = true
- addChild(backgroundMusic)
- // Add a label for the score
- let scoreLabel = SKLabelNode()
- scoreLabel.fontColor = UIColor.black
- scoreLabel.fontSize = 65
- scoreLabel.name = "scoreLabel"
- scoreLabel.position = CGPoint(x: size.width/2, y: size.height/2);
- scoreLabel.text = "0";
- self.addChild(scoreLabel)
- // Add a label for the level
- let levelLabel = SKLabelNode()
- levelLabel.fontColor = UIColor.black
- levelLabel.fontSize = 32.5
- levelLabel.name = "levelLabel"
- levelLabel.text = "level (Int(level))"
- levelLabel.horizontalAlignmentMode = .left
- levelLabel.verticalAlignmentMode = .top
- levelLabel.position = CGPoint(x: 0, y: self.size.height)
- self.addChild(levelLabel)
- // Add a label for the lives
- let livesLabel = SKLabelNode()
- livesLabel.fontColor = UIColor.black
- livesLabel.fontSize = 32.5
- livesLabel.name = "livesLabel"
- livesLabel.text = "3/3 lives"
- livesLabel.horizontalAlignmentMode = .right
- livesLabel.verticalAlignmentMode = .top
- livesLabel.position = CGPoint(x:self.size.width, y:self.size.height)
- self.addChild(livesLabel)
- // Get the starting level
- let urlComp = NSURLComponents(string: "---")!
- let params = [URLQueryItem(name: "UserName", value: (UIApplication.shared.delegate as! AppDelegate).userName)]
- urlComp.queryItems = params
- var request = URLRequest(url: urlComp.url!)
- request.httpMethod = "GET"
- let task = URLSession.shared.dataTask(with: request) { data, response, error in
- do {
- let result = try JSONDecoder().decode(LevelResponseObject.self, from: data!)
- let userHighestLevel = Int(result.level) ?? 1
- if userHighestLevel > 5 {
- self.level = CGFloat(userHighestLevel) - 5.0
- }
- else {
- self.level = CGFloat(userHighestLevel)
- }
- if let levelLabel = self.childNode(withName: "levelLabel") as? SKLabelNode {
- levelLabel.text = "level (Int(self.level))"
- }
- } catch {
- print(error)
- }
- }
- task.resume()
- }
- func touchDown(atPoint pos : CGPoint) {
- //net.position = CGPoint(x: pos.x, y: size.height * 0.1)
- }
- func touchMoved(toPoint pos : CGPoint) {
- //net.position = CGPoint(x: pos.x, y: size.height * 0.1)
- }
- func touchUp(atPoint pos : CGPoint) {
- }
- override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
- }
- override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
- for touch: AnyObject in touches {
- let touchLocation = touch.location(in: self)
- net.position = CGPoint(x: touchLocation.x, y: size.height * 0.1)
- }
- }
- override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
- }
- override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
- }
- override func update(_ currentTime: TimeInterval) {
- // Called before each frame is rendered
- }
- // MARK: Private functions
- func addFly() {
- let origin = (UIApplication.shared.delegate as! AppDelegate).dataOrigin
- let urlComp = NSURLComponents(string: "---")!
- let params = [URLQueryItem(name: "Origin", value: origin)]
- urlComp.queryItems = params
- var request = URLRequest(url: urlComp.url!)
- request.httpMethod = "GET"
- let task = URLSession.shared.dataTask(with: request) { data, response, error in
- do {
- let result = try JSONDecoder().decode(ResponseObject.self, from: data!)
- let rows = result.items[0].Data.components(separatedBy: ";")
- let firstPoint = Double(rows[0]) ?? 0.0
- //let xCoords = rows.map{ CGFloat(NSString(string: $0).doubleValue - firstPoint)*self.size.width/157.4*2 + self.size.width/2 }
- let xCoords = rows.map{ self.size.width/(1+exp(-(CGFloat(NSString(string: $0).doubleValue - firstPoint)/10)))} // increasing the denominator in the exponential will make the relationship more linear, decreasing it will exaggerate moves near to the center
- self.gameKey = result.items[0].Key
- self.fliesAdded += 1
- // Create sprite
- print("New Fly")
- print("Level (self.level)")
- let fly = SKSpriteNode(imageNamed: "fly")
- fly.scale(to: CGSize.init(width: self.size.width/20, height: fly.size.height/fly.size.width*self.size.width/20))
- fly.physicsBody = SKPhysicsBody(rectangleOf: fly.size)
- fly.physicsBody?.isDynamic = true
- fly.physicsBody?.categoryBitMask = PhysicsCategory.fly
- fly.physicsBody?.contactTestBitMask = PhysicsCategory.none
- fly.physicsBody?.collisionBitMask = PhysicsCategory.none
- // Position the fly slightly off-screen along the top edge,
- // in the middle of the x axis
- fly.position = CGPoint(x: self.size.width/2, y: self.size.height + fly.size.height/2)
- // Add the fly to the scene
- self.addChild(fly)
- var flightSequence: [SKAction] = []
- var currentY = fly.position.y
- var currentX = fly.position.x
- let yDistanceToTravel = currentY - (self.net.position.y + self.net.size.height/2)
- let yIncrement = yDistanceToTravel / CGFloat(xCoords.count - 1)
- var duration = CGFloat(8.28)/CGFloat(xCoords.count - 1)
- duration = duration/(1.0 + self.level/10)
- // Create a sequence of moves for the fly
- for targetX in xCoords {
- // Set the parameters for the move
- let targetY = currentY - yIncrement
- let flyTurn = SKAction.rotate(toAngle: -atan((targetX-currentX)/(targetY-currentY)), duration: 0.0, shortestUnitArc: true)
- flightSequence.append(flyTurn)
- let flyMovement = SKAction.move(to: CGPoint(x: targetX, y: targetY), duration: TimeInterval(duration))
- flightSequence.append(flyMovement)
- currentY = targetY
- currentX = targetX
- }
- // After the fly passes the net send it vertically down
- let flyTurn = SKAction.rotate(toAngle: 0.0, duration: 0.0, shortestUnitArc: true)
- flightSequence.append(flyTurn)
- let flyMovement = SKAction.move(to: CGPoint(x: currentX, y: -fly.size.height/2), duration: TimeInterval(duration))
- flightSequence.append(flyMovement)
- // Remove the fly after it passes the net and end the game
- let flightOver = SKAction.run() { [weak self] in
- guard let `self` = self else { return }
- if (self.gameKey != nil){
- self.recordDistance(fly: fly, net: self.net, gameKey: self.gameKey!, level: self.level, win: false)
- }
- fly.removeFromParent()
- self.gameOver()
- }
- flightSequence.append(flightOver)
- fly.run(SKAction.sequence(flightSequence))
- } catch {
- print(error)
- }
- }
- task.resume()
- }
- func gameOver() {
- if (lives == 1) {
- let reveal = SKTransition.flipHorizontal(withDuration: 0.5)
- let scoreScene = ScoreScene(size: self.size, score: fliesCaught, level: Int(level))
- view?.presentScene(scoreScene, transition: reveal)
- }
- else {
- lives = lives - 1
- if let livesLabel = self.childNode(withName: "livesLabel") as? SKLabelNode {
- livesLabel.text = "(lives)/3 lives"
- }
- addFly()
- }
- }
- func flyCaught(fly: SKSpriteNode, net: SKSpriteNode, gameKey: String?) {
- if (gameKey != nil) {
- recordDistance(fly: fly, net: net, gameKey: gameKey!, level: self.level, win: true)
- }
- fly.removeFromParent()
- fliesCaught += 1
- //print("Score = (fliesCaught)")
- if let scoreLabel = self.childNode(withName: "scoreLabel") as? SKLabelNode {
- scoreLabel.text = "(fliesCaught)"
- }
- if levelCounter == 4 {
- levelCounter = 0
- level = level + 1.0
- if let levelLabel = self.childNode(withName: "levelLabel") as? SKLabelNode {
- levelLabel.text = "level (Int(level))"
- }
- }
- else {
- levelCounter = levelCounter + 1
- }
- addFly()
- }
- func recordDistance(fly: SKSpriteNode, net: SKSpriteNode, gameKey: String, level: CGFloat, win: Bool) {
- let distance = fly.position.x - net.position.x
- //print("Distance to center of net = (distance)")
- // prepare json data
- let json: [String: Any] = ["UserName": (UIApplication.shared.delegate as! AppDelegate).userName,
- "DataKey": gameKey,
- "Level": Int(level),
- "Win": win,
- "DistanceToCenter": distance,
- "ScreenWidth": self.size.width]
- let jsonData = try? JSONSerialization.data(withJSONObject: json)
- // create post request
- let url = URL(string: "---")!
- var request = URLRequest(url: url)
- request.httpMethod = "POST"
- // insert json data to the request
- request.httpBody = jsonData
- let task = URLSession.shared.dataTask(with: request) { data, response, error in
- guard let _ = data, error == nil else { // check for fundamental networking error
- print("error=(String(describing: error))")
- return
- }
- if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
- print("statusCode should be 200, but is (httpStatus.statusCode)")
- print("response = (String(describing: response))")
- }
- }
- task.resume()
- }
- }
- extension GameScene: SKPhysicsContactDelegate {
- func didBegin(_ contact: SKPhysicsContact) {
- // 1
- 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.fly != 0) &&
- (secondBody.categoryBitMask & PhysicsCategory.net != 0)) {
- if let fly = firstBody.node as? SKSpriteNode,
- let net = secondBody.node as? SKSpriteNode {
- //print("Collision with net")
- if fly.position.y > net.position.y + net.size.height/2 {
- //print("Fly Caught")
- flyCaught(fly: fly, net: net, gameKey: gameKey)
- }
- }
- }
- }
- }
- struct ResponseObject: Decodable {
- let items: [RouteItem]
- }
- struct RouteItem: Decodable {
- let Key: String
- let Origin: String
- let Data: String
- }
- struct LevelResponseObject: Decodable {
- let level: String
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement