How do i make it so an enemy sprite follows the player sprite in Phaser 3? - phaser-framework

I'm using Phaser 3
create(){
this.player = this.physics.add.sprite(100, 450, 'player');
this.enemy = this.physics.add.sprite(100, 450, 'enemy');
this.physics.moveToObject(this.enemy, this.player, 100);
}
So far i have this but because i'm using this.physics.add.sprite and not this.physics.add.image it doesn't work.
I specifically need to use this.physics.add.sprite
editted:
enemyFollows () {
this.enemy.x = this.player.body.position.x;
this.enemy.y = this.player.body.position.y;
}
Now using this but need to have it slowly moving to player's body position.

I got it to work.
enemyFollows () {
this.physics.moveToObject(this.enemy, this.player, 100);
}
I didn't put it in the create() function but made a new function for it and called the enemyFollows() in the update()
like this
update() {
this.enemyFollows();
}

Related

Drawing Tool with Processing

I am trying to create a little drawing tool with processing. The final drawing should be exportable as a .svg file – so i thought this to be pretty easy… but actually it isnt…
I put the background function into setup – to be able to draw – the safed svg file unfortunately only contains a single frame – and not the whole drawing. :-(
What am I missing – how could I achieve that! I would be thankful for any kind of help!
This is my code so far:
import processing.svg.*;
boolean record;
void setup () {
size(1080, 1080);
background(255);
}
void draw() {
if (record) {
beginRecord(SVG, "frame-####.svg");
}
fill(255);
strokeWeight(1);
ellipse(mouseX, mouseY, 100, 100);
if (record) {
endRecord();
record = false;
}
}
void mousePressed() {
record = true;
}
Tried different things in organizing the code lines in different orders – but could not manage it…
Thank you!
That's because you're creating an image every time you beginRecord and endRecord. If you want to save the image as you see it, you can use save(fileName.png) instead. Here's a code snippet to demonstrate:
void setup() {
size(800, 600);
background(255);
fill(255);
strokeWeight(1);
}
void draw() {
ellipse(mouseX, mouseY, 100, 100);
}
void mousePressed() {
save("myImage.png");
}
If, on the other hand, you really want to use beginRecord, know that it'll save everything you draw between beginRecord and endRecord. You could programatically create an image file this way, as an example, but you cannot just add snapshots to an existing image (which is why you only see "one frame" with your current code). Every time you begin recording, you create a new image. I'm not especially familiar with this method, but one obvious way to do things would be to "save" whatever the user is doing and reproduce those instructions to save them. Here's an example which does this (it saves when you right-click, and I also took the liberty of drawing only when the left mouse button is down):
import processing.svg.*;
boolean record;
ArrayList<PVector> positionsList;
void setup() {
size(800, 600);
positionsList = new ArrayList<PVector>();
}
void draw() {
background(255);
fill(255);
strokeWeight(1);
for (PVector p : positionsList) {
ellipse(p.x, p.y, 100, 100);
}
ellipse(mouseX, mouseY, 100, 100);
if (record) {
positionsList.add(new PVector(mouseX, mouseY));
}
}
void mousePressed() {
record = mouseButton == LEFT;
if (mouseButton == RIGHT) {
beginRecord(SVG, "frame.svg");
fill(255);
strokeWeight(1);
for (PVector p : positionsList) {
ellipse(p.x, p.y, 100, 100);
}
endRecord();
}
}
void mouseReleased() {
record = false;
}
While drawing:
The file (as a png here but it was saved as a svg on my computer):
Hope it helps. Have fun!
import processing.pdf.*;
PShape shape;
void setup () {
size(1080, 1080);
beginRecord(PDF, "drawing.pdf");
shape = loadShape("shape.svg");
shapeMode(CENTER);
background(0,255,0);
}
void draw() {
shape.disableStyle();
fill(255);
strokeWeight(10);
shape(shape, mouseX, mouseY, 200, 200);
}
void keyPressed() {
if (key == 's') {
endRecord();
exit();
}
}

Phaser adding arcade physics messes up sprites

When I add Arcade physics to my sprites the whole game breaks and the sprites behave very oddly.
When the two lines to enable physics are commented out I get the behaviour I was expecting.
//game.physics.arcade.enable(paddle);
//game.physics.arcade.enable(ball);
I am trying to add it in so I can do some collision detection.
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
function preload() {
game.load.image('sky', 'assets/sky.png');
game.load.image('paddle', 'assets/reactangle.jpg');
game.load.image('circle', 'assets/circle.png');
}
var paddle;
var ball;
var ballDir;
var ballSpeed;
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.add.sprite(0, 0, 'sky');
paddle = game.add.sprite(game.width/2 ,500, 'paddle');
ballSpeed = 5
ballDir = -ballSpeed;
ball = game.add.sprite(10, 10, 'circle');
ball.x = 400;
ball.y = 20;
game.physics.arcade.enable(paddle);
game.physics.arcade.enable(ball);
}
function update() {
paddle.x = game.input.mousePointer.x - (paddle.width/2);
ball.y -= ballDir;
}

