JS, jQuery?? Rolling dice

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

JS, jQuery?? Rolling dice

Post by califdon »

I suspect this can be done with jQuery, but I haven't used fancy effects like this before. What I'm trying to do is switch images between randomly selected dice faces to simulate throwing dice, ending with one which becomes the number thrown. I don't need to get fancy, moving the images across the screen or simulating 3D, I'd just like to do better than simply displaying the new one (which I'm doing now). This is just something I tried to do as an exercise. It's a simple craps game and it works correctly now and displays 2 random images from the 6 possibilities for each, applying the rules of craps. But it would be cool to have them sort of look like they are rapidly changing for maybe 6 or 8 values before stopping. (In case anyone would like to have the JS code for the logic, etc., I'll be glad to send or post it.)
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: JS, jQuery?? Rolling dice

Post by Benjamin »

You can do this.

Probably write a function that selects a set number of random die and put them into an array. Then loop through the array and display each one for a set period of time. You can use jQuery to set the image (innerHTML), however you are doing it.

Then when it has finished looping through the array set the die to the value it's supposed to be.

You could also look into some jQuery effects too, in case it doesn't look very good.
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: JS, jQuery?? Rolling dice

Post by califdon »

That's exactly what I tried, but even with an empty timing loop of 10000 iterations, it executed so fast that there was no visible effect. I do have the die images in an array. I tried setInterval() and setTimeout(), with no useful results (maybe I just didn't use them properly). If I could figure out how to have each image display for, say, 0.2 seconds, that would be fine, but I haven't been able to make that work. And I am changing the image just with JS setting the innerHTML property to the <img> tag with the next random die image. All I see is the final image. That's fine for the logic of the game, it's just that I'd like to add a little visual interest. I've been reading about jQuery FX, but I'm a newcomer to jQuery, so it's going rather slowly. I have an idea that it can be done with jQuery UI, if I can just figure out how. Oh well, it keeps me off the streets. :wink:
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: JS, jQuery?? Rolling dice

Post by Benjamin »

Ok. Can you post the code. There's several things that can cause that.
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: JS, jQuery?? Rolling dice

Post by califdon »

Sure. I just uploaded it to my site, so you can take a look first, to see what I'm doing, then read or download the source:
http://ravey.net/test/craps.html

Thanks for your interest.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: JS, jQuery?? Rolling dice

Post by Benjamin »

Ok, I'll play around with it in the next day or two and post back.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: JS, jQuery?? Rolling dice

Post by VladSun »

You don't need to use for-timing-loops in Javascript - you have the beautiful setTimeout() abd setInterval() funcitons.

jQuery has a common function signature for animating functions:
.function( [duration,] [callback] )

So, you have to set the duration and the callback - e.g.:

Code: Select all

el.fadeIn(1000, function () {

   el.fadeOut(1000, function () {
      alert('FadeIn-Out sequence completed');
   });

})
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: JS, jQuery?? Rolling dice

Post by califdon »

VladSun wrote:You don't need to use for-timing-loops in Javascript - you have the beautiful setTimeout() abd setInterval() funcitons.

jQuery has a common function signature for animating functions:
.function( [duration,] [callback] )

So, you have to set the duration and the callback - e.g.:

Code: Select all

el.fadeIn(1000, function () {

   el.fadeOut(1000, function () {
      alert('FadeIn-Out sequence completed');
   });

})
Thanks, Vladsun. As I commented above, I have explored setTimeout() and setInterval(). But setTimeout() doesn't halt the rest of the execution, it only postpones the execution of the callback, so it doesn't help in this situation. I thought that setInterval() might work, but I wasn't able to get it to do it, either. jQuery looks more promising and I have been looking at that, but I have no prior experience with jQuery, so the learning is slow (at my age, everything is slow!--or doesn't work at all!). This morning I've been thinking that maybe the simplest approach is to create 6 animated .gif's, each one stepping through several frames to end with the designated die face, thus eliminating any need for JS logic to achieve the animation. Constructing the 6 .gif's would be tedious, but since the images should be displayed very rapidly, they could all be the same series of faces, ending with a different face. I think it wouldn't be noticeable that they were the same. If I had any experience with Flash, that would probably be the best solution, but I've only done a couple of very basic things with Flash.
Last edited by califdon on Mon Aug 01, 2011 12:53 pm, edited 1 time in total.
Reason: To clarify my explanation.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: JS, jQuery?? Rolling dice

Post by VladSun »

setTimeout() is the one that you need :)

