How can I properly scale Phaser sprites? - javascript

I have a couple problems with sprite scaling which seem to work fine for other people.
So, this is my game:
As you can see there are 2 big problems: the images are really pixelated and texture bleeding.
This is my config:
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: '100%',
height: '100%',
mode: Phaser.Scale.RESIZE,
autoCenter:Phaser.Scale.CENTER_BOTH,
physics: {
default: 'arcade',
arcade: {
debug: true,
},
pixelArt:true,
render:{
antialias: false,
}
},
scene: {
preload: preload,
create: create,
update: update,
}
};
This is how I preload my assets:
function preload(){
this.load.image("tiles", "assets/turtle_wars_tiles.png");
this.load.tilemapTiledJSON("tutorial_map", "assets/tutorial_map.json");
//preloading player
this.load.spritesheet("player", "assets/characters.png", {
frameWidth: 26,
frameHeight: 36,
});
}
And this is how I create the tilemap:
const map = this.make.tilemap({ key: "tutorial_map", tileWidth:48,tileHeight:48 });
const tileset = map.addTilesetImage("turtle_wars_tiles", "tiles");
for (let i = 0; i < map.layers.length; i++) {
const layer = map.createStaticLayer(i, tileset,0,0)
layer.setDepth(i);
layer.setScale(5)
layer.setCollisionByProperty({ collides: true });
this.physics.add.collider(this.player.collider, layer).collideCallback = () =>{
this.player.collide()
};
}
I tried extruding my tile set of 16x16 tiles but it messes up my whole map and it only solves texture bleeding.
Any idea how can I solve this?

I just tried it on a small demo project, I think the solution is just, to edit your game - config to this (check code below).
Info: You added the correct properties, but only into the physics- Object. I belongs one level higher.
Like this it should work:
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: '100%',
height: '100%',
mode: Phaser.Scale.RESIZE,
autoCenter: Phaser.Scale.CENTER_BOTH,
physics: {
default: 'arcade',
arcade: {
debug: true,
},
},
pixelArt: false,
render: {
antialias: false,
}
...
};

Related

why is this.input.keyboard.on('keyup-LEFT', function() {}) not working in phaser.js?

