Javascript function draw - javascript

var random = randomNumber(1, 7);
var Block = createSprite(200, 0);
var Blocks = createGroup();
Blocks.add(Block);
Blocks.setAnimationEach(random.toString());
createEdgeSprites();
function draw() {
background("white");
Move("down", 4, 1);
Move2("right", 4, 0, "left");
Move2("left", -4, 0, "right");
if (Blocks.isTouching(bottomEdge)) {
var Block = createSprite(200, 0);
Blocks.add(Block);
Blocks.setAnimationEach(randomNumber(1, 7).toString());
}
if (Blocks.isTouching(edges)) {
Blocks.collide(edges);
}
drawSprites();
}
function Move(Key, Velocity, Velocity2) {
if (keyDown(Key)) {
Block.velocityY = Velocity;
} else {
Block.velocityY = Velocity2;
}
}
function Move2(Key, Velocity, Velocity2, Key2) {
if (keyDown(Key)) {
Block.velocityX = Velocity;
} else if ((!keyDown(Key2))) {
Block.velocityX = Velocity2;
}
}
My issue is with
if (Blocks.isTouching(bottomEdge)) {
var Block = createSprite(200, 0);
Blocks.add(Block);
Blocks.setAnimationEach(randomNumber(1, 7).toString());
}
That code is basically for when a piece touches the ground, a new piece is made with a random Animation, that is the shape. I know I have to fix other stuff, but I know how to fix it. The thing I don't know how to do is set an animation once? Is there a code for that, because it constantly randomly changes the animation because the function draw() runs multiple times. But if I put it outside of that function, it only runs in the beginning of the program. Should I like push my sprite back up a little afterwards? I can't use const and I don't even know how to use it. Each time a sprite touches the ground, I want a new sprite to made and that animation is only set once. My biggest issue is that, I know there are other issues in that segment, but I can fix it myself

Related

Performance on Phaser.js

function preload() {
this.load.image('background', 'images/table_en.png.webp');
this.load.image('wheel', 'images/UpperWheel.png.webp');
this.load.image('ball', 'images/ball.png.webp');
roulette.circle.array.forEach(i => {
this.load.image(`${i.index}`, i.src);
});
roulette.lever.array.forEach(i => {
this.load.image(`${i.index}`, i.src)
});
}
function update() {
if (roulette.circle.previousCircle) {
roulette.circle.previousCircle.destroy()
}
if (roulette.circle.previousLever) {
roulette.circle.previousLever.destroy();
}
if (roulette.circle.currentStep === 100 && run) {
ball.run = true;
}
let circle = this.add.image(108, 110, `circle${roulette.circle.currentStep}`).setOrigin(0, 0).setScale(0.7);
let lever = this.add.image(200, 150, `lever${roulette.lever.currentStep}`).setOrigin(0, 0).setScale(0.7);
roulette.circle.method();
roulette.lever.method();
roulette.circle.previousCircle = circle;
roulette.circle.previousLever = lever;
}
I am writing roulette, where 359 pictures fall on a wheel (considering all its conditions). I uploaded all these pictures in the preload function, and in the update function I simply create the downloaded picture and delete the previous one. All this affects productivity (because the speed of changing images can be different). How to solve this problem?
Perhaps if i reduce the speed of the change of pictures, the problem would be solved, but I do not know how to do it
The update() method is called once per frame. The default target frames per second (fps) in Phaser games is 60 - API Reference.
Many factors in your game can influence the actual fps that you'll see. If you leave it at default, your update() method is being called approximately 60x per second. If you want the user to actually be able to see each image, this is probably not desired behavior.
You could lower the target fps number in your game config like this:
{
type: Phaser.AUTO,
...,
fps: {
target: 30 // 30x per second
}
}
... but that can be imperfect. It is a global change to your game's update speed and there may be other things you want to happen 60x per second (like checking for input, etc.).
To change how often your images change without modifying your game's fps, consider creating a separate method to handle the destroy/create of images and reference that method inside update().
function update() {
if (!changingImage) {
changingImage = true;
changeImage();
}
}
function changeImage() {
if (roulette.circle.previousCircle) {
roulette.circle.previousCircle.destroy()
}
if (roulette.circle.previousLever) {
roulette.circle.previousLever.destroy();
}
if (roulette.circle.currentStep === 100 && run) {
ball.run = true;
}
let circle = this.add.image(108, 110, `circle${roulette.circle.currentStep}`).setOrigin(0, 0).setScale(0.7);
let lever = this.add.image(200, 150, `lever${roulette.lever.currentStep}`).setOrigin(0, 0).setScale(0.7);
roulette.circle.method();
roulette.lever.method();
roulette.circle.previousCircle = circle;
roulette.circle.previousLever = lever;
changeImage = true;
}
If it's still happening too quickly, consider wrapping the changeImage boolean in a timeout to further delay how often your images get updated.
setTimeout(() => {
changingImage = true;
}, 1000);

