英文:
Phaser : Hitbox of character move anormally since animations added
问题
I managed to fix the issue with hardcoding the position of the hitbox with
this.player.body.setOffset(28, 24);
In every case for going up, left, and right, and the same set to 0, 0 for going down, but it is something I really don't like.
Thanks everyone!
英文:
I'm new to Phaser and trying to do a top down game.
Since I added walking animations, the hitbox of my characters moves anormaly :
Going down : ok !
Any other direction : not ok !
As you can see on the images, the hitbox is correctly placed around the character when going down, but if I go up, left, or right, the hitbox is always placed at the same spot : top left of the character.
This seems to happen since I added animations.
I really don't know what to change, there is not much code about this in my project yet :
main.js
import Phaser from "./lib/phaser.js";
import Game from "./scenes/Game.js";
export default new Phaser.Game({
type: Phaser.AUTO,
scene: Game,
width: 750,
height: 500,
autoCenter: Phaser.Scale.CENTER_BOTH,
physics: {
default: "arcade",
arcade: {
debug: true
}
}
});
Game.js
import Phaser from "../lib/phaser.js";
export default class Game extends Phaser.Scene {
constructor() {
super("game");
}
preload() {
this.load.image("tiles", "assets/MasterSimple.png");
this.load.image("character", "../../assets/Player/idle/idle down1.png");
// Marche
this.load.image("wd1", "../../assets/Player/walk/walk down1.png");
this.load.image("wd2", "../../assets/Player/walk/walk down2.png");
this.load.image("wd3", "../../assets/Player/walk/walk down3.png");
this.load.image("wd4", "../../assets/Player/walk/walk down4.png");
this.load.image("wu1", "../../assets/Player/walk/walk up1.png");
this.load.image("wu2", "../../assets/Player/walk/walk up2.png");
this.load.image("wu3", "../../assets/Player/walk/walk up3.png");
this.load.image("wu4", "../../assets/Player/walk/walk up4.png");
this.load.image("wl1", "../../assets/Player/walk/walk left1.png");
this.load.image("wl2", "../../assets/Player/walk/walk left2.png");
this.load.image("wl3", "../../assets/Player/walk/walk left3.png");
this.load.image("wl4", "../../assets/Player/walk/walk left4.png");
this.load.image("wr1", "../../assets/Player/walk/walk right1.png");
this.load.image("wr2", "../../assets/Player/walk/walk right2.png");
this.load.image("wr3", "../../assets/Player/walk/walk right3.png");
this.load.image("wr4", "../../assets/Player/walk/walk right4.png");
this.load.tilemapTiledJSON("level1", "assets/level1.json");
}
create() {
const level1 = this.make.tilemap({
key: "level1",
tileWidth: 16,
tileHeight: 16,
});
const tileset = level1.addTilesetImage("MasterSimple", "tiles");
// Calques
const eauLayer = level1.createLayer("eau", tileset, 0, 0);
eauLayer.scale = 3;
const solLayer = level1.createLayer("sol", tileset, 0, 0);
solLayer.scale = 3;
const murLayer = level1.createLayer("mur", tileset, 0, 0);
murLayer.scale = 3;
// Personnages
this.player = this.physics.add.sprite(500, 300, "character").setScale(3.5);
this.cursors = this.input.keyboard.createCursorKeys();
this.physics.add.collider(this.player, eauLayer);
eauLayer.setCollisionBetween(81, 82);
this.physics.add.collider(this.player, murLayer);
murLayer.setCollisionBetween(110, 140);
// Animations
// Vers le bas
const walkDownFrames = [
{ key: "wd1" },
{ key: "wd2" },
{ key: "wd3" },
{ key: "wd4" },
];
this.anims.create({
key: "walkDown",
frames: walkDownFrames,
frameRate: 10,
repeat: -1,
});
// Vers le haut
const walkUpFrames = [
{ key: "wu1" },
{ key: "wu2" },
{ key: "wu3" },
{ key: "wu4" },
];
this.anims.create({
key: "walkUp",
frames: walkUpFrames,
frameRate: 10,
repeat: -1,
});
// Vers la gauche
const walkLeftFrames = [
{ key: "wl1" },
{ key: "wl2" },
{ key: "wl3" },
{ key: "wl4" },
];
this.anims.create({
key: "walkLeft",
frames: walkLeftFrames,
frameRate: 10,
repeat: -1,
});
// Vers la droite
const walkRightFrames = [
{ key: "wr1" },
{ key: "wr2" },
{ key: "wr3" },
{ key: "wr4" },
];
this.anims.create({
key: "walkRight",
frames: walkRightFrames,
frameRate: 10,
repeat: -1,
});
// Camera
this.cameras.main.startFollow(this.player);
}
update() {
this.player.setVelocityY(0);
this.player.setVelocityX(0);
const speed = 300;
if (this.cursors.up.isDown) {
this.player.setVelocityY(-speed);
this.player.anims.play("walkUp", true);
} else if (this.cursors.down.isDown) {
this.player.setVelocityY(speed);
this.player.anims.play("walkDown", true);
} else if (this.cursors.left.isDown) {
this.player.setVelocityX(-speed);
this.player.anims.play("walkLeft", true);
} else if (this.cursors.right.isDown) {
this.player.setVelocityX(speed);
this.player.anims.play("walkRight", true);
} else {
this.player.anims.stop();
}
}
}
I managed to fix the issue with hardcoding the position of the hitbox with
this.player.body.setOffset(28,24);
In every case for going up, left, and right, and the same set to 0, 0 for going down, but it is something I really don't like.
Thanks everyone !
答案1
得分: 0
问题可能与图像的大小以及Sprite
对象的缩放有关。用于创建Sprite
对象的键/图像应具有与动画的frameSize完全相同的尺寸,否则物理体可能会偏移。
信息: 由于缩放,即使有轻微的偏移也会导致更大的偏移。
这里有一个演示展示了这个问题:
初始纹理用于创建物理体的大小和位置。
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 0 },
debug: true
}
},
scene: { preload, create }
};
function preload(){
this.load.spritesheet('brawler', 'https://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
}
function create () {
this.add.text(10, 10, 'Wrong Sprite')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
this.add.text(260, 10, 'Correct Sprite')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 10, 10);
graphics.generateTexture('img', 10, 10);
// just one animation for testing
this.anims.create({
key: 'walk',
frames: this.anims.generateFrameNumbers('brawler', { frames: [ 0, 1, 2, 3 ] }),
frameRate: 8,
repeat: -1
});
let wrongSprite = this.physics.add.sprite(50, 50, 'img').setScale(2).setOrigin(0);
wrongSprite.play('walk')
let correctSprite = this.physics.add.sprite(270, 50, 'brawler').setScale(2).setOrigin(0);
correctSprite.play('walk')
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
(请注意,这是代码的翻译,不包括代码本身。)
英文:
The problem has probably to do with the sizes of the images and also the scaling of the Sprite
object. They key / image used to create the Sprite
object, should have the exact dimensions of the frameSize of the animations, if not the physics body, can be offset.
> Info: And due to the scaling even an minor offset can cause much bigger offset.
Here a demo show casing this problem:
The initial texture is use to create the size and position of the physics body.
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 0 },
debug: true
}
},
scene: { preload, create }
};
function preload(){
this.load.spritesheet('brawler', 'https://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
}
function create () {
this.add.text(10, 10, 'Wrong Sprite')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
this.add.text(260, 10, 'Correct Sprite')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 10, 10);
graphics.generateTexture('img', 10, 10);
// just one animation for testing
this.anims.create({
key: 'walk',
frames: this.anims.generateFrameNumbers('brawler', { frames: [ 0, 1, 2, 3 ] }),
frameRate: 8,
repeat: -1
});
let wrongSprite = this.physics.add.sprite(50, 50, 'img').setScale(2).setOrigin(0);
wrongSprite.play('walk')
let correctSprite = this.physics.add.sprite(270, 50, 'brawler').setScale(2).setOrigin(0);
correctSprite.play('walk')
}
new Phaser.Game(config);
<!-- language: lang-html -->
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论