如何在 Phaser 游戏中反转平台生成?
How to reverse platform generation in Phaser game?
我正在创造一个无尽的赛跑者。在按下左箭头键的那一刻,玩家向左移动,摄像机跟随他,玩家下方的地砖在他们移出右侧的世界边界时被摧毁,并在他们进入世界边界之前重新创建在左侧。这让他可以永远保持 运行 而不会 运行 失控。我的代码运行完美,但有一个问题:我希望玩家 运行 在游戏的右侧,而不是左侧。请注意,我不需要播放器能够双向移动。通过执行以下操作,我可以让相机向右而不是向左跟随玩家:我从 -this in
中删除负片
this.world.setBounds(-this.player.yChange, 0, ...);
所以变成了
this.world.setBounds(this.player.yChange, 0, ...);
现在,当按下向右箭头键时,摄像机会跟随玩家向右奔跑,但地砖不会重新生成,并且他会跑出地面。所以基本上我需要反转地面再生的方向,但我不知道该怎么做。由于一切都在向左工作,我确定这是一些简单的设置,也许是一些需要正面的底片?我已经研究了好几天了,想不通。有谁能看到明显的解决方案?我会很感激。
我的代码在下面,或者看代码笔link:
https://codepen.io/clownhead/pen/BqyqOm
var Jumper = function() {};
Jumper.Play = function() {};
Jumper.Play.prototype = {
preload: function() {
this.load.image( 'hero', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/dude.png' );
this.load.image( 'pixel', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/pixel_1.png' );
},
create: function() {
// background color
this.stage.backgroundColor = '#6bf';
// scaling
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.maxWidth = this.game.width;
this.scale.maxHeight = this.game.height;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
this.scale.setScreenSize( true );
// physics
this.physics.startSystem( Phaser.Physics.ARCADE );
// camera and platform tracking vars
this.cameraXMin = 99999;
this.platformXMin = 99999;
// create platforms
this.platformsCreate();
// create hero
this.heroCreate();
// cursor controls
this.cursor = this.input.keyboard.createCursorKeys();
},
update: function() {
// this is where the main magic happens
// the x offset and the width of the world are adjusted
// to match the furthest point the hero has reached
this.world.setBounds(-this.hero.xChange, 0, this.world.width + this.hero.xChange, this.game.height);
// the built in camera follow methods won't work for our needs, we create a custom one
this.cameraXMin = Math.min( this.cameraXMin, this.hero.x - this.game.width + 130 );
this.camera.x = this.cameraXMin;
// hero collisions and movement
this.physics.arcade.collide( this.hero, this.platforms );
this.heroMove();
// these are pooled so they are very performant
this.platforms.forEachAlive( function( elem ) {
this.platformXMin = Math.min( this.platformXMin, elem.x );
if( elem.x > this.camera.x + this.game.width ) {
elem.kill();
this.platformsCreateOne( this.platformXMin - 70, this.world.height - 50, 50 );
}
}, this );
},
shutdown: function() {
// reset everything, or the world will be messed up
this.world.setBounds( 0, 0, this.game.width, this.game.height );
this.cursor = null;
this.hero.destroy();
this.hero = null;
this.platforms.destroy();
this.platforms = null;
},
platformsCreate: function() {
// platform basic setup
this.platforms = this.add.group();
this.platforms.enableBody = true;
this.platforms.createMultiple( 10, 'pixel' );
// create a batch of platforms that start to move across the level
for( var i = 0; i < 9; i++ ) {
this.platformsCreateOne( this.world.width - 70 - 70 * i, this.world.height - 50, 50);
}
},
platformsCreateOne: function( x, y, width ) {
// this is a helper function since writing all of this out can get verbose elsewhere
var platform = this.platforms.getFirstDead();
platform.reset( x, y );
platform.scale.x = width;
platform.scale.y = 16;
platform.body.immovable = true;
return platform;
},
heroCreate: function() {
// basic hero setup
this.hero = game.add.sprite( this.world.centerX, this.world.height - 69, 'hero' );
this.hero.anchor.set( 0.5 );
// track where the hero started and how much the distance has changed from that point
this.hero.xOrig = this.hero.x;
this.hero.xChange = 0;
// hero collision setup
// disable all collisions except for down
this.physics.arcade.enable( this.hero );
this.hero.body.gravity.y = 500;
this.hero.body.checkCollision.up = false;
this.hero.body.checkCollision.left = false;
this.hero.body.checkCollision.right = false;
},
heroMove: function() {
// handle the left and right movement of the hero
if( this.cursor.left.isDown ) {
this.hero.body.velocity.x = -400;
} else if( this.cursor.right.isDown ) {
this.hero.body.velocity.x = 400;
} else {
this.hero.body.velocity.x = 0;
}
// handle hero jumping
if( this.cursor.up.isDown && this.hero.body.touching.down ) {
this.hero.body.velocity.y = -350;
}
// wrap world coordinated so that you can warp from top to bottom
this.world.wrap( this.hero, this.hero.width / 2, false );
// track the maximum amount that the hero has travelled
this.hero.xChange = Math.max( this.hero.xChange, Math.abs( this.hero.x - this.hero.xOrig ) );
}
}
var game = new Phaser.Game( 500, 300, Phaser.CANVAS, '' );
game.state.add( 'Play', Jumper.Play );
game.state.start( 'Play' );
所以你的代码的相关部分基本上是这样的:
this.camera.x = this.cameraXMin;
如果我们查看代码的行为方式,它会跟踪英雄所在的位置,然后考虑英雄所在的位置。
this.cameraXMin = Math.min( this.cameraXMin, this.hero.x - this.game.width + 130 );
只要英雄向左移动,这就很好用,因为 x
不断变小。但是,一旦您开始向右移动,它们最初开始的位置(例如 0)将始终低于它们移动的位置(会越来越高)。
因此,您需要 Math.max
而不是跟踪 Math.min
。您需要重构的代码不止于此,但进行以下调整将使您走上正确的道路。
在 create
中,您必须设置更好的默认值:
// Instead of setting this to a high number, I would start it where the camera starts. Or just set it to 0.
this.cameraXMin = this.camera.x;
现在在你的 update
中,拥有它 Math.max
:
this.cameraXMin = Math.max( this.cameraXMin, this.hero.x - this.game.width + 130 );
您的平台代码也需要更改,但以上内容应该让您了解需要更改的内容。
我正在创造一个无尽的赛跑者。在按下左箭头键的那一刻,玩家向左移动,摄像机跟随他,玩家下方的地砖在他们移出右侧的世界边界时被摧毁,并在他们进入世界边界之前重新创建在左侧。这让他可以永远保持 运行 而不会 运行 失控。我的代码运行完美,但有一个问题:我希望玩家 运行 在游戏的右侧,而不是左侧。请注意,我不需要播放器能够双向移动。通过执行以下操作,我可以让相机向右而不是向左跟随玩家:我从 -this in
中删除负片this.world.setBounds(-this.player.yChange, 0, ...);
所以变成了
this.world.setBounds(this.player.yChange, 0, ...);
现在,当按下向右箭头键时,摄像机会跟随玩家向右奔跑,但地砖不会重新生成,并且他会跑出地面。所以基本上我需要反转地面再生的方向,但我不知道该怎么做。由于一切都在向左工作,我确定这是一些简单的设置,也许是一些需要正面的底片?我已经研究了好几天了,想不通。有谁能看到明显的解决方案?我会很感激。
我的代码在下面,或者看代码笔link: https://codepen.io/clownhead/pen/BqyqOm
var Jumper = function() {};
Jumper.Play = function() {};
Jumper.Play.prototype = {
preload: function() {
this.load.image( 'hero', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/dude.png' );
this.load.image( 'pixel', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/836/pixel_1.png' );
},
create: function() {
// background color
this.stage.backgroundColor = '#6bf';
// scaling
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.maxWidth = this.game.width;
this.scale.maxHeight = this.game.height;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
this.scale.setScreenSize( true );
// physics
this.physics.startSystem( Phaser.Physics.ARCADE );
// camera and platform tracking vars
this.cameraXMin = 99999;
this.platformXMin = 99999;
// create platforms
this.platformsCreate();
// create hero
this.heroCreate();
// cursor controls
this.cursor = this.input.keyboard.createCursorKeys();
},
update: function() {
// this is where the main magic happens
// the x offset and the width of the world are adjusted
// to match the furthest point the hero has reached
this.world.setBounds(-this.hero.xChange, 0, this.world.width + this.hero.xChange, this.game.height);
// the built in camera follow methods won't work for our needs, we create a custom one
this.cameraXMin = Math.min( this.cameraXMin, this.hero.x - this.game.width + 130 );
this.camera.x = this.cameraXMin;
// hero collisions and movement
this.physics.arcade.collide( this.hero, this.platforms );
this.heroMove();
// these are pooled so they are very performant
this.platforms.forEachAlive( function( elem ) {
this.platformXMin = Math.min( this.platformXMin, elem.x );
if( elem.x > this.camera.x + this.game.width ) {
elem.kill();
this.platformsCreateOne( this.platformXMin - 70, this.world.height - 50, 50 );
}
}, this );
},
shutdown: function() {
// reset everything, or the world will be messed up
this.world.setBounds( 0, 0, this.game.width, this.game.height );
this.cursor = null;
this.hero.destroy();
this.hero = null;
this.platforms.destroy();
this.platforms = null;
},
platformsCreate: function() {
// platform basic setup
this.platforms = this.add.group();
this.platforms.enableBody = true;
this.platforms.createMultiple( 10, 'pixel' );
// create a batch of platforms that start to move across the level
for( var i = 0; i < 9; i++ ) {
this.platformsCreateOne( this.world.width - 70 - 70 * i, this.world.height - 50, 50);
}
},
platformsCreateOne: function( x, y, width ) {
// this is a helper function since writing all of this out can get verbose elsewhere
var platform = this.platforms.getFirstDead();
platform.reset( x, y );
platform.scale.x = width;
platform.scale.y = 16;
platform.body.immovable = true;
return platform;
},
heroCreate: function() {
// basic hero setup
this.hero = game.add.sprite( this.world.centerX, this.world.height - 69, 'hero' );
this.hero.anchor.set( 0.5 );
// track where the hero started and how much the distance has changed from that point
this.hero.xOrig = this.hero.x;
this.hero.xChange = 0;
// hero collision setup
// disable all collisions except for down
this.physics.arcade.enable( this.hero );
this.hero.body.gravity.y = 500;
this.hero.body.checkCollision.up = false;
this.hero.body.checkCollision.left = false;
this.hero.body.checkCollision.right = false;
},
heroMove: function() {
// handle the left and right movement of the hero
if( this.cursor.left.isDown ) {
this.hero.body.velocity.x = -400;
} else if( this.cursor.right.isDown ) {
this.hero.body.velocity.x = 400;
} else {
this.hero.body.velocity.x = 0;
}
// handle hero jumping
if( this.cursor.up.isDown && this.hero.body.touching.down ) {
this.hero.body.velocity.y = -350;
}
// wrap world coordinated so that you can warp from top to bottom
this.world.wrap( this.hero, this.hero.width / 2, false );
// track the maximum amount that the hero has travelled
this.hero.xChange = Math.max( this.hero.xChange, Math.abs( this.hero.x - this.hero.xOrig ) );
}
}
var game = new Phaser.Game( 500, 300, Phaser.CANVAS, '' );
game.state.add( 'Play', Jumper.Play );
game.state.start( 'Play' );
所以你的代码的相关部分基本上是这样的:
this.camera.x = this.cameraXMin;
如果我们查看代码的行为方式,它会跟踪英雄所在的位置,然后考虑英雄所在的位置。
this.cameraXMin = Math.min( this.cameraXMin, this.hero.x - this.game.width + 130 );
只要英雄向左移动,这就很好用,因为 x
不断变小。但是,一旦您开始向右移动,它们最初开始的位置(例如 0)将始终低于它们移动的位置(会越来越高)。
因此,您需要 Math.max
而不是跟踪 Math.min
。您需要重构的代码不止于此,但进行以下调整将使您走上正确的道路。
在 create
中,您必须设置更好的默认值:
// Instead of setting this to a high number, I would start it where the camera starts. Or just set it to 0.
this.cameraXMin = this.camera.x;
现在在你的 update
中,拥有它 Math.max
:
this.cameraXMin = Math.max( this.cameraXMin, this.hero.x - this.game.width + 130 );
您的平台代码也需要更改,但以上内容应该让您了解需要更改的内容。