Save mouse location then have a second value that updates

I'm using the Phaser engine, and I want to have a line be drawn on a click and hold event from the initial mouse position and have it constantly update to draw to the mouse position as it moves. My problem is that when i try to store the initial mouse position it keeps changing. This seems like a simple problem but i'm not very good with this stuff. Here is the code:
var unitLine;
if(game.input.activePointer.isDown) {
const firstX = game.input.x;
const firstY = game.input.y;
unitLine = game.add.graphics(100, 100);
unitLine.beginFill(0xFF3300);
unitLine.lineStyle(10, 0xffd900, 1);
unitLine.moveTo(firstX, firstY);
unitLine.lineTo(game.input.x, game.input.y);
}
that firstX and firstY are changing even when i declare them as a const. Not sure what to do here.
The problem is that you're setting firstX and firstY whenever the mouse isDown, so they're basically overwritten every frame that the mouse is down.
To get around this, try using Phaser's game.input.onDown function:
var game = new Phaser.Game(500, 500, Phaser.CANVAS, 'test', {
preload: preload,
create: create,
update: update
});
function preload() {}
let firstX;
let firstY;
function create() {
game.input.onDown.add(function() {
firstX = game.input.x;
firstY = game.input.y;
}, this);
}
var unitLine;
function update() {
if (game.input.activePointer.isDown) {
unitLine = game.add.graphics(0, 0);
unitLine.beginFill(0xFF3300);
unitLine.lineStyle(10, 0xffd900, 1);
unitLine.moveTo(firstX, firstY);
unitLine.lineTo(game.input.x, game.input.y);
}
}
<script src="https://github.com/photonstorm/phaser-ce/releases/download/v2.11.1/phaser.min.js"></script>
(Also, I had to change the 100, 100 to 0, 0)
It's because you're declaring them in the statement, so the declaration is newly hit each time and the variables are created afresh.
Firsly, you need to create the variables outside of the statement.
And then, to fix your issue, I would use a bool to lock them in.
Something like this:
var unitLine;
var firstX;
var firstY;
var needToset_XY = true;
if(game.input.activePointer.isDown) {
if(needToset_XY){
firstX = game.input.x;
firstY = game.input.y;
needToset_XY = false;
}
unitLine = game.add.graphics(100, 100);
unitLine.beginFill(0xFF3300);
unitLine.lineStyle(10, 0xffd900, 1);
unitLine.moveTo(firstX, firstY);
unitLine.lineTo(game.input.x, game.input.y);
}
This means the firstX and firstY values can't be changed after the first time.
If this is all in a game loop, you'll need to declare the top four variables outside of the loop, otherwise they'll renew themselves each time.

Stop displaying the microphone signal when button is clicked

I am writing a function that takes input and displays it on the screen using the tone.JS framework.
I have a toggle function to switch the microphone on and off. Turning the microphone on displays the number correctly. However, turning the switch off gives me output like the following:
6.135655369512991e-28,
6.135655369512991e-29,
6.135655369512991e-30,
6.135655369512991e-31,
and so on.
How do I get the function to reset to 0 (stop completely) when the toggle is switched off?
I would also like to stop logging the console when the toggle is checked as 'false' (off). How would I achieve this?
The function for the microphone toggle looks like this -
function micToggle() {
if (micSwitch.checked === true) {
mic.open();
}
else {
mic.close();
}
}
The function for the level meter (output) looks like this -
function drawMeter() {
var level = meter.getLevel();
// var absoluteLevel = Math.abs(level);
level = Tone.dbToGain(level);
// meterContext.clearRect(0, 0, canvasWidth, canvasHeight);
// meterContext.fillStyle = meterGraident;
// meterContext.fillRect(0, 0, canvasWidth, canvasHeight);
// meterContext.fillStyle = "white";
// meterContext.fillRect(canvasWidth * level, 0, canvasWidth, canvasHeight);
console.log(level);
decibelMeter.innerText = level;
}
window.setInterval(drawMeter, 700);
A simple fix would be to use a global boolean, setting it to true when the mic is toggled open and false when toggled close.
However, this would still display the decibel level every so often. What you really want is to set the interval every time mic is toggled open and then clear it every time it is toggled close.
Your code might be modified to look like the following:
var interval;
function micToggle() {
if (micSwitch.checked === true) {
mic.open();
interval = window.setInterval(drawMeter, 700);
}
else {
mic.close();
mic.dispose(); // to do cleanup
window.clearInterval(interval);
}
}
Your code below without the setInterval() function would now look like:
function drawMeter() {
var level = meter.getLevel();
// var absoluteLevel = Math.abs(level);
level = Tone.dbToGain(level);
// meterContext.clearRect(0, 0, canvasWidth, canvasHeight);
// meterContext.fillStyle = meterGraident;
// meterContext.fillRect(0, 0, canvasWidth, canvasHeight);
// meterContext.fillStyle = "white";
// meterContext.fillRect(canvasWidth * level, 0, canvasWidth, canvasHeight);
console.log(level);
decibelMeter.innerText = level;
}
Hope this helps!