Phaser scaling is changing my game bounds

I'm building a platformer game in Phaser. I have a player which can move left or right & since the game bound is set it stops when hits the left & right portion of the screen.
Main game settings:
var game = new Phaser.Game(360, 592, Phaser.AUTO);
this.game.world.setBounds(0, 0, 360, 700);
A camera is following the player:
this.camera.follow(this.player);
I have a spritesheet of the player that contains the animation of it moving but it has only left moving animations & i'm using
this.player.scale.setTo(-1, 1);
to play the reverse animation in the right moving case which is working fine & but due to which the right bound has been decreased somehow i.e the player is hitting everything 15px before the actualy position where it should stop.
Here's the screenshots:
^ When the right collision is perfect i.e before adding scale on right key animation
^ When the scale is set to -1
Note:
Event the collision with fire when moving right is before the same distance off as with the wall.
Update:
Result after debugging the body of the player & when moving right:
The green box (i.e body)is actually on the right of the player when moving right & on moving left it's exactly on the player.(game.debug.body(this.player);)
The pink border is of the sprite (game.debug.spriteBounds(this.player, 'pink', false);)
Observation:
I think the sprite is flipping around it's center since the anchor of it is set to 0.5 but the debugger box is flipping around the right side of the sprite.. Weird 😕
Here is the complete code of the game:
var GameState = {
init: function() {
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.game.physics.arcade.gravity.y = 1500;
this.cursors = this.game.input.keyboard.createCursorKeys();
this.PLAYER_SPEED = 200;
this.JUMP_SPEED = 670;
this.game.world.setBounds(0, 0, 360, 700);
},
preload: function() {
this.load.image('ground', 'assets/monster-kong/ground.png');
this.load.image('actionButton', 'assets/monster-kong/actionButton.png');
this.load.image('arrowButton', 'assets/monster-kong/arrowButton.png');
this.load.image('barrel', 'assets/monster-kong/barrel.png');
this.load.image('gorilla', 'assets/monster-kong/gorilla3.png');
this.load.image('platform', 'assets/monster-kong/platform.png');
this.load.spritesheet('player', 'assets/monster-kong/player_spritesheet.png', 28, 30, 5, 1, 1);
this.load.spritesheet('fire', 'assets/monster-kong/fire_spritesheet.png', 20, 21, 2, 1, 1);
this.load.text('level', 'assets/monster-kong/level.json');
},
create: function() {
var levelData = JSON.parse(this.game.cache.getText('level'));
this.ground = this.add.sprite(0, 638, 'ground');
this.game.physics.arcade.enable(this.ground);
this.ground.body.allowGravity = false;
this.ground.body.immovable = true;
console.log(levelData);
this.platforms = this.add.group();
this.platforms.enableBody = true;
levelData.platformPositions.forEach(function(platform) {
this.platforms.create(platform.x, platform.y, 'platform');
}, this);
this.platforms.setAll('body.immovable', true);
this.platforms.setAll('body.allowGravity', false);
//fire
this.fires = this.add.group();
this.fires.enableBody = true;
this.fires.setAll('body.allowGravity', false);
console.log(levelData.firePositions);
levelData.firePositions.forEach(function(fire) {
var currentFire = this.fires.create(fire.x, fire.y, 'fire');
currentFire.animations.add('firedance', [0,1], 4, true);
currentFire.play('firedance');
}, this);
this.fires.setAll('body.allowGravity', false);
this.player = this.add.sprite(levelData.playerPosition.x, levelData.playerPosition.y, 'player', 3);
this.player.anchor.setTo(0.5,0.5);
this.player.animations.add('walking', [0, 1, 2, 1], 6, true);
this.player.properties = {};
this.game.physics.arcade.enable(this.player);
this.player.body.collideWorldBounds = true;
this.camera.follow(this.player);
this.createOnScreenControls();
},
update: function() {
this.game.physics.arcade.collide(this.player, this.ground);
this.game.physics.arcade.collide(this.player, this.platforms);
this.game.physics.arcade.overlap(this.player, this.fires, this.killPlayer);
this.player.body.velocity.x = 0;
if(this.cursors.left.isDown || this.player.properties.isMovingLeft) {
this.player.body.velocity.x = -this.PLAYER_SPEED;
this.player.scale.setTo(1,1);
this.player.play('walking');
}else if(this.cursors.right.isDown || this.player.properties.isMovingRight) {
this.player.body.velocity.x = this.PLAYER_SPEED;
this.player.scale.setTo(-1,1);
this.player.play('walking');
}else {
this.player.animations.stop();
this.player.frame = 4;
}
if((this.cursors.up.isDown || this.player.properties.isJumping )&& this.player.body.touching.down) {
this.player.body.velocity.y = -this.JUMP_SPEED;
}
},
createOnScreenControls: function() {
this.leftArrow = this.add.button(20, 535, 'arrowButton');
this.rightArrow = this.add.button(110, 535, 'arrowButton');
this.actionButton = this.add.button(280, 535, 'actionButton');
this.leftArrow.alpha = 0.5;
this.rightArrow.alpha = 0.5;
this.actionButton.alpha = 0.5;
this.leftArrow.fixedToCamera = true;
this.rightArrow.fixedToCamera = true;
this.actionButton.fixedToCamera = true;
this.leftArrow.events.onInputDown.add(function() {
this.player.properties.isMovingLeft = true;
}, this);
this.leftArrow.events.onInputUp.add(function() {
this.player.properties.isMovingLeft = false;
}, this);
this.rightArrow.events.onInputDown.add(function() {
this.player.properties.isMovingRight = true;
}, this);
this.rightArrow.events.onInputUp.add(function() {
this.player.properties.isMovingRight = false;
}, this);
this.actionButton.events.onInputDown.add(function() {
this.player.properties.isJumping = true;
}, this);
this.actionButton.events.onInputUp.add(function() {
this.player.properties.isJumping = false;
}, this);
},
killPlayer: function(player, fire) {
game.state.start('GameState');
},
render: function() {
game.debug.spriteInfo(this.player, 32, 32);
game.debug.body(this.player);
game.debug.spriteBounds(this.player, 'pink', false);
}
};
var game = new Phaser.Game(360, 592, Phaser.AUTO);
game.state.add('GameState',GameState);
game.state.start('GameState');
Anyone can help me with this issue ?
I understand your problem, your player physics body some how moved to right its not is center position. I can't give you solution without viewing proper code. I assumed that there is a line like this body.setSize(width, height, offsetX, offsetY); if there then comment out the line and see if its fix the issue. another solution set the anchor of the player - this.player.scale.setTo(-0.5, 0.5); if that solve your problem. In nutshell your player physics body moved to right of the player so that its occurring this wired problem.
SOLUTION (kind of) So I went ahead with editing the sprite & made a reflection & appended it on the right.. so now I have diff frames for right & diff for left but I still wasn't able to determine the reason of why that scale hack wasn't working.
Here's the new sprite:
Thank you everyone for your help.

