Обнаружение столкновений объектов массива

#javascript #arrays #class #collision-detection #p5.js

#javascript #массивы #класс #обнаружение столкновений #p5.js

Вопрос:

Я делаю небольшую игру в p5.js и когда аватар попадает на определенный объект, этот объект должен вызвать определенную сцену. Объектом, о котором идет речь, являются 4 песочных часа, содержащихся в массиве, как мне «получить доступ» к массиву, чтобы реализовать различное обнаружение столкновений для каждого объекта? Надеюсь, я достаточно ясно выразился.

 class HourGlass {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.w = 60
    this.h = 65
  }
  body() {
    imageMode(CENTER);
    for (let i = 0; i < timekNum; i  ) {
    image(hourglass, this.x (i*150) , this.y (sin(frameCount/(i 10))*(i 20)), this.w, this.h)
  }
  }
  
  checkCollision1(){
    if (me2.x   me2.w > this[0].x amp;amp; me2.x < this[0].x   me2.w amp;amp; me2.y   me2.h/2 > this[0].y amp;amp; me2.y < this[0].y   this[0].h){
      scene = 5
    } 
  }
  

вот ссылка на «полную» игру https://editor.p5js.org/larie438/sketches/uufycStNE (он должен быть запущен в Chrome, по какой-то причине он работает как мусор в Safari)

Заранее спасибо за помощь!

Ответ №1:

Проблема в функции checkCollision1(), замените this[0] только на this .

  checkCollision1(){
    if (me2.x   me2.w > this.x amp;amp; me2.x < this.x   me2.w amp;amp; me2.y   me2.h/2 > this.y amp;amp; me2.y < this.y   this.h){
      scene = 5
    } 
  }
  

Если вы хотите выбрать сцену столкновения, я рекомендую использовать параметры, подобные этому:

   checkCollision(sceneWanted){
    if (me2.x   me2.w > this.x amp;amp; me2.x < this.x   me2.w amp;amp; me2.y   me2.h/2 > this.y amp;amp; me2.y < this.y   this.h){
      scene = sceneWanted;
    } 
  }
  

И когда вы проверяете столкновения, используйте эту новую функцию:

 function hourGlassroom() {
  push()
  background(25, 25, 50)
  for (var i = 0; i < stars.length; i  ) {
    stars[i].body();
  }
    for (let i = 0; i < timekNum; i  ) {
  timekeeper[i].body()
    }
  me2.body()
  me2.move2()
  timekeeper[0].checkCollision(5)
  timekeeper[1].checkCollision(6)
  timekeeper[2].checkCollision(7)
  timekeeper[3].checkCollision(8)
  pop()
}
  

После этого момента, возможно, у вас возникнут проблемы с тем, что единственным работающим хронометристом является первый, это потому, что вы создали все хронометристы с одинаковыми параметрами X и Y.

 function setup() {
  createCanvas(640, 360);
  noStroke();
  frameRate(fps);
  y = 359;
  vid.loop();
  vid.hide();

  for (let i = 0; i < cloudNum; i  ) {
    clouds[i] = new Cloud(random(width), random(height - 180));
  }

  me = new Emi(10, 220);
  
  me2 = new Emi(20, 300);
  for (let i = 0; i < timekNum; i  ) {
    timekeeper[i] = new HourGlass(100, height / 2);
  }
  //All timekeeper with the same X and Y params HERE !!.

  for (var i = 0; i < 1000; i  ) {
    stars[i] = new Star();
  }
}

  

Фактически вы перемещаете всех хронометристов на холсте, но вам нужно обновить его параметры X и Y следующим образом.

  body(i) {
    imageMode(CENTER);
    this.x = 100 (i*150);
    this.rad  = 0.05;
    if(this.rad > 2*PI) this.rad = 0;
    this.y = (height/2   sin(this.rad)*20);
    image(hourglass, this.x , this.y, this.w, this.h);
  }
  

Комментарии:

1. Спасибо! но когда я подставляю ваш код в свои эскизы, песочные часы не отображаются, я все делаю правильно function hourGlassroom() { push() background(25, 25, 50) for (var i = 0; i < stars.length; i ) { stars[i].body(); } for (let i = 0; i < timekNum; i ) { timekeeper[i].body(i) } me2.body() me2.move2() timekeeper[0].checkCollision(5) timekeeper[1].checkCollision(6) timekeeper[2].checkCollision(7) timekeeper[3].checkCollision(8) pop() } извините, я не знаю, как сделать это красиво

2. editor.p5js.org/larie438/sketches/tUfC1rFte

3. @M0bi0usOne Это изменения, которые я внес: editor.p5js.org/piponsio96/sketches/mAJVlSLQ3