回答編集履歴
5
修正しました。
answer
CHANGED
|
@@ -14,11 +14,9 @@
|
|
|
14
14
|
{
|
|
15
15
|
const
|
|
16
16
|
GAIN = 0.99,
|
|
17
|
-
PI2 = Math.PI * 2
|
|
17
|
+
PI2 = Math.PI * 2,
|
|
18
|
+
DEF_COLOR = 'rgba(255,0,0,.5)';
|
|
18
19
|
|
|
19
|
-
const
|
|
20
|
-
square = (n) => n * n;
|
|
21
|
-
|
|
22
20
|
//__
|
|
23
21
|
class Point {
|
|
24
22
|
constructor (x = 0, y = 0) {
|
|
@@ -36,26 +34,28 @@
|
|
|
36
34
|
|
|
37
35
|
//__
|
|
38
36
|
class Ball extends Point {
|
|
39
|
-
constructor (name, x, y, r = 100,
|
|
37
|
+
constructor (name, x, y, r = 100, color = DEF_COLOR, direction = new Vector) {
|
|
40
38
|
super (x, y);
|
|
41
39
|
this.name = name;
|
|
42
40
|
this.r = r;
|
|
43
|
-
this.color =
|
|
41
|
+
this.color = color;
|
|
44
42
|
this.direction = direction;
|
|
45
43
|
this.touched = false;
|
|
46
44
|
this.offset = null;
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
setTouch (
|
|
47
|
+
setTouch ({x: px, y: py}) {
|
|
50
|
-
let {x, y, r} = this
|
|
48
|
+
let {x, y, r} = this;
|
|
51
|
-
if (
|
|
49
|
+
if ((px - x)**2 + (py - y)**2 < r**2) {
|
|
52
|
-
this.touched =
|
|
50
|
+
this.touched = true;
|
|
53
|
-
this.offset = new Point (x -
|
|
51
|
+
this.offset = new Point (x - px, y - py);
|
|
52
|
+
this.direction = new Vector;
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
|
-
|
|
55
|
+
|
|
57
|
-
isCollision ({
|
|
56
|
+
isCollision ({x: px, y: py, r: pr}) {
|
|
57
|
+
let {x, y, r} = this;
|
|
58
|
-
return
|
|
58
|
+
return (x - px)**2 + (y - py)**2 <= (r + pr)**2;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -82,25 +82,29 @@
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
mousemove (event) {
|
|
85
|
-
this.mx = this.x;
|
|
86
|
-
|
|
85
|
+
let {x, y, ary} = this;
|
|
87
86
|
|
|
88
|
-
let x = event.clientX, y = event.clientY;
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
ary.forEach (b => {
|
|
91
88
|
if (b.touched) {
|
|
89
|
+
let o = b.offset;
|
|
92
|
-
b.x =
|
|
90
|
+
b.x = x + o.x;
|
|
93
|
-
b.y =
|
|
91
|
+
b.y = y + o.y;
|
|
94
|
-
b.direction = new
|
|
92
|
+
b.direction = new Vector;
|
|
95
93
|
}
|
|
96
94
|
});
|
|
97
95
|
|
|
96
|
+
this.mx = x;
|
|
97
|
+
this.my = y;
|
|
98
|
-
this.x =
|
|
98
|
+
this.x = event.clientX;
|
|
99
|
+
this.y = event.clientY;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
mouseup (event) {
|
|
103
|
+
let
|
|
104
|
+
{mx, my, ary} = this,
|
|
102
|
-
|
|
105
|
+
v = new Vector (event.clientX - mx, event.clientY - my);
|
|
106
|
+
|
|
103
|
-
|
|
107
|
+
ary.forEach (b => {
|
|
104
108
|
if (b.touched) {
|
|
105
109
|
b.touched = false;
|
|
106
110
|
b.direction = v;
|
|
@@ -114,9 +118,9 @@
|
|
|
114
118
|
|
|
115
119
|
//__
|
|
116
120
|
class Field {
|
|
117
|
-
constructor (target,
|
|
121
|
+
constructor (target, ary = [ ]) {
|
|
118
122
|
this.target = target;
|
|
119
|
-
this.ary =
|
|
123
|
+
this.ary = ary;
|
|
120
124
|
this.w = target.width;
|
|
121
125
|
this.h = target.height;
|
|
122
126
|
}
|
|
@@ -126,20 +130,22 @@
|
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
progress () {
|
|
133
|
+
let { w, h, ary } = this;
|
|
134
|
+
|
|
129
|
-
|
|
135
|
+
ary.forEach (b => {
|
|
130
136
|
let
|
|
131
137
|
{x, y, r} = b,
|
|
132
138
|
d = b.direction;
|
|
133
139
|
|
|
134
|
-
x += d.x;
|
|
140
|
+
x += d.x *= GAIN;
|
|
135
|
-
y += d.y;
|
|
141
|
+
y += d.y *= GAIN;
|
|
136
142
|
|
|
137
143
|
if (x < r) {
|
|
138
144
|
x = r;
|
|
139
145
|
d.x *= -1;
|
|
140
146
|
}
|
|
141
|
-
else if (
|
|
147
|
+
else if (w - r < x) {
|
|
142
|
-
x =
|
|
148
|
+
x = w - r;
|
|
143
149
|
d.x *= -1;
|
|
144
150
|
}
|
|
145
151
|
|
|
@@ -147,15 +153,14 @@
|
|
|
147
153
|
y = r;
|
|
148
154
|
d.y *= -1;
|
|
149
155
|
}
|
|
150
|
-
else if (
|
|
156
|
+
else if (h - r < y) {
|
|
151
|
-
y =
|
|
157
|
+
y = h - r;
|
|
152
158
|
d.y *= -1;
|
|
153
159
|
}
|
|
154
160
|
|
|
155
|
-
//___
|
|
156
161
|
//当り判定後が雑すぎる
|
|
157
162
|
let tmp = new Ball ('tmp', x, y, r);
|
|
158
|
-
|
|
163
|
+
ary.forEach (tb => {
|
|
159
164
|
if (tb != b) {
|
|
160
165
|
if (tmp.isCollision (tb)) {
|
|
161
166
|
d.x *= -1;
|
|
@@ -166,13 +171,8 @@
|
|
|
166
171
|
}
|
|
167
172
|
})
|
|
168
173
|
|
|
169
|
-
//__
|
|
170
|
-
|
|
171
174
|
b.x = x;
|
|
172
175
|
b.y = y;
|
|
173
|
-
|
|
174
|
-
d.x *= GAIN;
|
|
175
|
-
d.y *= GAIN;
|
|
176
176
|
});
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -193,14 +193,15 @@
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
draw (balls) {
|
|
196
|
+
let ctx = this.ctx;
|
|
197
|
+
|
|
196
198
|
balls.forEach (b => {
|
|
197
|
-
let {name, x, y, r, color
|
|
199
|
+
let {name, x, y, r, color} = b;
|
|
198
|
-
let ctx = this.ctx;
|
|
199
200
|
|
|
200
201
|
ctx.fillStyle = color;
|
|
201
202
|
ctx.beginPath ();
|
|
202
203
|
ctx.arc (x, y, r, 0, PI2, false);
|
|
203
|
-
ctx.fill ();
|
|
204
|
+
ctx.fill ();
|
|
204
205
|
|
|
205
206
|
ctx.font = "18px 'MS Pゴシック'";
|
|
206
207
|
ctx.fillStyle = 'rgba(0,0,0,.5)';
|
|
@@ -209,7 +210,6 @@
|
|
|
209
210
|
ctx.fillText (name, x, y);
|
|
210
211
|
});
|
|
211
212
|
}
|
|
212
|
-
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
|
4
update
answer
CHANGED
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
balls = [
|
|
231
231
|
new Ball ('Hello', 200, 300),
|
|
232
232
|
new Ball ('こんにちは', 500, 300, 80),
|
|
233
|
-
new Ball ('当り判定
|
|
233
|
+
new Ball ('当り判定が雑', 700, 500, 70, 'rgba(0,255,255,.5)')
|
|
234
234
|
],
|
|
235
235
|
field = new Field (target, balls),
|
|
236
236
|
ctrl = new Mouse (target, balls);
|
3
update
answer
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
```javascript
|
|
2
2
|
<!DOCTYPE html>
|
|
3
|
-
<html>
|
|
4
3
|
<title></title>
|
|
5
4
|
<meta charset="utf-8">
|
|
5
|
+
|
|
6
6
|
<style>
|
|
7
7
|
canvas { background: #fd0; }
|
|
8
8
|
</style>
|
|
9
|
+
|
|
9
10
|
<body>
|
|
10
11
|
<canvas width="700" height="700"></canvas>
|
|
11
12
|
|
|
@@ -44,7 +45,7 @@
|
|
|
44
45
|
this.touched = false;
|
|
45
46
|
this.offset = null;
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
setTouch (p) {
|
|
49
50
|
let {x, y, r} = this, rst;
|
|
50
51
|
if (rst = square (p.x - x) + square (p.y - y) < square (r)) {
|
|
@@ -52,6 +53,10 @@
|
|
|
52
53
|
this.offset = new Point (x - p.x, y - p.y);
|
|
53
54
|
}
|
|
54
55
|
}
|
|
56
|
+
|
|
57
|
+
isCollision ({ x, y, r }) {
|
|
58
|
+
return square (this.x - x) + square (this.y - y) <= square (this.r+r);
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
|
|
@@ -63,25 +68,25 @@
|
|
|
63
68
|
this.ary = ary;
|
|
64
69
|
this.mx = 0;
|
|
65
70
|
this.my = 0;
|
|
66
|
-
|
|
71
|
+
|
|
67
72
|
['mousedown', 'mousemove', 'mouseup']
|
|
68
73
|
.forEach (etype => target.addEventListener (etype, this, false));
|
|
69
74
|
}
|
|
70
|
-
|
|
75
|
+
|
|
71
76
|
handleEvent (event) {
|
|
72
77
|
this[event.type](event);
|
|
73
78
|
}
|
|
74
|
-
|
|
79
|
+
|
|
75
80
|
mousedown (event) {
|
|
76
81
|
this.ary.forEach (b => b.setTouch (this));
|
|
77
82
|
}
|
|
78
|
-
|
|
83
|
+
|
|
79
84
|
mousemove (event) {
|
|
80
85
|
this.mx = this.x;
|
|
81
86
|
this.my = this.y;
|
|
82
|
-
|
|
87
|
+
|
|
83
88
|
let x = event.clientX, y = event.clientY;
|
|
84
|
-
|
|
89
|
+
|
|
85
90
|
this.ary.forEach (b => {
|
|
86
91
|
if (b.touched) {
|
|
87
92
|
b.x = this.x + b.offset.x;
|
|
@@ -89,7 +94,7 @@
|
|
|
89
94
|
b.direction = new Point;
|
|
90
95
|
}
|
|
91
96
|
});
|
|
92
|
-
|
|
97
|
+
|
|
93
98
|
this.x = x; this.y = y;
|
|
94
99
|
}
|
|
95
100
|
|
|
@@ -115,11 +120,11 @@
|
|
|
115
120
|
this.w = target.width;
|
|
116
121
|
this.h = target.height;
|
|
117
122
|
}
|
|
118
|
-
|
|
123
|
+
|
|
119
124
|
add (obj) {
|
|
120
125
|
this.ary.push (obj);
|
|
121
126
|
}
|
|
122
|
-
|
|
127
|
+
|
|
123
128
|
progress () {
|
|
124
129
|
this.ary.forEach (b => {
|
|
125
130
|
let
|
|
@@ -128,7 +133,7 @@
|
|
|
128
133
|
|
|
129
134
|
x += d.x;
|
|
130
135
|
y += d.y;
|
|
131
|
-
|
|
136
|
+
|
|
132
137
|
if (x < r) {
|
|
133
138
|
x = r;
|
|
134
139
|
d.x *= -1;
|
|
@@ -137,7 +142,7 @@
|
|
|
137
142
|
x = this.w - r;
|
|
138
143
|
d.x *= -1;
|
|
139
144
|
}
|
|
140
|
-
|
|
145
|
+
|
|
141
146
|
if (y < r) {
|
|
142
147
|
y = r;
|
|
143
148
|
d.y *= -1;
|
|
@@ -146,11 +151,21 @@
|
|
|
146
151
|
y = this.h - r;
|
|
147
152
|
d.y *= -1;
|
|
148
153
|
}
|
|
149
|
-
|
|
154
|
+
|
|
150
155
|
//___
|
|
151
|
-
//
|
|
156
|
+
//当り判定後が雑すぎる
|
|
152
|
-
|
|
157
|
+
let tmp = new Ball ('tmp', x, y, r);
|
|
153
|
-
|
|
158
|
+
this.ary.forEach (tb => {
|
|
159
|
+
if (tb != b) {
|
|
160
|
+
if (tmp.isCollision (tb)) {
|
|
161
|
+
d.x *= -1;
|
|
162
|
+
d.y *= -1;
|
|
163
|
+
x = b.x;
|
|
164
|
+
y = b.y;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
154
169
|
//__
|
|
155
170
|
|
|
156
171
|
b.x = x;
|
|
@@ -160,10 +175,10 @@
|
|
|
160
175
|
d.y *= GAIN;
|
|
161
176
|
});
|
|
162
177
|
}
|
|
163
|
-
|
|
178
|
+
|
|
164
179
|
}
|
|
165
|
-
|
|
166
180
|
|
|
181
|
+
|
|
167
182
|
//__
|
|
168
183
|
class Canvas {
|
|
169
184
|
constructor (canvas) {
|
|
@@ -176,7 +191,7 @@
|
|
|
176
191
|
cls () {
|
|
177
192
|
this.ctx.clearRect (0, 0, this.w, this.h);
|
|
178
193
|
}
|
|
179
|
-
|
|
194
|
+
|
|
180
195
|
draw (balls) {
|
|
181
196
|
balls.forEach (b => {
|
|
182
197
|
let {name, x, y, r, color } = b;
|
|
@@ -194,7 +209,7 @@
|
|
|
194
209
|
ctx.fillText (name, x, y);
|
|
195
210
|
});
|
|
196
211
|
}
|
|
197
|
-
|
|
212
|
+
|
|
198
213
|
}
|
|
199
214
|
|
|
200
215
|
|
2
update
answer
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
</style>
|
|
9
9
|
<body>
|
|
10
10
|
<canvas width="700" height="700"></canvas>
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
<script>
|
|
13
13
|
{
|
|
14
14
|
const
|
1
update
answer
CHANGED
|
@@ -233,5 +233,4 @@
|
|
|
233
233
|
|
|
234
234
|
</html>
|
|
235
235
|
|
|
236
|
-
|
|
237
236
|
```
|