In my sprite sheet I have two separate frames for when the character is not moving, one is for when she was moving left and then stopped and the other for when she was moving right and then stopped, so i need it to fire up on sort of a key up event. I've seen very similar question here, but the answer didn't work for me, it said to add:
scene.input.keyboard.on('keyup-LEFT', function()
{
});
but it just broke my code, screen goes black and nothing happens, i tried adding that code in either create() and update()
So i tried instead:
this.input.keyboard.on('keyup-LEFT', function()
{
player.setVelocityX(0);
player.anims.play('stopLeft');
});
this.input.keyboard.on('keyup-RIGHT', function()
{
player.setVelocityX(0);
player.anims.play('stopRight');
});
It doesn't break my code, but also nothing happens, I also tried player instead of scene or this, (player is a variable to which my sprite is assigned), but that also broke my code, just like scene did.
BTW, stopLeft and stopRight works fine, because i tested them on normal this.input.keyboard.createCursorKeys() events.
The most common way to implement player movement and/or input is, to put the logic in the update function, and check if the keys are pressed/down (isDown).
I would only use this.input.keyboard, for hot-key like 'ESC' or some special hot-keys.
Here a short working demo:
(for more details checkout this official example)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 100 }
}
},
scene: {
preload,
create,
update
},
banner: false
};
let player;
let cursor;
let animsKeyText;
function preload() {
this.load.spritesheet('dude', 'https://labs.phaser.io/src/games/firstgame/assets/dude.png', { frameWidth: 32, frameHeight: 48 });
}
function create() {
let floor = this.add.rectangle(0, config.height, config.width, 20, 0xcdcdcd)
.setOrigin(0, .5);
animsKeyText = this.add.text(10, 10, 'current anims-key: ??')
this.physics.add.existing(floor, true);
player = this.physics.add.sprite(100, 10, 'dude')
.setCollideWorldBounds(true);
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'stop-left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 1 }),
frameRate: 10,
repeat: 0
});
this.anims.create({
key: 'stop-right',
frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 6 }),
frameRate: 10,
repeat: 0
});
this.physics.add.collider(player, floor);
cursors = this.input.keyboard.createCursorKeys();
}
function update() {
if (cursors.left.isDown) {
player.setVelocityX(-160);
player.anims.play('left', true);
}
else if (cursors.right.isDown) {
player.setVelocityX(160);
player.anims.play('right', true);
}
else {
player.setVelocityX(0);
if (player.anims && player.anims.currentAnim) {
// just to prevent of keys "stop-stop....-right" or so
if (player.anims.currentAnim.key.indexOf('stop') == -1) {
let newKey = `stop-${player.anims.currentAnim.key}`;
player.anims.play(newKey, true);
}
}
}
if (player.anims && player.anims.currentAnim) {
animsKeyText.setText(`current anims-key: ${player.anims.currentAnim.key}`);
}
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Matter.js — How to prevent mouseConstraint to capture scroll events?

I am trying to enable scrolling into a page that contains a Matter.js canvas. I looked everywhere and the recommendation is to add removeEventListener so the mouse constraint won't hijack the scrolling event. Unfortunately, I am having no success. How can I enable a scroll?
Thank you in advance!
CodeSandbox
Code
import "./styles.css";
import Matter from "matter-js";
//Fetch our canvas
var canvas = document.getElementById("world");
//Setup Matter JS
var engine = Matter.Engine.create();
var world = engine.world;
var render = Matter.Render.create({
canvas: canvas,
engine: engine,
options: {
width: 500,
height: 500,
background: "transparent",
wireframes: false,
showAngleIndicator: false
}
});
//Add a ball
var ball = Matter.Bodies.circle(250, 250, 50, {
density: 0.04,
friction: 0.01,
frictionAir: 0.00001,
restitution: 0.8,
render: {
fillStyle: "#F35e66",
strokeStyle: "black",
lineWidth: 1
}
});
Matter.World.add(world, ball);
//Add a floor
var floor = Matter.Bodies.rectangle(250, 520, 500, 40, {
isStatic: true, //An immovable object
render: {
visible: false
}
});
Matter.World.add(world, floor);
//Make interactive
var mouseConstraint = Matter.MouseConstraint.create(engine, {
//Create Constraint
element: canvas,
constraint: {
render: {
visible: false
},
stiffness: 0.8
}
});
Matter.World.add(world, mouseConstraint);
// Why is this not working?
mouseConstraint.mouse.element.removeEventListener(
"mousewheel",
mouseConstraint.mouse.mousewheel
);
mouseConstraint.mouse.element.removeEventListener(
"DOMMouseScroll",
mouseConstraint.mouse.mousewheel
);
//Start the engine
Matter.Engine.run(engine);
Matter.Render.run(render);
It's a HTML issue. in index.html set the overflow to scroll

How to remove empty space between player and ground in Phaser 3

I am learning Phaser 3 by creating a small platform game, everything works as I want, but when the player loads there is some space between him and the ground, what is causing this and how can I fix it? I want him to be standing on the ground without any space between, here is a picture:
https://ibb.co/Px65JMR
and here is my js code:
var config = {
type: Phaser.AUTO,
width: 900,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 }
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
function preload() {
this.load.image('sky', 'assets/world/sky.png');
this.load.image('ground', 'assets/world/ground.png');
this.load.image('platform', 'assets/world/platform.png');
this.load.spritesheet('player', 'assets/characters/player.png', { frameWidth: 32, frameHeight: 48 });
}
function create() {
this.add.image(400, 300, 'sky');
platforms = this.physics.add.staticGroup();
ground = this.physics.add.staticGroup();
platforms.create(600, 400, 'platform');
platforms.create(50, 250, 'platform');
platforms.create(750, 220, 'platform');
ground.create(500, 550, 'ground')
// Creating the player
player = this.physics.add.sprite(50, 350, 'player');
player.setBounce(0.2);
player.setCollideWorldBounds(true);
player.body.setGravityY(300)
this.physics.add.collider(player, ground);
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('player', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [{ key: 'player', frame: 4 }],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('player', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
}
function update() {
cursors = this.input.keyboard.createCursorKeys();
if (cursors.left.isDown) {
player.setVelocityX(-160);
player.anims.play('left', true);
}
else if (cursors.right.isDown) {
player.setVelocityX(160);
player.anims.play('right', true);
}
else {
player.setVelocityX(0);
player.anims.play('turn');
}
if (cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-330);
}
}
this.load.spritesheet('player', 'assets/characters/player.png', { frameWidth: 32, frameHeight: 48 });
Did you make sure that the frameHeight of the sprite is 48 and not 32x32?
Also, I'd recommend you to add debug=true
to your configuration:
arcade: {
debug: true,
gravity: { y: 300 }
}
By doing so, each object will be marked by a purple outline, I bet you will figure it out in no time.
possible solution 1:
try to reduce the second param here:
ground.create(500, 550, 'ground')
to - lets say- 450.
possible solution 2:
ground.create(500, 550, 'ground').setSize(500,500, true);
ground.refresh();

How to change the hitbox's shape of a image in Phaser 3?

I am creating a skateboarding game in JavaScript using the Phaser 3 framework. I have loaded the ramp image onto the screen, and I am currently using the "arcade" physics engine in my file. I know I have to use the matter physics engine to have a non-rectangular hitbox. How do I implement it with the triangular hitbox?
I have the .png image file of the ramp, along with the .json file for its hitbox.
I tried following a tutorial off of a website on how to create new hitboxes for the matter physics engine. Everything ended up falling off the screen and I couldn't figure out how to use the .json file for the ramp.
//Configurations for the physics engine
var physicsConfig = {
default: 'arcade',
arcade : {
debug : true //CHANGE THIS TO TRUE TO SEE LINES
}
}
//Game configurations
var config = {
type: Phaser.AUTO,
width: 1200 ,
height: 600,
physics: physicsConfig,
scene: {
preload: preload,
create: create,
update: update
}
}
//Start the game
var game = new Phaser.Game(config);
function preload() {
//Images
this.load.image('sky', 'archery_assets/images/sky.png');
this.load.image('ground', 'skate_assets/images/ground.png');
this.load.image('up_ramp', 'skate_assets/images/up_ramp.png')
//Spritesheets
this.load.spritesheet('player', 'skate_assets/spritesheets/skater.png', {frameWidth: 160, frameHeight: 160});
}
function create() {
//Background
skyImg = this.add.image(600, 300, 'sky');
//Scale the images
skyImg.setDisplaySize(1200, 600);
groundImg = this.add.image(600, 600, 'ground');
groundImg.setDisplaySize(1200, 250);
//Create the player
this.player = this.physics.add.sprite(100, 410, 'player');
this.player.setCollideWorldBounds(true);
//Rolling animation
this.anims.create({
key: 'move',
frames: this.anims.generateFrameNumbers('player', {start: 0, end: 3}),
frameRate: 16,
repeat: -1 // <-- keeps the rolling animation going
});
//Pushing animation
this.anims.create({
key: 'push',
frames: this.anims.generateFrameNumbers('player', {start: 4, end: 8}),
frameRate: 16
});
//Start and keep the rolling animation going
this.player.anims.play('move', true);
//Up ramp (1st ramp)
this.upRamp = this.physics.add.sprite(700, 330, 'up_ramp');
this.upRamp.setSize(320, 150).setOffset(0, 175);
this.upRamp.enableBody = true;
this.upRamp.setImmovable();
this.upRamp.body.angle = 150;
//Input
this.cursors = this.input.keyboard.createCursorKeys();
//Spacebar
this.spacebar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
this.physics.add.collider(this.player, this.upRamp);
}
function update() {
//Set variable for push speed
var playerPushSpeed = 0;
//If the spacebar is pressed
if (this.spacebar.isDown) {
//Play the push animation
this.player.anims.play('push', true);
//Push speed
playerPushSpeed += 175;
//Move player
this.player.setVelocityX(playerPushSpeed);
}
if (this.upRamp.body.touching.left) {
this.player.setVelocityY(-200);
}
}
I need to know how to implement the .png image of the ramp along with its .json hitbox file, so that the player can properly "ride" up the ramp.
You'll have to use the physics: { default: 'matter' } in order to change the hitbox's shape. Use this code snippet for reference:
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: {
y: 0
},
debug: true
}
},
scene: {
create: create
}
};
var game = new Phaser.Game(config);
function create ()
{
this.matter.world.setBounds();
this.matter.add.rectangle(200, 200, 200, 200, {
chamfer: { radius: [230, 0, 200, 0 ] }
});
this.matter.add.mouseSpring();
}
You could also use a PhysicsEditor, you can check this tutorial on how to implement different shapes.
EDIT:
You can use console.log(this.matter.bodies) to check other available shapes to implement.

