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);
}
我目前正在评估在 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);
}