Skip to content

Commit 569c7e9

Browse files
committed
adpp post
1 parent 1c8f7d8 commit 569c7e9

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed

content/blog/p5/bounce-ball.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
title: 움직이는 볼
3+
date: 2024-07-21 12:52:21
4+
coverURL:
5+
---
6+
<br />
7+
<br />
8+
<br />
9+
10+
<script src="
11+
https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js
12+
"></script>
13+
14+
15+
# 움직이는 볼
16+
17+
p5를 이용해 움직이는 볼을 그려보겠습니다.
18+
결과물은 아래와 같습니다.
19+
20+
<div id="can"></div>
21+
22+
<script>
23+
class Vec3 {
24+
constructor(x, y, r){
25+
this.x = x;
26+
this.y = y;
27+
this.r = r;
28+
}
29+
}
30+
class Vec2 {
31+
constructor(x, y){
32+
this.x = x;
33+
this.y = y;
34+
}
35+
}
36+
class Ball {
37+
constructor(p, v){
38+
this.p = p;
39+
this.v = v;
40+
}
41+
}
42+
43+
44+
let ball;
45+
46+
function setup(){
47+
const can = createCanvas(250, 250);
48+
can.parent('can');
49+
ball = new Ball(new Vec3(10, 10, 20), new Vec2(90, 60));
50+
}
51+
52+
function draw(){
53+
ball.p.x = ball.p.x + ball.v.x / 60;
54+
ball.p.y = ball.p.y + ball.v.y / 60;
55+
56+
if(ball.p.x < 10 || ball.p.x > 240) {
57+
ball.v.x = -ball.v.x;
58+
}
59+
if(ball.p.y < 10 || ball.p.y > 240) {
60+
ball.v.y = -ball.v.y;
61+
}
62+
63+
background(250);
64+
circle(ball.p.x, ball.p.y, ball.p.r);
65+
}
66+
</script>
67+
68+
69+
## 코드
70+
71+
> p5는 전역에 정의된 setup, draw 함수를 실행해 canvas를 만들고
72+
그 위에 정의된 내용을 60 frame 단위로 draw 함수를 그려냅니다.
73+
74+
75+
```js
76+
class Vec3 {
77+
constructor(x, y, r){
78+
this.x = x;
79+
this.y = y;
80+
this.r = r;
81+
}
82+
}
83+
class Vec2 {
84+
constructor(x, y){
85+
this.x = x;
86+
this.y = y;
87+
}
88+
}
89+
class Ball {
90+
constructor(p, v){
91+
this.p = p;
92+
this.v = v;
93+
}
94+
}
95+
96+
97+
let ball;
98+
99+
function setup(){
100+
const can = createCanvas(250, 250);
101+
can.parent('can');
102+
ball = new Ball(new Vec3(10, 10, 20), new Vec2(90, 60));
103+
}
104+
105+
function draw(){
106+
ball.p.x = ball.p.x + ball.v.x / 60;
107+
ball.p.y = ball.p.y + ball.v.y / 60;
108+
109+
if(ball.p.x < 10 || ball.p.x > 240) {
110+
ball.v.x = -ball.v.x;
111+
}
112+
if(ball.p.y < 10 || ball.p.y > 240) {
113+
ball.v.y = -ball.v.y;
114+
}
115+
116+
background(250);
117+
circle(ball.p.x, ball.p.y, ball.p.r);
118+
}
119+
```
120+
121+
122+
위 코드를 하나씩 뜯어보겠습니다.
123+
124+
### 볼을 그리기 위한 위치 벡터
125+
126+
```js
127+
class Vec3 {
128+
constructor(x, y, r){
129+
this.x = x;
130+
this.y = y;
131+
this.r = r;
132+
}
133+
}
134+
```
135+
136+
볼을 좌표평면 위에 그리기 위해서는 세가지 값이 필요합니다.
137+
138+
그것은 바로 `(x, y, r)`입니다.
139+
x, y는 좌표값이며, r은 반지름입니다.
140+
141+
이 값들을 p5에서 정의해놓은 circle 함수에 인자로 주어주면
142+
canvas에 볼이 그려지게 됩니다.
143+
144+
### 볼을 움직이기 위한 속도 벡터
145+
146+
```js
147+
class Vec2 {
148+
constructor(x, y){
149+
this.x = x;
150+
this.y = y;
151+
}
152+
}
153+
```
154+
155+
볼을 그리기만하고 움직이지 못하면 안되겠습니다.
156+
157+
볼을 움직이기 위해서는 벡터가 필요합니다.
158+
위에서 언급한대로 1 프레임마다 draw 함수가 재실행되므로
159+
160+
`ball.p.x``ball.p.y``ball.v.x`, `ball.v.y`만큼 이동시켜주면 되는 것입니다.
161+
162+
```js
163+
function draw(){
164+
ball.p.x += ball.v.x / 60; // vector 만큼의 거리를 60만큼 나눠서
165+
ball.p.y += ball.v.y / 60;
166+
167+
// if(ball.p.x < 10 || ball.p.x > 240) {
168+
// ball.v.x = -ball.v.x;
169+
// }
170+
// if(ball.p.y < 10 || ball.p.y > 240) {
171+
// ball.v.y = -ball.v.y;
172+
// }
173+
174+
175+
background(250);
176+
circle(ball.p.x, ball.p.y, ball.p.r);
177+
}
178+
```
179+
180+
### 볼이 벽에 부딪힌 경우 계산될 반사 벡터
181+
182+
볼이 벽에 부딪힌 경우,
183+
184+
아래의 그래프로 설명할 수 있습니다.
185+
186+
- u: 벽
187+
- v: 공의 이동 벡터
188+
- rv: 공의 이동 벡터에 대해 - 곱셈
189+
- rvv: v + rvv
190+
191+
와 같이 설명됩니다.
192+
193+
<img src="/img/blog/p5/bounceball/bounce-ball.png" alt="vectors">
194+
195+
코드로는 아래와 같이 -를 곱해주면 됩니다.
196+
197+
- 240은 캔버스의 크기 - 볼의 반지름
198+
- 10은 볼의 반지름입니다.
199+
200+
```js
201+
202+
function draw(){
203+
ball.p.x += ball.v.x / 60; // vector 만큼의 거리를 60만큼 나눠서
204+
ball.p.y += ball.v.y / 60;
205+
206+
if(ball.p.x < 10 || ball.p.x > 240) {
207+
ball.v.x = -ball.v.x;
208+
}
209+
if(ball.p.y < 10 || ball.p.y > 240) {
210+
ball.v.y = -ball.v.y;
211+
}
212+
213+
background(250);
214+
circle(ball.p.x, ball.p.y, ball.p.r);
215+
}
216+
```
210 KB
Loading

0 commit comments

Comments
 (0)