TIL

2024년 10월 14일 TIL (15일 수정 내용 포함)

kagan-draca 2024. 10. 16. 02:20

오늘은 황금 고블린이 클라이언트에서 생성 돼

 

정해진 맵 안에서 방향만을 바꿔가며 이동 하는 로직을 작성했다.

(코드에도 주석문으로 설명을 적어 놨고, 아래에도 설명이 존재합니다^^)

export class SpecialMonster {
  constructor(path, specialMonster, specialMonsterImage, level) {
    // 생성자 안에서 몬스터의 속성을 정의한다고 생각하시면 됩니다!
    if (!path) {
      throw new Error('몬스터가 이동할 경로가 필요합니다.');
    }
    this.specialMonsterInfo = specialMonster;
    this.monsterId = this.specialMonsterInfo.monsterId;
    this.path = path; // 몬스터가 이동할 경로
    this.currentIndex = 0; // 몬스터가 이동 중인 경로의 인덱스
    this.x = path.x; // 몬스터의 x 좌표 (최초 위치는 경로의 첫 번째 지점)
    this.y = path.y; // 몬스터의 y 좌표 (최초 위치는 경로의 첫 번째 지점)
    this.width = this.specialMonsterInfo.width; // 몬스터 이미지 가로 길이
    this.height = this.specialMonsterInfo.height; // 몬스터 이미지 세로 길이
    this.speed = this.specialMonsterInfo.speed; // 몬스터의 이동 속도
    this.image = specialMonsterImage; // 몬스터 이미지
    this.level = level; // 몬스터 레벨

    // 초기 랜덤 방향 결정
    this.moveX = Math.random() * this.speed;
    this.moveY = Math.random() * this.speed;
    this.init(level);
  }

  init(level) {
    this.maxHp = this.specialMonsterInfo.maxHp + 10 * level; // 몬스터의 현재 HP
    this.hp = this.maxHp; // 몬스터의 현재 HP
    this.attackPower = this.specialMonsterInfo.attackPower + 5 * level; // 몬스터의 공격력 (기지에 가해지는 데미지)
  }

  move(canvas) {
    let canvasWidth = canvas.width;
    let canvasHeight = canvas.height;

    this.x += this.moveX;
    this.y += this.moveY;

    if (this.x <= 0 || this.x + this.width >= canvasWidth) {
      this.moveX *= -1;
      // x축 반대 방향으로 변경
    }

    if (this.y <= 0 || this.y + this.height >= canvasHeight) {
      this.moveY *= -1;
      // y축 반대 방향으로 변경
    }
  }

  draw(ctx) {
    ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
    ctx.font = '12px Arial';
    ctx.fillStyle = 'white';
    ctx.fillText(`(레벨 ${this.level}) ${this.hp}/${this.maxHp}`, this.x, this.y - 5);
  }
}

 

먼저 황금 고블린이 생성되면,

    // 초기 랜덤 방향 결정
    this.moveX = Math.random() * this.speed;
    this.moveY = Math.random() * this.speed;

