如何使用 Phaser 3 以模式和随机位置产生收藏品或拾取物
How to spawn collectables or pickups in patterns and at random positions using Phaser 3
我正在使用 Phaser 3 制作一个 2d 无尽的跑步者,我需要在随机位置以及不同的图案(例如菱形、方形、...
我真的没有太多代码,我不知道该怎么做。我很乐意以任何方式提供任何帮助。谢谢。
这取决于您的代码,但我会使用函数 Phaser.Math.Between
来生成随机 positions/numbers (link to the documentation).
这里有一个很简单的方法:
代码中:
- 生成金币的时间间隔是随机的
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.PlaceOnCircle
Phaser.Actions.PlaceOnLine
Phaser.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>
我正在使用 Phaser 3 制作一个 2d 无尽的跑步者,我需要在随机位置以及不同的图案(例如菱形、方形、... 我真的没有太多代码,我不知道该怎么做。我很乐意以任何方式提供任何帮助。谢谢。
这取决于您的代码,但我会使用函数 Phaser.Math.Between
来生成随机 positions/numbers (link to the documentation).
这里有一个很简单的方法:
代码中:
- 生成金币的时间间隔是随机的
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.PlaceOnCircle
Phaser.Actions.PlaceOnLine
Phaser.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>