Angular 我的 P5js 中没有 Gameloop

There's no Gameloop in my P5js with Angular

我目前正在评估在 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 和 Angular/Typescript

非常感谢任何想法。

我无法重现您的问题。您没有提供足够的代码来构成最小的可重现示例。这是工作 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

我自己找到了解决办法。这是我的错,是的,我提供了更少的代码。我其实很确定,错误不在我这边,因为那里没有错误,似乎我做错了。

在我的 class 播放器中,我创建了一个绘制函数。这个draw函数写错了,因为我想起了P5js的draw函数。因此,我的播放器已渲染但循环中断。

原来是这样:

  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);
  }