p5js 中朝向 (0,0) 的向量

问题描述 投票:0回答:1

我目前正在尝试创建一个 2d 游戏,其中“僵尸”追逐玩家,场景在 p5j 中四处移动。我的问题是僵尸直线前往点 (0,0),然后绕着它旋转,有效地停留在那里。

我创建了一个测试项目,其中僵尸跟随鼠标。它使用几乎相同的代码,但我不知道有什么区别。

这是使用我原始项目中的一些代码的堆栈片段。如果有人能帮助我解决这个错误,那就太好了。它包含相同的错误。与僵尸相关的代码位于 ZombieHandler 类下

winX = 666
winY = 400
//If you are looking through this for the issue go down to the class ZombieHandler
function setup() {
  createCanvas(winX, winY);
  background(150);
  angleMode(DEGREES)
  rectMode(CENTER)
}
class User {
  constructor(x, y, rotation, speed, rotspeed) {
    this.posX = x;
    this.posY = y;
    this.rotation = rotation;
    this.speed = speed;
    this.size = 30;
    this.rotspeed = 0;
  }
  render() {
    translate(winX / 2, winY / 2);
    rotate(this.rotation);
    translate(-winX / 2, -winY / 2);
    fill(70);
    rect(winX / 2 + this.size / 2, winY / 2, this.size, this.size / 2, 5, 5, 5, 5);
    fill(0);
    rect(winX / 2, winY / 2, this.size, this.size, 5, 5, 5, 5);
    translate(winX / 2, winY / 2);
    rotate(-this.rotation);
    translate(-winX / 2, -winY / 2);
  }
  control(cameraX, cameraY) {
    this.rotation += this.rotspeed;
    let pos = createVector(this.speed, 0)
    pos.rotate(this.rotation)
    console.log("Player.posX: " + this.posX.toString())
    console.log("Player.posY: " + this.posY.toString())
    //set x to left if past right, and vice versa
    //update pos
    if (this.posX - pos.x < 2295 && this.posX - pos.x > -1630) {
      this.posX -= pos.x;
      cameraX -= pos.x;
    }
    if (this.posY - pos.y < 860 && this.posY - pos.y > -1065) {
      this.posY -= pos.y;
      cameraY -= pos.y
    }
    //speed decay
    this.speed *= 0.91;
    if (this.speed < 0.5 && this.speed > 0 || this.speed > 0.5 && this.speed < 0) {
      this.speed = 0;
    }
    //rot decay
    this.rotspeed *= 0.95;
    if (this.rotspeed > 0) {
      this.rotspeed -= 0.5
    } else if (this.rotspeed < 0) {
      this.rotspeed += 0.5
    }
    return [cameraX, cameraY]
  }
}
class ZombieHandler {
  constructor(list) {
    this.list = list;
  }
  render(Player) {
    //zombie list format [[x,y,speed],[x,y,speed]]
    this.list.forEach(zombie => {
      var x = zombie[0] - Player.posX;
      var y = zombie[1] - Player.posY;
      var hyp = Math.hypot(x, y)
      var point = Math.acos(x / hyp) * (180 / Math.PI)
      fill(0)
      rect(zombie[0] + Player.posX + winX / 2, zombie[1] + Player.posY + winY / 2, 30, 30, 5, 5, 5, 5)
    });
  }
  control(Player) {
    for (let i = 0; i < this.list.length; i++) {
      let angle = Math.atan2(Player.posY - this.list[i][1], Player.posX - this.list[i][0]);
      if (angle < 0) {
        angle += Math.PI * 2
      }
      // at this point the zombie is attempting to rotate between angles 145 and -35 around 0, leaving it trapped in a loop
      this.list[i][0] += this.list[i][2] * Math.cos(angle);
      this.list[i][1] += this.list[i][2] * Math.sin(angle);
    }
  }
}
Player = new User(50, 50, 0, 0, 0)
Zombie = new ZombieHandler([])
var inputchecker = [0, 0, 0, 0, 0];
var tick = 0
var zombie_timer = 0
var cameraX = 0
var cameraY = 0

function draw() {
  background(150)
  noStroke()
  //Input Handler
  document.onkeydown = (e) => { //inputlist input checker
    e = e || window.event;
    if (e.key === "ArrowUp") {
      inputchecker[0] = 1;
    } else if (e.key === "ArrowLeft") {
      inputchecker[1] = 1;
    } else if (e.key === "ArrowRight") {
      inputchecker[2] = 1;
    } else if (e.key === "ArrowDown") {
      inputchecker[3] = 1;
    }
  };
  document.onkeyup = (e) => { //inputlist input checker
    e = e || window.event;
    if (e.key === "ArrowUp") {
      inputchecker[0] = 0;
    } else if (e.key === "ArrowLeft") {
      inputchecker[1] = 0;
    } else if (e.key === "ArrowRight") {
      inputchecker[2] = 0;
    } else if (e.key === "ArrowDown") {
      inputchecker[3] = 0;
    }
  };
  if (tick == 4) {
    if (inputchecker[0] == 1) {
      Player.speed += 3
    } else if (inputchecker[3] == 1) {
      Player.speed -= 2
    }
    if (inputchecker[1] == 1) {
      Player.rotspeed -= 2.5;
    } else if (inputchecker[2] == 1) {
      Player.rotspeed += 2.5;
    }
    tick = 0
  };
  //Function Call
  var camera = Player.control(cameraX, cameraY)
  cameraX = parseInt(camera[0])
  cameraY = parseInt(camera[1])


  if (zombie_timer == 50) {
    //add zombie creation code here
    //distance 1000
    //create a 0-359 random number generator for angle
    //zombie list format [[x,y,speed],[x,y,speed]]
    let pos = createVector(200, 0)
    pos.rotate(Math.floor(Math.random() * 360))
    Zombie.list.push([cameraX + pos.x, cameraY + pos.y, 3])
  }
  Zombie.control(Player)
  Player.render()
  Zombie.render(Player)
  zombie_timer += 1;
  tick += 1;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>

javascript p5.js
1个回答
0
投票

我认为这个错误存在于渲染/显示代码中,而不是

control(...)
函数将僵尸移向玩家。

再看看您的

rect(...)
来电
ZombieHandler.render(Player)
;我认为您错误地将僵尸坐标添加到玩家的坐标中,而不是计算它们之间的差异。

这个 codepen 做了一个小调整,它似乎让僵尸向玩家移动:https://codepen.io/lecrte/pen/PoVmrzV?editors=0010


另外,您可能想研究一下聚集代码,例如:https://p5js.org/examples/simulate-flocking.html ...这样僵尸就不会堆叠在一起。

您可以将这些

document.onkeydown
document.onkeyup
移到您的 draw() 函数之外,因为它们只需要设置一次;每帧设置关键侦听器的额外开销很小。 (有 https://p5js.org/reference/#/p5/keyPressed 和类似的 keyReleased 您可以查看)

编码快乐!

© www.soinside.com 2019 - 2024. All rights reserved.