Today I started listening to “The Subtle Art of Not Giving a F*ck”. I was wondering where this has been for the past 14K+ days I’ve been on this earth. I feel it’s something that a lot of people could have in their lives.
This is the thing. I’ve been contemplating a lot lately. I think I given way to many f*cks to all the wrong things. This needs to change. My task for the next few weeks? Find the right things to give f*cks about.
Well, now that that is out of my system, lets talk about something different. What is that you say? Public Speaking I answer. I am terrified of public speaking, as most people I know are. The few times I’ve done it I barely remember the events of the actual speech. The problem with this is… I kinda want to talk at conferences and give back to the development community. So, this will be my challenge this year. I plan on starting small. Either start my own meetup to talk at or find one that will let me talk. I’ll probably plan a “Tech Talk” for my company as well. Try to get some practice in. What’s the worst that can happen? … ….
Well, enough talk of me. I’ll leave you with a quote I just can’t get enough of.
“I’m not running away. But this is one corner of one country on one continent on one planet that’s a corner of a galaxy that’s a corner of a universe that is forever growing and shrinking and creating and destroying and never remaining the same for a single millisecond, and there is so much, so much, to see. Because it goes so fast. I’m not running away from things, I am running to them. Before they flare and fade forever.”
So, instead of my yearly post I’ve done the past two years I’m going to announce something very exciting to start of 2015. Last week Apple approved my first app to the app store. Today is the day that I am going to make it live!
This is very exciting for me and even though the app is not 100% where I want it to be I will be adding in features throughout the year. The app is called Carbs to Go! and is a simple app to count your carb intake.
Carbs to Go! will be free to download and contain no ads. The only thing I ask for is donation to allow me to further develop the app and add all the features that I want to get in there.
The first new feature that will be added within the first part of the year will be the ability to search, yes search, for food! This one of the features that I have not yet completed. I wanted to get the app out the first of this year so I would hit my deadline. Even though this is a large piece that the app needs to have I submitted anyways.
PARL (Providence Animal Rescue League) dropped the ball pretty badly this past week. In the past I had heard relatively good things about the animal shelter. I even donated some food and cat toys this past year. So when my mom said she was interested in adopting a cat the first place I thought of was PARL. Well after the past couple days and the treatment we have received from them I will never do business with them again.
It all started this past Tuesday, November 4th 2014. My mom, wife and myself went down to the local PARL shelter that happens to be right next to where I work. We were one of the first people in when they opened. There were two other people looking to adopt. PARL was having a special on cats as they had received a large amount just recently when an apartment was found to have 69 cats in it. We thought that this would be the perfect time to adopt a cat that needed a home. We had looked at the selection of cats and even checked out the dogs. There were the usual selection of kittens that most people will swarm to. However we caught our eye on an older cat and instantly fell in love with him. His name is Oscar and he is 13 years old.
Now I understand that by adopting an older cat that the cat is bound to come with some health issues. We had (and still do not have) no problem with that. I just want to dispel anyone saying we shouldn’t have adopted him if we didn’t want to deal with the health issues. That is not ultimately what I am complaining about here.
We had asked to see Oscar to see if he is a good fit for my mom. They took us into what they call the Green room. Basically a meet and greet room with the cats. You could tell instantly that Oscar became attached to my mom. We knew that we would want to adopt him.
This is where things start to go downhill. We asked the lady about his past and what health issues he has. She said that she would look up his sheet. A few minutes later she told us that he was with the same family for 13 years. The family had to move and couldn’t take Oscar with them so they brought him to the shelter. This was back in August of 2014. She also said that aside from not eating much he is in perfect health. I chalked up the not eating due to being cooped up in a small cage and becoming depressed. I figured we would get him to a nice home and after a few days, maybe a week he would be back to eating. If not we would work with a Vet to get him back to health.
So we went up to pay the adoption fee so they could hold Oscar for us. We had to go out and purchase a few supplies before we could bring him to his new home. When we got back to the shelter PARL dropped the first bit of sketchy behavior on us. They told us that the lady we spoke to had looked at the wrong records. They proceeded to tell us that he had severe teeth problems and was also treated for ringworm. Also while getting his paperwork together they had found paperwork in his file for a different cat. We figured that people can make mistakes and we’ll make sure he gets good treatment at the Vet. We ended up taking Oscar home.
Now keep in mind they told us this AFTER we got back from purchasing the needed supplies and paying the adoption fee. Also according to there contract once the pet is paid for anything that comes up is our responsibility… but we can always bring him back…
Now Oscar is the sweetest cat. He is extremely loving and is perfect for my mom who had lost her husband 15 months ago.
We also asked if Oscar was declawed at which they clearly stated he was not declawed. After getting him home we noticed he was, indeed, declawed. This is not a huge deal to us other than that they should know this basic information.
As predicted Oscar wasn’t eating much. He would have treats and drink but shied away from both the wet and dry food. We planned on giving him a few days to settle in and we were willing to experiment with the food till we found what worked for him. We also received Oscars medical records from the shelter. After reading though them in detail we realized he came into the shelter at 18 pounds and only a month later was down to 10 pounds. This is something we hoped would remedy itself by being in a loving home.
Everything was rolling along smoothly until the next night, Wednesday November 5th. Oscar had his first movement. We were excited cause that means he is getting comfortable in his new home. I noticed that he had gotten some on his back paw. I proceeded to clean off his paw when my wife noticed that it looked like he had some still on his bum. I went to help clean it up when i noticed it wasn’t poo left over but a worm coming out. Now i’m sure you can imagine our surprise. The shelter had told us he was in good health. You would think that they do a thorough exam before the pets can be adopted. Apparently PARL does not do complete exams.
Needless to say we ended up bringing Oscar to the emergency vet 30 min away to find out what was up. We discovered that he has roundworm and by the looks of it he has and it for at least a month if not more. How did PARL miss this? This can’t be the first time signs of this has shown. The day after he is adopted.
We came home with medicine to deworm him and plans on moving up his initial Vet appointment so he can be seen earlier. We also had plans of letting PARL know how we felt.
When My mom finally got in touch with PARL they tried to brush it off. She spoke with a lady named Amy who is supposed to be the manager. First they said that Oscar was eating fine and that the 8 pound loss was that they put him on a diet cause 18 pounds is too heavy. I agree with that but did they starve him? Also the lady we spoke to the other day said he wasn’t eating. Also when you look at his medical records they supplied us they were treating him for anorexia… They then repeated to say that if she wanted to she could bring Oscar back. Now at this point we are like “Why would we bring him back to you?”.
So to sum up. PARL clearly lied to us and didn’t tell us the whole truth behind Oscar’s past and medical history until AFTER we paid. They then tried to take back what was said earlier by saying the volunteers don’t know what there talking about. They had their paperwork mixed up. The whole interaction was a mess.
We love Oscar and will make sure he gets the treatment he needs to become healthy again. However this leaves such a bad taste in my mouth, as well as my mom and wife, that I will never do business with them again. I will never donate to them again. I am on the search for a shelter that treats their customers and pets better. “Being busy” is no excuse for messing up this bad. We will also be taking full advantage of the pet insurance provided to us for free for the first 30 days to get Oscar his treatment.
If you are looking to work with PARL do one thing. Make sure you have all the facts. Double, triple check all the paperwork and make sure that if something is missing from the medical records that it gets checked before you put down any money to adopt the pet. I’m not saying to not adopt but make sure you know. PARL should not be able to lie to it’s customers just to get an animal adopted.
Recently I have moved to a new affordable hosting solution for my cloud based servers. I wanted to pass on the savings to anyone looking. Check them out here (Digital Ocean), or look them up on Google! Happy Hosting!
First off I’ll recap 2013. 2013 was an overall good year. There were some rough patches but what year doesn’t have those? The year started out as many do, Gun-ho about completing everything on my list. Looking back most of the things I posted as my goals last year I did not complete but I did make some serious progress. To start I have yet to finish the games but I am closer to completion. I didn’t pick my guitar back up as I wanted. However I did read a good deal throughout the year! So out of the 3 goals I came in at 1 complete, 2 missed.
Along with a recap on my goals I had a downturn in events regarding my dad. The leukemia came back and this time it was fatal. My dad passed August 11th. It has been pretty hard on all of us in the family but we are slowly picking up the pieces and moving forward. He would of wanted us to keep going and not let this event hold any of us back.
On the work front I took the newly created mobile department head on and developed an app utilizing the Titanium framework. After this was completed we hired on a few more mobile developers and rebuilt the app in native Objective-C and Java. The mobile team is pretty much where I am and I can now put on my resume Objective-C developer along side iOS Developer. This is a huge accomplishment and something I have been working towards for a while now. I still do work with the web team and code in PHP when needed, especially when it comes to the API that the mobile app interacts with.
On the game end of things I recently picked up Unity and am playing around with that. I may release my games utilizing Unity. I’m not 100% sure yet. Only 2014 will tell.
Now lets talk about 2014! This next year I’m going to keep a few old goals and add a few more.
1: Make a game darn it all!!!
For this goal I want to finally complete a game and market it somewhere. Even if it’s an old school arcade style game it will get done. Speaking of old school arcade style games… Maybe one of them could be a collection of these classics all in one… hmmm. That sounds pretty promising 🙂 I also want to make some progress on a platformer style game that I have brewing in my head.
2: Publish at least 2 mobile apps to the app store.
I have a couple plain jane app ideas in the works and one already prototyped. These will most likely be iOS only apps but if I get extra motivated I may release them to the play store as well 🙂
3: Blog more often.
I would like to pick up and finish something i started a while back… Making a weekly blog post about a random programming topic. I did this with a few focused on PHP but I may expand it to Objective-C as well.
4: Loose more weight!
OK OK… This is one of those new years resolutions that everyone and their pets make… As for this past year I actually made some progress. I lost around 20 or so pounds! Not too shabby I think 🙂 I want to step it up for this year with increased exercise and even better eating habits.
5: Organize myself (Attempt 8,643)
Here we go again with another traditional one. I will eventually get this down 🙂
Now to accomplish this I may utilize a service a friend of mine has mentioned a few times, Beeminder. This seems like a cool concept. You basically pledge money to stay on track with a goal. If you fall off track you have to pay the beeminder service your pledge and then the cost goes up. I might give it a go.
Anyways here is my new years resolutions/goals. Now it’s time for me to get on with the night!
Farewell 2013! Hello 2014! Have a happy and safe new years everyone!
So, here we are again. Another new year! I want to say goodbye to 2012 and say hello to 2013!
This past year was crazy and it went by faster then I ever thought it would. I stopped 90% of my freelance work, picked up a full time gig at a local Providence company called ShapeUp as one of their PHP developers, and started taking a few classes online again at http://www.coursera.com. I also picked up my game development and have a few iPhone and desktop titles in the works.
A few other things about this past year… My dad went into remission from the leukemia he was diagnosed with in late 2011. He is still in remission and is doing good. The world did not end in 2012, which is good 🙂 It’s been a year since I’ve moved back up north ( still missing Florida though 🙂 ).
So with 2012 behind me I have a new year to look forward to. With this new year I have set myself some goals that I’m going to shoot for. My main goal is going to have a couple games finished either on the iPhone or desktop by the end of the year. They will most likely be free to play games but it’ll be a start into my indie game endeavor. I also plan to be more outgoing and actually take some time off to get back into a few hobbies of mine that have been slacking. Mainly I would like to play a bit more guitar again and find more time to read a couple books here or there.
So to recap, my goals for this coming year is:
Complete two or more games.
Pick up my guitar again
Find time to read a few new books
Now to state some traditional resolutions. These will be more of your traditional resolutions. Well here they are 🙂
Since I’m now officially a member at a gym I will be working on getting into shape and finally loosing a few pounds this year. I’m not going to put an amount or date on the goal. I just want to loose something 🙂
I would like to be more outgoing
Get my act together 😉
And now it’s time to celebrate the new year! Good bye 2012 and welcome 2013!
So today I picked out a transformation card from my wife’s “The Nature of Infinite Love & Gratitude‘ set. We try to pull out one card a week to see what we should focus on to better improve our lives. This week’s card for me was spot on. I am in the process of moving my Freelance business into an s-corp so lots of changes (and the accompanying challenges) are happening. I though I would share it here 🙂 I hope you enjoy!
I do not really have “problems”; I only think I do by the way I interpret my circumstances. A “problem” is an illusion. It is a limiting perception without gratitude.
1ST VERSE:
Oh, no. Don’t pretend I didn’t see
You roll your eyes at my gaming tee
Don’t know if you can read or if you’ve seen
The sweet piece in this week’s Wired magazine
The latest trend has hit its peak
They say that geek’s becomin’ chic
So now you’re out of style as you can be
And I’m in vogue, so you can bite me
To all the ass-hat jocks who beat me up in school
Now I’m the one that’s cool
I’m the one that’s cool
To all the prom queen bitches thinking they still rule
Now I’m the one that’s cool
I’m the one that’s cool
2ND VERSE:
Try to cop my style but I’m the real thing
While you played sports, I played Magic the Gathering
Never earned your part in nerd society
My Aquaman pajamas prove my pedigree
Watched my Next Gen every night
Wore a headgear to fix my overbite
Your black-rimmed glasses are prescription free, where as me
I literally can’t see my hand in front of my face
To all the asshat jocks who beat me up in school
Now I’m the one that’s cool
I’m the one that’s cool
To all the prom queen bitches thinking they still rule
Now I’m the one that’s cool
I’m the one that’s cool
And to my eighth-grade crush who pushed me in the pool
Now I’m the one that’s cool
I’m the one that’s cool
You may be tan and fit and rich but you’re a tool
And I’m the one that’s cool
I’m the one that’s cool
3RD VERSE:
Role reversal must be a total drag
But there’s no point, no point for me to humblebrag
I appreciate you for being cruel
I’m burning bright thanks to your rejection fuel
Have my in-jokes you won’t get
Like Honey Badger, Troll Face and Nyan Cat
So now your ballin’ parties seem so dumb
You can Evite me, and I’ll say yes, but I won’t really come
Got my comics
Got my games
All the things you thought were lame
Got my cosplay
Fanfic too
Got you pegged
STFU You
CHORUS
Outro
And I’m the one thats cool, I’m the one that… I’m the one thats cool
And I’m the one thats cool, I’m the one that… I’m the one thats cool
And I’m the one thats cool, I’m the one that… I’m the one thats cool
And I’m the one thats cool, I’m the one that… I’m the one thats cool
Hello. In this tutorial post I am going to show you how I made my simplified version of Craps. The purpose of this tutorial is to show the basics of using the HTML5 canvas tag and drawing simple 2D shapes. You can see the game in action on my website.
To start off lets lay out the simple rules so we know what we are trying to accomplish.
The player rolls two dice. The sum of the dice is the only thing that matters. (i.e. 1 and 3 is the same as 2 and 2)
Initial Roll
On a roll of 7 or 11 the player wins.
On a roll of 2, 3, or 12 the player looses.
Any other roll is stored as the players ‘Point’ and a Follow Up Roll is played.
Follow Up Roll
On a roll of 7 the player looses
On a roll of the players ‘Point’ the player wins.
Any other roll is discarded and play continues with another Follow Up Roll.
This is a very simplified version that only takes into account one player. If you want to expand this simple game with the full rules you can check out the wikipedia article for more info.
With the rules in place lets start digging into the code. On the first part we will go over the HTML and CSS that I use. Lastly I’ll go over the Javascript needed to implement the game logic and display the appropriate text when needed.
HTML/CSS
The HTML is pretty basic. We have a series of nested divs to control layout. Here is the full HTML:
This is the canvas tag. This is where we will be drawing out the dice when the player makes a roll. You can use the canvas tag to draw anything you need be it simple 2D graphics, 3D scenes, or just about anything you can think of. We will be covering how to draw basic 2D shapes.
I do not use anything out of the ordinary for the CSS so I won’t go over that in detail but for completeness here is the CSS code I use.
Before I move onto the Javascript and how to actually use the canvas element. You will notice one class in the HTML not listed here. It is the clearfix class attached to the main game wrapper div. This class is used to fix floated elements with no extra markup. You can read about it and obtain the CSS here.
Javascript
Now to go over the Javascript used. Before we get to the code lets go over the canvas tag and how to obtain it’s 2D context so you can start drawing.
Getting the canvas context
To get the canvas context you use the getContext method. We need to pass which context we want to use. to obtain the 2D context you pass the function the string ‘2d’. You call this method after obtaining the DOM element. Their are a couple ways of doing this depending on if you are using a javascript library or not. I personally use jQuery but you can use plain old Javascript as well. I will show both methods below.
// Using jQuery
ctx = $('#craps_game_demo')[0].getContext('2d');
// Using plain jane Javascript
ctx = document.getElementByID('craps_game_demo').getContext('2d');
While using jQuery notice the [0] after the selector. This is needed to get the context. If it is missing you will receive a Javascript error saying getContext is undefined. The canvas coordinate system starts with 0, 0, in the top left corner and counts up as you move right and down. Here is an illustration:
HTML5 Canvas Coordinate System
Now that we know how to obtain the canvas context I’ll go through the rest of the Javascript used in the game. I’ll post it piece by piece and go over each section in turn. The first part of the file is defining all the basic variables used.
var cwidth = 275; // Canvas width
var cheight = 150; // Canvas height
var dicex = 25; // Position of dice (x)
var dicey = 25; // Position of dice (y)
var dicew = 100; // Dice width
var diceh = 100; // Dice height
var dotrad = 6; // Radius of dots on dice face
var ctx; // Our context object
var roll1 = 0; // Die 1 roll
var roll2 = 0; // Die 2 roll
var rolltotal = 0; // Total roll
var point = 0; // Current 'Point' value
var round = 'initial'; // The round we are on. Either 'initial' or 'followup'
var total_loot = 100; // Current 'loot' total
var current_bet = 0; // Current bet amount
At the top of our javascript file we define all the variables used. The first two (cwidth, cheight) is the width and height of our canvas element. We use this to clear the canvas of all drawing when the game is reset. The next 5 variables define the dice. We start with dicex and dicey, this is the position on the canvas we will draw each die starting with it’s top left corner. Next we have dicew, and diceh. This defines the width and height of each die. Our dice will each be 100px wide and 100px high. Lastly we have dotrad. This is the radius of each dot on the dice.
Our next variable is ctx. This holds our canvas context object. We use this object to draw the dice onto the canvas. We will learn how to use it in more detail as we go over each function used in the game.
The last 7 variables holds various information needed to process each roll. We start with roll1, roll2, and rolltotal. Each of these store the current die roll and the total of the two. Next is point. This will store the current rounds ‘Point’ value. Then comes round. Here is a simple string to distinguish what round we are on. I could have used a boolean variable here which may be a better choice in the end. It’s not hard to change the code to use a boolean instead of a string so feel free to make the necessary adjustments. Next we store the players ‘total loot’ in a variable called total_loot. This will increase or decrease as the game goes by depending on if the player won or lost a round. The last variable needed is current_bet. This will keep track of the players current bet. The player wil have a chance to change this before each round starts.
After this I have a basic initialize function called when the page is loaded.
function crapsInit() {
ctx = $('#craps_game_demo')[0].getContext('2d');
crapsNewGame(); // Initialize a new game
// Reset some of the variables to the page open state
$('#craps_roll_button').hide();
$('#craps_setbet_button').hide();
$('#craps_newGame_button').show();
$('#craps_round_stage').html('');
}
This function gets our context using the jQuery method. It will next call crapsNewGame() (discussed next). Lastly is resets the buttons so only the ‘New Game’ button is displayed and then clears the stage value. (note: You do not have to use jQuery. If you have a preferred library you can easily replace the jQuery calls with the appropriate library calls.)
The next function in our file is crapsNewGame(). The purpose of this function is to set all the default values needed to start a new game of Craps. Below is the complete function:
function crapsNewGame() {
// Reset the variables
total_loot = 100;
current_bet = 0;
round = 'initial';
point = 0;
roll1 = 0;
roll2 = 0;
rolltotal = 0;
// Update all the HTML elements so they will
// be in their default state.
$('#craps_bet_input').val('10');
$('#craps_bet_span').html('???');
$('#craps_loot_span').html(total_loot);
$('#craps_point').html(' ');
$('#craps_current_roll').html(' ');
$('#craps_round_stage').html('Initial Throw');
$('#craps_winlose').hide();
$('#craps_newGame_button').hide();
$('#craps_roll_button').hide();
$('#craps_setbet_button').show();
// Clear the canvas of any previous drawing
ctx.clearRect(0,0,cwidth,cheight);
}
Here we reset all the Javascript variables and HTML layout elements to their default states. The most interesting part of this function is the call to clearRect() at the end of the function. This function is used to clear a rectangle shaped space on a canvas. It will remove any drawing done within that area. The function takes four arguments, the top (x) and left (y) and then the total width and height of the rectangle to clear. You pass the arguments in this order: clearRect(x, y, width, height). In this function we want to clear the entire canvas of any drawing so we can have a clean slate to draw on so we will be passing the following to the function: 0, 0, cwidth, cheight.
The next function used is crapsSetBet(). This function is called when the player sets their bet. Here is the complete function:
function crapsSetBet() {
round = 'initial';
current_bet = $('#craps_bet_input').val();
if (current_bet > total_loot) {
alert('You cannot bet less then your total loot. Please enter a different bet.');
return;
}
$('#craps_bet_span').html(current_bet);
$('#craps_point').html(' ');
$('#craps_current_roll').html(' ');
$('#craps_round_stage').html('Initial Throw');
$('#craps_winlose').hide();
$('#craps_newGame_button').hide();
$('#craps_setbet_button').hide();
$('#craps_roll_button').show();
ctx.clearRect(0,0,cwidth,cheight);
}
We start off in this function by setting the round to the ‘initial’ string so we know we are going to be making the Initial Roll. Next we get the value the player inputs for their bet. We then check to make sure the bet is less then the players total_loot. If the player is trying to bet more then what they have available we give them a nice Javascript alert letting them know they cannot bet more then their available loot then return from the function early so the player can enter a new bet value. After this we set the HTML Elements to the state we need them in to have the player make the Initial Roll. Lastly you will notice we make another call to clearRect(). This is to make sure we clear the canvas of any drawing that might have taken place before we make the initial roll.
Our next function crapsRollDice() contains the core logic for the game. Below is the complete function:
function crapsRollDice() {
// reset the dice x position
dicex = 25;
roll1 = 1 + Math.floor(Math.random() * 6);
roll2 = 1 + Math.floor(Math.random() * 6);
rolltotal = igz_roll1 + igz_roll2;
if (round == 'initial') {
switch (rolltotal) {
// WIN
case 7:
case 11:
$('#craps_winlose').html('YOU WIN!').show();
setScore(true);
break;
// LOSE
case 2:
case 3:
case 12:
$('#craps_winlose').html('YOU LOSE!').show();
setScore(false);
break;
default:
point = igz_rolltotal;
$('#craps_point').html(point);
$('#craps_round_stage').html('Follow up Throw');
round = 'followup';
}
} else {
// LOSE
if (rolltotal == 7) {
$('#craps_winlose').html('YOU LOSE!').show();
setScore(false);
}
// WIN
else if (rolltotal == point) {
$('#craps_winlose').html('YOU WIN!').show();
setScore(true);
}
}
if (total_loot <= 0) {
total_loot = 0;
$('#craps_roll_button').hide();
$('#craps_setbet_button').hide();
$('#craps_newGame_button').show();
}
$('#craps_current_roll').html(rolltotal);
// Display the dice
crapsDrawface(roll1); // Die 1
dicex = dicew + 50; // Move over the width plus 50
crapsDrawface(roll2); // Die 2
}
We start off this function by setting the dicex variable to it’s default of 25. This will make sure when when actually draw the dice the first die will be drawn in the correct position. Next we get two random numbers and assign them to roll1, and roll2.
We use the Javascript Math functions to do this. Here is the call we make: 1 + Math.floor(Math.random() * 6). Lets break this line down. The Math.random() function will return a value between 0.0 and 1.0. We then multiply this number by 6. For example lets say the function returns 0.4. The final value of the inner expression, Math.random() * 6, will be 2.4. We then use the Math.floor() function to strip away the decimal part of the number leaving us with 2. Lastly to get our random number between 1 and 6 we add 1 to the returned value of Math.floor(Math.random() * 6) giving us a final value of 3.
We repeat the above to get a random value for roll2. Next we add the two rolls together to get the value we will be using to check against for the rest of the function. You may wonder why I am getting two random numbers between 1 and 6 and not one random number between 2 and 12. I could have done this but I would have to split the number somehow in order to display the values of each individual die when we go to draw the dice. This way will make it much easier to call the drawing function to draw each individual die.
The next part of the function we determine what round we are in. If it is the Initial Roll we will be making different checks then if it is the Follow Up Roll. In the Initial Roll part of the if statement we use a switch() to see what the total roll is. If it is a 7 or 11 we display the message YOU WIN! then call the setScore() function to add the players bet to their total loot. If the total roll is either a 2, 3, or 12 we display the message YOU LOSE! then call setScore() to subtract the players bet from their total loot. If any other roll is found we set the point variable to the value of rolltotal and display the number in the Point box. We also update the round text to Follow Up Roll and update the round variable accordingly.
If we are already on the Follow Up Roll we check to see if the rolltotal is equal to 7. If it is we display the YOU LOSE! text and call setScore() to subtract the players bet from their total loot. If this isn’t true we check to see if the rolltotal equals the players point value. If it does we display YOU WIN! and call setScore() to update the score appropriately. If any other number is rolled we ignore it and move on.
Next we check to see if the players total_loot is less then or equal to 0. If it is we set the players total_loot to 0 then update the HTML Elements so the New Game button is showing. We then display the current totalroll in the appropriate spot.
After this we call the crapsDrawFace() function to draw the result of roll1 onto the canvas. Next we move dicex over the width of the die plus 50. Lastly we call crapsDrawFace() again to draw the results of roll2. crapsDrawFace() will take care of drawing the dice. I’ll be going over this function and it’s accompanying functions in a minute.
Before we get to the meat of the drawing code we have one more simple function to go over. The setScore() function. This function takes one argument, a boolean value. If we won the round and want to add the bet to the players total lot we pass true else we will pass false to subtract the bet from the players total loot. Here is the full function:
This function is simple. We check to see if the player has won the round. If so we add the value of current_bet to the players total_loot and update the HTML Elements. I call parseInt() to make sure I am adding integer numbers and not strings as the javascript + operator is used for both addition and concatenation of strings. If you don’t use parseInt() you may end up with a number like 10010 instead of 110 when adding the players bet and total loot together.
Now we get to the fun part, crapsDrawFace(). This function will draw a die onto the canvas at dicex and dicey. This function will call other functions depending on the number we need to draw. These function are crapsDraw1(), crapsDraw2() and crapsDraw2mid(). I’ll go ever each in turn.
function crapsDrawface(n) {
ctx.lineWidth = 5;
ctx.clearRect(dicex,dicey,dicew,diceh);
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(dicex,dicey,dicew,diceh);
ctx.fillStyle = "#000000";
ctx.strokeRect(dicex,dicey,dicew,diceh);
ctx.fillStyle = "#009966";
switch (n) {
case 1:
crapsDraw1();
break;
case 2:
crapsDraw2();
break;
case 3:
crapsDraw2();
crapsDraw1();
break;
case 4:
crapsDraw2();
crapsDraw2(true);
break;
case 5:
crapsDraw2();
crapsDraw2(true);
crapsDraw1();
break;
case 6:
crapsDraw2();
crapsDraw2(true);
crapsDraw2mid();
break;
}
}
The first thing we do inside this function is set the line width we will be drawing with. We do this by setting the lineWidth data member of our ctx variable. This is the complete call: ctx.lineWidth = 5;. This is setting the width to 5px. The next function should look familiar. We used it in two previous functions. It’s the clearRect() function. The difference here is that w are clearing only the space that the dice is occupying. Next will set the fill color we want to use, in this instance #FFFFFF or white. We do this be setting the fillStyle data member of the ctx object. The next function is new, fillRect(). This function is identical to clearRect in all ways except one. the fillRect() function will fill the rectangle provided with the setting of fillStyle. This gives our dice a nice white background (if your game is on a white background you can skip this). Next we change the fillStyle so it is #000000 or black. We want this to be the color of the border for our dice. We create this by calling the function strokeRect(). Once again this takes the exact same parameters as clearRect() and fillRect(). The only difference here is that the function will stroke (put a border) around the outside of the rectangle with a width of lineWidth and the color stored in fillStyle. Lastly we set the fillStyle one last time to a nice green color, #009966. This color wil be used for the dots on the face of the dice.
The function then uses a switch() statement to determine how to draw the dots. It will call one of the crapsDraw?() functions or a combination of them to accomplish this. All of these functions are almost identical besides how they calculate the dot position. I will show all three functions then go over the most interesting parts.
/*
* This function draws a dot in the center of the die.
*/
function crapsDraw1() {
var dot_x;
var dot_y;
ctx.beginPath();
dot_x = dicex + .5 * dicew;
dot_y = dicey + .5 * diceh;
ctx.arc( dot_x, dot_y, dotrad, 0, Math.PI * 2, true );
ctx.closePath();
ctx.fill();
}
/*
* This function draws a dot in two oposit corners (lower right and upper left).
* If reverse is true it draws the dots in the oposite corners.
*/
function crapsDraw2(reverse) {
reverse = typeof(reverse) != 'undefined' ? reverse : false;
var dot_x;
var dot_y;
ctx.beginPath();
dot_x = dicex + 3 * dotrad;
dot_y = reverse ? dicey + diceh - 3 * dotrad : dicey + 3 * dotrad;
ctx.arc( dot_x, dot_y, dotrad, 0, Math.PI * 2, true );
dot_x = dicex + dicew - 3 * dotrad;
dot_y = reverse ? dicey + 3 * dotrad : dicey + diceh - 3 * dotrad;
ctx.arc( dot_x, dot_y, dotrad, 0, Math.PI * 2, true );
ctx.closePath();
ctx.fill();
}
/*
* This function draws two dots on either side (left and right) centered vertically
* on the y axis. It is used to create the '6'.
*/
function crapsDraw2mid() {
var dot_x;
var dot_y;
ctx.beginPath();
dot_x = dicex + 3 * dotrad;
dot_y = dicey + .5 * diceh;
ctx.arc( dot_x, dot_y, dotrad, 0, Math.PI * 2, true );
dot_x = dicex + dicew - 3 * dotrad;
ctx.arc( dot_x, dot_y, dotrad, 0, Math.PI * 2, true );
ctx.closePath();
ctx.fill();
}
There are four functions that we are concerned with that we need to look at, beginPath(), arc(), closePath(), and finally fill(). I will go over arc() last as that is the more interesting function of the bunch (Don’t forget to add ctx. in front of each function call). To tell the context we want to start drawing a path we use the beginPath() function: We tell the context we are done when we call closePath(). We then can either use fill() or stroke() to either fill the path or stroke is accordingly. I do not use the stroke() function in this game but the work the same as fillRect() and strokeRect().
Now for the real work. We use the arc() function to create our path. arc() is used as follows: arc(cx, cy, radius, start_angle, end_angle, direction). cx is the center horizontal coordinate and cy is the vertical coordinate of the circle. radius is the radius we want to use. Now the arc method uses radians for the angle arguments. In a circle their are 2 * PI radians (a little more then 6). Luckily Javascripts Math library has a PI function which returns PI with as many decibles as needed. So if we want to make a half circle we start at 0 and end at Math.PI. For a complete circle we start at 0 and end at Math.PI * 2. The last argument is the direction. This is either a true or false value. Setting it to true will draw counterclockwise and false is clockwise. This is more important when drawing arcs that are not whole circles. Since we are drawing a whole circle we can use either value.
Now that we know about the arc() function will pass it the calculated dot_x and dot_y variables along with the dotrad defined at the top of the file. The last three variables deals with the angles and since we are making a complete circle we pass 0, Math.PI * 2, and lastly the Javascript true value. The complete call is: ctx.arc( dot_x, dot_y, dotrad, 0, Math.PI * 2, true).
Finally at the end of the file we add the crapsInit() function to the document ready queue. I use jQuery but you can assign it in any manner that will work if you do not use the jQuery library.
$(document).ready(function () {
crapsInit();
});
Thats about it for the code. When the page is initially loaded it will call the crapsInit() function. This will set the stage and display the New Game button. Once the player clicks this it will call the crapsNewGame() function and prompt the user to set the bet for the round. Once the player enters their bet and clicks the button the crapsSetButton() function is fired off. Next the player clicks the Roll Dice button to call crapsRollDice() until they either win or loose the round. At this point it prompts the player to enter another bet and play continues till either the player stops or looses all his loot.
I hope this tutorial on how to build my simplified version of Craps was useful. The main parts I wanted to make sure to hit was how to draw basic 2d shapes on a canvas. You can do so much more with the canvas then I did here but hopefully this gave any one just jumping into HTML 5 some useful info to help them along.
I plan on doing more tutorials based around more complex games that will take full advantage of the canvas. I will also do some 3D based ones as well. If you liked this let me know. If you found any mistakes or know how I can do something better don’t hesitate to submit a comment.
UPDATE:
Here are some screen shots of the finished game ( should have added this a while ago 🙂 ):
A screenshot of me winning a round!This is a screenshot of me losing a round!