I have a single webpage that I want to be able to run three JavaScript games, sequentially. I start one with
//jQuery to start a game
$(document).ready(() => {
//When the logo image is clicked
$("#logo").click(() => {
//Get the archery game
$.getScript('archery.js', () => {
//Start it
startArchGame();
//Remove the image from the HTML doc
$("#logo").remove();
});
})
})
Then, inside archery.js, once a condition is met, the following code is executed
$.getScript('skateboarding.js', () => {
startSkateGame();
});
game.destroy();
The game.destroy(); stops the game from running in Phaser 3, but the next game is just loaded below the first one, so you can't see it. How can I fix this? Is it possible to delete the first script I got entirely?
I was able to solve this issue within the Phaser framework.
I changed game.destroy() to game.destroy(true, false).
The first argument of the destroy method, true, says that I want to remove the game from the canvas element of the page when I destroy the game. The second argument, false, says to NOT remove all of Phaser and its plugins for the page. I set this to false because I want to create another game in Phaser on the page after I destroy my first one.
Related
I have a method that renders an icon (font-awesome icon) inside provided container. Icon rendering can happen by user clicking on specific div or by program itself automatically calling rendering function when it mimics user clicking specific div.
To better understand this. I have created this so called TicTacToe game. It is possible to play player vs player or player vs cpu. If two players are playing then there is no problem, everything is rendered fine.
Now when player plays against CPU, something strange happens. If first player is CPU, then its first move is not rendered (icon does not appear). But the rest appears fine.
And if I make both players to be CPU (CPU plays against another CPU), then nothing gets rendered. Could it be that ReactDOM.render ignores changes if they happen too fast?;)
So here is part of the program (game):
$( document ).ready(function() {
const ICONS_CLASSES = {
x: 'fa fa-times fa-lg',
o: 'fa fa-circle-o fa-5x'
}
function renderMove(el, turn){
const classes = ICONS_CLASSES[turn];
ReactDOM.render(
React.createElement('span', {'className': classes}),
el
)
}
...
...
});
Also here is a function that is called by program itself to mimic clicking on a specific div in a game (well let say CPU "clicks" it):
function clickPosition(el, tic){
if(tic.state == 'running'){
// Save which player played, because after playing move, it will
// switch turn for another player.
const type = tic.turn.type;
const res = tic.play(el.id);
if(res != 'invalid')
renderMove(el, type);
updateInfo(tic.info)
// Add start block to be able to play again.
if(tic.state == 'stopped'){
// Highlight win combo if there is any
if(tic.winCombo)
highlightWin(tic.winCombo)
toggleEl($('#start'))
}
}
}
So calling such render as previously said will not render all the time (when playing with CPU).
But if I change that render to this:
el.innerHTML = `<span class="${classes}"></span>`;
Then it renders any icon just fine. No matter if game is played player vs player, cpu vs player, player vs cpu or even cpu vs cpu (in this case all icons are rendered instantly, because the end result is always draw).
Is there some gotcha with ReactDOM.render?
P.S. If you are interested, you can find full code here (currently it is enabled to be played cpu vs player, meaning first will play CPU. And because it is rendering with ReactDOM.render, first move will be invisible. Others should appear fine): https://codepen.io/andriusl/pen/qjyBdB
It looks like everything is OK with ReactDOM.render. But I was kind of right with guess about rendering happening too fast. But from another place.
There was a function (that I haven't mentioned in question) which cleared all rendered icons. And it would clear after starting the game. When players are playing, then there is no problem, because clearing does happen later then user clicks a div. But when cpu does that, it does much faster, so it plays its turn before clearing up is called and it clears that move icon.
So technically it is rendered, but it is instantly removed, looking like it was never rendered, at least to us humans:)
So fix was to move ReactDOM.unmountComponentAtNode before tic.start. Then it always clears before starting game, not after (or before starting another game).
$('#x, #o').on('click', function() {
const second = {'x': 'o', 'o': 'x'};
// Clear filled positions if any.
let positions = document.getElementsByClassName('pos');
_.each(positions, pos => {
ReactDOM.unmountComponentAtNode(pos);
})
tic.start(this.id, second[this.id]);
toggleEl($('#start'));
updateInfo(tic.info);
})
I have a jQuery mobile page that has a jQuery chat feature. Essentially I type something into the chat and then a few seconds later the bot responds.
Behind the chat feature and filling up the whole page is a class that has a background image, and I wish to have it so when I type into the text field and hit SEND the background image class toggles to another class which has a different background image. I also wish it to have like a 2-3 second delay.
I have tried
$(function () {
$("#chatSend").click(function () {
$(this).parent(".tasteTheRainbow").toggleClass("orNot");
});
});
Here is my JSfiddle...the background image does not show up but its there. https://jsfiddle.net/mattmega4/d9yodhtm/
One solution could be this:
$(this).closest(".tasteTheRainbow").fadeTo('fast', 0, function () {
$(this).toggleClass("orNot").fadeTo('fast', 1);
});
See the DEMO: https://jsfiddle.net/d9yodhtm/3/
I found a partial answer to my question. I can get the image to change, but not the delay, but I can keep looking into that. Here is the code:
$(document).ready(function(){
$("button#chatSend").click(function(){
$(".tasteTheRainbow").addClass("orNot");
});
});
I have a reveal.js presentation with approximately 300 slides. The purpose of this presentation is to cycle slides in "kiosk mode" on a monitor behind a conference booth.
To create a "kiosk mode" I've got:
Reveal.initialize({
controls: false, // hide the control arrows
progress: false, // hide the progress bar
history: false, // don't add each slide to browser history
loop: true, // loop back to the beginning after last slide
transition: fade, // fade between slides
autoSlide: 5000, // advance automatically after 5000 ms
});
This works very well, but I'd like to randomize the slides. The slides are currently just a list of 300 <section> tags in the index document - they aren't being pulled from anywhere external. Currently random: true isn't a configuration option in reveal.js.
The display order of fragments can be controlled with data-fragment-index. Is it possible to do something like that with sections? Is there a way to trick reveal.js into randomizing my slides?
My preference would be to shuffle them each time around - that is, to show slides 1-300 in random order, and then shuffle them, and show 1-300 again in a different random order. I would also be happy with just jumping to a random slide for each transition, though.
While Reveal itself does not have this functionality built in, it does let you set up event hooks to do actions when all the slides are loaded, this means JQUERY TO THE RESCUE!
You can combine Reveal's "All slides are ready" event with simple javascript to reorder all the sections, here's a simple PoC:
First import jQuery, I did this by adding it directly above the import for js/reveal.min.js:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Then, set up an event listener:
Reveal.addEventListener('ready', function(event) {
// Declare a function to randomize a jQuery list of elements
// see http://stackoverflow.com/a/11766418/472021 for details
$.fn.randomize = function(selector){
(selector ? this.find(selector) : this).parent().each(function(){
$(this).children(selector).sort(function(){
return Math.random() - 0.5;
}).detach().appendTo(this);
});
return this;
};
// call our new method on all sections inside of the main slides element.
$(".slides > section").randomize();
});
I put this right after declaring my Reveal settings and dependencies, but I'm pretty sure you can put it anywhere.
What this does is waits for all javascript, css, etc to load, manually reorders the slides in the DOM, then lets Reveal start off doing its thing. You should be able to combine this with all your other reveal settings since it's not doing anything disruptive to reveal itself.
Regarding the "shuffling them each time around" portion, the easiest way to do this would be to use another event listener, slidechanged. You could use this listener to check if the last slide has just been transitioned to, after which the next time slidechanged is called you could simply refresh the page.
You can do this with something like:
var wasLastPageHit = false;
Reveal.addEventListener('slidechanged', function(event) {
if (wasLastPageHit) {
window.location.reload();
}
if($(event.currentSlide).is(":last-child")) {
// The newly opened slide is the last one, set up a marker
// so the next time this method is called we can refresh.
wasLastPageHit = true;
}
});
As of reveal.js 3.3.0 there is now a built in helper function for randomizing slide order.
If you want the slide order to be random from the start use the shuffle config option:
Reveal.initialize({ shuffle: true });
If you want to manually tell reveal.js when to shuffle there's an API method:
Reveal.shuffle();
To shuffle the presentation after each finished loop you'll need to monitor slide changes to detect when we circle back to the first slide.
Reveal.addEventListener( 'slidechanged', function( event ) {
if( Reveal.isFirstSlide() ) {
// Randomize the order again
Reveal.shuffle();
// Navigate to the first slide according to the new order
Reveal.slide( 0, 0 );
}
} );
I'm working with cookies to run or not run a jQuery animation someone else built:
$(function () {
$('div.transitional').click(function () {
$('div.intro').removeClass('hidden');
$('div.final').off('click');
});
ShowDiv($("div.transitional.hidden")[0]);
});
function ShowDiv(target) {
target = $(target);
target.removeClass('hidden');
target.delay(500).animate({
opacity: 1.0
}, 300, 'easeInExpo', function () {
ShowDiv($("div.transitional.hidden")[0]);
})
}
I have the cookie part working, but I'm confused about the anonymous function and the "ShowDiv" function.
What is each part doing?
Functionally, the animation makes visible a series of pictures, then the whole site. I want to skip the animation and just make the whole site visible (if cookies='visited'.) I'd like to do this without rewriting the animation script.
Here's a link: http://claytonsalem.com/bottlecap.
What happens now is if you have the cookie the animation doesn't run and everything is hidden.
That script only fades in elements, one after the other. If you want to skip that, use something like this in the anonymous function (which is also known as a DOM ready handler) :
$(function() {
$('div.transitional').click(function() {
$('div.intro').removeClass('hidden');
$('div.final').off('click');
});
if(cookies === "visited") //Assuming you already have the variable set.
ShowDiv($("div.transitional.hidden")[0]);
else
$("div.transitional.hidden").css('opacity', 1).removeClass('hidden')
});
I will focus on how it works:
$("div.transitional.hidden")
This would select ALL elements with div.transitional.hidden, placing them in a list.
By placing [0] in the selector, we are picking ONLY the first element in this list.
Then, when the script begins to run, this element is modified by target.removeClass('hidden'), which removes the hidden class.
When the scripts ends, it calls the $("div.transitional.hidden")[0] selector again, but this time it will not include the previously selected element (because it no longer has the hidden class).
That's why the script show images one after the other: it removes the hidden class and selects the next remaining element.
You might refer to Karl's answer on how to show your whole site.
My question title may seem confusing, let explain my situation. Any help would be much appreciated.
I have never done this before, hence why I can't pin point a solution in google.
I have a jquery slideshow, which I wrapped inside a function because I have some addition animation to go with it, please see below...
// my slider function
bikeSlider = function () {
var slider = $('#bike-minislider').bxSlider({
displaySlideQty: 5,
infiniteLoop: false,
hideControlOnEnd: true
});
$('#bike-minislider-fade').fadeIn();
};
// this runs the function
bikeSlider();
As you can see, immediately after the bikeSlider function, I run the function using... bikeSlider();
Now later on, I hide some slides within the slideshow using jquery .hide().
Because my jquery slideshow function, calculates the number of visible slides within the #bike-minislider div, it means that the new number of visible slides causes the slideshow to not work. I guess it needs to re-calculate the new number of slides.
In a nutshell, I think this can be resolved by running the bikeSlider(); function again.
So I tried this below, but it did not work.
bikeFilter = function (y) {
$('.bike').fadeOut();
$('.bike[data-group=' + y + ']').fadeIn();
bikeSlider();
return false;
}
As you can see I am trying to re-run the function bikeSlider(); - but it seems to be running this over the top of the old one, so my question is, how do you remove the original slide function before running it again.
Or reloading/refreshing the original function so it re-calculate the new number slides?
Any pointers would be so helpful.
Thank You.
As i understood you dont need re-create slider, but you do exectly this by calling twice
bxSlider()
According doc you need reinit slider by
reloadShow()
//Reinitialize a slide show
For more info take a look here bxslider in section Public functions
You need to call reloadShow() for slider-object
var mySlider;
$(function(){
mySlider= $('#bike-minislider').bxSlider({
auto: true,
controls: true
});
mySlider.reloadShow();
})