Today we continue a series of articles on game development in HTML5 using canvas. Finally, today we will start adding animation, and few more interesting features. Our demonstration will include a spaceship flying through space, and a new element – the Dialogue. The dialogue will contain two pages, and our button will toggle the dialog pages + hide the dialog on the second click.
Our previous article you can read here: Developing Your First HTML5 Game – Lesson 2. Our base script will taken from previous letter.
Here are our demo and downloadable package:
[sociallocker]
[/sociallocker]
Ok, download the example files and lets start coding !
Step 1. HTML
Here are all html of my demo
index.html
04 | <meta charset="utf-8" /> |
05 | <title>HTML5 Game Development - Lesson 3 | Script Tutorials</title> |
06 | <link href="css/main.css" rel="stylesheet" type="text/css" /> |
10 | <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script> |
11 | <script type="text/javascript" src="js/script.js"></script> |
14 | <div class="container"> |
15 | <canvas id="scene" width="800" height="600"></canvas> |
18 | <h2>HTML5 Game Development - Lesson 3</h2> |
Step 2. CSS
Here are used CSS styles.
css/main.css
07 | font-family: "DS-Digital"; |
08 | src: url("../fonts/Ds-digib.ttf"); |
11 | background-color:#bababa; |
12 | background-image: -webkit-radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); |
13 | background-image: -moz-radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); |
14 | background-image: -o-radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); |
15 | background-image: radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); |
17 | font:14px/1.3 Arial,sans-serif; |
28 | background-color:#212121; |
30 | box-shadow: 0 -1px 2px #111111; |
47 | footer a.stuts,a.stuts:visited{ |
54 | margin:23px 0 0 110px; |
Pay attention to ‘@font-face’. We will using this way to link custom font file (ttf) to our lesson (to draw at canvas).
Step 3. JS
js/jquery-1.5.2.min.js
We will using jQuery for our demo. This allows easy bind different events (for mouse etc). Next file most important (here are all our html5 functional):
js/script.js
006 | var iBgShiftX = 1024; |
007 | var bDrawDialog = true; |
011 | function Button(x, y, w, h, state, image) { |
020 | function SpaceShip(x, y, w, h, image) { |
031 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
033 | function drawDialog() { |
035 | var bg_gradient = ctx.createLinearGradient(0, 200, 0, 400); |
036 | bg_gradient.addColorStop(0.0, 'rgba(160, 160, 160, 0.8)'); |
037 | bg_gradient.addColorStop(1.0, 'rgba(250, 250, 250, 0.8)'); |
039 | ctx.fillStyle = bg_gradient; |
040 | ctx.moveTo(100, 100); |
041 | ctx.lineTo(700, 100); |
042 | ctx.lineTo(700, 500); |
043 | ctx.lineTo(100, 500); |
044 | ctx.lineTo(100, 100); |
048 | ctx.strokeStyle = 'rgba(128, 128, 128, 0.5)'; |
051 | ctx.font = '42px DS-Digital'; |
052 | ctx.textAlign = 'center'; |
053 | ctx.textBaseline = 'top'; |
054 | ctx.shadowColor = '#000'; |
055 | ctx.shadowOffsetX = 2; |
056 | ctx.shadowOffsetY = 2; |
058 | ctx.fillStyle = '#fff'; |
059 | if (iDialogPage == 1) { |
060 | ctx.fillText('Welcome to lesson #3', ctx.canvas.width/2, 150); |
061 | ctx.font = '24px DS-Digital'; |
062 | ctx.fillText('After closing dialog you will able', ctx.canvas.width/2, 250); |
063 | ctx.fillText('to handle with spaceship with your mouse', ctx.canvas.width/2, 280); |
064 | } else if (iDialogPage == 2) { |
065 | ctx.fillText('Second page of dialog', ctx.canvas.width/2, 150); |
066 | ctx.font = '24px DS-Digital'; |
067 | ctx.fillText('Any another text', ctx.canvas.width/2, 250); |
071 | function drawScene() { |
075 | if (iBgShiftX <= 0) { |
078 | ctx.drawImage(backgroundImage, 0 + iBgShiftX, 0, 1024, 768, 0, 0, 800, 600); |
080 | ctx.drawImage(spaceShip.image, 0, 0, spaceShip.w, spaceShip.h, spaceShip.x-128, spaceShip.y-128, spaceShip.w, spaceShip.h); |
084 | ctx.drawImage(button.image, 0, button.imageShift, button.w, button.h, button.x, button.y, button.w, button.h); |
086 | ctx.font = '22px DS-Digital'; |
087 | ctx.fillStyle = '#ffffff'; |
088 | ctx.fillText('next/hide/show', 400, 465); |
089 | ctx.fillText('dialog', 400, 500); |
094 | canvas = document.getElementById('scene'); |
095 | ctx = canvas.getContext('2d'); |
096 | var width = canvas.width; |
097 | var height = canvas.height; |
099 | backgroundImage = new Image(); |
100 | backgroundImage.src = 'images/stars.jpg'; |
101 | backgroundImage.onload = function() { |
103 | backgroundImage.onerror = function() { |
104 | console.log('Error loading the background image.'); |
107 | var oSpShipImage = new Image(); |
108 | oSpShipImage.src = 'images/space_ship.png'; |
109 | oSpShipImage.onload = function() { |
111 | spaceShip = new SpaceShip(400, 300, 256, 256, oSpShipImage); |
113 | var buttonImage = new Image(); |
114 | buttonImage.src = 'images/button.png'; |
115 | buttonImage.onload = function() { |
117 | button = new Button(310, 450, 180, 120, 'normal', buttonImage); |
118 | $('#scene').mousedown(function(e) { |
119 | var mouseX = e.layerX || 0; |
120 | var mouseY = e.layerY || 0; |
122 | mouseX > spaceShip.x-128 && mouseX < spaceShip.x-128+spaceShip.w && |
123 | mouseY > spaceShip.y-128 && mouseY < spaceShip.y-128+spaceShip.h) { |
124 | spaceShip.bDrag = true; |
125 | spaceShip.x = mouseX; |
126 | spaceShip.y = mouseY; |
129 | if (mouseX > button.x && mouseX < button.x+button.w && mouseY > button.y && mouseY < button.y+button.h) { |
130 | button.state = 'pressed'; |
131 | button.imageShift = 262; |
134 | $('#scene').mousemove(function(e) { |
135 | var mouseX = e.layerX || 0; |
136 | var mouseY = e.layerY || 0; |
137 | if (!bDrawDialog && spaceShip.bDrag) { |
138 | spaceShip.x = mouseX; |
139 | spaceShip.y = mouseY; |
142 | if (button.state != 'pressed') { |
143 | button.state = 'normal'; |
144 | button.imageShift = 0; |
145 | if (mouseX > button.x && mouseX < button.x+button.w && mouseY > button.y && mouseY < button.y+button.h) { |
146 | button.state = 'hover'; |
147 | button.imageShift = 131; |
151 | $('#scene').mouseup(function(e) { |
152 | spaceShip.bDrag = false; |
154 | if (button.state == 'pressed') { |
155 | if (iDialogPage == 0) { |
157 | bDrawDialog = !bDrawDialog; |
158 | } else if (iDialogPage == 2) { |
160 | bDrawDialog = !bDrawDialog; |
165 | button.state = 'normal'; |
166 | button.imageShift = 0; |
168 | setInterval(drawScene, 30); |
Here are several explanations about new features. 1. Drawing animated space with stars (pretty easy – we will shift image coordinates):
5 | ctx.drawImage(backgroundImage, 0 + iBgShiftX, 0, 1024, 768, 0, 0, 800, 600); |
Hope that all rest code pretty understandable. I added comments quite anywhere.
Step 4. Custom files
All these files will available in our package
Separate big thanks to this book. This tell us about development of games in HTML5. Now it’s one of my favorite books 🙂
Conclusion
Are you like our new spaceship? 🙂 I will be glad to see your thanks and comments. Good luck!