Phaser overlap doesnt work

Why my Phaser.js 's overlap work sometimes and doesn't somtimes.
I have enabled arcade for my character and obstacle.
Here are the codes.
function create(){
...//other sprite
obs = game.add.group();
obs.enableBody = true;
obstacle = obs.create(800, game.world.height - 68, 'obstacle');
obstacle.scale.setTo(0.5,0.5);
game.physics.arcade.enable(obstacle);
obstacle.events.onOutOfBounds.add(function(obstacle) {
obstacle.kill();
}, this);
}
function update(){
...
game.physics.arcade.collide(character, obstacle, gameOver, null, this);
}
function generateObs(){//its where i generate new obstacle, and is my biggest suspect as well
obstacle = obs.create(800, game.world.height - 68, 'obstacle');
obstacle.scale.setTo(0.5,0.5);
game.physics.arcade.enable(obstacle);
obstacle.body.velocity.x = -300;
}
Thks a lot
Before giving you a possible solution to your problem:
It is not necessary to apply physics to the element created within
the group that already has physics.
If you need to know if two bodies
overlap but you do not need to emulate a complete collision use 'overlap'.
Try this:
var obs;
function create(){
//Active Physics ARCADE
game.physics.startSystem(Phaser.Physics.ARCADE);
...//other sprite
obs = game.add.group();
obs.enableBody = true;
obs.physicsBodyType = Phaser.Physics.ARCADE;
var obstacle = obs.create(800, game.world.height - 68, 'obstacle');
obstacle.scale.setTo(0.5,0.5);
obstacle.events.onOutOfBounds.add(function(obstacle) {
obstacle.kill();
}, this);
}
function update(){
...
//Use the group, since the callback will automatically pass the group element that overlaps with the player. A group is used to handle multiple elements, otherwise use only one variable :)
game.physics.arcade.overlap(character, obs, gameOver, null, this);
/*If you want your obstacle to move in the game you must implement this in the Update function
You can access an element of the group, for this there are multiple methods one of them is to get the element from the element's exists attribute
var obstacle = obs.getFirstExists(true);
if (obstacle) { obstacle.body.velocity.x = -300; }
*/
}
function gameOver(character, obstacle) {
//From here you have access to the element that collides with the player (you can evaluate with a condition if it is the obstacle you want)
//if (obstacle.name == 'x') { console.log(obstacle); }
console.log('Game Over!');
}
function generateObs(){
var obstacle = obs.create(800, game.world.height - 68, 'obstacle');
obstacle.scale.setTo(0.5,0.5);
obstacle.body.velocity.x = -300;
}

Simple ball animation HTML5 using requestAnimationFrame

I am just starting trying to make some animation using HTML5 and JavaScript.
Currently I have created a JavaScript class for the ball. It has an update function which should update the position of the ball and a draw function which should draw it:
/*global Vector*/
var Ball = (function () {
function Ball(pPostion) {
this.setPosition(pPostion);
}
Ball.prototype.getPosition = function () {
return this.mPosition;
};
Ball.prototype.setPosition = function (pPosition) {
this.mPosition = pPosition;
};
Ball.prototype.draw = function (pContext) {
pContext.save();
pContext.beginPath();
pContext.arc(100, 100, 20, 0, Math.PI * 2, true);
pContext.closePath();
pContext.fillStyle = '#ff0000';
pContext.stroke();
pContext.restore();
};
Ball.prototype.update = function () {
this.getPosition().add(new Vector(10, 0));
};
return Ball;
}());
In the my main section I have created the following method:
function ballGameLoop() {
ball.draw(mainContext);
ball.update();
requestAnimationFrame(ballGameLoop);
}
And when called, it does draw the ball but it doesn't seem to move at all. I don't have a specific type of way I want the ball to be animated, just any kind of movement would be good. Can anyone give any advice on where I may be going wrong?
From the looks of it, it seems you are just drawing an arc at the same coordinates over and over again (center at (100,100)).
Incorporating your Ball's position into this would be the way to make the render location dependent on the object's position. From what it seems, something along the lines of the following would give movement:
Ball.prototype.draw = function (pContext) {
var coordinates = this.getPosition();
pContext.save();
pContext.beginPath();
pContext.arc(coordinates.X, coordinates.Y, 20, 0, Math.PI * 2, true);
pContext.closePath();
pContext.fillStyle = '#ff0000';
pContext.stroke();
pContext.restore();
};
I'm of course assuming on how you setup the Vector object, so I'm guessing x and y can be accessed by (Vector).X and (Vector).Y respectively.
anyway just my approach at it.

Categories

Resources