Silverback9

#야생으로

Creative Coding 독학 제113일 2024년07월18일(목)

오늘은 본격적으로 코딩 작업을 하는 날이예요~^^*

지난 주 오늘은 아주 반가운 햇살이 아침을 채워 주었는데요~^^*

이번 주 오늘은 차분한 빗살이 유리창을 쓰다듬어 주고 있어요~^^*

창문이 하늘을 향해 고개를 젖히고 있어서요~^^* 뺨에 닿는 빗살의 보드란 손길을 창문이 두 눈을 감고 가만히 편안히 느끼고 있어요~^^*

편안하고 즐거운 아침 시작하시구요~^^* 저는 오후에 코딩 공부해서 다시 찾아 올게요~^^*

바람은 잔잔해서 내리는 비를 상쾌하게 만들어 주는 오늘의 오후입니다~^^*

어제 본 동영상 강의를 다시 한 번 보면서 본격적인 코딩 작업을 해 볼게요~^^*

힘의 한계와 속력의 한계를 지닌 생명체가 환경의 변화에 반응하며 자신의 행동 계획을 수립하고 수정하고 실행해 나가는 우리의 현실 세계를 코드에 담는 오늘이네요~^^*

힘의 한계와 속력의 한계를 지닌 채 자신의 최선을 다하는 연약하고도 멋진 우리 Vehicle~^^*

Vehicle이 차근차근 생각하고 멋지게 실행해 내는 과정을 단계별로 살펴 볼까요~^^*

(1) 자신과 target 사이의 거리를 최대한 빨리 0으로 줄이는 desired_vector를 계산하고

let force = p5.Vector.sub(target, this.pos);

(2) 자신이 낼 수 있는 속력의 한계를 desired_vector에 반영하고

force.setMag(this.maxSpeed);

(3) 자신의 현재 움직임에 영향을 주는 속도 current_vel를 뺄셈하고

force.sub(this.vel);

(4) 자신이 낼 수 있는 힘의 한계를 반영하고

force.limit(this.maxForce);

(5) 현재 자신에 의해 작용되는 힘에 이 steering 힘을 더하고~^^*

this.applyForce(force);

(6) 이 힘의 영향으로 새롭게 변화된 자신의 현재 속도에 자신이 낼 수 있는 속력의 한계를 반영합니다~^^*

this.vel.limit(this.maxSpeed);

(7) Vehicle이 자신이 움직이는 방향으로 자신의 얼굴도 향하도록 하여 자연스러운 움직임을 보여주겠습니다~^^*

하나. Vehicle의 위치(x, y)를 중심으로 하는 좌표체계로 변환합니다.

둘. Vehicle의 움직임 방향으로 좌표축을 회전합니다.

셋. Vehicle을 삼각형 형태로 그립니다.

넷. push()-pop() 구조를 사용하여, 위 세 단계의 일을 실행한 후 실행문 데이터를 삭제를 함으로써, 좌표체계 변환과 좌표축 회전이 Vehicle에게만 독립적으로 적용되도록 합니다.

 push();
 translate(this.pos.x, this.pos.y);
 rotate(this.vel.heading());
 triangle(-this.r, -this.r / 2, -this.r, this.r / 2, this.r, 0);
 pop();

Autonomous Agent의 Steering Behaviour의 핵심 코드를 살펴 보았으니, 이제 전체 코드를 함께 살펴 볼까요~^^*

<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="vehicle.js"></script>
    <script src="sketch.js"></script>
  </body>
</html>
class Vehicle {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(0, 0);
    this.acc = createVector(0, 0);
    this.maxSpeed = 4;
    this.maxForce = 0.25;
    this.r = 16;
  }

  seek(target) {
    let force = p5.Vector.sub(target, this.pos);
    force.setMag(this.maxSpeed);
    force.sub(this.vel);
    force.limit(this.maxForce);
    this.applyForce(force);
  }

  applyForce(force) {
    this.acc.add(force);
  }

  update() {
    this.vel.add(this.acc);
    this.vel.limit(this.maxSpeed);
    this.pos.add(this.vel);
    this.acc.set(0, 0);
  }

  show() {
    stroke(255);
    strokeWeight(2);
    fill(255);
    push();
    translate(this.pos.x, this.pos.y);
    rotate(this.vel.heading());
    triangle(-this.r, -this.r / 2, -this.r, this.r / 2, this.r, 0);
    pop();
  }

  edges() {
    if (this.pos.x > width + this.r) {
      this.pos.x = -this.r;
    } else if (this.pos.x < -this.r) {
      this.pos.x = width + this.r;
    }
    if (this.pos.y > height + this.r) {
      this.pos.y = -this.r;
    } else if (this.pos.y < -this.r) {
      this.pos.y = height + this.r;
    }
  }
}
let vehicle;
let target;

function setup() {
  createCanvas(400, 400);
  vehicle = new Vehicle(100, 100);
}

function draw() {
  background(0);
  fill(255, 0, 0);
  noStroke();
  target = createVector(mouseX, mouseY);
  circle(target.x, target.y, 32);
  vehicle.seek(target);
  vehicle.update();
  vehicle.show();
}
//마우스/손가락을 움직여 target의 위치를 변화시켜 보셔요~^^*

이제 나 잡아 봐라~~^^* 게임 시간이 돌아왔습니다~~^^* 마우스/손가락을 움직여 Target의 위치를 변화시켜 보셔요~^^* 우리의 연약하지만 멋진 Vehicle이 Target을 부지런히 잘 따라다니나요~^^*

Target을 찾을 때까지 Vehicle은 계속 달립니다~^^*

Target이 뒤돌아보면 항상 Vehicle이 거기 서있을테요~!

“전세계에서 가장 성공한 Seeker의 노래”처럼 우리 Vehicle도 임무를 성공하였습니다~^^*

몇 달 전에도 멋진 공연을 해내신 Sting처럼, 우리도 코딩 공부 꾸준히 해볼까요~~^^*

오늘도 저와 함께 코딩공부 해주셔서 감사합니다~^^*

내일도 우리 새로운 도전을 향해 함께 나아가면 좋겠어요~~^^*

네!! 꿈은 이루어 집니다~!!!

댓글 남기기