@@ -2,19 +2,22 @@ export class Dot {
2
2
constructor ( x , radius ) {
3
3
this . x = x ;
4
4
this . y = 0 ;
5
- this . u = 1 ;
5
+ this . u = 0.3 ;
6
6
this . v = 0 ;
7
+ this . r = radius ;
8
+ this . g = 12 ;
9
+ this . viscosity = 4 ;
7
10
this . xPrev = this . x ;
8
11
this . yPrev = this . y ;
9
12
this . uPrev = this . u ;
10
13
this . vPrev = this . v ;
11
14
this . xTarget = this . x ;
12
15
this . yTarget = this . y ;
13
- this . r = radius ;
14
16
this . colour = "blue" ;
15
17
this . hasCollided = false ;
16
18
this . hasCollidedWithGround = false ;
17
19
this . prevCollidedWithGround = false ;
20
+ this . inSlowMo = false ;
18
21
this . inFloatingMode = false ;
19
22
}
20
23
@@ -32,7 +35,10 @@ export class Dot {
32
35
this . xTarget = this . x + this . u * deltaTime ;
33
36
34
37
// y-motion
35
- if ( this . inFloatingMode ) {
38
+ if ( this . inSlowMo ) {
39
+ this . v -= this . viscosity * this . v * deltaTime ;
40
+ this . v += ( 0.2 * this . g ) * deltaTime ;
41
+ } else if ( this . inFloatingMode ) {
36
42
this . v += ( - 0.5 * this . g ) * deltaTime ;
37
43
} else {
38
44
this . v += this . g * deltaTime ;
@@ -45,22 +51,31 @@ export class Dot {
45
51
// Check for collision
46
52
const collisionResult =
47
53
checkPathCollision ( collisionImgBuffer , this . xPrev , this . yPrev , this . xTarget , this . yTarget , this . r , this . xScale , this . yScale ) ;
48
- this . hasCollided = collisionResult . hasCollided ;
54
+ this . hasCollided = collisionResult . hasCollided > 0 ;
49
55
if ( this . hasCollided ) {
50
56
this . prevCollidedWithGround = false ;
51
57
}
52
58
const yCollision = collisionResult . y ;
53
59
54
60
// No collision
55
- if ( ! this . hasCollided ) {
61
+ if ( collisionResult . hasCollided == 0 ) {
62
+ this . hasCollided = false ;
56
63
this . x = this . xTarget ;
57
64
this . y = this . yTarget ;
58
65
this . inFloatingMode = false ;
66
+ this . inSlowMo = false ;
67
+ return ;
68
+ } else if ( collisionResult . hasCollided == 2 ) {
69
+ this . hasCollided = true ;
70
+ this . x = this . xTarget ;
71
+ this . y = this . yTarget ;
72
+ this . inFloatingMode = false ;
73
+ this . inSlowMo = true ;
59
74
return ;
60
75
}
61
76
62
77
// Collision detected, but in floating mode, so no need to push out
63
- if ( this . inFloatingMode ) {
78
+ if ( this . inFloatingMode || this . inSlowMo ) {
64
79
this . x = this . xTarget ;
65
80
this . y = this . yTarget ;
66
81
return ;
@@ -70,12 +85,21 @@ export class Dot {
70
85
const xTargetCollision = this . xTarget ;
71
86
const yTargetCollision = yCollision - ( this . yTarget - yCollision ) ;
72
87
73
- if ( checkCollision ( collisionImgBuffer , xTargetCollision , yTargetCollision , this . r , this . xScale , this . yScale ) ) {
88
+ const origCollisionResult = checkCollision (
89
+ collisionImgBuffer , xTargetCollision , yTargetCollision ,
90
+ this . r , this . xScale , this . yScale ) ;
91
+ if ( origCollisionResult == 1 ) {
74
92
// Cannot push out of collision: enter floating mode
75
93
this . x = this . xTarget ;
76
94
this . y = this . yTarget ;
77
95
this . inFloatingMode = true ;
78
96
return ;
97
+ } else if ( origCollisionResult == 2 ) {
98
+ // Soft collision: enter floating mode
99
+ this . x = this . xTarget ;
100
+ this . y = this . yTarget ;
101
+ this . inSlowMo = true ;
102
+ return ;
79
103
}
80
104
81
105
if ( this . yTarget < this . yPrev ) {
@@ -136,19 +160,6 @@ export class Dot {
136
160
ctx . arc ( this . x * this . xScale , this . y * this . yScale , this . r , 0 , Math . PI * 2 ) ;
137
161
ctx . fill ( ) ;
138
162
}
139
-
140
- async playSound ( y , snapPitch = true ) {
141
- Tone . start ( ) ;
142
- const minPitch = 110 ; // lowest frequency (Hz)
143
- const maxPitch = 880 ; // highest frequency (Hz)
144
-
145
- const normFactor = Math . max ( Math . min ( 1 - ( y / this . height ) , 1 ) , 0 ) ; // 1 at top, 0 at bottom
146
- var frequency = minPitch + normFactor * ( maxPitch - minPitch ) ;
147
- if ( snapPitch ) {
148
- frequency = noteId2frequency ( frequency2noteId ( frequency , true ) ) ;
149
- }
150
- synth . triggerAttackRelease ( frequency , "8n" ) ;
151
- }
152
163
}
153
164
154
165
function checkCollision ( collisionImgBuffer , dotX , dotY , radius , xScale , yScale ) {
@@ -160,19 +171,25 @@ function checkCollision(collisionImgBuffer, dotX, dotY, radius, xScale, yScale)
160
171
161
172
// Make sure sample inside canvas
162
173
if ( sampleX < 0 || sampleX >= canvas . width || sampleY < 0 || sampleY >= canvas . height ) continue ;
163
- let pixel ;
174
+ let alpha ;
175
+ let r ;
164
176
try {
165
177
const alphaId = ( sampleY * collisionImgBuffer . width + sampleX ) * 4 + 3 ;
166
- pixel = collisionImgBuffer . data [ alphaId ] ;
178
+ alpha = collisionImgBuffer . data [ alphaId ] ;
179
+ const rId = ( sampleY * collisionImgBuffer . width + sampleX ) * 4 ;
180
+ r = collisionImgBuffer . data [ rId ] ;
167
181
} catch ( e ) {
168
182
console . error ( "Error getting pixel data at " , sampleX , sampleY , ": " , e ) ;
169
183
}
170
184
171
- if ( pixel > 0 ) {
172
- return true ; // collision detected
185
+ if ( alpha > 0 ) {
186
+ if ( r > 50 ) {
187
+ return 2 ; // soft collision
188
+ }
189
+ return 1 ; // hard collision
173
190
}
174
191
}
175
- return false ; // no collision
192
+ return 0 ; // no collision
176
193
}
177
194
178
195
function checkPathCollision ( collisionImgBuffer , startX , startY , endX , endY , radius , xScale , yScale , steps = 6 ) {
@@ -187,11 +204,12 @@ function checkPathCollision(collisionImgBuffer, startX, startY, endX, endY, radi
187
204
continue ;
188
205
}
189
206
190
- if ( checkCollision ( collisionImgBuffer , x , y , radius , xScale , yScale ) ) {
191
- return { hasCollided : true , x : prevX , y : prevY }
207
+ const collisionResult = checkCollision ( collisionImgBuffer , x , y , radius , xScale , yScale )
208
+ if ( collisionResult > 0 ) {
209
+ return { hasCollided : collisionResult , x : prevX , y : prevY }
192
210
}
193
211
prevX = x ;
194
212
prevY = y ;
195
213
}
196
- return { hasCollided : false , x : endX , y : endY }
214
+ return { hasCollided : 0 , x : endX , y : endY }
197
215
}
0 commit comments