Phaser: remove a circle previously drawn with drawCircle

In Phaser (2.4.x), I'm drawing a circle around a sprite when it is dragged:
function dragStart(sprite, pointer, dragX, dragY) {
var graphics = game.add.graphics(0, 0);
graphics.lineStyle(6, 0x909090, 0.3);
graphics.drawCircle(dragX, dragY, 200);
}
That works fine, but now I need to remove the circle when the drag ends, and I can't figure that part out:
function dragStop() {
// ?
}
Is it possible to remove graphics? Is there a better or simpler option to draw a circle and remove it later?
You could kill() the object
But be carefull with the scope of the var you want kill (you are defining it inside the function).
Or you could just create the graphic and then show or hide depending of your event (drag)
I leave you a very simple example with both solutions:
var game = new Phaser.Game(500, 500, Phaser.AUTO, 'game');
var mainState = {
create:function(){
var graphics = game.add.graphics(0, 0);
graphics.lineStyle(6, 0x909090, 0.3);
graphics.drawCircle(game.world.centerX+100,game.world.centerY+100, 200);
console.log(graphics);
setTimeout(function(){
graphics.kill();
},2000);
this.graphics2 = game.add.graphics(0, 0);
this.graphics2.lineStyle(6, 0xff0000, 1);
this.graphics2.drawCircle(game.world.centerX-100,game.world.centerY-100, 200);
this.graphics2.visible = false;
this.show_later = game.time.now + 2000;
this.hide_again = game.time.now + 4000;
},
update:function(){
if(this.show_later < game.time.now){
this.graphics2.visible = false;
}
if(this.hide_again < game.time.now){
this.graphics2.visible = true;
}
},
};
game.state.add('main', mainState);
game.state.start('main');
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.4.4/phaser.min.js"></script>
<div id="game"></div>

