how to run JavaScript game animations sequentially after each one is finished - javascript

Currently, I am using an archaic method of setting a variable true at the start of the animation and false after the animation has played (see below.) I also think something might be wrong with how I process animations in the interval because when I add an animation to the array of animations to be processed, it isn't processed. Here's my code:
var animationDone = true;
function g_e(e){
return document.getElementById(e);
};
class Main{
constructor(){
this.animations = [];
this.tasks = [];
}
start_animating(){
var x = setInterval(function (){
if (animationDone == true){
try{
alert(this.animations[0]);
this.aminations[0].func(this.animations[0].args);
this.animations.shift();
}
catch(e){
}
}
},1);
}
add_animation(f, a){
this.animations.push({func:f, args:a});
alert("animation added");
}
start_working(){
var x = setInterval(function (){
try{
this.tasks[0].func(this.tasks[0].args);
this.tasks.shift();
}
catch(e){
}
},1);
}
animation_blink(){
var blink = 0;
window.setInterval(function blinking(){
if (blink == 0){
document.getElementById("blinker").innerHTML = ">";
blink= 1;
}
else if(blink == 1){
document.getElementById("blinker").innerHTML=" ";
blink = 0;
}
}, 1000);
}
animation_fade(object){
var fade = 0;
var fadeOut = 0;
animationDone = false;
var interval = setInterval(function startFade(){
g_e(object.element).style.opacity = fade;
if(fade>1 && fadeOut == 0){
fadeOut = 1;
}
else if(fade < 0){
clearInterval(interval);
}
else if(fadeOut == 0){
fade = fade + 0.2;
}
else if(fadeOut == 1){
fade = fade - 0.2;
}
}, 500);
animationDone = true;
}
plbl(object){
animationDone = false;
var p = plbl.intervals;
if (!p)
plbl.intervals = p = {};
if (p[object.destination])
clear();
function clear() {
clearInterval(p[object.destination]);
delete p[object.destination];
}
var i = 0;
var elem = document.getElementById(object.destination);
p[object.destination] = setInterval(function(){
checkChar = object.message.charAt(i);
if(checkChar =="|"){
elem.innerHTML += "<br>";
}
else{
elem.innerHTML += object.message.charAt(i);
}
i++;
if (i > message.length){
animationDone = true;
clear();
}
}, object.speed);
}
command(input){
alert(input);
if(input == "y"){
g_e("start").style.display = "none";
g_e("startUp").style.display = "block";
this.add_animation("test", "test");
}
}
get_input(){
var x = g_e("input").value;
g_e("input").value = "";
return x;
}
key_checker(event){
var key = event.keyCode;
if (key == 13){
this.command(this.get_input());
return false;
}
}
start(){
this.start_working();
this.start_animating();
this.animation_blink();
}
}
alert("compiled");
main = new Main();
main.start();

Related

I can't stop setInterval with clearInterval

Im creating simple slider for Mobile devices. It's all based on checking width and setInterval() method. The case is when the device width reaches above 800px I want it to stop ! To be honest Im not excatcly sure where to put clearInterval(). I tried it in resize event and it did not work too. The timer is still working and I can't stop it after its already triggered.
class mobileSlider {
constructor() {
this.image = document.querySelector(".mobile__top-slider");
this.topCircles = document.querySelector(".top__circles");
this.paths = ["xgarda.jpg", "logofinal.png", "my.jpg"];
this.initialWidth = window.innerWidth;
this.width = null;
this.timer = null;
this.isMobile = true;
this.createSlider();
}
createSlider() {
this.drawDots();
this.checkWidth();
this.animateSlider();
}
drawDots() {
this.paths.forEach((_, index) => {
const circle = document.createElement("div");
circle.setAttribute("class", "top circle");
circle.setAttribute("data-id", `${index + 1}`);
this.topCircles.appendChild(circle);
});
}
animateSlider() {
let currentIndex = 0;
this.image.style.backgroundImage = `url(./images/${this.paths[currentIndex]})`;
this.topCircles.children[currentIndex].style.border = "2px solid #322B0F";
if (this.isMobile) {
this.timer = setInterval(() => {
currentIndex++;
if (currentIndex > 2) {
currentIndex = 0;
this.topCircles.children[this.paths.length - 1].style.border = "none";
}
this.image.style.backgroundImage = `url(./images/${this.paths[currentIndex]})`;
this.topCircles.children[currentIndex].style.border =
"2px solid #322B0F";
if (currentIndex > 0) {
this.topCircles.children[currentIndex - 1].style.border = "none";
} else {
this.topCircles.children[currentIndex + 1].style.border = "none";
}
}, 2000);
} else if (!this.isMobile) {
console.log("przekroczony");
window.clearInterval(this.timer);
}
}
checkWidth() {
if (this.initialWidth >= 800) {
this.isMobile = false;
}
window.addEventListener("resize", () => {
if (window.innerWidth >= 800) {
this.isMobile = false;
this.animateSlider();
} else {
this.isMobile = true;
this.animateSlider();
}
});
}
}
const run = new mobileSlider();

