Javascript setInterval unwanted pause - javascript

I am trying to create an animation with a few images in javascript and I have the code working, but after it runs through images in reverse then it pauses slightly before it starts going forward again. I'm wondering how I get rid of the pause?
Here is the code in action http://isogashii.com/projects/javascript/ch10/dp10-6.html
HTML
<img id="pin" src="assets/pin0.gif" alt="pin animation" />
Javascript
var pin = new Array(9);
var curPin = 0;
var x = false;
// caching images
for (var imagesLoaded=0; imagesLoaded < 9; ++imagesLoaded) {
pin[imagesLoaded] = new Image();
pin[imagesLoaded].src = "assets/pin" + imagesLoaded + ".gif";
//starts pinF function when all images are cached
if (imagesLoaded == 8) {
setInterval("pinF()", 120);
}
}
function pinF() {
if (x == true) {
--curPin;
if (curPin == 0) {
x = false;
}
}
if (x == false) {
++curPin;
if (curPin == 8) {
x = true;
}
}
document.getElementById("pin").src = pin[curPin].src;
}

in the x == true portion of the if statement, you should set the curPin to be one otherwise you are duplicating the curPin = 1.
http://jsfiddle.net/A77cx/
function pinF() {
if (x == true) {
--curPin;
if (curPin == 0) {
curPin = 1;
x = false;
}
}
if (x == false) {
++curPin;
if (curPin == 8) {
x = true;
}
}
document.getElementById("pin").src = pin[curPin].src;
}

Currently, you do two "frames" of pin1. Change the logic of pinF not to do that.
To be specific, the first time x == true and curPin == 2, the first if executes, reducing curPin to 1.
The second time, x == true still, the first if brings curPin down to 0 and inverts x. Then, the second if increments curPin back to 1.

Related

Hide faces of a box geometry that won't be seen by the camera in THREE.js

I'm making a project that includes many squares and if too many are rendered than it makes it really laggy. Is there a way to check if there is a block right next to it and not render a face of it in order to make it run faster?
Currently I am making boxes using 6 different planes and moving them around to make a box. I am aware this is not the most efficient way to do it and I have fixed that as of right now and that was the best way for my little brain to visualize it. Here is the code that checks if there is another box next to it:
let blRight = false
let blLeft = false
let blBack = false
let blFront = false
let blTop = false
let blBottom = false
for(let i = 0; i < blocks.coord.x.length; i++) {
if(blocks.coord.x[i] == x + 10) {
if(!blocks.coord.y[i] == y) {
blRight = true
}
}
}
for(let i = 0; i < blocks.coord.x.length; i++) {
if(blocks.coord.x[i] == x - 10) {
if(!blocks.coord.y[i] == y) {
blLeft = true
}
}
}
for(let i = 0; i < blocks.coord.y.length; i++) {
if(blocks.coord.y[i] == y + 10) {
blTop = false
}
}
for(let i = 0; i < blocks.coord.y.length; i++) {
if(blocks.coord.y[i] == y - 10) {
blBottom = true
}
}
for(let i = 0; i < blocks.coord.z.length; i++) {
if(blocks.coord.z[i] == z + 10) {
if(!blocks.coord.y[i] == y) {
blFront = true
}
}
}
for(let i = 0; i < blocks.coord.z.length; i++) {
if(blocks.coord.z[i] == x - 10) {
if(!blocks.coord.y[i] == y) {
blBack = true
}
}
}
if(blRight == false) {
scene.add(right)
}
if(blLeft == false) {
scene.add(left)
}
if(blTop == false) {
scene.add(blockTop)
}
if(blBottom == false) {
scene.add(bottom)
}
if(blFront == false) {
scene.add(front)
}
if(blBack == false) {
scene.add(back)
}
blocks.coord.x.push(x)
blocks.coord.y.push(y)
blocks.coord.z.push(z)
blocks.coord.id.push(3)
This is in a function that is called to make a new block. blTop meaning top face and so on. This is actually how Minecraft makes its game faster. Any suggestions to make it more effecient?

How to make a Pause Mode work effectively in a game?

I am having trouble getting my pausing to work well.
When I hit the 'p' key, I want to toggle pause on/off.
I have created this fiddle
window.keyController = {
p: false, // p
}
Is the keycontroller i set to capture multiple keys, i only have the P key here now.
I use two event listeners to set this.
// listeners
window.addEventListener("keydown", (e) => {
e.preventDefault();
if (e.key == "p") {
keyController.p = true;
}
});
window.addEventListener("keyup", (e) => {
if (e.key == "p") {
keyController.p = false;
}
});
Then in my main loop, a request anim frame loop.
i am checking if p is hit or true and then looping trough game loop.
if (keyController.p == true) { // 'p' pause on/off toggle
pause = !pause;
}
if (pause == 0 || (pause == 1 && cyc != 14)) { // pause=0 Or (pause=1 And cyc<>(16-mov/2))
if (cyc == 0) {
levticker -= 1;
if (levticker == 0) {
levticker = 15;
levtime -= 1;
}
if (levtime < 0) levtime = 0;
}
cyc = cyc + 2;
if (cyc == 16) cyc = 0;
}
Any ideas what i am doing wrong, should we be able to pause between each middle figure and not skip or delay? this middle timer counts down from 15 to 0 so 16 cycles before we effect the first timer.

