В моем P5js нет Gameloop с угловым

#angular #typescript #p5.js

Вопрос:

В настоящее время я оцениваю структуру / возможность создания игры внутри приложения Angular. Я попробовал Canvas, теперь я хочу использовать P5.

Проблема в том, что он запускает всю функцию рисования только один раз.

 
ngOnInit(): void {
    this.scrWidth = window.innerWidth;
    this.scrHeight = window.innerHeight;

    this.createCanvas();
  }

  private createCanvas() {
    const sketch = (s: p5) => {
      s.preload = () => {};

      s.setup = () => {
        s.frameRate(30);
        s.createCanvas(this.scrWidth, this.scrHeight - 10);
        s.background(50);

        this.objLayer = new ObjectLayer();

        this.player = new Player(
          this.scrHeight / 20, // Width (Using the screen height to scale the player)
          (this.scrHeight / 20) * 1.5, // Height (Using the screen height to scale the player)
          30, // X Starting Position
          30 // Y Starting Position
        );
        this.objLayer.children.push(this.player);
      };

      s.draw = () => {
        this.update(); //Updating states, coordinates, ..
        this.render(); // Drawing Objects to the sketch
      };
    };

    this.p5 = new p5(sketch.bind(this), this.container.nativeElement);
  }
 

Я не знаю, блокирует ли Angular каким-то образом цикл, или я просто допустил ошибку. к сожалению, в Интернете почти нет помощи в использовании P5.js с помощью Углового/машинописного текста.

Я очень благодарен за любые идеи.

Ответ №1:

Я не могу воспроизвести вашу проблему. Вы предоставили недостаточно кода, чтобы создать минимальный воспроизводимый пример. Вот полный код рабочего компонента Angular 12:

 import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import p5 from 'p5';

class Ball {
  public x: number;
  public y: number;
  public velocity: p5.Vector;
  public radius: number;

  constructor(x: number, y: number, velocity: p5.Vector, radius: number = 20) {
    this.x = x;
    this.y = y;
    this.velocity = velocity;
    this.radius = radius;
  }

  public render(p: p5) {
    p.circle(this.x, this.y, this.radius);
  }

  public update(p: p5) {
    // update position
    this.x  = this.velocity.x * (p.deltaTime / 1000);
    this.y  = this.velocity.y * (p.deltaTime / 1000)
    
    // check for collisions
    if (this.x < this.radius) {
      // Collision with the left hand edge of the "room" reverses the horizontal component of the velocity
      this.velocity.x *= -1;
      this.x = this.radius   (this.radius - this.x);
    } else if (this.x > p.width - this.radius) {
      this.velocity.x *= -1;
      this.x = p.width - this.radius - (this.x - (p.width - this.radius));
    }
    if (this.y < this.radius) {
      this.velocity.y *= -1;
      this.y = this.radius   (this.radius - this.y);
    } else if (this.y > p.height - this.radius) {
      this.velocity.y *= -1;
      this.y = p.height - this.radius - (this.y - (p.height - this.radius));
    }
  }
}

@Component({
  selector: 'app-p5js-sample',
  templateUrl: './p5js-sample.component.html',
  styleUrls: ['./p5js-sample.component.css']
})
export class P5jsSampleComponent {
  public instance?: p5;
  public ball?: Ball;

  @ViewChild('container')
  public container?: ElementRef<HTMLDivElement>;

  constructor() { }

  // Switched to ngAfterViewInit instead of ngOnInit just to support
  // the parent element for the sketch (not strictly necessary)
  ngAfterViewInit(): void {
    this.createSketch();
  }

  private createSketch() {
    const sketch = (p: p5) => {
      p.setup = () => {
        p.createCanvas(p.windowWidth - 20, p.windowHeight - 50);
        p.ellipseMode(p.RADIUS);
        p.fill('green');

        this.ball = new Ball(
          p.random(20, p.width - 20),
          p.random(20, p.height - 20),
          p.createVector(100, 0).rotate(p.random(0, p.TWO_PI))
        );
      };

      p.draw = () => {
        p.background(0);
        if (this.ball) {
          this.ball.update(p);
          this.ball.render(p);
        }
      };
    };
    
    this.instance = new p5(
      // this bind is not necessary
      sketch.bind(this),
      // Specifying a parent element is good practice, but is also
      // not strictly necessary
      this.container?.nativeElement
    );
  }
}
 

Полный, выполнимый пример можно найти здесь: https://replit.com/@KumuPaul/Angular-P5js-Sample

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

1. Спасибо. Я уже понял свою ошибку, когда увидел твой ответ.

Ответ №2:

Я сам нашел решение. Это была моя вина, и да, я предоставил меньше кода. Я на самом деле был уверен, что ошибка не на моей стороне, потому что там, где ошибок не было, и казалось, что я все сделал неправильно.

В своем классе для игрока я создал функцию розыгрыша. Эта функция рисования была написана неправильно, потому что я вспомнил функцию рисования из P5js. Из-за этого мой плеер был визуализирован, но цикл прервался.

Вот как это было:

   public draw(p: p5) {
    s.draw = () => {
      p.fill(255);
      p.rect(this.x, this.y, this.width, this.height);
    }
  }
 

Вот как это работает:

   public draw(p: p5) {
    p.fill(255);
    p.rect(this.x, this.y, this.width, this.height);
  }