Javascript: Why does my Raphaeljs animation lag? It's not even consistent - javascript

I have an animation of an abstract character who is to rotate 90 degrees in time with the beat of a song (which hasn't been added yet), but when I click the play button, I start a loop of functions and my character lags inconsistently and I don't know why. If anyone could help me out, I'd really appreciate the help.
window.onload = function()
{
var paper = new Raphael(0,0,800,600);
var backGround = paper.rect(0,0,800,600).attr({fill: "#AAAAAA"});
var outerBody = paper.circle(300,400,60);
var innerBody = paper.circle(300,400,45);
//Initially bottom foot
var foot1pt1 = paper.path(["M300,490 C300,470 340,470 340,490z"]); //main foot shape (semi circle)
var foot1pt2 = paper.path(["M300,490L340,490"]); //bottom of foot
var foot1pt3 = paper.path(["M300,460L300,490"]); //leg
//Initially right foot
var foot2pt1 = paper.path(["M390,360 C370,360 370,400 390,400z"]);
var foot2pt2 = paper.path(["M390,400L390,360"]);
var foot2pt3 = paper.path(["M360,400L390,400"]);
//Initially top foot
var foot3pt1 = paper.path(["M260,310 C260,330 300,330 300,310z"]);
var foot3pt2 = paper.path(["M300,310L260,310"]);
var foot3pt3 = paper.path(["M300,340L300,310"]);
//Initially left foot
var foot4pt1 = paper.path(["M210,400 C230,400 230,440 210,440z"]);
var foot4pt2 = paper.path(["M210,400L210,440"]);
var foot4pt3 = paper.path(["M240,400L210,400"]);
//Modifying parts
outerBody.attr({fill: "#000000"});
innerBody.attr({fill: "#AAAAAA"});
foot1pt1.attr({fill: "#000000"});
foot2pt1.attr({fill: "#000000"});
foot3pt1.attr({fill: "#000000"});
foot4pt1.attr({fill: "#000000"});
//Grouping whole character
var character = paper.set();
character.push(
outerBody,innerBody,
foot1pt1,foot1pt2,foot1pt3,
foot2pt1,foot2pt2,foot2pt3,
foot3pt1,foot3pt2,foot3pt3,
foot4pt1,foot4pt2,foot4pt3
);
//Animation variables
var rotationOne = Raphael.animation({transform:"R90,300,400"},150,'ease-in',rotationTwoFunc);
var rotationTwo = Raphael.animation({transform:"R0,300,400"},0,'ease-in',rotationOneFunc);
function rotationOneFunc() {
character.animate(rotationOne.delay(300));
}
function rotationTwoFunc() {
character.animate(rotationTwo.delay(300));
}
var overlayBackground = paper.rect(0,0,800,600).attr({fill: "#555", opacity: "0.6"});
var playIcon = paper.path(["M11.166,23.963L22.359,17.5c1.43-0.824,1.43-2.175,0-3L11.166,8.037c-1.429-0.826-2.598-0.15-2.598,1.5v12.926C8.568,24.113,9.737,24.789,11.166,23.963z"]);
playIcon.attr({fill: "#000", stroke: "none"}).transform("t388.834,276.037 s6,6");
var playButtonOverlay = paper.set();
playButtonOverlay.push(
overlayBackground,
playIcon
);
//Hovering over the play button
playIcon.hover (
function() { //Hover in animation
playIcon.animate({fill: "#410000"});},
function() { //Hover out animation
playIcon.animate({fill: "#000"});}
);
//Start animation clicking on play button
playIcon.click (function() {
playButtonOverlay.animate({opacity: 0}, 300);
rotationOneFunc();
});
};

If you want to have transition continuously, you need to add ... in front of every transform string like the one below:
transform:"...R90,300,400"

Related

How do I remove setInterval from progress bar in Javascript and make appear the VerticalBar instantaneously?

I have the classical Progress bar in Javascript. I Would like to simply place the vertical bar without seeing it moving on the screen.
function progressbar() {
var vertical_bar2 = document.querySelector("#P5 .vl5");
var element = document.getElementById("myprogressBar");
var ValueSet = 25
var width = 0;
document.getElementById("vl5").style.display='';
document.getElementById("value2").style.display='';
document.getElementById("value1").style.display='';
var identity = setInterval(scene, 10);
function scene() {
if (width >= ValueSet) {
clearInterval(identity);
} else {
width++;
vertical_bar2.style.left = `${width}%`;
document.getElementById("value2").innerHTML = ValueSet
}
}
}
I am trying the following script but it is not working
function progressbar() {
var vertical_bar2 = document.querySelector("#P5 .vl5");
var element = document.getElementById("progressBar");
var CE = 25
var width = 0;
document.getElementById("vl5").style.display='';
document.getElementById("Value2").style.display='';
document.getElementById("Value1").style.display='';
vertical_bar2.style.left = 25;
document.getElementById("Value").innerHTML = CE
}
Based on the code your provided, it looks like you just need to set a unit for the left property of your bar. Currently you are only setting a value (25), but without a unit (%, px, em, etc.) it will not apply anything.
vertical_bar2.style.left = "25%";
or
vertical_bar2.style.left = `${CE}%`;

Javascript - "print" mouse on document by cords

I have list of mouse cords (x,y)
Because it is impossible to move mouse with javascript, I would like to print a fake mouse on the document followed by the cords that I already have.
Is it possible? How?
My solution was to print PNG that shows the mouse and hide the original one with css:
createCursor: function() {
var cursor = document.createElement("img");
cursor.src = chrome.extension.getURL('pics/cursor.png');
cursor.style.zIndex = "9999";
cursor.setAttribute("id", "recordMeCursor");
var body = document.getElementsByTagName("BODY")[0];
body.style.cursor = 'none';
body.appendChild(cursor);
},
moveCursor: function(cords, i, callback) {
var cursor = document.getElementById("recordMeCursor");
setTimeout(function() {
cursor.style.position = "absolute";
cursor.style.left = cords.x+'px';
cursor.style.top =cords.y+'px';
return callback('OK');
}, i * 50);
},
destroyMouse: function() {
var cursor = document.getElementById("recordMeCursor");
cursor.parentNode.removeChild(cursor);
var body = document.getElementsByTagName("BODY")[0];
body.style.cursor = 'default';
}

How to remove a tween with createjs

I have a clock hand that rotates as a timer. If the user completed activity before the time runs out I need to stop that tween.
I tried remove tween with no luck. What am I doing wrong?
I get into my levelup function but the remove tween does not work.
function Clock() {
// this.board = board;
clockContainer = new createjs.Container();
contain = new createjs.Container();
var clockBack = new createjs.Bitmap(queue.getResult("clockBack"));
clockHand = new createjs.Bitmap(queue.getResult("clockHand"));
clockBack.x = 40;
clockBack.y = 480;
clockHand.x = 95;
clockHand.y = 539;
clockHand.regX = 20
clockHand.regY = 105;
clockHand.scaleX = clockHand.scaleY = 0.50;
clockBack.scaleX = clockBack.scaleY = 0.50;
clockContainer.addChild(clockBack, clockHand);
TimerLength = 30000;
stage.addChild(clockContainer)
mytweentodisable = createjs.Tween.get(clockHand, { loop: false }).to({ rotation: 360 }, TimerLength).call(function () {
//this will trigger the timer is up
GamehasEnded = true;
checkWrongAndRight();
});
}
function levelUp() {
createjs.Tween.removeTweens(mytweentodisable)
console.log("adding Level up button");
levelUpContainer = new createjs.Container();
levelUpIcon = new createjs.Bitmap(queue.getResult("levelUp"));
levelUpContainer.addChild(levelUpIcon);
stage.addChild(levelUpContainer)
levelUpContainer.x = 350
levelUpContainer.y = 500
levelUpContainer.addEventListener("click", function () {
console.log("clicked it");
});
}
This should do the trick:
mytweentodisable.setPaused(true);

Creating a click event in Javascript Canvas

I'm having trouble creating a click event for my Javascript canvas game. So far I have been following a tutorial, however the way you interact with the game is through mouse hover. I would like to change it so that instead of hovering over objects in the canvas to interact, I instead use a mouse click.
The following is the code I use to detect the mouse hover.
getDistanceBetweenEntity = function (entity1,entity2) //return distance
{
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx*vx+vy*vy);
}
testCollisionEntity = function (entity1,entity2) //return if colliding
{
var distance = getDistanceBetweenEntity(entity1,entity2);
return distance < 50;
}
I then use this in a loop to interact with it.
var isColliding = testCollisionEntity(player,nounList[key]);
if(isColliding)
{
delete nounList[key];
player.score = player.score + 10;
}
Below is a complete copy of my game at its current state.
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
<script>
var ctx = document.getElementById("ctx").getContext("2d");
ctx.font = '30px Arial';
//Setting the height of my canvas
var HEIGHT = 500;
var WIDTH = 500;
//Player class
var player =
{
x:50,
spdX:30,
y:40,
spdY:5,
name:'P',
score:0,
};
//Creating arrays
var nounList ={};
var adjectivesList ={};
var verbsList ={};
getDistanceBetweenEntity = function (entity1,entity2) //return distance
{
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx*vx+vy*vy);
}
testCollisionEntity = function (entity1,entity2) //return if colliding
{
var distance = getDistanceBetweenEntity(entity1,entity2);
return distance < 50;
}
Nouns = function (id,x,y,name)
{
var noun =
{
x:x,
y:y,
name:name,
id:id,
};
nounList[id] = noun;
}
Adjectives = function (id,x,y,name)
{
var adjective =
{
x:x,
y:y,
name:name,
id:id,
};
adjectivesList[id] = adjective;
}
Verbs = function (id,x,y,name)
{
var verb =
{
x:x,
y:y,
name:name,
id:id,
};
verbsList[id] = verb;
}
document.onmousemove = function(mouse)
{
var mouseX = mouse.clientX;
var mouseY = mouse.clientY;
player.x = mouseX;
player.y = mouseY;
}
updateEntity = function (something)
{
updateEntityPosition(something);
drawEntity(something);
}
updateEntityPosition = function(something)
{
}
drawEntity = function(something)
{
ctx.fillText(something.name,something.x,something.y);
}
update = function ()
{
ctx.clearRect(0,0,WIDTH,HEIGHT);
drawEntity(player);
ctx.fillText("Score: " + player.score,0,30);
for(var key in nounList)
{
updateEntity(nounList[key]);
var isColliding = testCollisionEntity(player,nounList[key]);
if(isColliding)
{
delete nounList[key];
player.score = player.score + 10;
}
}
for(var key in adjectivesList)
{
updateEntity(adjectivesList[key])
var isColliding = testCollisionEntity(player,adjectivesList[key]);
if(isColliding)
{
delete adjectivesList[key];
player.score = player.score - 1;
}
}
for(var key in verbsList)
{
updateEntity(verbsList[key])
var isColliding = testCollisionEntity(player,verbsList[key]);
if(isColliding)
{
delete verbsList[key];
player.score = player.score - 1;
}
}
if(player.score >= 46)
{
ctx.clearRect(0,0,WIDTH,HEIGHT);
ctx.fillText("Congratulations! You win!",50,250);
ctx.fillText("Refresh the page to play again.",50,300);
}
}
Nouns('N1',150,350,'Tea');
Nouns('N2',400,450,'Park');
Nouns('N3',250,150,'Knee');
Nouns('N4',50,450,'Wall');
Nouns('N5',410,50,'Hand');
Adjectives('A1',50,100,'Broken');
Adjectives('A2',410,300,'Noisy');
Verbs('V1',50,250,'Smell');
Verbs('V2',410,200,'Walk');
setInterval(update,40);
To summarize all I want to do is change it so that instead of mousing over words to delete them you have to click.
(Apologies for not using correct terminology in places, my programming knowledge is quite limited.)
You can have your canvas listen for mouse clicks on itself like this:
// get a reference to the canvas element
var canvas=document.getElementById('ctx');
// tell canvas to listen for clicks and call "handleMouseClick"
canvas.onclick=handleMouseClick;
In the click handler, you'll need to know the position of your canvas relative to the viewport. That's because the browser always reports mouse coordinates relative to the viewport. You can get the canvas position relative to the viewport like this:
// get the bounding box of the canvas
var BB=canvas.getBoundingClientRect();
// get the left X position of the canvas relative to the viewport
var BBoffsetX=BB.left;
// get the top Y position of the canvas relative to the viewport
var BBoffsetY=BB.top;
So your mouseClickHandler might look like this:
// this function will be called when the user clicks
// the mouse in the canvas
function handleMouseClick(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the canvas postion relative to the viewport
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
// calculate the mouse position
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// report the mouse position using the h4
$position.innerHTML='Click at '+parseInt(mouseX)+' / '+parseInt(mouseY);
}
If your game doesn't let the window scroll or resize then the canvas postion won't change relative to the viewport. Then, for better performance, you can move the 3 lines relating to getting the canvas position relative to the viewport to the top of your app.
// If the browser window won't be scrolled or resized then
// get the canvas postion relative to the viewport
// once at the top of your app
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
function handleMouseClick(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calculate the mouse position
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// report the mouse position using the h4
$position.innerHTML='Click at '+parseInt(mouseX)+' / '+parseInt(mouseY);
}