Why can't I clear this timer in JavaScript?

There is an object.
There is this method that initializes the timer in another method within the same object.
initstep1() {
var totAns = TriviaGame.corAnswered + TriviaGame.incorAnswered;
//for (let v=0;v<TriviaGame.arrayOfSelected.length;v++){TriviaGame.arrayOfSelected.pop();}
//for (let u=0;u<TriviaGame.arrayOfIntervals.length;u++){clearInterval(TriviaGame.arrayOfIntervals[u]);TriviaGame.arrayOfIntervals.pop();}
$("#maincontact0").css("display", "none");
$("#maincontact2").css("display", "none");
$("#maincontact1").css("display", "flex");
if (totAns != 10) {
TriviaGame.populatePromptContent();
} else {
TriviaGame.initstep3();
}
if (TriviaGame.corAnswered == 0 && TriviaGame.incorAnswered == 0) {
TriviaGame.giveQuestionsClickEvents();
TriviaGame.giveAnswersClickEvents();
}
$("#maincontact1qr").text() == 30;
TriviaGame.timerOnTheRight();
}
It's called timerOnTheRight...
Here it is...
Never gets cleared no matter what I do.
timerOnTheRight() {
//for (let u=0;u<TriviaGame.arrayOfIntervals.length;u++){clearInterval(TriviaGame.arrayOfIntervals[u]);TriviaGame.arrayOfIntervals.pop();}
console.log(TriviaGame.arrayOfIntervals);
let countDown1 = 30;
var thisVeryTimer = setInterval(function() {
countDown1--;
if ($("#maincontact1qr").text() != 1) {
$("#maincontact1qr").text(countDown1);
}
if ($("#maincontact1qr").text() < 11) {
$("#maincontact1qr").css("color", "orange");
}
if ($("#maincontact1qr").text() < 4) {
$("#maincontact1qr").css("color", "red");
}
if ($("#maincontact1qr").text() == 1) {
TriviaGame.arrayOfCurrent[0].timespent = "Yes";
clearInterval(thisVeryTimer);
TriviaGame.initstep2();
}
}, 600);
}
Make sure the conditional is correct, and the inside the conditional block is working when conditioning is met. You should console out thisVeryTimer to make sure it is the same interval id.
Another issue should be the scope of the variable.
clearInterval(thisVeryTimer);
Try to move the above code out of the interval block.

Snake Game in Javascript