How to detect collision between a graphic and a Sprite in phaser 3?

In my game I want to implement a range sort of feature that would restrict players area. I tried to draw a graphic circle and assign it physics properties. Then I setup collision detection between sprite and graphic. The code shows no errors but the collision is not detected.
I followed the following tutorial.
Graphic and Sprite
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
loader: {
baseURL: 'https://cdn.jsdelivr.net/gh/samme/phaser-examples-assets#v2.0.0/assets/',
crossOrigin: 'anonymous'
},
width: 800,
height: 600,
physics: {
default: 'arcade'
},
scene: {
preload: preload,
create: create,
update:update
}
};
var game = new Phaser.Game(config);
var player;
function preload()
{
this.load.image('dude', 'sprites/phaser-dude.png')
}
function create ()
{
player = this.physics.add.sprite(100, 100, 'dude');
player.setCollideWorldBounds(true);
var graphics = this.add.graphics({ fillStyle: { color: 0xff0000 } });
var circle = new Phaser.Geom.Circle(50, 50, 25);
graphics.fillCircleShape(circle);
this.physics.add.existing(graphics);
cursors = this.input.keyboard.createCursorKeys();
this.physics.add.collider(player, graphics);
}
function update()
{
if (cursors.left.isDown)
{
player.setVelocityX(-160);
}
else if (cursors.right.isDown)
{
player.setVelocityX(160);
}
else if (cursors.down.isDown)
{
player.setVelocityY(160);
}
else if (cursors.up.isDown)
{
player.setVelocityY(-160);
}
}
<script src="//cdn.jsdelivr.net/npm/phaser#3.17.0/dist/phaser.min.js"></script>

Categories

Resources