Processing is a flexible software sketchbook and a language for learning how to code.
프로세싱은 미디어아트 및 교육용으로 만들어진 프로그래밍 언어로, JAVA로 작성되어 있다.
우리의 웹사이트는 Javascript를 사용하기 때문에, 변환과정을 거쳐야 한다.
Processing은 별도의 설치 과정이 존재하지 않는다. processing-[version] 폴더 내의 processing.exe을 실행하면 된다.
LMS 강의자료실에 올라온 ball-bouncing.txt 파일 내의 코드를 Processing에 붙여넣은 다음
왼쪽 위의 실행 버튼 혹은 Ctrl+R로 코드를 실행시켜보면 결과를 볼 수 있다.
이제 우리는 새로운 공 하나를 추가할 것이다. 원래 코드에서 공 하나를 만들기 위한 여러 속성들을 똑같이 추가하면 된다.
원래 코드
PVector location; // Location of shape
PVector velocity; // Velocity of shape
PVector gravity; // Gravity acts at the shape's acceleration
이제부터 기존의 공을 공1, 새로운 공을 공2라고 해보자. 공1의 변수 이름을 다음과 같이 수정하자. (//으로 시작하는 주석은 같을 필요 없다.)
PVector location1; // Location of ball_1
PVector velocity1; // Velocity of ball_1
PVector gravity1; // Gravity of ball_1
그리고 그 밑에 공2 속성을 새롭게 추가하자.
PVector location1; // Location of ball_1
PVector velocity1; // Velocity of ball_1
PVector gravity1; // Gravity of ball_1
PVector location2; // Location of ball_2
PVector velocity2; // Velocity of ball_2
PVector gravity2; // Gravity of ball_2
원래는 다음과 같이 속성 이름을 하나하나 모두 바꿔주어야 하지만, 하나하나 수정하기는 쉽지 않기에 Processing의 찾기 및 바꾸기 기능을 이용하자.
Ctrl+F를 눌러 찾기 기능을 킨다.
모두 바꾸기를 클릭하여 모든 'location'을 'location1'으로 바꾸어준다.
PVector location1; // Location of ball_1
.
.
.
PVector location2; // location1 of ball_2
location을 제외한 velocity와 location도 동일하게 작업해주자.
프로그램 실행시 공 하나가 튀고 있다면 오류가 없는 것이다.
이제 모든 코드 중 location1/velocity1/gravity1과 관련된 코드가 있다면, 모두 복사하여 location2/velocity2/gravity2와 관련된 코드도 추가하자. 예를 들어 다음과 같은 원본 코드가 있다면(16-21줄)
void setup() {
size(640,360);
location1 = new PVector(100,100);
velocity1 = new PVector(1.5,2.1);
gravity1 = new PVector(0,0.2);
}
다음과 같은 코드로 수정하자.
void setup() {
size(640,360);
location1 = new PVector(100,100);
velocity1 = new PVector(1.5,2.1);
gravity1 = new PVector(0,0.2);
location2 = new PVector(100,100);
velocity2 = new PVector(1.5,2.1);
gravity2 = new PVector(0,0.2);
}
원본 코드(27-33줄)
void draw() {
background(0);
// Add velocity1 to the location1.
location1.add(velocity1);
// Add gravity1 to velocity1
velocity1.add(gravity1);
수정 코드
void draw() {
background(0);
// Add velocity1 to the location1.
location1.add(velocity1);
// Add gravity1 to velocity1
velocity1.add(gravity1);
// Add velocity1 to the location1.
location2.add(velocity2);
// Add gravity1 to velocity1
velocity2.add(gravity2);
원본 코드(40-50줄)
// Bounce off edges
if ((location1.x > width) || (location1.x < 0)) {
velocity1.x = velocity1.x * -1;
}
if (location1.y > height) {
// We're reducing velocity1 ever so slightly
// when it hits the bottom of the window
velocity1.y = velocity1.y * -0.95;
location1.y = height;
}
수정코드
// Bounce off edges
if ((location1.x > width) || (location1.x < 0)) {
velocity1.x = velocity1.x * -1;
}
if (location1.y > height) {
// We're reducing velocity1 ever so slightly
// when it hits the bottom of the window
velocity1.y = velocity1.y * -0.95;
location1.y = height;
}
// Bounce off edges
if ((location2.x > width) || (location2.x < 0)) {
velocity2.x = velocity2.x * -1;
}
if (location2.y > height) {
// We're reducing velocity1 ever so slightly
// when it hits the bottom of the window
velocity2.y = velocity2.y * -0.95;
location2.y = height;
}
다음과 같이 세 가지 부분을 모두 수정했다면, 이제 공2를 그려보자.
다음과 같은 원본 코드에서(ellipse는 원을 그리는 함수이다.)
// Display circle at location1 vector
stroke(255);
strokeWeight(2);
fill(127);
ellipse(location1.x,location1.y,48,48);
다음과 같이 바꿔주자.
// Display circle at location1 vector
stroke(255);
strokeWeight(2);
fill(127);
ellipse(location1.x,location1.y,48,48);
ellipse(location2.x,location2.y,48,48);
프로그램 실행 시 두 공의 위치/속도/중력이 모두 동일하여 겹쳐서 보이므로, 이제 공2의 속성을 조금씩 바꿔야 한다.
void setup() {
size(640,360);
location1 = new PVector(100,100);
velocity1 = new PVector(1.5,2.1);
gravity1 = new PVector(0,0.2);
location2 = new PVector(100,100);
velocity2 = new PVector(1.5,2.1);
gravity2 = new PVector(0,0.2);
}
location2,velocity2,gravity2의 숫자를 바꾸어주자.
location : 시작 위치의 (x좌표,y좌표)
location1 = new PVector(100,100); //공1의 시작 위치 : (x : 100, y : 100)
location2 = new PVector(200,100); //공2의 시작 위치 : (x : 200, y : 100)
velocity : (x방향 속도, y방향 속도)
gravity : (x방향의 중력 세기, y방향의 중력 세기)
이제 마지막으로 달라야 하는 속성인 크기를 바꾸자.
크기 관련 코드(68-69줄)
ellipse(location1.x,location1.y,48,48);
ellipse(location2.x,location2.y,48,48);
ellipse 함수의 속성
ellipse(공의 시작 x좌표, 공의 시작 y좌표, 공의 가로 크기, 공의 세로 크기)
공 두개가 튀기고 있는 모습을 스크린샷 찍어 저장해놓자.
만약 공의 색깔을 바꾸고 싶다면? fill() | color()
// Display circle at location vector
stroke(255);
strokeWeight(2);
fill(127); //127 = gray
ellipse(location1.x,location1.y,60,60);
ellipse(location2.x,location2.y,48,48);
fill() 함수는 다음 그리기 함수 시 색깔을 지정한다. 따라서 코드의 순서는 fill -> ellipse이어야 한다.
// Display circle at location vector
stroke(255);
strokeWeight(2);
fill(color(16,71,173)); //한양블루
ellipse(location1.x,location1.y,60,60);
fill(color(115,115,115)); //한양실버
ellipse(location2.x,location2.y,48,48);
이제 ball-bouncing-new.txt파일을 새롭게 만들고, 위에서 작성한 Processing 코드를 붙여넣자.
Task 2의 마지막 단계이다. "diff" 명령어를 사용해 어느 부분을 수정했는지 보여주자. 맥에서는 그냥 터미널에 예시로 나온 명령어를 그대로 입력하면 되지만 윈도우에서는 불가능하다.
첫 번째 방법 : "diff"와 비슷한 "FC" 사용
두 번째 방법 : cygwin(윈도우에서 리눅스 명령어을 쓸 수 있도록 해주는 프로그램)을 설치
편하긴 하지만, 실제 diff 명령어와 모양새가 조금 다른 결과물을 만들어낼 수 있다. 교수님은 상관쓰지 않음.
CMD를 열고 ball-bouncing.txt 파일과 ball-bouncing-new.txt 파일이 있는 위치로 이동하자. 예를 들어 파일이 D:\Downloads에 있다면 다음과 같이 이동할 수 있다.
D: //D 드라이브로 이동
cd Downloads //Downloads 폴더로 이동
*참고
만약 현재 경로에서 부모 폴더(상위 폴더)로 이동하고 싶다면
cd ..
파일이 있는 폴더로 이동 후 FC 명령어를 실행한다.
FC ball-bouncing.txt ball-bouncing-new.txt
cd `cygpath -m -a "윈도우 경로"`
예를 들면 다음과 같다.
cd `cygpath -m -a "D:\downloads"`
이제 diff 명령어를 사용하면 된다.
LMS 강의자료실에 올라온 ball-colliding.txt 파일 내의 코드를 Processing에 붙여넣는다. 왼쪽 위의 실행 버튼 혹은 Ctrl+R로 코드를 실행시켜보자.다음과 같이 충돌하는 두 공을 볼 수 있다.
충돌하는 새로운 공을 추가해보자.
우리가 수정해야 할 부분은 두 가지이다.
Ball[] balls = {
new Ball(공이 나타나는 x좌표, 공이 나타나는 y좌표, 공의 반지름)
};
원본코드(142줄부터)
Ball[] balls = {
new Ball(100, 400, 20),
new Ball(700, 400, 80)
};
수정코드
Ball[] balls = {
new Ball(100, 400, 20),
new Ball(700, 400, 80),
new Ball(300, 200, 50)
};
원본코드
balls[0].checkCollision(balls[1]);
수정코드
balls[0].checkCollision(balls[1]); //ball의 0번째 객체와 1번째 객체 충돌효과
balls[0].checkCollision(balls[2]); //ball의 0번째 객체와 2번째 객체 충돌효과
balls[1].checkCollision(balls[2]); //ball의 1번째 객체와 2번째 객체 충돌효과
2-4와 동일하게 diff(혹은 FC)명령어를 사용하여 차이를 기록하면 Task 3 완료!
웹페이지에 올리기 전, 프로세싱으로 만든 자바 파일을 자바스크립트로 변환하는 과정을 거쳐야 한다. p5.js 웹 에디터로 이동한 후, 로그인 과정을 거치자. 로그인해야만 작성한 sketch.js 파일을 다운로드 받을 수 있다.
이제 웹 에디터에 우리가 만든 ball-bouncing-new.txt 파일 내의 코드를 붙여넣어보자.다음과 같이 에러가 날 것이다.(당연히 java문법을 사용해 작성한 파일이니까!)
지금부터 javascript 문법으로 바꾸어보자.
PVector location1; // Location of shape
PVector velocity1; // Velocity of shape
PVector gravity1; // Gravity acts at the shape's acceleration
PVector location2; // Location of shape
PVector velocity2; // Velocity of shape
PVector gravity2; // Gravity acts at the shape's acceleration
위의 코드를
let location1; // Location of shape
let velocity1; // Velocity of shape
let gravity1; // Gravity acts at the shape's acceleration
let location2; // Location of shape
let velocity2; // Velocity of shape
let gravity2; // Gravity acts at the shape's acceleration
다음과 같이 바꾸어주자.
let 변수명; // javascript에서는 변수 타입(정수/실수/문자열)에 관계없이 변수를 만든다.
void setup() {
size(640,360);
location1 = new PVector(100,100);
velocity1 = new PVector(1.5,2.1);
gravity1= new PVector(0,0.2);
location2 = new PVector(350,350);
velocity2 = new PVector(2,2);
gravity2 = new PVector(0,1);
}
위 코드를 아래와 같이 바꾸어주자.
function setup() { //javascript에서 함수를 선언하는 방법
createCanvas(640,360); //p5.js에서의 size()함수
location1 = createVector(100,100); //p5.js에서의 PVector 생성 방법
velocity1 = createVector(1.5,2.1);
gravity1= createVector(0,0.2);
location2 = createVector(350,350);
velocity2 = createVector(2,2);
gravity2 = createVector(0,1);
}
void draw() {
위 코드를 아래와 같이 바꾸어주자.
function draw() {
28번째 줄까지 수정을 모두 완료했다면, 실행 버튼을 클릭하여 두 개의 공이 제대로 튀기고 있는지 확인해보자.
이제 Save -> Download 순서대로 눌러주자.
그러면 [괴상한 파일명.zip]이 다운로드 될텐데, 압축을 풀어준다.
안쪽의 파일들을 살펴보자면 다음과 같다.
index.html //HTML파일로, 페이지 파일이다.
p5.js //sketch.js가 제대로 작동하도록 돕는다.
p5.sound.min.js //sketch.js에 소리를 넣었을 시 제대로 작동하도록 돕는다.
sketch.js //우리가 만든 js코드가 들어가있다.
style.css //HTML파일의 스타일(모양새)를 지정한다.
우리의 ball-bouncing-new에는 소리가 들어가지 않으므로, p5.sound.min.js파일은 삭제해주자.
Render HTML file in pages of next js
위와 같은 설명 페이지를 참고했다.
아까 다운로드한 파일
p5.js
sketch.js
style.css
세 개의 파일을 모두 public폴더에 넣어준다.
다음과 같은 폴더 구조로 api.js 파일을 만들어주자.
pages/api/api.js
api.js에 다음과 같은 코드를 입력한다.
import fs from "fs";
const filename = "/index.html";
export default async function api(req, res) {
res.setHeader("Content-Type", "text/html; charset=utf-8");
res.write(await fs.readFileSync(filename, "utf-8"));
res.end();
}
다음과 같이 BEGIN-NEXTJS(혹은 nextjs-blog)폴더 바로 밑에, 즉 루트 폴더 밑에 next.config.js파일을 만든다.
nextjs-blog/next.config.js
next.config.js에 다음과 같은 코드를 입력한다.
rewrites: async() => [
{
source: "/public/index.html",
destination: "/pages/api/api.js",
},
]
최종 폴더 구조는 다음과 같다.
npm run dev
http://localhost:3000/index.html로 접속하여 테스트해보자. 혹은 직접 url을 바꾸어주어도 된다.
아름답게 작동하는 것을 볼 수 있다!
Task 4를 모두 완수한 당신, 축하드립니다. 만약 Link 태그를 사용하여 웹페이지 연결까지 하고 싶다면, 4-2-5 단계까지 따라해보세요!
index.js파일에서 연결하고 싶은 부분을 선택하고, Link태그로 위의 주소로 연결만 시켜주면 된다.
<Link href="/index.html">
<span>You can see bouncing balls by clicking this card!</span>
</Link>
Processing과 동일하다.
// Display circle at location vector
stroke(255);
strokeWeight(2);
fill(color(16,71,173));
ellipse(location1.x,location1.y,60,60);
fill(color(115,115,115));
ellipse(location2.x,location2.y,48,48);