-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcar_ORG.kojo
182 lines (167 loc) · 5.03 KB
/
car_ORG.kojo
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Use the four arrow keys to avoid the blue cars
// You gain energy every second, and lose energy for every collision
// You lose if your energy drops below zero, or you hit the edges of the screen
// You win if you stay alive for a minute
switchToDefault2Perspective()
cleari()
drawStage(black)
// setRefreshRate(50)
val cb = canvasBounds
val carHeight = 100
val markerHeight = 80
// The collision polygon for the (very similarly sized) car images car1.png and car2.png
val carE = trans(2, 14) -> Picture {
repeat(2) {
forward(70); right(45); forward(20); right(45)
forward(18); right(45); forward(20); right(45)
}
}
def car(img: String) = Picture.image(img, carE)
val cars = collection.mutable.Map.empty[Picture, Vector2D]
val carSpeed = 3
val pResponse = 3
var pVel = Vector2D(0, 0)
var disabledTime = 0L
val bplayer = newMp3Player
val cplayer = newMp3Player
def createCar() {
val c = trans(player.position.x + randomNormalDouble * cb.width / 10, cb.y + cb.height) ->
car("/media/car-ride/car2.png")
draw(c)
cars += c -> Vector2D(0, -carSpeed)
}
val markers = collection.mutable.Set.empty[Picture]
def createMarker() {
val mwidth = 20
val m = fillColor(white) * penColor(white) *
trans(cb.x + cb.width / 2 - mwidth / 2, cb.y + cb.height) -> Picture.rect(markerHeight, mwidth)
draw(m)
markers += m
}
val player = car("/media/car-ride/car1.png")
draw(player)
drawAndHide(carE)
timer(800) {
createMarker()
createCar()
}
animate {
player.moveToFront()
val enabled = epochTimeMillis - disabledTime > 300
if (enabled) {
if (isKeyPressed(Kc.VK_LEFT)) {
pVel = Vector2D(-pResponse, 0)
player.translate(pVel)
}
if (isKeyPressed(Kc.VK_RIGHT)) {
pVel = Vector2D(pResponse, 0)
player.translate(pVel)
}
if (isKeyPressed(Kc.VK_UP)) {
pVel = Vector2D(0, pResponse)
player.translate(pVel)
if (!isMp3Playing) {
playMp3Sound("/media/car-ride/car-accel.mp3")
}
}
else {
stopMp3()
}
if (isKeyPressed(Kc.VK_DOWN)) {
pVel = Vector2D(0, -pResponse)
player.translate(pVel)
if (!bplayer.isMp3Playing) {
bplayer.playMp3Sound("/media/car-ride/car-brake.mp3")
}
}
else {
bplayer.stopMp3()
}
}
else {
player.translate(pVel)
}
if (player.collidesWith(stageLeft) || player.collidesWith(stageRight)) {
cplayer.playMp3Sound("/media/car-ride/car-crash.mp3")
player.setOpacity(0.5)
drawCenteredMessage("You Crashed!", red, 30)
stopAnimation()
}
else if (player.collidesWith(stageTop)) {
pVel = Vector2D(0, -pResponse)
player.translate(pVel * 2)
disabledTime = epochTimeMillis
}
else if (player.collidesWith(stageBot)) {
pVel = Vector2D(0, pResponse)
player.translate(pVel * 2)
disabledTime = epochTimeMillis
}
cars.foreach { cv =>
val (c, vel) = cv
c.moveToFront()
if (player.collidesWith(c)) {
cplayer.playMp3Sound("/media/car-ride/car-crash.mp3")
pVel = bouncePicVectorOffPic(player, pVel - vel, c) / 2
player.translate(pVel * 3)
c.translate(-pVel * 3)
disabledTime = epochTimeMillis
updateEnergyCrash()
}
else {
val newVel = Vector2D(vel.x + randomDouble(1) / 2 - 0.25, vel.y)
cars += c -> newVel
c.translate(newVel)
}
if (c.position.y + carHeight < cb.y) {
c.erase()
cars -= c
}
}
markers.foreach { m =>
m.translate(0, -carSpeed * 2)
if (m.position.y + markerHeight < cb.y) {
m.erase()
markers -= m
}
}
}
var energyLevel = 0
def energyText = s"Energy: $energyLevel"
val energyLabel = Picture.textu(energyText, 20, ColorMaker.aquamarine)
energyLabel.translate(cb.x + 10, cb.y + cb.height - 10)
def updateEnergyTick() {
energyLevel += 2
energyLabel.update(energyText)
}
def updateEnergyCrash() {
energyLevel -= 10
energyLabel.update(energyText)
if (energyLevel < 0) {
drawCenteredMessage("You're out of energy! You Lose", red, 30)
stopAnimation()
}
}
def manageGameScore() {
var gameTime = 0
val timeLabel = Picture.textu(gameTime, 20, ColorMaker.azure)
timeLabel.translate(cb.x + 10, cb.y + 50)
draw(timeLabel)
draw(energyLabel)
timeLabel.forwardInputTo(stageArea)
timer(1000) {
gameTime += 1
timeLabel.update(gameTime)
updateEnergyTick()
if (gameTime == 60) {
drawCenteredMessage("Time up! You Win", green, 30)
stopAnimation()
}
}
}
manageGameScore()
playMp3Loop("/media/car-ride/car-move.mp3")
activateCanvas()
// Car images, via google images, from http://motor-kid.com/race-cars-top-view.html
// and www.carinfopic.com
// Car sounds from http://soundbible.com