- Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathBall.js
More file actions
Latest commit
150 lines (111 loc) · 3.69 KB
/
Copy pathBall.js
File metadata and controls
150 lines (111 loc) · 3.69 KB
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
functionBall(position,color){
this.position=position;
this.velocity=newVector2();
this.moving=false;
this.sprite=getBallSpriteByColor(color);
this.color=color;
this.visible=true;
}
Ball.prototype.update=function(delta){
if(!this.visible){
return;
}
this.position.addTo(this.velocity.mult(delta));
// Apply friction
this.velocity=this.velocity.mult(1-CONSTANTS.frictionEnergyLoss);
if(this.velocity.length()<CONSTANTS.minVelocityLength){
this.velocity=newVector2();
this.moving=false;
}
}
Ball.prototype.draw=function(){
if(!this.visible){
return;
}
Canvas.drawImage(this.sprite,this.position,CONSTANTS.ballOrigin);
}
Ball.prototype.shoot=function(power,rotation){
this.velocity=newVector2(power*Math.cos(rotation),power*Math.sin(rotation));
this.moving=true;
}
Ball.prototype.collideWithBall=function(ball){
if(!this.visible||!ball.visible){
return;
}
// Find a normal vector
constn=this.position.subtract(ball.position);
// Find distance
constdist=n.length();
if(dist>CONSTANTS.ballDiameter){
return;
}
// Find minimum translation distance
constmtd=n.mult((CONSTANTS.ballDiameter-dist)/dist);
// Push-pull balls apart
this.position=this.position.add(mtd.mult(1/2));
ball.position=ball.position.subtract(mtd.mult(1/2));
// Find unit normal vector
constun=n.mult(1/n.length());
// Find unit tangent vector
constut=newVector2(-un.y,un.x);
// Project velocities onto the unit normal and unit tangent vectors
constv1n=un.dot(this.velocity);
constv1t=ut.dot(this.velocity);
constv2n=un.dot(ball.velocity);
constv2t=ut.dot(ball.velocity);
// Find new normal velocities
letv1nTag=v2n;
letv2nTag=v1n;
// Convert the scalar normal and tangential velocities into vectors
v1nTag=un.mult(v1nTag);
constv1tTag=ut.mult(v1t);
v2nTag=un.mult(v2nTag);
constv2tTag=ut.mult(v2t);
// Update velocities
this.velocity=v1nTag.add(v1tTag);
ball.velocity=v2nTag.add(v2tTag);
this.moving=true;
ball.moving=true;
}
Ball.prototype.handleBallInPocket=function(){
if(!this.visible){
return;
}
letinPocket=CONSTANTS.pockets.some(pocket=>{
returnthis.position.distFrom(pocket)<CONSTANTS.pocketRadius;
});
if(!inPocket){
return;
}
this.visible=false;
this.moving=false;
}
Ball.prototype.collideWithTable=function(table){
if(!this.moving||!this.visible){
return;
}
letcollided=false;
if(this.position.y<=table.TopY+CONSTANTS.ballRadius){
this.position.y=table.TopY+CONSTANTS.ballRadius;
this.velocity=newVector2(this.velocity.x,-this.velocity.y);
collided=true;
}
if(this.position.x>=table.RightX-CONSTANTS.ballRadius){
this.position.x=table.RightX-CONSTANTS.ballRadius;
this.velocity=newVector2(-this.velocity.x,this.velocity.y);
collided=true;
}
if(this.position.y>=table.BottomY-CONSTANTS.ballRadius){
this.position.y=table.BottomY-CONSTANTS.ballRadius;
this.velocity=newVector2(this.velocity.x,-this.velocity.y);
collided=true;
}
if(this.position.x<=table.LeftX+CONSTANTS.ballRadius){
this.position.x=table.LeftX+CONSTANTS.ballRadius;
this.velocity=newVector2(-this.velocity.x,this.velocity.y);
collided=true;
}
if(collided){
this.velocity=this.velocity.mult(1-CONSTANTS.collisionEnergyLoss);
}
}