Stop loop in typewriter effect using JS

I am so close to the perfect typewriter effect for my website - mostly thanks to the support of your fantastic input here! What I'm looking for is a slight variation of the typewriter effect below: To have the last line of text remain on the screen rather than being erased (but not, as instructed in another post, the ENTIRE text, only the LAST LINE).
So ideally, the first line would build up, then get erased, then the second one would build up, then get erased as well, and then, finally, the third one would build up and remain on screen (while the cursor still continues to blink). If you could help me figure out this modification, I'd really be eternally grateful! Thank you a million in advance!
PS: If there is any chance to add a DELAY as well so the very first line starts building up after e.g. 5 seconds (in which only the cursor blinks), this would be the cherry on the icing! :-)
PPS: Here's the link to the original code:
consoleText(['Hello World.', 'Console Text', 'Made with Love.'], 'text',['tomato','rebeccapurple','lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
Here's my take on it:
// function([string1, string2], target id, [color1,color2], initial pause, final pause)
consoleText(['Hello World.', 'Console Text', 'Made with Love.'], 'text',['tomato','rebeccapurple','lightblue'], 5000, 500000);
function consoleText(words, id, colors, initialPause, finalPause) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var initialCount = 0;
var waiting = false;
var target = document.getElementById(id);
var justStarted = true;
target.setAttribute('style', 'color:' + colors[0]);
window.setInterval(function() {
if(initialCount < initialPause){
initialCount += 120;
} else if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount);
window.setTimeout(function() {
var usedColor = colors.shift();
var usedWord = words.shift();
x = 1;
target.setAttribute('style', 'color:' + colors[0]);
letterCount += x;
waiting = false;
}, 1000);
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, words.length === 1 ? finalPause : 1000);
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount);
letterCount += x;
}
}, 120);
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden';
visible = false;
} else {
con.className = 'console-underscore';
visible = true;
}
}, 400);
}

Stop loop in typewriting effect using JS