Control z-index in Fabric.js

In fabricjs, I want to create a scene in which the object under the mouse rises to the top of the scene in z-index, then once the mouse leaves that object, it goes back to the z-index where it came from. One cannot set object.zindex (which would be nice). Instead, I'm using a placeholder object which is put into the object list at the old position, and then the old object is put back in the position where it was in the list using canvas.insertAt. However this is not working.
See http://jsfiddle.net/rFSEV/ for the status of this.
var canvasS = new fabric.Canvas('canvasS', { renderOnAddition: false, hoverCursor: 'pointer', selection: false });
var bars = {}; //storage for bars (bar number indexed by group object)
var selectedBar = null; //selected bar (group object)
var placeholder = new fabric.Text("XXXXX", { fontSize: 12 });
//pass null or a bar
function selectBar(bar) {
if (selectedBar) {
//remove the old topmost bar and put it back in the right zindex
//PROBLEM: It doesn't go back; it stays at the same zindex
selectedBar.remove();
canvasS.insertAt(selectedBar, selectedBar.XZIndex, true);
selectedBar = null;
}
if (bar) {
//put a placeholder object ("XXX" for now) in the position
//where the bar was, and put the bar in the top position
//so it shows topmost
selectedBar = bar;
canvasS.insertAt(placeholder, selectedBar.XZIndex, true);
canvasS.add(bar);
canvasS.renderAll();
}
}
canvasS.on({
'mouse:move': function(e) {
//hook up dynamic zorder
if (!e.target) return;
if (bars[e.target])
selectBar(e.target);
else
selectBar(null);
},
});
var objcount = canvasS.getObjects().length;
//create bars
for (var i = 0; i < 20; ++i) {
var rect = new fabric.Rect({
left: 0,
top: 0,
rx: 3,
ry: 3,
stroke: 'red',
width: 200,
height: 25
});
rect.setGradientFill({
x1: 0,
y1: 0,
x2: 0,
y2: rect.height,
colorStops: {
0: '#080',
1: '#fff'
}
});
var text = new fabric.Text("Bar number " + (i+1), {
fontSize: 12
});
var group = new fabric.Group([ rect, text ], {
left: i + 101,
top: i * 4 + 26
});
group.hasControls = group.hasBorders = false;
//our properties (not part of fabric)
group.XBar = rect;
group.XZIndex = objcount++;
canvasS.add(group);
bars[group] = i;
}
canvasS.renderAll();
Since fabric.js version 1.1.4 a new method for zIndex manipulation is available:
canvas.moveTo(object, index);
object.moveTo(index);
I think this is helpful for your use case. I've updated your jsfiddle - i hope this is what you want:
jsfiddle
Also make sure you change z-index AFTER adding object to canvas.
So code will looks like:
canvas.add(object);
canvas.moveTo(object, index);
Otherwise fabricjs don`t care about z-indexes you setup.
After I added a line object, I was make the line appear under the object using:
canvas.add(line);
canvas.sendToBack(line);
Other options are
canvas.sendBackwards
canvas.sendToBack
canvas.bringForward
canvas.bringToFront
see: https://github.com/fabricjs/fabric.js/issues/135
You can modify your _chooseObjectsToRender method to have the following change at the end of it, and you'll be able to achieve css-style zIndexing.
objsToRender = objsToRender.sort(function(a, b) {
var sortValue = 0, az = a.zIndex || 0, bz = b.zIndex || 0;
if (az < bz) {
sortValue = -1;
}
else if (az > bz) {
sortValue = 1;
}
return sortValue;
});
https://github.com/fabricjs/fabric.js/pull/5088/files
You can use these two functions to get z-index of a fabric object and modify an object's z-index, since there is not specific method to modify z-index by object index :
fabric.Object.prototype.getZIndex = function() {
return this.canvas.getObjects().indexOf(this);
}
fabric.Canvas.prototype.moveToLayer = function(object,position) {
while(object.getZIndex() > position) {
this.sendBackwards(object);
}
}

Resources