-
Notifications
You must be signed in to change notification settings - Fork 0
/
ball.js
162 lines (151 loc) · 4.3 KB
/
ball.js
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
// 定义球类
class Ball {
/* 定义彩球的公共属性 */
constructor (x, y, velX, velY, color, size) {
this.x = x // x坐标
this.y = y // y坐标
this.velX = velX // x轴速度
this.velY = velY // y轴速度
this.color = color // 颜色类
this.size = size // 半径大小
this.velSpeed = 0 // 球的速度的递增速度,如一轮后,velY = velY + velSpeed
}
// 定义所有彩球
static balls = []
// 定义关于 Ball 的常量,可设置
static ballConfig = {
maxLen: 6, // 球的个数
minSize: 25, // 球的最小半径
maxSize: 35, // 球的最大半径
minVel: 1, // 球的最小速度
maxVel: 4 // 球的最大速度
}
// 定义关于 颜色 衍生的属性,5种颜色,随机获取, 可设置
static colorConfig = [
{
color: 'white',
click: 1, // 需要点击的次数
// clicked: 0, // 已点击的次数,每次调用randomColor()时初始化clicked
score: -1, // 点击一次的得分
life: -1, // 点击一次得的生命值
border: 0 // 触到下边界得的生命值
},
{
color: 'grey',
click: 1,
// clicked: 0,
score: 1,
life: 0,
border: -1
},
{
color: 'green',
click: 1,
// clicked: 0,
score: 1,
life: 1,
border: 0
},
{
color: 'yellow',
click: 2,
// clicked: 0,
score: 1,
life: 0,
border: -2
},
{
color: 'red',
click: 3,
// clicked: 0,
score: 1,
life: 0,
border: -3
}
]
// 生成随机数的函数
static random (min, max) {
const num = Math.floor(Math.random() * (max - min)) + min
return num
}
// 生成随机颜色值的函数
static randomColor () {
// 先重置操作
const colorConfig = Ball.colorConfig.map((color) => {
color['clicked'] = 0 // 重置clicked次数
return color
})
// 随机颜色类0-5,random包括0不包括5
return colorConfig[Ball.random(0, colorConfig.length)]
}
// 初始化所有彩球
static initBalls ({ width, height } = {}) {
Ball.balls = JSON.parse('[]')
while(Ball.balls.length < Ball.ballConfig.maxLen) {
const size = Ball.random(Ball.ballConfig.minSize, Ball.ballConfig.maxSize)
Ball.balls.push(new Ball(
// 为避免绘制错误,球至少离画布边缘球本身一倍宽度的距离
Ball.random(0 + size, width - size),
size,
Ball.random(Ball.ballConfig.minVel, Ball.ballConfig.maxVel),
Ball.random(Ball.ballConfig.minVel, Ball.ballConfig.maxVel),
Ball.randomColor(),
size
))
}
console.log('initBalls balls', Ball.balls)
}
// 定义彩球初始化函数
init ({ width, height } = {}) {
const size = Ball.random(Ball.ballConfig.minSize, Ball.ballConfig.maxSize)
this.x = Ball.random(0 + size, width - size)
this.y = size
this.velX = Ball.random(Ball.ballConfig.minVel, Ball.ballConfig.maxVel)
this.velY = Ball.random(Ball.ballConfig.minVel, Ball.ballConfig.maxVel)
this.color = Ball.randomColor()
this.size = size
}
// 定义彩球绘制函数
draw (ctx) {
if (!ctx) {
return
}
ctx.beginPath()
ctx.fillStyle = this.color.color
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI)
ctx.fill()
}
// 定义彩球更新函数
update ({ width, height, borderWork } = {}) {
// 是否触到下边界
if((this.y + this.size) >= height) {
// 球触到下边界的处理
borderWork(this)
// 重置
this.init({ width, height })
// 速度递增,增加难度
this.velSpeed += 0.1
this.velY += this.velSpeed
}
this.y += this.velY
}
// 定义碰撞检测函数
collisionDetect () {
for(const ball of Ball.balls) {
if(this !== ball) {
const dx = this.x - ball.x
const dy = this.y - ball.y
const distance = Math.sqrt(dx * dx + dy * dy)
// 检测两个小球是否相撞:两个小球中心的距离是否小于两个小球的半径之和
if (distance < this.size + ball.size) {
// 碰撞则改变颜色
ball.color = Ball.randomColor()
// 速度变化
ball.velY = ball.velY - 0.5
this.velY = this.velY + 0.5
break
}
}
}
}
}