HTML5 Game Development – Lesson 2
Join the DZone community and get the full member experience.
Join For Free
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:
live demo
download in package
ok, download the example files and lets start coding !
step 1. html
here are all html of my demo
index.html
<!doctype html> <html lang="en" > <head> <meta charset="utf-8" /> <title>html5 game development - lesson 2 | script tutorials</title> <link href="css/main.css" rel="stylesheet" type="text/css" /> <!--[if lt ie 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <script type="text/javascript" src="js/jquery-1.5.2.min.js"></script> <script type="text/javascript" src="js/script.js"></script> </head> <body> <div class="container"> <canvas id="scene" width="800" height="600"></canvas> </div> <footer> <h2>html5 game development - lesson 2</h2> <a href="http://www.script-tutorials.com/html5-game-development-lesson-2" class="stuts">back to original tutorial on <span>script tutorials</span></a> </footer> </body> </html>
step 2. css
here are used css styles.
css/main.css
/* general styles */ *{ margin:0; padding:0; } @font-face { font-family: "ds-digital"; src: url("../fonts/ds-digib.ttf"); } body { background-color:#bababa; background-image: -webkit-radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); background-image: -moz-radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); background-image: -o-radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); background-image: radial-gradient(600px 300px, circle, #ffffff, #bababa 60%); color:#fff; font:14px/1.3 arial,sans-serif; min-height:1000px; } .container { width:100%; } .container > * { display:block; margin:50px auto; } footer { background-color:#212121; bottom:0; box-shadow: 0 -1px 2px #111111; display:block; height:70px; left:0; position:fixed; width:100%; z-index:100; } footer h2{ font-size:22px; font-weight:normal; left:50%; margin-left:-400px; padding:22px 0; position:absolute; width:540px; } footer a.stuts,a.stuts:visited{ border:none; text-decoration:none; color:#fcfcfc; font-size:14px; left:50%; line-height:31px; margin:23px 0 0 110px; position:absolute; top:0; } footer .stuts span { font-size:22px; font-weight:bold; margin-left:5px; } h3 { text-align:center; } #scene { background-image:url(../images/01.jpg); position:relative; }
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
var canvas, ctx; var circles = []; var selectedcircle; var hoveredcircle; var button; var moving = false; var speed = 2.0; // ------------------------------------------------------------- // objects : function circle(x, y, radius){ this.x = x; this.y = y; this.radius = radius; } function button(x, y, w, h, state, image) { this.x = x; this.y = y; this.w = w; this.h = h; this.state = state; this.imageshift = 0; this.image = image; } // ------------------------------------------------------------- // draw functions : function clear() { // clear canvas function ctx.clearrect(0, 0, ctx.canvas.width, ctx.canvas.height); } function drawcircle(ctx, x, y, radius) { // draw circle function ctx.fillstyle = 'rgba(255, 35, 55, 1.0)'; ctx.beginpath(); ctx.arc(x, y, radius, 0, math.pi*2, true); ctx.closepath(); ctx.fill(); ctx.linewidth = 1; ctx.strokestyle = 'rgba(0, 0, 0, 1.0)'; ctx.stroke(); // draw border } function drawscene() { // main drawscene function clear(); // clear canvas // draw the title text ctx.font = '42px ds-digital'; ctx.textalign = 'center'; ctx.fillstyle = '#ffffff'; ctx.filltext('welcome to lesson #2', ctx.canvas.width/2, 50); var bg_gradient = ctx.createlineargradient(0, 200, 0, 400); bg_gradient.addcolorstop(0.0, 'rgba(255, 0, 0, 0.8)'); bg_gradient.addcolorstop(0.5, 'rgba(0, 255, 0, 0.8)'); bg_gradient.addcolorstop(1.0, 'rgba(0, 0, 255, 0.8)'); ctx.beginpath(); // custom shape begin ctx.fillstyle = bg_gradient; ctx.moveto(circles[0].x, circles[0].y); for (var i=0; i<circles.length; i++) { ctx.lineto(circles[i].x, circles[i].y); } ctx.closepath(); // custom shape end ctx.fill(); // fill custom shape ctx.linewidth = 2; ctx.strokestyle = 'rgba(0, 0, 255, 0.5)'; ctx.stroke(); // draw border // reverting direction if (circles[0].x <= 300 || circles[0].x >= 385) { speed = -speed; } // central object behavior if (moving) { circles[0].x -= speed; circles[0].y -= speed; circles[1].x += speed; circles[1].y -= speed; circles[2].x += speed; circles[2].y += speed; circles[3].x -= speed; circles[3].y += speed; } drawcircle(ctx, circles[0].x, circles[0].y, (hoveredcircle == 0) ? 25 : 15); drawcircle(ctx, circles[1].x, circles[1].y, (hoveredcircle == 1) ? 25 : 15); drawcircle(ctx, circles[2].x, circles[2].y, (hoveredcircle == 2) ? 25 : 15); drawcircle(ctx, circles[3].x, circles[3].y, (hoveredcircle == 3) ? 25 : 15); // draw button ctx.drawimage(button.image, 0, button.imageshift, button.w, button.h, button.x, button.y, button.w, button.h); // draw text ctx.font = '30px ds-digital'; ctx.fillstyle = '#ffffff'; ctx.filltext('play/pause', 135, 480); ctx.filltext(button.state, 135, 515); } // ------------------------------------------------------------- // initialization $(function(){ canvas = document.getelementbyid('scene'); ctx = canvas.getcontext('2d'); var circleradius = 15; var width = canvas.width; var height = canvas.height; // lets add 4 circles manually circles.push(new circle(width / 2 - 20, height / 2 - 20, circleradius)); circles.push(new circle(width / 2 + 20, height / 2 - 20, circleradius)); circles.push(new circle(width / 2 + 20, height / 2 + 20, circleradius)); circles.push(new circle(width / 2 - 20, height / 2 + 20, circleradius)); // load the guide sprite image buttonimage = new image(); buttonimage.src="images/button.png"; buttonimage.onload = function() { } button = new button(50, 450, 180, 120, 'normal', buttonimage); // binding mousedown event (for dragging) $('#scene').mousedown(function(e) { var mousex = e.layerx || 0; var mousey = e.layery || 0; for (var i=0; i<circles.length; i++) { // checking through all circles - are mouse down inside circle or not var circlex = circles[i].x; var circley = circles[i].y; var radius = circles[i].radius; if (math.pow(mousex-circlex,2) + math.pow(mousey-circley,2) < math.pow(radius,2)) { selectedcircle = i; break; } } // button behavior if (mousex > button.x && mousex < button.x+button.w && mousey > button.y && mousey < button.y+button.h) { button.state = 'pressed'; button.imageshift = 262; } }); $('#scene').mousemove(function(e) { // binding mousemove event for dragging selected circle var mousex = e.layerx || 0; var mousey = e.layery || 0; if (selectedcircle != undefined) { // var canvasposition = $(this).offset(); var radius = circles[selectedcircle].radius; circles[selectedcircle] = new circle(mousex, mousey,radius); // changing position of selected circle } hoveredcircle = undefined; for (var i=0; i<circles.length; i++) { // checking through all circles - are mouse down inside circle or not var circlex = circles[i].x; var circley = circles[i].y; var radius = circles[i].radius; if (math.pow(mousex-circlex,2) + math.pow(mousey-circley,2) < math.pow(radius,2)) { hoveredcircle = i; circles[hoveredcircle] = new circle(circlex, circley, 25); break; } } // button behavior if (button.state != 'pressed') { button.state = 'normal'; button.imageshift = 0; if (mousex > button.x && mousex < button.x+button.w && mousey > button.y && mousey < button.y+button.h) { button.state = 'hover'; button.imageshift = 131; } } }); $('#scene').mouseup(function(e) { // on mouseup - cleaning selectedcircle selectedcircle = undefined; // button behavior if (button.state == 'pressed') { moving = !moving; } button.state = 'normal'; button.imageshift = 0; }); setinterval(drawscene, 30); // loop drawscene });
here are several explanations about new features. 1. we can draw text (with custom font) using next code:
ctx.font = '42px ds-digital'; ctx.textalign = 'center'; ctx.fillstyle = '#ffffff'; ctx.filltext('welcome to lesson #2', ctx.canvas.width/2, 50);
2. applying gradient color to objects:
var bg_gradient = ctx.createlineargradient(0, 200, 0, 400); bg_gradient.addcolorstop(0.0, 'rgba(255, 0, 0, 0.8)'); bg_gradient.addcolorstop(0.5, 'rgba(0, 255, 0, 0.8)'); bg_gradient.addcolorstop(1.0, 'rgba(0, 0, 255, 0.8)'); 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:
buttonimage = new image(); buttonimage.src="images/button.png"; ....... ctx.drawimage(image, sx, sy, swidth, sheight, dx, dy, width, height);
step 4. custom files
fonts/ds-digib.ttf and images/button.png
both files will available in our package
live demo
download in 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
cool, isn`t it? i will be glad to see your thanks and comments. good luck!
Opinions expressed by DZone contributors are their own.
Comments