回答編集履歴

2

相手

2023/12/01 13:55

投稿

TN8001
TN8001

スコア9367

test CHANGED
@@ -1,6 +1,6 @@
1
1
  > 衝突したときにめり込んだ影響で、振動してしまってうまく反射してくれない。
2
2
 
3
- コードが不完全で再現できませんが、こういうことですよね?(質問者のほうで**再現可能な最小サンプル**を提供してください)
3
+ コードが不完全で実行できませんが、こういうことですよね?(質問者のほうで**再現可能な最小サンプル**を提供してください)
4
4
  ![めり込み動画](https://ddjkaamml8q8x.cloudfront.net/questions/2023-11-29/4017b477-2ccd-4beb-a937-30f25083d830.gif)
5
5
 
6
6
 
@@ -122,9 +122,7 @@
122
122
 
123
123
  わたしだったら難しいことを考えたくないので、[fisica](http://www.ricardmarxer.com/fisica/)かなんかで作ると思います(別の難しさはありますが^^;
124
124
 
125
- ---
126
-
127
- 追記
125
+ ## 追記
128
126
  > 円の反射についてですがモンストでは基本的には単純に向きを反転する反射をします。
129
127
  > なのでその点については気にしなくて大丈夫です!
130
128
 
@@ -195,11 +193,11 @@
195
193
  if (d < r + m_r) {
196
194
  if (abs(velocity.x) >= abs(velocity.y)) {
197
195
 
198
- // 右向きに進んでいて、自分がより左にいるなら反射
196
+ // 右向きに進んでいて、自分が相手より左にいるなら反射
199
197
  if (0 < velocity.x && x < m_position.x) {
200
198
  velocity.x *= -1;
201
199
  }
202
- // 左向きに進んでいて、自分がより右にいるなら反射
200
+ // 左向きに進んでいて、自分が相手より右にいるなら反射
203
201
  if (velocity.x < 0 && m_position.x < x) {
204
202
  velocity.x *= -1;
205
203
  }
@@ -228,4 +226,4 @@
228
226
  sp = ep = null;
229
227
  }
230
228
  ```
231
- かすったような時すり抜けは発生するかな?(当たり判定がやや小さくなる)
229
+ かすったような時に、すり抜けは発生するかな?(当たり判定がやや小さくなる)

1

追記

2023/12/01 04:25

投稿

TN8001
TN8001

スコア9367

test CHANGED
@@ -121,3 +121,111 @@
121
121
  ---
122
122
 
123
123
  わたしだったら難しいことを考えたくないので、[fisica](http://www.ricardmarxer.com/fisica/)かなんかで作ると思います(別の難しさはありますが^^;
124
+
125
+ ---
126
+
127
+ 追記
128
+ > 円の反射についてですがモンストでは基本的には単純に向きを反転する反射をします。
129
+ > なのでその点については気にしなくて大丈夫です!
130
+
131
+ なるほど反射は`dx`・`dy`の大きいほう(=角度)で決まるのですね。
132
+
133
+ > 重ならない位置まで補正すればうまく解決しそうなのはわかるのですが、うまくできないのが現状です…
134
+
135
+ 押し出すような手法もあると思いますが、面倒なので向きと位置で反射するかどうかを判断するのはどうでしょう?
136
+
137
+ 現状↓のような状態でめり込みが発生しています。
138
+ ![めり込み発生図](https://ddjkaamml8q8x.cloudfront.net/questions/2023-12-01/0d1bd7e1-50c1-4455-8bf6-f0e10af8763f.png)
139
+ 青い線のところで反射しないようにすれば、そのまま抜けて連続反射にはならなくなりますね?
140
+ ```Processing
141
+ PVector position = new PVector(50, 350);
142
+ PVector m_position = new PVector(200, 200);
143
+ PVector velocity = new PVector();
144
+ float r = 30;
145
+ float m_r = 50;
146
+
147
+ PVector sp, ep;
148
+
149
+
150
+ void setup() {
151
+ size(400, 400);
152
+ ellipseMode(RADIUS);
153
+ }
154
+
155
+ void draw() {
156
+ background(255);
157
+
158
+ fill(#ff0000);
159
+ circle(m_position.x, m_position.y, m_r);
160
+
161
+ if (sp != null) {
162
+ var p = PVector.add(position, PVector.sub(sp, ep));
163
+ line(position.x, position.y, p.x, p.y);
164
+ }
165
+
166
+ updateBall();
167
+ showChara();
168
+ }
169
+
170
+ void updateBall() {
171
+ velocity.mult(0.99);
172
+ if (velocity.mag() < 0.5) {
173
+ velocity.set(0, 0);
174
+ }
175
+
176
+ move();
177
+ bound();
178
+ }
179
+
180
+ void showChara() {
181
+ fill(0);
182
+ circle(position.x, position.y, r);
183
+ }
184
+
185
+ void bound() {
186
+ var x = position.x;
187
+ var y = position.y;
188
+
189
+ if (x > width && velocity.x > 0) velocity.x *= -1;
190
+ if (x < 0 && velocity.x < 0) velocity.x *= -1;
191
+ if (y > height && velocity.y > 0) velocity.y *= -1;
192
+ if (y < 0 && velocity.y < 0) velocity.y *= -1;
193
+
194
+ var d = position.dist(m_position);
195
+ if (d < r + m_r) {
196
+ if (abs(velocity.x) >= abs(velocity.y)) {
197
+
198
+ // 右向きに進んでいて、自分が敵より左にいるなら反射
199
+ if (0 < velocity.x && x < m_position.x) {
200
+ velocity.x *= -1;
201
+ }
202
+ // 左向きに進んでいて、自分が敵より右にいるなら反射
203
+ if (velocity.x < 0 && m_position.x < x) {
204
+ velocity.x *= -1;
205
+ }
206
+ } else {
207
+ if ((0 < velocity.y && y < m_position.y) ||
208
+ (velocity.y < 0 && m_position.y < y)) {
209
+ velocity.y *= -1;
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ void move() {
216
+ position.add(velocity);
217
+ }
218
+
219
+ void mousePressed() {
220
+ sp = new PVector(mouseX, mouseY);
221
+ ep = sp.copy();
222
+ }
223
+ void mouseDragged() {
224
+ ep.set(mouseX, mouseY);
225
+ }
226
+ void mouseReleased() {
227
+ velocity.set(sp.sub(ep).div(10));
228
+ sp = ep = null;
229
+ }
230
+ ```
231
+ かすったような時すり抜けは発生するかな?(当たり判定がやや小さくなる)