【发布时间】:2022-06-11 16:33:04
【问题描述】:
我正在使用 Phaser 3 制作一个 2d 无尽的跑步者,我需要在随机位置以及不同的图案(如菱形、正方形、... 我真的没有太多代码,我不知道该怎么做。我很乐意以任何方式提供任何帮助。谢谢。
【问题讨论】:
标签: javascript phaser-framework
我正在使用 Phaser 3 制作一个 2d 无尽的跑步者,我需要在随机位置以及不同的图案(如菱形、正方形、... 我真的没有太多代码,我不知道该怎么做。我很乐意以任何方式提供任何帮助。谢谢。
【问题讨论】:
标签: javascript phaser-framework
这取决于您的代码,但我会使用内置函数 Phaser.Math.Between 来生成随机位置/数字 (link to the documentation)。
(旁注:第一个例子是为arcade物理制作的,最后一个是为matter.js制作的)
这是一个非常简单的方法:
在代码中:
setTimeout(_ => this.loadCoins(coins), Phaser.Math.Between(2500, 3000));
let yCoord = Phaser.Math.Between(20, 180);let xCord = 400 + Phaser.Math.Between(0, 100);
let coinType = Phaser.Math.Between(0, 2);
let coinsToSpawn = Phaser.Math.Between(1, 5);
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
}
loadCoins(coins){
let coin;
// Generate random amount of coins each time
let coinsToSpawn = Phaser.Math.Between(1, 5);
for(let i = 0; i < coinsToSpawn; i++){
// Get Random y position (x is always bigger than the scene width)
let yCoord = Phaser.Math.Between(20, 180);
let xCord = 400 + Phaser.Math.Between(0, 100);
// Randomly generate types
let coinType = Phaser.Math.Between(0, 2);
switch(coinType){
case 0:
coin = this.add.rectangle(xCord, yCoord, 15, 15, 0xFFFF00);
break;
case 1:
coin = this.add.circle(xCord, yCoord, 7, 0xFF0000);
break;
case 2:
coin = this.add.star(xCord, yCoord, 5, 5, 15, 0x00FF00);
break;
}
coin = this.physics.add.existing(coin);
coins.add(coin);
}
coins.setVelocityX(-100);
// Start next Coin loading randomly in 2.5 - 3 Seconds
setTimeout(_ => this.loadCoins(coins), Phaser.Math.Between(2500, 3000));
}
create() {
this.player = this.add.rectangle(200, 100, 20, 20, 0xffffff);
this.physics.add.existing(this.player);
//Add World Physics
this.physics.world.setBounds(0, 0, 400, 200);
this.player.body.setCollideWorldBounds(true);
this.player.body.setImmovable(true);
let coins = this.physics.add.group({immovable: true, allowGravity: false});
this.loadCoins(coins);
this.physics.add.collider(this.player, coins,
(player, coin) => {
coin.destroy();
});
}
}
const config = {
type: Phaser.AUTO,
width: 400,
height: 200,
scene: [ GameScene ],
physics: {
default: 'arcade',
}
};
const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
更新(用硬币创建形状):
-> 在 Phaser.Actions 命名空间 (like to the documentation) 中查看一些很酷的内置函数。
比如_(仅举几例)):
Phaser.Actions.PlaceOnCirclePhaser.Actions.PlaceOnLinePhaser.Actions.PlaceOnTriangle免责声明:此代码不是最优的,只是这样创建以证明这一点。
生成更新:
旁注:
setInterval,但您可以使用事件、用户输入,或者只是在update 函数中,或者...class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
//keep reference to the groups
this.coinGroups = [];
}
spawnCoins(){
let coins = this.physics.add.group({immovable: true, allowGravity: false});
var circle = new Phaser.Geom.Circle(440, 80, 40);
for(let i = 0; i < 10; i++){
let coin = this.add.circle(0, 0, 8, 0xFFFF00);
coin = this.physics.add.existing(coin);
coins.add(coin);
}
coins.setVelocityX(-100);
this.coinGroups.push(coins);
Phaser.Actions.PlaceOnCircle(coins.getChildren(), circle);
}
create() {
this.add.text(10,10,'Spawing every 2sec')
.setColor('#ffffff');
// Spawing ever 2 Sec
setInterval( _ => {
this.spawnCoins();
}, 2000);
}
update(){
// Minor Cleanup
for(let group of this.coinGroups){
group.getChildren().forEach(child => {
if(child.x < 0){
group.remove(child, true, true);
}
});
}
this.coinGroups = this.coinGroups.filter(group => group.length > 0 );
}
}
const config = {
type: Phaser.AUTO,
width: 400,
height: 200,
scene: [ GameScene ],
physics: {
default: 'arcade',
}
};
const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
matter.js的迷你演示:
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
//keep reference to the groups
this.coinGroups = [];
}
spawnCoins(){
// standart Phaser Group
let coins = this.add.group();
var circle = new Phaser.Geom.Circle(440, 80, 40);
for(let i = 0; i < 10; i++){
let coin = this.matter.add.image(50, 50, 'coin').setOrigin(.5);
coin.setIgnoreGravity(true);
coin.setVelocityX(-3);
coin.setFrictionAir(0);
coins.add(coin);
}
this.coinGroups.push(coins);
Phaser.Actions.PlaceOnCircle(
coins.getChildren(), circle);
}
create() {
this.add.text(10, 10, 'Coins spawned every second')
.setOrigin(0)
.setColor('#ffffff');
// Just creating a texture/image for matter
let g = this.make.graphics({x: 0, y: 0, add: false});
g.fillStyle(0xffff00);
g.fillCircle(7, 7, 7);
g.generateTexture('coin', 14, 14);
setInterval( _ => this.spawnCoins(), 1000);
}
update(){
// Clean Up
for(let group of this.coinGroups){
group.getChildren().forEach(child => {
if(child.x < 0){
group.remove(child, true, true);
}
});
}
this.coinGroups = this.coinGroups.filter(group => group.getChildren().length > 0);
}
}
const config = {
type: Phaser.AUTO,
width: 400,
height: 200,
scene: [ GameScene ],
physics: {
default: 'matter'
},
};
const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>
【讨论】:
setTimeout 仅用于展示概念。编写整个实际的生成脚本会更长/更复杂。我尽量用最少的代码来回答,以免混淆。我将更新第二个示例以生成 "better"。