I'm running into a bit of an odd issue with Paper.js - I'm using the library to scale the "petals" of a randomly generated flower while audio plays.
The issue crops up if the flower is "growing" and the user navigates to a different tab in the browser. Even though it appears that the onFrame event is not firing when the window is out of view, whichever petal is currently scaling at the time will continue to scale indefinitely.
I even tried using a special js library to determine if the window is in view and still wasn't able to get the petals to stop scaling.
You can view a demo here, as I was not even able to replicate this in a Paper sketch: https://demos2.paperbeatsscissors.com/
Also including my onFrame code here in case the problem is obvious to someone:
view.onFrame = function(event) {
// See if something is playing
if (playing > -1) {
// Get the active flower
var activeFlower = garden[playing],
activeData = activeFlower.data;
// Active layer and petal
var activeLayer = getEl(activeFlower, activeData.lIndex),
activePetal = getEl(activeLayer, activeData.pIndex);
// Variables
var time = activeData.audio.seek(),
scaleAmount = (1 / (activeData.timing / event.delta.toFixed(3))) * 2;
// Petal progression
if (!activeData.completed) {
if (activePetal.scaling.x < 1 && activePetal.scaling.y < 1) {
activePetal.pivot = {x: 0, y: activePetal.height / 2};
activePetal.scaling.x = activePetal.scaling.x + scaleAmount;
activePetal.scaling.y = activePetal.scaling.y + scaleAmount;
} else {
if (activeData.pIndex < (activeLayer.children.length - 1)) {
// If the petal is scaled, jump to a new petal
activeData.pIndex += 1;
} else {
if (activeData.lIndex > 0) {
// When all petals are bloomed, jump to a new layer
activeData.pIndex = 0;
activeData.lIndex -= 1;
} else {
// Set the flower as completed
activeData.completed = true;
}
}
}
}
activeFlower.rotate(.125, activeData.center);
// Reset the playing variable if the audio clip is complete and the flower has completed
if (!activeData.audio.playing() && time === 0 && activeData.completed) {
playing = -1;
}
}
}
Really stumped on this one so any help is greatly appreciated!
I think that your problem is coming from the fact that you base your scaling calculation on event.delta which represents the time elapsed since the last event fired.
The thing is that, if I'm not mistaken, under the hood, Paper.js onFrame event relies on requestAnimationFrame which does not fire when the tab if inactive.
So when you switch tab, wait for a while and get back to your tab event.delta value is big and your scaling value too, hence the size of your petals. This basic sketch showcase this behavior.
So in my opinion, you should simply check event.delta value and limit it if it's too high.
I am currently working on a small scale game for my project. My goal is for the 'player' to navigate through a group of enemies without touching them. To make the player die, I intend to listen for the coordinates of the animating 'Circle' and look for an event whereby the distance between the player and the enemy is 0. Is there a way to listen to the animating coordinates of the circle because currently, it is listening to where my mouse clicked rather than where the circle actually is when it is animating.
bg.node.addEventListener("mousedown",function(ev){
console.log("mouse is down");
if(ev.button==2){
char.animate({
'cx':ev.offsetX,
'cy':ev.offsetY
},900,"linear")
charX = ev.offsetX;
charY=ev.offsetY;
}
let drawT = function(){
let n=0;
while(n<numDisk){
diskT[n].xpos += diskT[n].xrate;
diskT[n].ypos += diskT[n].yrate;
// Now actually move the disk on screen using our 'state' variables
diskT[n].attr({'cx': diskT[n].xpos, 'cy': diskT[n].ypos});
// keep the object on the paper
if (diskT[n].xpos > dimX)
{diskT[n].xrate = -diskT[n].xrate};
if (diskT[n].ypos > dimY) {
diskT[n].ypos = dimY
diskT[n].yrate = - diskT[n].yrate};
if (diskT[n].xpos < 0)
{diskT[n].xrate = -diskT[n].xrate};
if (diskT[n].ypos < 0) {
diskT[n].ypos = 0
diskT[n].yrate = - diskT[n].yrate};
if(distance(charX,diskT[n].xpos,charY,diskT[n].ypos)<=30){
confirm("You died!");
These are my codes for animating the movement of the character and how I intend to make the character die. The disks in the array are the enemies.
I have written a function loja() in an external js. In another html file, at the end of the file I have linked it to the external js and then at the body of the html file I have created a div and onclick it will call the function loja(). It all works well but the thing is that the javascript function is not loaded inside the div but at the end of the page.Can you help me out?
This is from html file.
<div class="section-title" onclick="loja()">Luaj
</div>
This one is the javascript file.
// Create our 'main' state that will contain the game
function loja(){
var mainState = {
preload: function() {
game.load.image('bird', 'assets/car.png');
game.load.image('pipe', 'assets/pipe.png');
game.load.audio('jump', 'assets/jump.wav');
game.load.image('background', 'assets/background.png');
},
create: function() {
game.add.tileSprite(0, 0, 1000, 600, 'background');
// Set the physics system
game.physics.startSystem(Phaser.Physics.ARCADE);
// Display the bird at the position x=100 and y=245
this.bird = game.add.sprite(100, 245, 'bird');
// Add physics to the bird
// Needed for: movements, gravity, collisions, etc.
game.physics.arcade.enable(this.bird);
// Add gravity to the bird to make it fall
this.bird.body.gravity.y = 1000;
// Call the 'jump' function when the spacekey is hit
var spaceKey = game.input.keyboard.addKey(
Phaser.Keyboard.SPACEBAR);
spaceKey.onDown.add(this.jump, this);
// Create an empty group
this.pipes = game.add.group();
this.timer = game.time.events.loop(1500, this.addRowOfPipes, this);
this.score = 0;
this.labelScore = game.add.text(20, 20, "0",
{ font: "30px Arial", fill: "#ffffff" });
// Move the anchor to the left and downward
this.bird.anchor.setTo(-0.2, 0.5);
this.jumpSound = game.add.audio('jump');
},
update: function() {
// If the bird is out of the screen (too high or too low)
// Call the 'restartGame' function
if (this.bird.y < 0 || this.bird.y > 490)
this.restartGame();
game.physics.arcade.overlap(
this.bird, this.pipes, this.hitPipe, null, this);
if (this.bird.angle < 20)
this.bird.angle += 1;
},
// Make the bird jump
jump: function() {
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -300;
// Create an animation on the bird
var animation = game.add.tween(this.bird);
// Change the angle of the bird to -20° in 100 milliseconds
animation.to({angle: -20}, 100);
// And start the animation
animation.start();
if (this.bird.alive == false)
return;
this.jumpSound.play();
},
// Restart the game
restartGame: function() {
// Start the 'main' state, which restarts the game
game.state.start('main');
},
addOnePipe: function(x, y) {
// Create a pipe at the position x and y
var pipe = game.add.sprite(x, y, 'pipe');
// Add the pipe to our previously created group
this.pipes.add(pipe);
// Enable physics on the pipe
game.physics.arcade.enable(pipe);
// Add velocity to the pipe to make it move left
pipe.body.velocity.x = -200;
// Automatically kill the pipe when it's no longer visible
pipe.checkWorldBounds = true;
pipe.outOfBoundsKill = true;
},
addRowOfPipes: function() {
// Randomly pick a number between 1 and 5
// This will be the hole position
var hole = Math.floor(Math.random() * 5) + 1;
// Add the 6 pipes
// With one big hole at position 'hole' and 'hole + 1'
for (var i = 0; i < 8; i++)
if (i != hole && i != hole + 1)
this.addOnePipe(400, i * 60 + 10);
this.score += 1;
this.labelScore.text = this.score;
},
hitPipe: function() {
// If the bird has already hit a pipe, do nothing
// It means the bird is already falling off the screen
if (this.bird.alive == false)
return;
// Set the alive property of the bird to false
this.bird.alive = false;
// Prevent new pipes from appearing
game.time.events.remove(this.timer);
// Go through all the pipes, and stop their movement
this.pipes.forEach(function(p){
p.body.velocity.x = 0;
}, this);
},
};
// Initialize Phaser, and create a 400px by 490px game
var game = new Phaser.Game(600, 800);
// Add the 'mainState' and call it 'main'
game.state.add('main', mainState);
// Start the state to actually start the game
game.state.start('main');
}
Where javascript code appears in your page in this case seems out of point.
You linked it at the end of file? Than it will appear at the end of file.
What I understand you want is your code to interact with some part of a html file structure, called DOM, some DIV tag in particular.
You need to use Javascript to interact with that DIV node. Probably to render your game inside of it.
In your JS file I only see definition and some method calls. I cant see part that would render some content into DOM.
Summarizing: place where your javascript methods definitions are it not the same place where effects of execution of those methods will appear.
It looks like you're trying to implement an open-source Phaser game (https://github.com/photonstorm/phaser/blob/v2.4.4/src/core/Game.js)
Since your issue is with functionality regarding that framework, that should be your starting place for information. Also you shouldn't leave out important information like any framework you're using when asking for help (especially since in this case the issue is only that you're not using the it properly).
If you look at the fourth parameter it actually allows you to specify a DOM parent, it accepts either the ID or the element itself. So you could just do something like this after inserting another element in your HTML with the ID pgame:
var game = new Phaser.Game(600, 800, void(0), 'pgame');
I found this codepen.io for the game 2048: http://codepen.io/anon/pen/dMzmae
The game is written in JavaScript with a GameManager, HTMLActuator to create the HTML elements, a ScoreManager to keep track of the score and a KeyboardInputManager to track what is pressed and what to do.
The application uses window.requestAnimationFrame to redraw the window. I was wondering how it does that. When the code actuates, it uses the window.requestAnimationFrame() and inside for each cell in the grid it uses the addTile() method to add each tile to the DOM.
HTMLActuator.prototype.actuate = function (grid, metadata) {
var self = this;
window.requestAnimationFrame(function () {
self.clearContainer(self.tileContainer);
grid.cells.forEach(function (column) {
column.forEach(function (cell) {
if (cell) {
self.addTile(cell);
}
});
});
self.updateScore(metadata.score);
if (metadata.over) self.message(false); // You lose
if (metadata.won) self.message(true); // You win!
});
};
If you look at the addTime() method, it too has a window.requestAnimationFrame method that updates the class with the currentPosition if the tile it's adding had a previousPosition property:
HTMLActuator.prototype.addTile = function (tile) {
var self = this;
var element = document.createElement("div");
var position = tile.previousPosition || { x: tile.x, y: tile.y };
positionClass = this.positionClass(position);
// We can't use classlist because it somehow glitches when replacing classes
var classes = ["tile", "tile-" + tile.value, positionClass];
this.applyClasses(element, classes);
element.textContent = tile.value;
if (tile.previousPosition) {
// Make sure that the tile gets rendered in the previous position first
window.requestAnimationFrame(function () {
classes[2] = self.positionClass({ x: tile.x, y: tile.y });
self.applyClasses(element, classes); // Update the position
});
} else if (tile.mergedFrom) {
classes.push("tile-merged");
this.applyClasses(element, classes);
// Render the tiles that merged
tile.mergedFrom.forEach(function (merged) {
self.addTile(merged);
});
} else {
classes.push("tile-new");
this.applyClasses(element, classes);
}
// Put the tile on the board
this.tileContainer.appendChild(element);
};
I guess I'm wondering how does this requestAnimationFrame work to correctly display the tiles when moved? It's building up each tile with the tile information in the grid. Then in addTile() it first uses the tile's previousPosition to build a tile that used to be on the board and creates a class for that position but then it checks if the tile has a previous position and updates the class back to the tile's new position on the grid.
But that only happens in a requestAnimationFrame method for tiles with a previous position and before the method finishes and appends the tile to the tile container in the DOM.
I hope the question makes sense. Are those nested window.RequestAnimationFrame's in the addTile method() called right after the original window.RequestAnimationFrame call in the HTMLActuator.prototype.actuate method so it moves to the new position after an instant and the CSS transition shows it moving?
I can't seem to remove a sprite from the HTML 5 canvas.
function collision_detect(a,b){
if(Neither the enemy or the bullet exist){
return;
}else if(the bullet position is the same as the enemy position){
console.log("Test")
destroyed=true;
}
else
{
destroyed=false;
}
}
The if/else statement works fine, "Test" is logged to the console every time a bullet collides with the enemy.
Here is where I am having a problem-in the game loop function.
if((enemy[x] !==null) && (destroyed===true)){
enemy[x]=null;
}
How can I make this work?