How to stop sprite size changes from stopping collision detection in Phaser?

I am developing a small JavaScript game with Phaser and I have a sprite that changes its size at certain points. It does this with the sprite.body.setSize method. However, it looks like the sprite stops colliding with objects that it should be colliding with when it is changing size. I understand why it does this, since the sprite's boundaries are in a state of flux during a change of size, but I'm afraid my user can take advantage of this problem and move through walls. I'm not sure how to get the sprite to be responsive to collisions while it's in the process of changing size. Is there a way to prevent this?
Edit at Supamiu's request:
Here is a quick example of what I'm trying to do in my game. Also, here is the source code for that example.
// Global constants
var GAME_WIDTH = 800;
var GAME_HEIGHT = 600;
var TEXT_X_POS = 150;
var TEXT_Y_POS = 50;
var PHASER_DUDE_WIDTH = 27;
var PHASER_DUDE_HEIGHT = 40;
var MASTER_WIDTH = 57;
var MASTER_HEIGHT = 77;
var SPRITE_X_POS = 200;
var SPRITE_Y_POS = 400;
var SPRITE_GRAVITY = 300;
var LEFT_VELOCITY = -300;
var RIGHT_VELOCITY = 300;
var JUMP_VELOCITY = -300;
var STOPPED = 0;
var WALL_X_POS = 500;
var WALL_Y_POS = 300;
// Global variables
var sprite;
var wall;
var cursors;
var game = new Phaser.Game(GAME_WIDTH, GAME_HEIGHT, Phaser.AUTO, "game", {preload: preload, create: create, update: update});
function preload () {
game.load.image("master", "sprites/master.png");
game.load.image("phaser dude", "sprites/phaser_dude.png");
game.load.image("wall", "sprites/wall.png");
}
function create () {
game.add.text(TEXT_X_POS, TEXT_Y_POS, "Use the cursor keys to jump and move", {fontSize: "16px", fill: "white"});
sprite = game.add.sprite(SPRITE_X_POS, SPRITE_Y_POS, "master");
game.physics.arcade.enable(sprite);
sprite.body.collideWorldBounds = true;
sprite.body.gravity.y = SPRITE_GRAVITY;
wall = game.add.sprite(WALL_X_POS, WALL_Y_POS, "wall");
game.physics.arcade.enable(wall);
wall.body.immovable = true;
cursors = game.input.keyboard.createCursorKeys();
}
function update () {
game.physics.arcade.collide(sprite, wall);
sprite.body.velocity.x = STOPPED;
cursors.up.onDown.add(jump);
if (cursors.left.isDown) {
sprite.body.velocity.x = LEFT_VELOCITY
}
if (cursors.right.isDown) {
sprite.body.velocity.x = RIGHT_VELOCITY;
}
if (sprite.isJumping && sprite.body.onFloor()) {
sprite.isJumping = false;
sprite.loadTexture("master");
sprite.body.setSize(MASTER_WIDTH, MASTER_HEIGHT);
}
}
function jump () {
sprite.isJumping = true;
sprite.body.velocity.y = JUMP_VELOCITY;
sprite.loadTexture("phaser dude");
sprite.body.setSize(PHASER_DUDE_WIDTH, PHASER_DUDE_HEIGHT);
}
You can see that if you push on the left side of the wall as the sprite changes size (and texture), it can move through the wall.
if you don't want users to usebug this, make them go back to the start of the wall if they are trying to go through it.
like this:
U is the user
|| is a wall
||
U ||
||
||
The start
||
|U|
||
||
Oh, U is going through a wall !
||
U ||
||
||
U goes to the start of the wall.
or you can make the user unable to move while you change his size
EDIT:
there is two more solutions, set the walls with bounds system with a 0 value for bouncing:
function create () {
game.add.text(TEXT_X_POS, TEXT_Y_POS, "Use the cursor keys to jump and move", {fontSize: "16px", fill: "white"});
sprite = game.add.sprite(SPRITE_X_POS, SPRITE_Y_POS, "master");
game.physics.arcade.enable(sprite);
sprite.body.collideWorldBounds = true;
sprite.body.gravity.y = SPRITE_GRAVITY;
wall = game.add.sprite(WALL_X_POS, WALL_Y_POS, "wall");
game.physics.arcade.enable(wall);
wall.body.immovable = true;
//here is what i added
wall.body.collideWorldBounds = true;
wall.body.bounce.set(0);
cursors = game.input.keyboard.createCursorKeys();
}
or make the sprite body immovble while you change his size:
function update () {
game.physics.arcade.collide(sprite, wall);
sprite.body.velocity.x = STOPPED;
cursors.up.onDown.add(jump);
if (cursors.left.isDown) {
sprite.body.velocity.x = LEFT_VELOCITY
}
if (cursors.right.isDown) {
sprite.body.velocity.x = RIGHT_VELOCITY;
}
if (sprite.isJumping && sprite.body.onFloor()) {
sprite.isJumping = false;
sprite.loadTexture("master");
//Here is what i added
sprite.body.velocity.x = STOPPED;
sprite.body.setSize(MASTER_WIDTH, MASTER_HEIGHT);
}
}

Categories