I'm really new to Javascript, so I decided to create a simple SnakeGame to embed in HTML. However, my code for changing the snake's direction freezes up after a few turns.
Note: I'm running this in an HTML Canvas.
Source:
var Canvas;
var ctx;
var fps = 60;
var x = 0;
var seconds = 0;
var lastLoop;
var thisLoop;
var tempFPS = 0;
var blockList = [];
var DEFAULT_DIRECTION = "Right";
var pendingDirections = [];
function update() {
x += 1;
thisLoop = new Date();
tempFPS = 1000 / (thisLoop - lastLoop);
lastLoop = thisLoop;
tempFPS = Math.round(tempFPS*10)/10;
if (x==10){
document.getElementById("FPS").innerHTML = ("FPS: " + tempFPS);
}
//Rendering
for (var i = 0; i<blockList.length; i++){
var block = blockList[i];
draw(block.x, block.y);
}
if (x==5){
x=0;
seconds+=1;
//Updates once per x frames
moveBlocks();
}
}
function moveBlocks(){
if(blockList.length === 0){
return;
}
for (var j = 0; j<pendingDirections.length; j++){
if (b >= blockList.length -1){
pendingDirections.shift();
}else {
//Iterates through each direction that is pending
var b = pendingDirections[j].block;
try{
blockList[b].direction = pendingDirections[j].direction;
} catch(err){
alert(err);
}
pendingDirections[j].block++;
}
}
for (var i = 0; i<blockList.length; i++){
var block = blockList[i];
clear(block.x, block.y);
if (block.direction == "Down"){
block.y += BLOCK_SIZE;
} else if (block.direction == "Up"){
block.y -= BLOCK_SIZE;
} else if (block.direction == "Left"){
block.x -= BLOCK_SIZE;
} else if (block.direction == "Right"){
block.x += BLOCK_SIZE;
} else {
alert(block.direction);
}
draw(block.x, block.y);
}
}
function init(){
lastLoop = new Date();
window.setInterval(update, 1000/fps);
Canvas = document.getElementById("Canvas");
ctx = Canvas.getContext("2d");
}
//The width/height of each block
var BLOCK_SIZE = 30;
//Draws a block
function draw(x, y) {
ctx.fillStyle = "#000000";
ctx.fillRect(x,y,BLOCK_SIZE,BLOCK_SIZE);
}
function clear(x,y){
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(x,y,BLOCK_SIZE,BLOCK_SIZE);
}
function processInput(key){
if (key == 110){
//n (new)
newBlock(BLOCK_SIZE*4,0);
newBlock(BLOCK_SIZE*3,0);
newBlock(BLOCK_SIZE*2,0);
newBlock(BLOCK_SIZE*1,0);
newBlock(0,0);
} else if (key == 119){
changeDirection("Up");
} else if (key == 115){
changeDirection("Down");
} else if (key == 97){
changeDirection("Left");
} else if (key == 100){
changeDirection("Right");
} else if (key==122){
var pDir = "Pending Directions: ";
for (var i = 0; i<pendingDirections.length; i++){
pDir += pendingDirections[i].direction + ", ";
}
alert(pDir);
} else if (key == 120){
var dir = "Directions: ";
for (var j = 0; j<blockList.length; j++){
dir += blockList[j].direction + ", ";
}
alert(dir);
} else {
alert("KEY: " +key);
}
}
function changeDirection(d){
var LD = blockList[0].direction;
var valid = false;
if (d == "Up"){
if(LD != "Down"){
valid = true;
}
} else if (d == "Down"){
if(LD != "Up"){
valid = true;
}
} else if (d == "Left"){
if(LD != "Right"){
valid = true;
}
} else if (d == "Right"){
if(LD != "Left"){
valid = true;
}
}
if (d == LD) { valid = false;}
if (valid){
var dir = {'direction' : d, 'block' : 0};
pendingDirections.unshift(dir);
}
}
function newBlock(x, y){
var block = {'x': x, 'y' : y, 'direction' : DEFAULT_DIRECTION};
//This works: alert(block['x']);
draw(x,y);
blockList.push(block);
}
Thanks
As Evan said, the main issue is how you are handling pending directions.
The issue occurs when you turn twice in rapid succession, which causes two pending directions to be added for the same block. If these aren't handled in the correct order, then the blocks may move in the wrong direction. On every update, only one pending direction for each block is needed, so I redesigned how this is handled to avoid multiple directions on one block during a single update.
Here is the link to it: http://jsbin.com/EkOSOre/5/edit
Notice, when a change in direction is made, the pending direction on the first block is updated, overwriting any existing pending direction.
if (valid) {
blockList[0].pendingDirection = direction;
}
Then, when an update occurs, the list of blocks is looped through, and the pending direction of the next block is set to be the current direction of the current block.
if(!!nextBlock) {
nextBlock.pendingDirection = block.direction;
}
If the current block has a pending direction, set the direction to the pending direction.
if(block.pendingDirection !== null) {
block.direction = block.pendingDirection;
}
Then update the block locations like normal.
You also had various other issues, such as using a variable (b) before it was initialized, and how you caught the null/undefined error (you should just do a check for that situation and handle it appropriately), but this was the main issue with your algorithm.
You'll also want to remove the old blocks when the user hits 'n', because the old one is left, increasing the speed and number of total blocks present.
Good luck with the rest of the game, and good luck learning JavaScript.

Simulating shuffle in js

All,
I have three cards which can be shuffled by the user, upon hover, the target card pops to the top, the last card on top should sit in the second position. While with the code below, I can have this effect in one direction (left to right), I am struggling to come up with logic & code for getting the effect to work in both directions without having to write multiple scenarios in js (which doesnt sound like very good logic).
Hopefully the demo will do a better explanation.
Code:
$(".cBBTemplates").on (
{
hover: function (e)
{
var aBBTemplates = document.getElementsByClassName ("cBBTemplates");
var i = 2;
while (i < aBBTemplates.length && i >= 0)
{
var eCurVar = aBBTemplates[i];
if (eCurVar === e.target)
{
eCurVar.style.zIndex = 3;
} else if (eCurVar.style.zIndex === 3) {
console.log (eCurVar);
eCurVar.style.zIndex = 3-1;
} else
{
eCurVar.style.zIndex = i;
}
i--;
}
}
});
Try this:
$(function(){
var current = 2;
$(".cBBTemplates").on (
{
hover: function ()
{
var target = this,
newCurrent, templates = $(".cBBTemplates");
templates.each(
function(idx){
if(this === target){
newCurrent = idx;
}
});
if(newCurrent === current){return;}
templates.each(function(index){
var zIndex = 0;
if(this === target) {
zIndex = 2;
}
else if (index == current) {
zIndex = 1;
}
$(this).css('zIndex', zIndex);
});
current = newCurrent;
}
});
});

Categories

Resources