I found this typewriting effect on Codepen, which works great, however, I'm trying to stop the loop so the typewriting effect only loads once and no more. I tried asking the author but no answer. Can you point me in the right direction? Here's the link to the original https://codepen.io/Tbgse/pen/dYaJyJ
// function([string1, string2],target id,[color1,color2])
consoleText(['Divi Notes.', 'Divi Tips and Tricks', 'Made with Love.'], 'text', ['#BD6983', 'tomato', 'lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
You literally need to comment out one line of code:
// function([string1, string2],target id,[color1,color2])
consoleText(['Divi Notes.', 'Divi Tips and Tricks', 'Made with Love.'], 'text', ['#BD6983', 'tomato', 'lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord); <--- This one right here!
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
}
The general mechanics:
var usedWord = words.shift();
words.push(usedWord);
Takes the next word to say and then adds it to the end of the array. Assuming this is what keeps track of the words, to stop it at the very end simply remove the push
var usedWord = words.shift();
//words.push(usedWord);
As #mark_m says you should also stop the setInterval:
// function([string1, string2],target id,[color1,color2])
consoleText(['Divi Notes.', 'Divi Tips and Tricks', 'Made with Love.'], 'text', ['#BD6983', 'tomato', 'lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
var interval = window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord); <--- This one right here!
if(words.length==0) clearInterval(interval)
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
}
P.S. I realise this is your first post, but this is not a coding service. Show us how you tried to fix the issue. Otherwise you are unlikely to get a real response.
I'm not sure if you need the underscore at the end blinking or not so I just left it there.
Following changes are needed
Comment out the circular insertion into the arrays.
var usedColor = colors.shift();
//colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord);
Stop interval at the the end of the array
var wordsInterval = window.setInterval(function() {
if(words.length == 0) {
window.clearInterval(wordsInterval);
return;
}
Here's whole code (working link https://codepen.io/anon/pen/LrqmPg)
// function([string1, string2],target id,[color1,color2])
consoleText(['Hello World.', 'Console Text', 'Made with Love.'], 'text',['tomato','rebeccapurple','lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
var wordsInterval = window.setInterval(function() {
if(words.length == 0) {
window.clearInterval(wordsInterval);
return;
}
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
//colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
#import url(https://fonts.googleapis.com/css?family=Khula:700);
body {
background: #111;
}
.hidden {
opacity:0;
}
.console-container {
font-family:Khula;
font-size:4em;
text-align:center;
height:200px;
width:600px;
display:block;
position:absolute;
color:white;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
.console-underscore {
display:inline-block;
position:relative;
top:-0.14em;
left:10px;
}
<div class='console-container' id='console-container'><span id='text'></span><div class='console-underscore' id='console'>_</div></div>
Edit: Without erasure (https://codepen.io/anon/pen/eKxrvM)
// function([string1, string2],target id,[color1,color2])
consoleText(['Hello World.', 'Console Text.', 'Made with Love.'], 'console-container',['tomato','rebeccapurple','lightblue']);
function consoleText(words, containerId, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var container = document.getElementById(containerId);
var targets = [];
words.forEach(() => {
var newTarget = document.createElement('span');
targets.unshift(newTarget);
container.prepend(newTarget);
});
var target = targets.shift();
target.setAttribute('style', 'color:' + colors[0])
var wordsInterval = window.setInterval(function() {
if(words.length == 0) {
window.clearInterval(wordsInterval);
return;
}
if (letterCount === 0 && waiting === false) {
waiting = true;
targets.length && (target = targets.shift());
//target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
//colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + (colors.length == 0? usedColor: colors[0]))
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = false;
letterCount = 0;
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
#import url(https://fonts.googleapis.com/css?family=Khula:700);
body {
background: #111;
}
.hidden {
opacity:0;
}
.console-container {
font-family:Khula;
font-size:4em;
text-align:center;
height:200px;
width:600px;
display:block;
position:absolute;
color:white;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
.console-underscore {
display:inline-block;
position:relative;
top:-0.14em;
left:10px;
}
<div class='console-container' id='console-container'><span id='text'></span><div class='console-underscore' id='console'>_</div></div>
just remove push() into words array, comment the following line, it is enough to typewrite it once.
words.push(usedWord);
PS: Clear interval should be used to avoid calling the function code again.
if(!words || words.length == 0){
clearInterval(t);
return;
}
Check Codepen for the demo

Please review my code, it doesn't work. and always says it is not a function in console

I created a game in javascript but the game does not work. it always said its not a function in Chrome log.
So I want to know what's wrong with that. like liubei.fight() etc. This is a game that you fight against caocao. I create 3 character. if liubei is not alive, the game is over. if caocao is not alive, you win the game.
var character = function(name,power,hp){
this.name=name;
this.power=power;
this.hp= hp;
this.alive=true;
this.checkalive = function(){
if(this.hp <=0){
this.alive==false;
}
this.fight=function(){
var attack = Math.random()
if(attack < 0.5){
caocao.hp-=this.power;
caocao.checkalive();
checkwin()
}
else{
console.log("miss attack")
}
}
this.fullattack=function(){
var attack = Math.random()
if(attack < 0.5){
caocao.hp-= 3;
caocao.checkalive();
checkwin()
}
else {
this.hp-=2
this.checkalive()
this.checklose()
}
}
}
}
//*create the character//
var liubei = new character("liubei",1,5);
var guanyu = new character("guanyu",1,5);
var zhangfei = new character("zhangfei",1,5);
var caocao={
name:"caocao",
power: 2,
hp :8,
alive : true,
checkalive: function(){
if(caocao.hp<=0){
caocao.alive===false;
};
},
fight: function(){
var caocaoattack = Math.random()
if(caocaoattack<0.33){
liubei.hp-=2;
liubei.checkalive();
checklose();
}
else if(caocaoattack>0.66){
zhangfei.hp-=2;
zhangfei.checkalive()
}
else{
guanyu.hp-=2
guanyu.checkalive();
}
}
}
//*define the action//
var gameover = false;
var gameOver = function(){
gameover==true;
confirm("gameover");
return;
}
var checkwin = function(){
if(caocao.alive == false ){
confirm("you win the game");
gameOver();
}
}
var checklose = function(){
if(liubei.alive == false)
confirm("you loose the game");
gameOver();
}
//*start game//
var gamestart = function(){
while(gameover==false){
if(liubei.alive==true){
liubei.fight();
}
if(guanyu.alive==true){
guanyu.fight();
}
if(zhangfei.alive==true){
zhangfei.fight();
}
if(caocao.alive==true){
caocao.fight();
}
}
}
gamestart()
var character = function(name,power,hp){
this.name=name;
this.power=power;
this.hp= hp;
this.alive=true;
this.checkalive = function(){
if(this.hp <=0){
this.alive==false;
}
}
this.fight=function(){
var attack = Math.random()
if(attack < 0.5){
caocao.hp-=this.power;
caocao.checkalive();
checkwin()
}
else{
console.log("miss attack")
}
}
this.fullattack=function(){
var attack = Math.random()
if(attack < 0.5){
caocao.hp-= 3;
caocao.checkalive();
checkwin()
}
else {
this.hp-=2
this.checkalive()
this.checklose()
}
}
}
The last bracket is missing as mentioned by Jaromanda

clearInterval is not clearing

Take a look at the function below, It purpose is to change the button text
to "Abort", "Abort 0", "Abort 1" and so on.
Once the counter reaches 10 another function should be executed, but if
the button is clicked, the counter should stop, and the button text should return
to it's original value ("Sync DB").
It seems I'm trying to clear out the interval in a wrong way.
Any assistance will be appreciated.
function sync_database(abort)
{
if (abort == true) { sync_db_btn.innerHTML = "Sync DB"; return false }
sync_db_btn.innerHTML = "Abort"
var i = 0;
sync_db_btn.addEventListener("click", function() { sync_database(true) } );
var x = setInterval(function() {
if (abort == true) {
clearInterval(x);
}
if (i < 10) {
sync_db_btn.innerHTML = "Abort " + i++;
}
}, 1000);
}
var x;
sync_db_btn.addEventListener("click", function() {
sync_database(true);
clearInterval(x);
} );
function sync_database(abort)
{
if (abort == true) { sync_db_btn.innerHTML = "Sync DB"; return false }
sync_db_btn.innerHTML = "Abort"
var i = 0;
x = setInterval(function() {
if (i < 10) {
sync_db_btn.innerHTML = "Abort " + i++;
}
}, 1000);
}
I think you need something like this:
var sync_db_btn = document.getElementById('but'),
abortSync = -1,
interval,
sync_database = function () {
var i = 0;
abortSync *= -1;
if (abortSync < 0) {
sync_db_btn.innerHTML = 'Sync DB';
clearInterval(interval);
return false;
}
sync_db_btn.innerHTML = 'Abort';
interval = setInterval(function () {
if (i < 10) {
sync_db_btn.innerHTML = 'Abort ' + i++;
} else {
sync_db_btn.innerHTML = 'Sync DB';
clearInterval(interval);
abortSync = -1;
}
}, 1000);
};
sync_db_btn.addEventListener('click', sync_database);
A live demo at jsFiddle.

Categories