HTML5 Game Development – Lesson 2. Today we continue a series of articles on game development in HTML5. Today we will continue basics (and maybe even advanced basics). I going to show you how to fill objects with gradient color, draw text, use custom fonts to draw text, basic animation, and most important: ui element – Button.
Our previous article you can read here: Developing Your First HTML5 Game – Lesson 1. I going to work with our previous script – we will just enhance it. I going to draw text using custom font, animate object (square) filled with gradient color, and will draw ‘Play / Pause’ button to pausing animation.
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 2 | 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 2</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; |
67 | background-image:url(../images/01.jpg); |
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
010 | function Circle(x, y, radius){ |
013 | this.radius = radius; |
015 | function Button(x, y, w, h, state, image) { |
027 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
029 | function drawCircle(ctx, x, y, radius) { |
030 | ctx.fillStyle = 'rgba(255, 35, 55, 1.0)'; |
032 | ctx.arc(x, y, radius, 0, Math.PI*2, true); |
036 | ctx.strokeStyle = 'rgba(0, 0, 0, 1.0)'; |
039 | function drawScene() { |
042 | ctx.font = '42px DS-Digital'; |
043 | ctx.textAlign = 'center'; |
044 | ctx.fillStyle = '#ffffff'; |
045 | ctx.fillText('Welcome to lesson #2', ctx.canvas.width/2, 50); |
046 | var bg_gradient = ctx.createLinearGradient(0, 200, 0, 400); |
047 | bg_gradient.addColorStop(0.0, 'rgba(255, 0, 0, 0.8)'); |
048 | bg_gradient.addColorStop(0.5, 'rgba(0, 255, 0, 0.8)'); |
049 | bg_gradient.addColorStop(1.0, 'rgba(0, 0, 255, 0.8)'); |
051 | ctx.fillStyle = bg_gradient; |
052 | ctx.moveTo(circles[0].x, circles[0].y); |
053 | for (var i=0; i<circles.length; i++) { |
054 | ctx.lineTo(circles[i].x, circles[i].y); |
059 | ctx.strokeStyle = 'rgba(0, 0, 255, 0.5)'; |
062 | if (circles[0].x <= 300 || circles[0].x >= 385) { |
067 | circles[0].x -= speed; |
068 | circles[0].y -= speed; |
069 | circles[1].x += speed; |
070 | circles[1].y -= speed; |
071 | circles[2].x += speed; |
072 | circles[2].y += speed; |
073 | circles[3].x -= speed; |
074 | circles[3].y += speed; |
076 | drawCircle(ctx, circles[0].x, circles[0].y, (hoveredCircle == 0) ? 25 : 15); |
077 | drawCircle(ctx, circles[1].x, circles[1].y, (hoveredCircle == 1) ? 25 : 15); |
078 | drawCircle(ctx, circles[2].x, circles[2].y, (hoveredCircle == 2) ? 25 : 15); |
079 | drawCircle(ctx, circles[3].x, circles[3].y, (hoveredCircle == 3) ? 25 : 15); |
081 | ctx.drawImage(button.image, 0, button.imageShift, button.w, button.h, button.x, button.y, button.w, button.h); |
083 | ctx.font = '30px DS-Digital'; |
084 | ctx.fillStyle = '#ffffff'; |
085 | ctx.fillText('Play/Pause', 135, 480); |
086 | ctx.fillText(button.state, 135, 515); |
091 | canvas = document.getElementById('scene'); |
092 | ctx = canvas.getContext('2d'); |
093 | var circleRadius = 15; |
094 | var width = canvas.width; |
095 | var height = canvas.height; |
097 | circles.push(new Circle(width / 2 - 20, height / 2 - 20, circleRadius)); |
098 | circles.push(new Circle(width / 2 + 20, height / 2 - 20, circleRadius)); |
099 | circles.push(new Circle(width / 2 + 20, height / 2 + 20, circleRadius)); |
100 | circles.push(new Circle(width / 2 - 20, height / 2 + 20, circleRadius)); |
102 | buttonImage = new Image(); |
103 | buttonImage.src = 'images/button.png'; |
104 | buttonImage.onload = function() { |
106 | button = new Button(50, 450, 180, 120, 'normal', buttonImage); |
108 | $('#scene').mousedown(function(e) { |
109 | var mouseX = e.layerX || 0; |
110 | var mouseY = e.layerY || 0; |
111 | for (var i=0; i<circles.length; i++) { |
112 | var circleX = circles[i].x; |
113 | var circleY = circles[i].y; |
114 | var radius = circles[i].radius; |
115 | if (Math.pow(mouseX-circleX,2) + Math.pow(mouseY-circleY,2) < Math.pow(radius,2)) { |
121 | if (mouseX > button.x && mouseX < button.x+button.w && mouseY > button.y && mouseY < button.y+button.h) { |
122 | button.state = 'pressed'; |
123 | button.imageShift = 262; |
126 | $('#scene').mousemove(function(e) { |
127 | var mouseX = e.layerX || 0; |
128 | var mouseY = e.layerY || 0; |
129 | if (selectedCircle != undefined) { |
131 | var radius = circles[selectedCircle].radius; |
132 | circles[selectedCircle] = new Circle(mouseX, mouseY,radius); |
134 | hoveredCircle = undefined; |
135 | for (var i=0; i<circles.length; i++) { |
136 | var circleX = circles[i].x; |
137 | var circleY = circles[i].y; |
138 | var radius = circles[i].radius; |
139 | if (Math.pow(mouseX-circleX,2) + Math.pow(mouseY-circleY,2) < Math.pow(radius,2)) { |
141 | circles[hoveredCircle] = new Circle(circleX, circleY, 25); |
146 | if (button.state != 'pressed') { |
147 | button.state = 'normal'; |
148 | button.imageShift = 0; |
149 | if (mouseX > button.x && mouseX < button.x+button.w && mouseY > button.y && mouseY < button.y+button.h) { |
150 | button.state = 'hover'; |
151 | button.imageShift = 131; |
155 | $('#scene').mouseup(function(e) { |
156 | selectedCircle = undefined; |
158 | if (button.state == 'pressed') { |
161 | button.state = 'normal'; |
162 | button.imageShift = 0; |
164 | setInterval(drawScene, 30); |
Here are several explanations about new features. 1. We can draw text (with custom font) using next code:
1 | ctx.font = '42px DS-Digital'; |
2 | ctx.textAlign = 'center'; |
3 | ctx.fillStyle = '#ffffff'; |
4 | ctx.fillText('Welcome to lesson #2', ctx.canvas.width/2, 50); |
2. Applying gradient color to objects:
1 | var bg_gradient = ctx.createLinearGradient(0, 200, 0, 400); |
2 | bg_gradient.addColorStop(0.0, 'rgba(255, 0, 0, 0.8)'); |
3 | bg_gradient.addColorStop(0.5, 'rgba(0, 255, 0, 0.8)'); |
4 | bg_gradient.addColorStop(1.0, 'rgba(0, 0, 255, 0.8)'); |
5 | ctx.fillStyle = bg_gradient; |
3. Button itself – I used one sprite image with all 3 button states. Also I added event handlers to hover/down events. Here are way of loading and drawing image at canvas:
1 | buttonImage = new Image(); |
2 | buttonImage.src = 'images/button.png'; |
4 | ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, width, height); |
Step 4. Custom files
Both files will available in our package
Conclusion
Cool, isn’t it? I will be glad to see your thanks and comments. Good luck!