This repository has been archived by the owner on May 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ball.swift
138 lines (119 loc) · 5.06 KB
/
Ball.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// Ball.swift
// PaddleBattle
//
// Created by Emad Mohamad on 7/1/15.
// Copyright (c) 2015 Apportable. All rights reserved.
//
import Foundation
class Ball: CCSprite {
enum BallCorner {
case BottomLeft
case BottomRight
case TopLeft
case TopRight
}
let maxSpeed = CGFloat(600)
let minSpeed = CGFloat(250)
let ballLocation : CGFloat = 40
var ballCorner : BallCorner = .BottomLeft
weak var gameScene : MainScene?
// add trail particle effect to the ball
func addTrail() {
let trail = CCBReader.load("Trail") as! CCParticleSystem
trail.name = "trail"
trail.position = CGPoint(x: contentSizeInPoints.width/2, y: contentSizeInPoints.height/2)
trail.particlePositionType = CCParticleSystemPositionType.Free
self.addChild(trail)
trail.zOrder = -1
}
func addBallAndApplyImpulse(speed: CGFloat) {
var velocityX = CGFloat(arc4random_uniform(6) + 18)
var velocityY = CGFloat(arc4random_uniform(6) + 5)
var x = CGFloat(0), y = CGFloat(0)
gameScene?.gamePhysicsNode.addChild(self)
switch ballCorner {
case .BottomLeft:
x = velocityX * speed; y = velocityY * speed
case .BottomRight:
x = -velocityX * speed; y = velocityY * speed
case .TopLeft:
x = velocityX * speed; y = -velocityY * speed
case .TopRight:
x = -velocityX * speed; y = -velocityY * speed
}
physicsBody.applyImpulse(CGPoint(x: x, y: y))
gameScene?.balls.append(self)
GameSound.sharedInstance.playSound(GameSettings.spawnSound, volume: 1.0)
}
func spawnBallAtLocation(corner: UInt32) {
if let gameScene = gameScene {
var ballPosition : CGPoint
switch corner {
case 1:
ballPosition = CGPoint(x: ballLocation, y: ballLocation)
ballCorner = .BottomLeft
case 2:
ballPosition = CGPoint(x: gameScene.contentSizeInPoints.width - ballLocation, y: ballLocation)
ballCorner = .BottomRight
case 3:
ballPosition = CGPoint(x: ballLocation, y: gameScene.contentSizeInPoints.height - ballLocation)
ballCorner = .TopLeft
case 4:
ballPosition = CGPoint(x: gameScene.contentSizeInPoints.width - ballLocation, y: gameScene.contentSizeInPoints.height - ballLocation)
ballCorner = .TopRight
default:
ballPosition = CGPointZero
}
position = ballPosition
}
}
func limitBallSpeed() {
// Clamp the speed of the ball manually between Min and Max Speed values
DebugLog("Ball speed \(ccpLength(physicsBody.velocity))")
if ccpLength(physicsBody.velocity) > maxSpeed {
DebugLog("TOO FAST")
physicsBody.velocity = ccpMult(physicsBody.velocity, 0.8)
} else if ccpLength(physicsBody.velocity) < minSpeed {
DebugLog("TOO SLOW")
physicsBody.velocity = ccpMult(physicsBody.velocity, 1.2)
}
}
func unstuckBall() {
// if the ball get stuck on a certain path, give it impulse to unstuck it
if physicsBody.velocity.y < 10 && physicsBody.velocity.y > -10 {
physicsBody.velocity.y *= 25
}
if physicsBody.velocity.x < 10 && physicsBody.velocity.x > -10 {
physicsBody.velocity.x *= 25
}
}
override func update(delta: CCTime) {
if let gameScene = gameScene {
if gameScene.gamePhysicsNode.children != nil {
for child in gameScene.gamePhysicsNode.children {
if let ball = child as? Ball {
if CGRectContainsPoint(gameScene.playBox.boundingBox(), position) {
limitBallSpeed()
unstuckBall()
if let trail = getChildByName("trail", recursively: false) as? CCParticleSystem {
trail.startSize = Float(ccpLength(physicsBody.velocity)*0.03)
}
} else {
removeFromParentAndCleanup(true)
if let index = find(gameScene.balls, self) {
gameScene.balls.removeAtIndex(index)
}
// always keep a ball in the play field
if gameScene.balls.count == 0 && gameStatus == .Running {
gameScene.runAction(CCActionSequence(array: [CCActionDelay(duration: 0.25), CCActionCallBlock(block: { () -> Void in
gameScene.createNewBall()
})]))
}
}
}
}
}
}
}
}