Code: Select all

    var point = 0;

	function animateRoll(times)
	{
		times = times || 1;

		var roll = generateRoll();
		drawRoll(roll[0], roll[1]);
		
		if (times > 10)
		{
			checkRoll(roll[0], roll[1]);
			return;
		}
		
		setTimeout('animateRoll(' + (times + 1) + ')', 200);
	}

	function generateRoll() 
	{
                        return [ Math.floor(Math.random()*6) + 1, Math.floor(Math.random()*6) + 1 ];
	}

	function drawRoll(die1, die2) 
	{
		document.getElementById('die1').innerHTML = '<img src="dice' + die1 +'.gif" />';
		document.getElementById('die2').innerHTML = '<img src="dice' + die2 +'.gif" />';
	}

	function checkRoll(die1, die2)
	{
		var sum = die1 + die2;
         document.getElementById("sum").innerHTML = "= &nbsp;&nbsp;&nbsp;"+sum;
         
         if(point == 0) {  // if this is the come-out roll:
            switch (sum) {
               case 2:
               case 3:
               case 12:
                  clr = "red";
                  msg = "Sorry!  You Crapped Out!  Roll Again";
                  point = 0;
                  break;
               case 7:
               case 11:
                  clr = "green";
                  msg = "You Win!  "+sum+" Is A Natural!";
                  point = 0;
                  break;
               default:
                  clr = "black";
                  msg = "Roll Again.  Your Point Is "+sum;
                  point = sum;
            }
         } else {  // this is NOT the come-our roll:
            switch (sum) {
               case 7:
                  clr = "red";
                  msg = "Sorry, You Crapped Out!  Next Roll";
                  point = 0;
                  break;
               case point:
                  clr = "green";
                  msg = "Congratulations!  You Made Your Point!";
                  point = 0;
                  break;
               default:
                  clr = "black";
                  msg = "Your Point Is "+point+".  Roll Again";
            }
         }
         document.getElementById("roll").style.color=clr;
         document.getElementById("roll").value=msg;
      }  

Code: Select all

   <input type='button' id='roll' onClick='animateRoll();' value='Roll Your Dice' />
PS: If you want OOP style solution - check this out viewtopic.php?f=13&t=124654
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: JS, jQuery?? Rolling dice

Post by califdon »

Great! Thanks very much. I only have a few minutes before I have to leave for an appointment, but when I return I will try this out. I see how you have done this and will study it to learn more about how setTimeout() really works, it has always been unclear to me. I appreciate your interest and will let you know how it works out for me.
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: JS, jQuery?? Rolling dice

Post by califdon »

Fantastic! Thank you, Vladsun. I need to add in some of my game logic, which I will do in the morning, but your code definitely does what I was trying to do unsuccessfully. I'll need to study it some more to really understand the way you used setTimeout(). When I get it running the way I want, I will modify the version that's at the URL I gave earlier.

If I wanted to actually develop a game for others to play, I should provide for betting, perhaps starting everyone with $1,000 or something, but when I read the official casino rules, the betting logic is really hideous! I don't think I'll spend the time doing that. This was only a mental exercise to begin with.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: JS, jQuery?? Rolling dice

Post by VladSun »

Nothing complex about setTimeout() :) animateRoll() function is a recursive like function, with delayed calls. You could do the same by using an "external" for loop and setTimeout(). Something like that:

Code: Select all

var delayStep = 200;
var steps = 10;

for (var i=1; i <= steps; i++)
{
    setTimeout('generateRoll(); drawRoll();', i*delayStep);
}

setTimeout('checkRoll()', (steps+1) * delayStep);
Some things to clarify:

Code: Select all

function animateRoll(times)
{
     times = times || 1;
It will set variable times to 1, IF parameter times is not passed (or zero, or false) - i.e. "undefined". It's almost the same as this code in PHP:

Code: Select all

function animateRoll($times = 1)
setTimeout() is often used instead of direct function calls in recursions. While it should be done carefully it grealty improves performance.

EDIT: Added the missing IF :)
Last edited by VladSun on Wed Aug 03, 2011 12:02 pm, edited 1 time in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
califdon
Jack of Zircons
Posts: 4484
Joined: Thu Nov 09, 2006 8:30 pm
Location: California, USA

Re: JS, jQuery?? Rolling dice

Post by califdon »

Thanks again. That will help me get the concept. I did note the "times" technique and understood it; nice compact syntax. I hadn't thought of the performance improvement aspect.
Post Reply