-
Notifications
You must be signed in to change notification settings - Fork 339
/
Copy pathmonster.rb
115 lines (83 loc) · 2.92 KB
/
monster.rb
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
module Escape # Monster
# states => :idle | :walking | :seek | :throw
class Monster < SKSpriteNode
def initWithImageNamed(name)
super.tap do
@score = 0
@currentState = :idle
end
end
def moveToSpriteNode(target, withTimeInterval:time)
if @currentState == :idle
targetVector = Vector.subtract(target.position, self.position)
unitizedVector = Vector.normalize(targetVector)
shootAmt = Vector.multiply(unitizedVector, withScalar:self.screenSize.height + self.screenSize.width)
actualDistance = Vector.add(shootAmt, self.position)
moveAction = SKAction.moveTo(actualDistance, duration:time)
self.runAction(moveAction)
@currentState = :seek
end
end
def endSeek
self.removeAllActions
self.chooseNextAction
end
def chooseNextAction
if randomizer(1..3) <= 1 # 67 % chance to walk
@currentState = :walk
self.monsterWalk
else
if self.score >= 0 && Random.rand(1).zero? # 100% chance to throw projectile (33% overall)
self.shootProjectile
end
end
end
def resetState
@currentState = :idle
end
def shootProjectile
@currentState = :throw
end
def monsterWalk
multiplier = 1.5
if @currentState == :walk
randomInterval = Random.rand * multiplier # Time between 0 and 1.5s
# Decide magnitude of walk
walkDistance = randomizer(-80..80)
# Decide direction of walk depending on the current wall
if self.wallIdentifier == Wall::LEFT || self.wallIdentifier == Wall::RIGHT
wallVertical = SKAction.moveByX(0, y:walkDistance, duration:randomInterval)
resetState = SKAction.performSelector(:resetState, onTarget:self)
self.runAction SKAction.sequence([wallVertical, resetState])
elsif self.wallIdentifier == Wall::BOTTOM || self.wallIdentifier == Wall::TOP
walkHorizontal = SKAction.moveByX(walkDistance, y:0, duration:randomInterval)
resetState = SKAction.performSelector(:resetState, onTarget:self)
self.runAction SKAction.sequence([walkHorizontal, resetState])
end
end
end
def updateWithTimeSinceLastUpdate(timeSinceLast)
if self.score >= 100
time = if self.score <= 1000
Random.rand + 2.0
elsif self.score.between?(1000, 3000)
Random.rand + 1.5
elsif self.score.between?(3000, 5000)
Random.rand + 1.0
else
Random.rand + 0.7
end
if @currentState == :idle
self.moveToSpriteNode(self.target, withTimeInterval:time)
end
end
end
attr_accessor :screenSize, :target, :score, :wallIdentifier
attr_reader :currentState
private
def randomizer(range)
@randomizer ||= Random.new
@randomizer.rand(range)
end
end
end