으로 황금 고블린이 매 프래임 마다 이동할 X 축 거리와 Y축 거리를 결정해줍니다.

  move(canvas) {
    let canvasWidth = canvas.width;
    let canvasHeight = canvas.height;

canvas는 맵의 크기 정보로

 

canvas.width에서 가로 크기 정보와,

canvas.height에서 세로 크기 정보를 가져 옵니다.

 
    if (this.x <= 0 || this.x + this.width >= canvasWidth) {
      this.moveX *= -1;
      // x축 반대 방향으로 변경
    }

    if (this.y <= 0 || this.y + this.height >= canvasHeight) {
      this.moveY *= -1;
      // y축 반대 방향으로 변경
    }

this.x가 0 이하일 경우, X 축 기준 맵 왼쪽 모서리에 닿거나 왼쪽 맵을 벗어나는 상황 입니다.

this.x + this.width가 canvasWidth 일 경우, X 축 기준 맵 오른쪽 모서리에 닿거나 오른쪽 맵을 벗어나는 상황 입니다.

(Y 축 또한 동일하게 작동합니다)

 

그 경우 맵을 벗어나지 않도록 하기 위해 -1을 곱해줍니다.

 

위와 같은 처리로 초반에 결정된 X축 이동 속도, Y축 이동 속도로 황금 고블린이 맵 전체에서 랜덤하게 이동시킬 수 있습니다.

 

15일은 발표 준비만 해서 딱히 한 내용이 없다

변경 점 발생 : 삼각함수 사용

 

발표 15일 발표 준비 중 황금 고블린에 문제가 있다는 사실을 파악하고 문제 해결을 진행했다. 어떤 문제였냐면,

기존 코드를 바탕으로 황금 고블린이 이동을 하면 최대 8 * root(2) 만큼의 속도로 이동하거나, 최소 0으로

황금 고블린 마다 속도가 달라지는 문제가 발생했다.

 

따라서, 위의 문제를 해결하기 위해 삼각 함수를 사용했다.

(전체 코드 밑에 설명 있음)

export class SpecialMonster {
  constructor(path, specialMonster, specialMonsterImage, level) {
    // 생성자 안에서 몬스터의 속성을 정의한다고 생각하시면 됩니다!
    if (!path) {
      throw new Error('몬스터가 이동할 경로가 필요합니다.');
    }
    this.specialMonsterInfo = specialMonster;
    this.monsterId = this.specialMonsterInfo.monsterId;
    this.path = path; // 몬스터가 이동할 경로
    this.currentIndex = 0; // 몬스터가 이동 중인 경로의 인덱스
    this.x = path.x; // 몬스터의 x 좌표 (최초 위치는 경로의 첫 번째 지점)
    this.y = path.y; // 몬스터의 y 좌표 (최초 위치는 경로의 첫 번째 지점)
    this.width = this.specialMonsterInfo.width; // 몬스터 이미지 가로 길이
    this.height = this.specialMonsterInfo.height; // 몬스터 이미지 세로 길이
    this.speed = this.specialMonsterInfo.speed; // 몬스터의 이동 속도
    this.image = specialMonsterImage; // 몬스터 이미지
    this.level = level; // 몬스터 레벨

    this.setRandomDirection();
    this.init(level);
  }

  init(level) {
    this.maxHp = this.specialMonsterInfo.maxHp + 10 * level; // 몬스터의 현재 HP
    this.hp = this.maxHp; // 몬스터의 현재 HP
    this.attackPower = this.specialMonsterInfo.attackPower + 5 * level; // 몬스터의 공격력 (기지에 가해지는 데미지)
  }

  setRandomDirection() {
    let randomAngle = Math.random() * 2 * Math.PI;
    this.moveX = Math.cos(randomAngle);
    this.moveY = Math.sin(randomAngle);

    // 속도의 일관성을 위해 방향 벡터의 크기를 speed로 조정
    let magnitude = Math.sqrt(this.moveX * this.moveX + this.moveY * this.moveY);
    this.moveX = (this.moveX / magnitude) * this.speed;
    this.moveY = (this.moveY / magnitude) * this.speed;
  }

  move(canvas) {
    let canvasWidth = canvas.width;
    let canvasHeight = canvas.height;

    this.x += this.moveX;
    this.y += this.moveY;

    if (this.x <= 0 || this.x + this.width >= canvasWidth) {
      this.moveX *= -1;
      // x축 반대 방향으로 변경
    }

    if (this.y <= 0 || this.y + this.height >= canvasHeight) {
      this.moveY *= -1;
      // y축 반대 방향으로 변경
    }
  }

  draw(ctx) {
    ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
    ctx.font = '12px Arial';
    ctx.fillStyle = 'white';
    ctx.fillText(`(레벨 ${this.level}) ${this.hp}/${this.maxHp}`, this.x, this.y - 5);
  }
}

 

생성자에서 호출된 setRandomDirection으로

  setRandomDirection() {
    let randomAngle = Math.random() * 2 * Math.PI;
    this.moveX = Math.cos(randomAngle);
    this.moveY = Math.sin(randomAngle);

    // 속도의 일관성을 위해 방향 벡터의 크기를 speed로 조정
    let magnitude = Math.sqrt(this.moveX * this.moveX + this.moveY * this.moveY);
    this.moveX = (this.moveX / magnitude) * this.speed;
    this.moveY = (this.moveY / magnitude) * this.speed;
  }

 

0 ~ 360도 사이의 랜덤한 각도를 만든 후

Math.cos()으로 X 축 이동 방향을 결정하고,

Math.sin()으로  Y 축 이동 방향을 결정해줬다.

 

그후, root((X축 이동 방향)^2 + (Y축 이동 방향)^2)로 XY 축 이동에 따른 방향 백터의 크기를 계산하고,

 

    this.moveX = (this.moveX / magnitude) * this.speed;
    this.moveY = (this.moveY / magnitude) * this.speed;

 

(this.moveX / mangnitude)와 (this.moveY / mangnitude)로 이동 방향 백터를 정규화 해준 후,

* this.speed로 속도를 일정하게 만들어줍니다.

 

 

'TIL' 카테고리의 다른 글

2024년 10월 21일 TIL  (0) 2024.10.21
2024년 10월 17일 TIL  (0) 2024.10.17
2024년 10월 11일 TIL  (0) 2024.10.12
2024년 10월 10일 TIL  (0) 2024.10.11
2024년 10월 7일 TIL  (0) 2024.10.08