You are on page 1of 114

YIN YANG

2012

HTML5 Canvas Lp Trnh Game 2D


v1.0
L thuyt v demo thc hnh v lp trnh game 2D vi API Canvas trong Html5

http://vietgamedev.net/ http://yinyangit.wordpress.com/ 1/7/2012

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2 |P age

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

LI TA
Flash l mt cng ngh rt hiu qu, ph bin v cho php lp trnh vin c th to ra nhng ng dng vi y cc hiu ng hnh nh, m thanh c sc. Nhng cng ngh tng t nh Java Applet hay mt a con sng gi ca Microsoft l Silverlight cng khng th ng vng v cnh tranh c vi Flash. Nhng mt vn ny sinh y l kh nng tng tc gia cc cng ngh ny vi cc thnh phn xung quanh n (nh cc th HTML) dng nh khng th. Chng b c lp v hot ng c lp vi th gii bn ngoi. Gii php l quay tr li s dng thun HTML, Javascript v CSS, lp trnh vin vn c th to c ra ng dng vi hiu ng c bit v khng b cc gii hn m nhng cng ngh trn gp phi. Nhng tr ngi ln nht l khng c API to ra c nhng ng dng tng t nh trn Flash. V tc ca cc ng dng thun HTML kh chm, hu nh khng th chp nhn c vi mt game c yu cu cu hnh trung bnh. Nhng vi s ra i ca HTML5 cng vi cc thnh phn v API mi, gii hn trn b ph b v ang tng bc thay th dn cc cng ngh nh Flash. Vi cc ng dng cn nhng hiu ng ha v chuyn ng c bit, lp trnh vin c th s dng Canvas vi kiu bitmap hoc SVG vi kiu vector. Khng ch p dng cho vic thit k cc trang web trc quan, HTML5 cn c p dng to ra cc th vin ha gip to ra cc ng dng th, game trong c mi trng 2D v 3D nh nhng ng dng trn desktop. Mt iu ng mng na l HTML, Javascript v CSS khng cn b gii hn trn trnh duyt m c th c trin khai trn desktop di dng cc widget, trn cc thit b di ng v c th bt k thit b no. Nh vy, lp trnh vin khng cn s dng hay yu cu ngi dng ci t bt k th vin no c th chy c cc ng dng ca h. Mt li th rt ln m ch c HTML mi c th t c. Tuy nhin vic xy dng game trn trnh duyt c th l mt tri nghim kh khn v phi cn nhc gia vic chn la gia cc th vin hin i, y chc nng hay lm theo cc API cp thp ca HTML (thng qua Javascript). Qu trnh thc hin sch ny khng th trnh khi sai st, bn c c th gi phn hi ti http://vietgamedev.vn hoc blog http://yinyangit.wordpress.com hoc gi email trc tip cho ti (yinyang.it@gmail.com) thc mc, trao i cng nh gip ti sa i, cp nht nu cn thit. Xin cm n!

3 |P age

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Mc lc
A. B. I. GII THIU .......................................................................................................................... 9 HTML5 v cc API mi....................................................................................................... 10 Web Storage (DOM Storage)............................................................................................. 10 1. 2. 3. 4. 5. 6. II. 1. 2. 3. 4. III. 1. 2. 3. IV. 1. 2. 3. 4. C. I. Gii thiu .................................................................................................................... 10 Interface Storage ......................................................................................................... 10 Local Storage v Session Storage ............................................................................... 11 S dng ....................................................................................................................... 12 Storage event .............................................................................................................. 14 Thm cc phng thc vo Storage ........................................................................... 15 Web SQL Database ........................................................................................................ 16 Gii thiu .................................................................................................................... 16 Open Database ............................................................................................................ 16 Transaction ................................................................................................................. 17 Execute SQL ............................................................................................................... 17 Web Worker ................................................................................................................... 18 Gii thiu .................................................................................................................... 18 V d n gin nht: ................................................................................................... 19 Kt lun....................................................................................................................... 20 To chuyn ng vi WindowAnimationTiming API................................................... 20 setTimeout v setInterval............................................................................................ 21 WindowAnimationTiming.......................................................................................... 21 Li ch v hiu qu ..................................................................................................... 22 S dng ....................................................................................................................... 23

Canvas 2D API ..................................................................................................................... 25 V nh v thao tc vi pixel............................................................................................... 25 1. 2. II. 1. 2. III. 1. 2. Np v v nh ............................................................................................................. 25 Thao tc vi pixel ....................................................................................................... 26 V hnh bng chut ........................................................................................................ 30 Xc nh ta chut ................................................................................................. 30 Lu ni dung ca Canvas ........................................................................................... 31 Chn v di chuyn i tng ......................................................................................... 34 To cu trc d liu .................................................................................................... 34 Cc phng thc v bng context .............................................................................. 35 4 |P age

Yin Yang 3. IV. 1. 2. 3. V. 1. 2. 3. D. I.

HTML5 Canvas - Lp trnh Game 2D Cc s kin chut ca Canvas .................................................................................... 36

S dng bn phm .......................................................................................................... 37 Bt s kin bn phm .................................................................................................. 37 Kim tra trng thi ca nhiu phm ............................................................................ 38 Gii hn cc phm c bt ........................................................................................ 38 Chuyn ng trong Canvas ............................................................................................ 39 C bn ......................................................................................................................... 39 Thm hiu ng bng di chuyn .................................................................................. 41 Kim tra va chm ........................................................................................................ 42

K thut lp trnh Game C bn ........................................................................................ 44 Vng lp game (Game loop) hot ng th no? .............................................................. 44 1. 2. 3. 4. II. 1. 2. 3. III. IV. 1. 2. 3. 4. 5. V. VI. 1. 2. 3. VII. 1. 2. VIII. Vng lp c bn .......................................................................................................... 44 Vng lp c tnh ton thi gian .................................................................................. 45 Gii php cui cng .................................................................................................... 46 V d hon chnh......................................................................................................... 46 Kim tra va chm: hnh trn v ch nht ....................................................................... 47 Gia hai hnh ch nht................................................................................................ 47 Gia hai hnh trn ....................................................................................................... 48 Gia hnh trn v hnh ch nht ................................................................................. 48 Kim tra mt im nm trn on thng........................................................................ 50 Vector 2D c bn .......................................................................................................... 51 Khi nim ................................................................................................................... 51 Vector n v (Unit Vector, Normalized Vector) ....................................................... 51 Tch v hng (Dot product, Scalar product)............................................................. 52 Php chiu (Projection)............................................................................................... 52 Hin thc vi javascript .............................................................................................. 53 Khong cch t im n on thng ............................................................................ 54 Giao im ca hai ng thng ..................................................................................... 56 To phng trnh ng thng t on thng ............................................................ 56 Tnh giao im ca hai ng thng .......................................................................... 57 Minh ha vi HTML5 Canvas.................................................................................... 58 Va chm v phn x ....................................................................................................... 58 Kim tra hai on thng ct nhau ............................................................................... 58 Phng php ............................................................................................................... 59 Va chm gia ng trn v on thng .................................................................... 59 5 |P age

Yin Yang 1. 2. IX. 1. X. 1. 2. 3. E. I.

HTML5 Canvas - Lp trnh Game 2D Va chm ...................................................................................................................... 59 Phn x........................................................................................................................ 60

Va chm gia nhiu ng trn ..................................................................................... 62 X l va chm ca nhiu ng trn.......................................................................... 63 Kim tra va chm da trn pixel .................................................................................... 64 Mt wrapper ca Image .............................................................................................. 65 Xc nh vng giao hai hnh ch nht ........................................................................ 66 Kim tra va chm ........................................................................................................ 67

K thut lp trnh Game Nng cao .................................................................................... 69 Cun nh nn v bn (Map Scrolling) .......................................................................... 69 1. 2. 3. II. III. IV. 1. 2. 3. 4. V. 1. VI. 1. 2. VII. 1. 2. 3. nh nn nhiu tng ..................................................................................................... 69 Cun gi ...................................................................................................................... 70 v cun tht ............................................................................................................ 70 To Amimated Sprite ..................................................................................................... 71 Np trc hnh nh v ti nguyn .................................................................................. 75 Phng to/thu nh game bng nt cun chut ................................................................. 76 S kin Mouse Wheel trong javascript....................................................................... 78 Thay i kch thc bn ........................................................................................ 78 V tng vng bn ................................................................................................... 79 p dng cho cc nhn vt trn bn ........................................................................ 79 Thay i kch thc Canvas theo trnh duyt ................................................................ 80 iu chnh canvas thao kch thc trnh duyt .......................................................... 80 S dng Full Screen API................................................................................................ 82 Gii thiu .................................................................................................................... 82 V d ........................................................................................................................... 84 To menu v chuyn i gia cc mn hnh Game ....................................................... 86 Lp MenuItem ............................................................................................................ 86 Lp Screen .................................................................................................................. 87 Kim tra kt qu.......................................................................................................... 89

F. I. II.

AI trong game....................................................................................................................... 90 Gii thiu ........................................................................................................................... 90 Phn tch la chn thut ton .................................................................................... 90 Thut ton Breadth First Search ..................................................................................... 91 Cc quy tc trong game .................................................................................................. 92 Xy dng mt lp Queue da trn mng ....................................................................... 93 6 |P age

III. IV. V.

Yin Yang VI. VII. VIII. G. I.

HTML5 Canvas - Lp trnh Game 2D

Ci t thut ton Breadth First Search.......................................................................... 94 Di chuyn i tng theo ng i................................................................................ 96 Vng lp chnh ca game ........................................................................................... 96

Mt nn tng game 2D side-scrolling .................................................................................. 98 C bn ................................................................................................................................ 98 1. 2. II. 1. 2. 3. 4. To bn .................................................................................................................. 98 Kim tra va chm ........................................................................................................ 98 Thm cc chc nng v nhn vt ................................................................................. 101 Lp Character ........................................................................................................... 101 Lp Monster ............................................................................................................. 103 Lp Player................................................................................................................. 104 Lp Map ................................................................................................................... 105

H. I.

Mt s ng dng minh ha ................................................................................................ 107 Game ua xe..................................................................................................................... 107 1. 2. 3. 4. 5. 6. II. 1. 2. 3. 4. 5. 6. 7. III. Cc thng s ca xe .................................................................................................. 107 Di chuyn v quay xe ............................................................................................... 107 Kim tra va chm (tip xc) vi a hnh ................................................................. 108 Hn ch xe di chuyn v xoay khi b va chm ......................................................... 109 To cc checkpoint ................................................................................................... 109 Kt qu ...................................................................................................................... 109 Game bn i bc ......................................................................................................... 110 Bn v a hnh .................................................................................................... 110 Ph hy mt phn a hnh ....................................................................................... 111 Trng lc v Gi ....................................................................................................... 111 Di chuyn Cannon .................................................................................................... 111 St thng ca n.................................................................................................... 111 H tr nhiu ngi chi............................................................................................ 112 Kt qu ...................................................................................................................... 112 Game Mario.................................................................................................................. 113

I. J.

Li kt ................................................................................................................................ 114 Ti liu tham kho .............................................................................................................. 114

7 |P age

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

8 |P age

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

A. GII THIU
HTML5 c h tr hu trn tt c trnh duyt. N l mt tp hp cc tnh nng c bit. nhng ta c th tm thy h tr cho mt s phn c trng nh canvas, video hoc nh v a l. Nhng c im k thut HTML5 cng xc nh lm th no nhng du ngoc nhn tng tc vi JavaScrip, thng qua cc ti liu thng qua cc ti liu Object Model (DOM) HTML5 khng ch xc nh mt tag <video>, cng l mt DOM API tng ng cho cc i tng video trong DOM. Bn c th s dng API ny tm kim h tr cho cc nh dng video khc nhau, nghe nhc, tm dng mt on video, mute audio , theo di bao nhiu video c ti v, v mi th khc bn cn phi xy dng mt tri nghim ngi dng phong ph xung quanh tag <video> . Khng cn phi vt b bt k th g: Ta khng th ph nhn rng HTML 4 l cc nh dng nh du thnh cng nht t trc n nay. HTML5 c xy dng da trn thnh cng . Bn khng cn phi b nhng nh du hin c. Bn khng cn phi hc li nhng iu bn bit. Nu ng dng web ca bn trc y s dng HTML 4, n vn s hot ng trong HTML5. By gi, nu bn mun ci thin cc ng dng web, bn n ng ni. V d c th: HTML5 h tr tt c cc hnh thc kim sot t HTML 4, nhng n cng bao gm iu khin u vo mi. Mt s trong s ny l qu hn b sung nh cc thanh trt v date pickkers, nhng thnh phn khc tinh t hn. V d, cc loi email input trng ging nh mt textbox, nhng cc trnh duyt linh ng s ty bin bn phm trn mn hnh ca h c th d dng hn khi nhp a ch email. Cc trnh duyt c khng h tr cc loi email input s xem n nh l mt vn bn thng thng, v hnh thc vn lm vic khng c thay i nh du hoc kch bn hack. iu ny c ngha l bn c th bt u ci thin cc hnh thc web ca bn ngy hm nay, ngay c khi mt s khch truy cp vo web ca bn. Rt d dng bt u: "Nng cp" ln HTML5 c th n gin ch bng vic thay i th DOCTYPE ca bn. DOCTYPE cn phi nm trong dng u tin ca tt c cc trang HTML. Cc phin bn trc ca HTML c nh ngha rt nhiu loi doctype, v la chn mt doctype ng rt rc ri. Trong HTML5 ch c mt DOCTYPE:
<!DOCTYPE html>

Nng cp ln DOCTYPE HTML5 s khng ph v cu trc ti liu ca bn, bi v cc th li thi trc y c nh ngha trong HTML 4 vn c v ra trong HTML5. Nhng n cho php bn s dng v xc nhn cc th mi nh <article> <section> , <header> , v <footer>

9 |P age

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

B. HTML5 v cc API mi
HTML5 b sung rt nhiu API mi m lp trnh vin c th s dng h tr cho cc ng dng game ca mnh. V d nh lu li d liu vi Web Storage, Web Sql, Indexed DB, thc hin cng vic song song vi Web Worker, giao tip vi server thng qua Web Socket. Do thi lng c lng, ti ch trnh by mt phn nh trong s ny.

I. Web Storage (DOM Storage)


HTML5 cung cp mt tnh nng lu tr d liu ti client vi dung lng gii hn ln hn nhiu so vi cookie. Tnh nng ny c gi l Web Storage v c chia thnh hai i tng l localStorage v sessionStorage. Bi vit ny s gip bn nm c cc kin thc y v s dng hai i tng ny trong vic lp trnh web.

1. Gii thiu
Hin nay, mi cookie ch cho php lu tr ti a 4KB v vi chc cookie cho mt domain. V th cookie ch c dng lu tr nhng thng tin n gin v ngn gn nh email, username, gip ngi dng ng nhp t ng vo trang web. iu ny khin cho nhng trang web mun nng cao hiu sut lm vic bng cch cache d liu ti client hu nh khng th thc hin c. S xut hin ca Web Storage l mt im nhn cho vic ra i cc ng dng web c kh nng tng tc v np d liu tc th trn trnh duyt. Mt hiu q u na l dung lng truyn ti qua mng c th c gim thiu ng k. V d mt ng dng tra cu sch trc tuyn, cc sch c tra s c lu li trn my ca ngi dng. Khi cn tra li, my ngi dng s khng cn kt ni n server ti li nhng d liu c. Vi nhng ng dng web c c s d liu nh gn, lp trnh vin c th thc hin vic cache m thm c s d liu xung client v sau ngi dng c th thoi mi tra cu m khng cn request n server.

2. Interface Storage
interface Storage { readonly attribute unsigned long length; DOMString? key(unsigned long index); getter DOMString getItem(DOMString key); setter creator void setItem(DOMString key, DOMString value); deleter void removeItem(DOMString key); void clear(); };

10 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Nh bn thy, cc d liu lu tr trong Storage ch l kiu chui, vi cc loi d liu khc s nguyn, s thc, bool, bn cn phi thc hin chuyn i kiu. Mi i tng Storage l mt danh sch cc cp key/value, i tng ny bao gm cc thuc tnh v phng thc: length: s lng cp key/value c trong i tng. key(n): tr v tn ca key th n trong danh sch. getItem(key): tr v value c gn vi key. setItem(key,value): thm hoc gn mt cp key/value vo danh sc h. removeItem(key): xa cp key/value khi danh sch. clear: xa ton b d liu trong danh sch.

Bn cnh , i tng Storage cn c th c truy xut qua cc thuc tnh l cc key trong danh sch. V d:
localStorage.abc="123"; // equivalent to: // localStorage.setItem("abc","123");

3. Local Storage v Session Storage


Hai i tng ny l c to ra t interface Storage, bn s dng hai i tng ny trong javascript qua hai bin c to sn l window.localStorage v window.sessionStorage. Hai li ch m chng mang li l: D s dng: bn c th truy xut d liu ca hai i tng ny thng qua cc thuc tnh hoc cc phng thc. D liu c lu tr theo tng cp key/value v khng cn bt k cng vic khi to hay chun b no. Dung lng lu tr ln: Ty theo trnh duyt, bn c th lu tr t 5MB n 10MB cho mi domain. Theo Wikipedia th con s ny l: 5MB trong Mozilla Firefox, Google Chrome,v Opera, 10MB trong Internet Explorer. Phm vi: sessionStorage: gii hn trong mt ca s hoc th ca trnh duyt. Mt trang web c m trong hai th ca cng mt trnh duyt cng khng th truy xut d liu ln nhau. Nh vy, khi bn ng trang web th d liu lu trong sessionStorage hin ti cng b xa. 11 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

localStorage: c th truy xut ln nhau gia cc ca s trnh duyt. D liu s c lu tr khng gii hn thi gian. i vi localStorage:
Each domain and subdomain has its own separate local storage area. Domains can access the storage areas of subdomains, and subdomains can access the storage areas of parent domains. For example, localStorage['example.com'] is accessible to example.com and any of its subdomains. The subdomain localStorage['www.example.com'] is accessible to example.com , but not to other subdomains, such as mail.example.com . http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx

4. S dng
Bn c th to mt tp tin HTML vi ni dung pha di chy trn trnh duyt. y ta s dng Chrome v n cung cp sn ca s xem phn Resources trong Google Chrome Developer Tools (Ctrl + Shift + I). Ni dung ca tp tin HTML nh sau:
<!DOCTYPE html> <html> <body> <script type="text/javascript"> sessionStorage.myVariable="Hello. "; localStorage.myVariable="Nice to meet you!"; document.write(sessionStorage.myVariable); document.write(localStorage.myVariable); </script> </body> </html>

Kt qu hin th:

12 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Trong giao din xem Resources, bn c th m phn Console g cc lnh javascript tng tc vi trang web hin ti. V d y ta thm cc gi tr mi vo trong localStorage v dng alert() hin th chng ln.

13 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

5. Storage event
i tng Window trong javascript cung cp mt event vi tn storage. Event ny c kch hot mi khi storageArea b thay i.
interface StorageEvent : Event { readonly attribute DOMString key; readonly attribute DOMString? oldValue; readonly attribute DOMString? newValue; readonly attribute DOMString url; readonly attribute Storage? storageArea; };

Event ny c th khng hot ng khi bn xem tp tin HTML my cc b v ch c kch hot nhng ca s/th khc. Tc l khi bn m nhiu ca s trnh duyt truy xut n cng domain, nu bn thay i mt i tng Storage bn ca s ny th cc ca s cn li s c kch hot event storage, cn ca s hin ti s khng xy ra g c.
<!DOCTYPE html> <html> <body> <button onclick="changeValue();">Change Value</button> <script type="text/javascript"> localStorage.clear(); console.log(localStorage); if (window.addEventListener) window.addEventListener('storage', storage_event, false); else if (window.attachEvent) // IE window.attachEvent('onstorage', storage_event, false); function storage_event(event){ console.log(event); } function changeValue() { localStorage.myValue=Math.random(); } </script> </body> </html>

14 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

6. Thm cc phng thc vo Storage


Cc phng thc ca Storage c th khng p ng yu cu ca bn, v vy bn c th thm mt vi phng thc mi vo s dng khi cn thit. V d ta s thm phng thc search() lc ra cc gi tr cha t kha cn tm kim.
Storage.prototype.search = function(keyword) { var array=new Array(); var re = new RegExp(keyword,"gi"); for (var i = 0; i < this.length; i++) { var value=this.getItem(this.key(i)); if(value.search(re)>-1) array.push(value); } return array; }

Phng thc trn s dng biu thc chnh quy tm kim theo hai ty chn g (tm kim ton b chui) v i (khng phn bit hoa thng). Phng thc string.search() tr v v tr ca k t u tin khp vi t kha tm kim, ngc li l -1 nu khng tm thy.

15 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

II. Web SQL Database


Web SQL Database l mt cng ngh kt hp gia trnh duyt v SQLite h tr vic to v qun l database pha client. Cc thao tc vi database s c thc hin bi javasc ript v s dng cc cu lnh SQL truy vn d liu.

1. Gii thiu
Li ch ca SQLite l c c tch hp vo cc ng dng vi mt th vin duy nht truy xut c database. Chnh v vy, bn c th s dng n lm c s d liu cho nhng ng dng nh v khng cn thit ci t bt k phn mm hoc driver no. Hin ti Web SQL Database c h tr trong cc trnh duyt Google Chrome, Opera v Safari. Trong javascript, bn s dng cc phng thc chnh sau lm vic vi Web SQL Database. openDatabase: m mt database c sn hoc to mi nu n cha tn ti. transaction / readTransaction: h tr thc hin cc thao tc vi database v rollback nu xy ra sai st. executeSql: thc thi mt cu lnh SQL.

2. Open Database
Phng thc ny c nhim v m mt database c sn hoc to mi nu n cha tn ti. Phng thc ny c khai bo nh sau:
Database openDatabase( in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback );

Tham s: name: tn ca database. version: phin bn. Hai database trng tn nhng khc phin bn th khc nhau. displayname: m t. estimatedSize: dung lng c tnh theo n v byte. creationCallback: phng thc callback c thc thi sau khi database m/to. V d to mt database vi tn mydb v dung lng l 5 MB:
var db = openDatabase("mydb", "1.0", "My First DB", 5 * 1024 * 1024);

16 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Transaction
Bn cn thc thi cc cu SQL trong ng cnh ca mt transactio n. Mt transaction cung cp kh nng rollback khi mt trong nhng cu lnh bn trong n thc thi tht bi. Ngha l nu bt k mt lnh SQL no tht bi, mi thao tc thc hin trc trong transaction s b hy b v database khng b nh hng g c. Interface Database h tr hai phng thc gip thc hin iu ny l transaction() v readTransaction(). im khc bit gia chng l transaction() h tr read/write, cn readTransaction() l read-only. Nh vy s dng readTransaction() s cho hiu sut cao hn nu nh bn ch cn c d liu.
void transaction( in SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback );

V d:
var db = openDatabase("mydb", "1.0", "My First DB", 5 * 1024 * 1024); db.transaction(function (tx) { // Using tx object to execute SQL Statements });

4. Execute SQL
executeSql() l phng thc duy nht thc thi mt cu lnh SQL trong Web SQL. N c s dng cho c mc ch c v ghi d liu
void executeSql( in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback );

V d 1: to bng Customers v thm hai dng d liu vo bng ny.


db.transaction(function tx.executeSql("CREATE tx.executeSql("INSERT tx.executeSql("INSERT }); (tx) { TABLE IF NOT EXISTS CUSTOMERS(id unique, name)"); INTO CUSTOMERS (id, name) VALUES (1, 'peter')"); INTO CUSTOMERS (id, name) VALUES (2, 'paul')");

Tuy nhin cch thc thi SQL trn khng c r rng v c th b cc vn v bo mt nh SQL injection. V vy tt hn bn nn cc tham s cn truyn cho cu SQL trong mt mng v t vo lm tham s th 2 ca phng thc executeSql(). Cc v tr trong cu SQL cha tham s s c thay th bi du ?: 17 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

tx.executeSql("INSERT INTO CUSTOMERS (id, name) VALUES (?,?)", [1,"peter"]); tx.executeSql("INSERT INTO CUSTOMERS (id, name) VALUES (?,?)", [2,"paul"]);

III. Web Worker


Vi cng ngh phn cng hin nay, vic s dng a lung tr nn mt phn khng th thiu trong cc phn mm. Tuy nhin, cng ngh thit k web vn cha tn dng c sc mnh ny. Vi cc cng vic i hi mt qu trnh x l lu, lp trnh vin thng phi s dng nhng th thut nh setTimeout(), setInterval(), thc hin tng phn cng vic. Hin nay, gii quyt vn ny, mt API mi dnh cho javascript xut hin vi tn gi Web Worker.

1. Gii thiu
i tng Web Worker c to ra s thc thi trong mt thread c lp v chy ch nn nn khng nh hng n giao din tng tc ca trang web vi ngi dng. Vi c im ny, bn c th s dng Web Workert cc cng vic i hi thi gian x l lu np d liu, to cache, im hn ch ca Web Worker l khng th truy xut c thnh phn trn DOM, v c cc i tng window, document hay parent. M lnh cc cng vic cn thc thi cng phi c cch ly trong mt tp tin script. Vic to mt Web Worker s cn thc hin nh sau:
var worker = new Worker('mytask.js');

Tp tin script s c ti v v Worker ch c thc thi sau khi tp tin ny ti hon tt. Trong tp tin script ny, ta s x l s kin message ca Worker t cc d liu nhn c thng qua phng thc postMessage(). Phng thc ny chp nhn mt tham s cha thng ip cn gi n tp tin script x l. D liu ny s c ly thng qua thuc tnh data ca tham s event trong hm x l s kin message. Quy trnh ny c m t trong hnh sau:

18 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2. V d n gin nht:
To hai tp tin sau trong cng mt th mc: mytask.js:
this.onmessage = function (event) { var name = event.data; postMessage("Hello "+name); };

Test.html:
<!DOCTYPE html> <body> <input type="text" id="username" value="2" /> <br /> <button id="button1">Submit</button> <script> worker = new Worker("mytask.js"); worker.onmessage = function (event) { alert(event.data); }; document.getElementById("button1").onclick = function() {

19 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D


var name = document.getElementById("username").value;

worker.postMessage(name); }; </script> </body> </html>

By gi bn chy th v nhn nt Submit, mt thng ip s hin th vi ni dung tng t Hello Yin Yang.

3. Kt lun
Vi cc cng vic n gin, lp trnh vin s gi i mt d liu kiu mng bao gm tn lnh v cc d liu cn x l. Worker s phn tch d liu nhn c v gi cc phng thc x l tng ng. Tuy nhin, mt Worker bn to ra ch nn dnh ring thc hin mt cng vic c th. Bi v mc ch chnh ca vic to ra chng l lm nhng cng vic nng nhc. Cui cng, khi hon tt cng vic, bn hy gii phng cho Worker bng cch dng phng thc worker.terminate(). Bn c th xem demo sau v cch s dng Web Worker thc hin ng thi vic tnh ton tm cc s nguyn t v cp nht li canvas:

IV. To chuyn ng vi WindowAnimationTiming AP I


Thay v t timeout gi cc phng thc v li hnh nh, cch tt nht m bn nn s dng to cc hiu ng chuyn ng trong canvas l dng API WindowAnimationTiming, thng qua phng thc chnh l requestAnimationFrame().

20 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

1. setTimeout v setInterval
Cch truyn thng m bn dng to cc hiu ng ha chuyn ng vi javascript l gi lin tc cng vic update v draw sau nhng khong thi gian xc nh thng qua phng thc setInterval() hoc setTimeout(). Mi ln gi, mt frame (khung hnh) mi s c to ra v v ln mn hnh c. Kh khn ca phng php ny l kh xc nh c gi tr thi gian thch hp da trn mi thit b c s dng (thng thng khong 60 fps frames per second). Ngoi ra vi nhng hiu ng phc tp th vic update/draw c th din ra lu hn so vi thi gian gia hai ln gi. Cch tng qut gii quyt vn trn l thc hin tnh ton da vo khong cch thi gian gia ln gi trc v hin ti, sau xc nh b qua mt vi bc draw hoc thay i gi tr timeout cho ph hp.

2. WindowAnimationTiming
Mt tnh nng mi ra i cho php bn n gin ha cng vic ny l API WindowAnimationTiming. y l mt interface bao gm hai phng thc l requestAnimationFrame() v cancelAnimationFrame(). Vic xc nh thi im cp nht frame s c t ng chn gi tr thch hp nht.
interface WindowAnimationTiming { long requestAnimationFrame(FrameRequestCallback callback); void cancelAnimationFrame(long handle); }; Window implements WindowAnimationTiming; callback FrameRequestCallback = void (DOMTimeStamp time);

requestAnimationFrame: gi request n trnh duyt thc hin mt hnh ng update/draw

frame mi thng qua tham s callback. Cc request ny s c lu trong i tng document vi cc cp <handle, callback> v c thc hin ln lt. Gi tr handle l mt s nh danh c to ra v tr v sau khi gi phng thc ny. cancelAnimationFrame: hy mt request c to ra requestAnimationFrame vi tham s l handle ca request. Ngoi ra cn c thuc tnh window.mozAnimationStartTime (ch mi c h tr trn Firefox) cha gi tr milisecond l khong cch t mc thi gian (1/1/1970) n thi im bt u ca request cui cng c thc hin. Gi tr ny tng ng vi gi tr tr v ca Date.now() hoc Date.getTime(), mc thi gian l bao nhiu khng quan trng nhng n gip bn bit c khong thi gian gia hai ln thc hin request.

21 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Li ch v hiu qu
Microsoft cho ta mt v d trc quan v hiu qu ca requestAnimationFrame() so vi setTimeout() ti trang requestAnimationFrame API. Qua v d ny, ta thy c s ln gi callback (update) thc t ca setTimeout() ln hn so vi d tnh. Ngoi ra cc kt qu cho thy hiu sut ca vic thc thi callback, CPU, mc tiu tn nng lng v nh hng n cc tc v nn ca requestAnimationFrame() hn hn so vi setTimeout():

22 | P a g e

Yin Yang
setTimeout Expected callbacks Actual callbacks Callback Efficiency Callback Efficiency Power Consumption Background Interference 40543 41584 59.70% Medium Medium High

HTML5 Canvas - Lp trnh Game 2D


requestAnimationFrame 40544 40544 100.00% High Low Low

Mt hiu qu khc cc animation s t ng dng li nu tab cha n khng c hin th (khi bn chuyn sang mt tab khc ca trnh duyt). iu ny gip hn ch c ti nguyn s dng mt cch hp l.

4. S dng
Kim tra trnh duyt h tr: Ty theo trnh duyt m tn ca phng thc ny s c nhng prefix khc nhau (vendor):
_reqAnimation = window.requestAnimationFrame || window.mozRequestAnimationFrame window.webkitRequestAnimationFrame window.msRequestAnimationFrame window.oRequestAnimationFrame || || || ;

if(_reqAnimation) update(); else alert("Your browser doesn't support requestAnimationFrame.");

V d hon chnh:
<HTML> <head> <script> const RADIUS = 20; var cx = 100; var cy = 100; var speedX = 2; var speedY = 2; var _canvas; var _context; var _reqAnimation; var _angle = 0; function update(time) { cx += speedX; cy += speedY;

23 | P a g e

Yin Yang
if(cx<0 || cx > _canvas.width) speedX = -speedX; if(cy<0 || cy > _canvas.height) speedY = -speedY;

HTML5 Canvas - Lp trnh Game 2D

// draw _context.clearRect(0, 0, _canvas.width, _canvas.height); _context.beginPath(); _context.arc(cx, cy, RADIUS, 0, Math.PI*2, false); _context.closePath(); _context.fill(); _reqAnimation(update); } window.onload = function(){ _canvas = document.getElementById("canvas"); _context = _canvas.getContext("2d"); _context.fillStyle = "red"; cx = _canvas.width/2; cy = _canvas.height/2; _reqAnimation = window.requestAnimationFrame || window.mozRequestAnimationFrame window.webkitRequestAnimationFrame window.msRequestAnimationFrame window.oRequestAnimationFrame || || || ;

if(_reqAnimation) update(); else alert("Your browser doesn't support requestAnimationFrame."); }; </script> </head> <body> <canvas id="canvas" width="400px" height="300px" style="border: 1px solid"></canvas> </body> </HTML>

24 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

C. Canvas 2D API
HTML5 xc nh <canvas> nh mt bitmap ph thuc vo phn gii, c s dung v th, ha game hoc hnh nh trc quan khc. Canvas l hnh ch nht trn trang v c th s dng JavaScript v bt c iu g bn mun. HTML5 nh ngha mt tp cc chc nng ( canvas API) v hnh dng, xc nh ng dn, to gradient. HTML5 Canvas l mt JavaScript API m ha cc bn v. Canvas API cho php nh ngha mt i tng canvas nh l th <canvas> trn trang HTML ,chng ta c th v bn trong n. <canvas> l mt khi khng gian v hnh, mc nh l 300x250 pixels (trn tt c trnh duyt) Chng ta c th v c hnh 2D v 3D (WebGL). 2D c sn trong tt c cc trnh duyt Web hin i, IE9, v thng qua th vin excanvas.js trong cc phin bn IE hin ti. Canvas 2D cung cp mt API n gin nhng mnh m c th v mt cch nhanh chng trn b mt bitmap 2D. Khng c nh dng tp tin, v bn ch c th v bng cch s dng script. Bn khng c bt k cc nt DOM cho cc hnh khi bn v - bn ang v pixels, khng phi vect v ch l cc im nh c ghi nh. Mt s tnh nng c Canvas: V hnh nh T mu To hnh hc v cc kiu mu Vn bn Sao chp hnh nh, video, nhng canvas khc Thao tc im nh Xut ni dung ca mt th <canvas> sang tp tin nh tnh.

I. V nh v thao tc vi pixel
Mun to ra nhng hiu ng ha c bit khi s dng canvas, bn khng th ch s dng c thuc tnh v phng thc c sn ca i tng context. Chnh v vy, bi vit ny s gii thiu cho bn cch v nh v thao tc vi cc pixel t i tng ImageData.

1. Np v v nh
v mt nh ra canvas, ta to mt i tng image v thc hin phng thc context.drawImage() trong s kin load ca image. Nh vy m bo rng hnh nh ch c v sau khi c np hon tt. Ngoi ra, bn nn t s kin load trc khi gn ng dn cho nh. Nu khng image c th c load xong trc khi bn gn s kin load cho n. Phng thc drawImage() c ba overload sau: 25 | P a g e

Yin Yang - V image ti mt v tr destX, destY:


context.drawImage(image,destX,destY);

HTML5 Canvas - Lp trnh Game 2D

- V image ti v tr destX, destY v kch thc destWidth, destHeight:


context.drawImage(image,destX,destY,destWidth,destHeight);

- Ct image ti v tr [sourceX, sourceY, sourceWidth, sourceHeight] v v ti [destX, destY, destWidth, destHeight]:


context.drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);

V d:
window.onload = function(){ var canvas = document.getElementById("mycanvas"); var context = canvas.getContext("2d"); var img = new Image(); img.onload = function(){ context.drawImage(img, 10, 10,50,50); }; img.src = "foo.png"; };

2. Thao tc vi pixel
Mt nh bao gm mt mng cc pixel vi cc gi tr red, green, blue v alpha (RGBA). Trong alpha l gi tr xc nh m c (opacity) ca nh. Gi tr alpha cng ln th mu sc cng r nt v mu sc s tr nn trong sut nu alpha l 0. Trong Canvas 2D API, d liu nh c lu trong mt i tng ImageData vi 3 thuc tnh l width, height v data. Trong data l mt mng mt chiu cha cc pixel. Mi pixel cha 4 phn t tng ng l R,G,B,A. Nh vy vi mt nh c kch thc 1020 ta s c 200 pixel v c 200*4=400 phn t trong mng ImageData.data. 26 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Bn c th tham kho thng tin v cc API ny ti: http://www.whatwg.org/specs/webapps/current-work/multipage/the-canvas-element.HTML#pixel-manipulation:

imagedata = context.createImageData(sw, sh) Tr v mt i tng ImageData vi kch thc sw x sh. Tt c pixel ca i tng ny c mu en trong sut. imagedata = context.createImageData(imagedata) Tr v i tng ImageData vi kch thc bng vi i tng trong tham s. Tt c pixel c mu en trong sut. imagedata = context.getImageData(sx, sy, sw, sh) Tr v mt i tng ImageData cha d liu nh vng ch nht (xc nh bi cc tham s) ca canvas. Nm NotSupportedError exception nu nh c bt k tham s no khng phi l s hp l. Nm IndexSizeError exception nu width hoc height l zero. imagedata.width imagedata.height
Tr v kch thc tht ca i tng ImageData, tnh theo pixel. imagedata.data

Tr v mng mt chiu cha d liu dng RGBA, mi gi tr nm trong khong 0 n 255. context . putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])

27 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

V d liu t i tng ImageData ln canvas ti v tr dx, dy. Nu nh hnh ch nht (t cc tham s dirtyX, dirtyY, dirtWidth, dirtyHeight) c xc nh, th phn d liu ca ImageData trong vng ch nht ny mi c v ln canvas.

Cc thuc tnh xc nh hiu ng v ca context s b b qua khi phng thc ny c gi. Cc pixel t canvas s c thay th hon ton bi ImageData m khng c cc s kt hp mu sc, hiu ng, vi cc d liu nh sn c trn canvas. Mt trong nhng v d thng gp v n gin nht l o ngc mu ca nh. iu ny c thc hin bng cch ly gi tr mu ti a (255) tr i gi tr ca mi knh mu RGB hin ti ca mi pixel. Gi tr alpha s gi tr ti a nh c r nt nht.
<HTML> <head> <script> window.onload = function(){ var img = new Image(); img.onload = function(){ invertColor(this); }; img.src="panda.jpg"; }; function invertColor(img){ var canvas = document.getElementById("mycanvas"); var context = canvas.getContext("2d"); // draw image at top-left corner context.drawImage(img,0,0); // draw original image right beside the previous image context.drawImage(img,img.width,0); // get ImageData object from the left image var imageData = context.getImageData(0, 0, img.width, img.height); var data = imageData.data;

28 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D


for (var i = 0; i < data.length; i += 4) { data[i] data[i + 1] data[i + 2] data[i + 3] } context.putImageData(imageData,0,0); = = = = 255 - data[i]; // red 255 - data[i+1]; // green 255 - data[i+2]; // blue 255; // alpha

} </script> </head> <body> <canvas id="mycanvas" width="600" height="250"></canvas> </body> </HTML>

Kt qu:

Bn c th thm cc tham s to mt dirty rectangle trong phng thc putImageData() nu mun v ImageData ln mt vng ch nht xc nh ca canvas. V d ta chn cng mt vng ch nht trn ImageData v v ln hai vng ch nht khc nhau trn canvas c kt qu sau:
context.putImageData(imageData,0,0,0,0,img.width/2,img.height/2); context.putImageData(imageData,img.width,0,0,0,img.width/2,img.height/2);

29 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

II. V hnh bng chut


Trong phn ny, ta s tm hiu cch bt v x l cc thao tc chut trn Canvas thc hin mt ng dng v hnh n gin. Bn cnh , bn c th bit c cch lu v phc hi li d liu ca canvas khi cn thit.

1. Xc nh ta chut
xc nh c ta chut trn canvas, ta s s dng tham s ca cc s kin nh mousedown, mousemove, Tham s ca cc s kin ny cha ta chut lu trong hai bin pageX v pageY. Ta s dng ta ny tr i ta ca canvas (canvas.offsetLeft v canvas.offsetTop) ly c v tr chnh xc ca chut trn canvas. u tin l vic m phng cng c Pen cho php v t do trong canvas:
<HTML> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> var preX; var preY; var paint; var canvas; var context; $(function(){ canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); $('#canvas').mousedown(function(e){ preX = e.pageX - this.offsetLeft; preY = e.pageY - this.offsetTop; paint = true; }); $('#canvas').mousemove(function(e){

30 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

if(paint){ var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); preX = x; preY = y; } }); $('#canvas').mouseenter(function(e){ if(paint) { preX = e.pageX - this.offsetLeft; preY = e.pageY - this.offsetTop; } }); $("#canvas").mouseup(function(){ paint = false; }); $('#canvas').mouseleave(function(e){ paint = false; }); }); </script> </head> <body> <canvas id="canvas" width="500px" height="500px" style="border: 1px solid gray;"></canvas> </body> </HTML>

2. Lu ni dung ca Canvas
lu li d liu ca Canvas nhm phc hi khi cn thit (chng hn nh chc nng Undo, Redo), ta s s dng phng thc context.getImageData().Ta s s dng phng php ny thc hin chc nng v on thng trn Canvas. Trc k hi bt u v mt on thng, canvas cn c lu li ni dung v mi khi chut di chuyn, ta s phc hi li ni dung c lu ng thi v mt on thng t im bt u n v tr chut. Ta cng sa v d trn thnh mt jQuery plugin tin s dng:
<HTML> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> (function( $ ) { var preX; var preY;

31 | P a g e

Yin Yang
var var var var var tool; canvas; context; imageData; paint; // pen, line

HTML5 Canvas - Lp trnh Game 2D

$.fn.makeDrawable = function() { canvas = this[0]; if( !$(canvas).is("canvas") ) throw "The target element must be a canvas"; context = canvas.getContext("2d"); $(canvas).mousedown(function(e){ preX = e.pageX - canvas.offsetLeft; preY = e.pageY - canvas.offsetTop; paint = true; if(tool=="line") { imageData = context.getImageData(0, canvas.height); } }); $(canvas).mousemove(function(e){ if(paint) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; if(tool=="pen") { context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); preX = x; preY = y; } else if(tool=="line") { canvas.width=canvas.width; content context.putImageData(imageData,0,0); context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); } } }); $(canvas).mouseup(function(e){ if(tool=="line") { var x = e.pageX - canvas.offsetLeft;

0,

canvas.width,

//

clear

canvas

32 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D


var y = e.pageY - canvas.offsetTop; context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); } paint = false;

}); $(canvas).mouseleave(function(e){ paint = false; }); return $(canvas); }; $.fn.setTool = function(newTool) { tool=newTool; return $(canvas); } $.fn.clear = function() { canvas.width=canvas.width; return $(canvas); } })( jQuery ); $(function(){ $("#canvas").makeDrawable(); $("#button1").click(function(){ $("#canvas").clear(); }); $("#pen").change(function(){ if(this.value) $("#canvas").setTool("pen"); }); $("#line").change(function(){ if(this.value) $("#canvas").setTool("line"); }); $("#canvas").setTool("pen"); }); </script> </head> <body> <div> <button id="button1">Clear</button> <input name="tool" type="radio" id="pen" checked="true">Pen</input> <input name="tool" type="radio" id="line">Line</input> </div> <canvas id="canvas" width="500px" height="500px" style="border: 1px solid gray;"></canvas> </body> </HTML>

Kt qu:

33 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

III. Chn v di chuyn i tng


Thay v lu tr ni dung ca Canvas di dng ImageData, ta c th lu tr cc i tng ha di dng cu trc d liu v thc hin v tng phn t ln Canvas. Vi phng php ny, ta s minh ha bng mt v d s dng chut chn v di chuyn cc hnh v trn Canvas.

1. To cu trc d liu
u tin ta s to mt lp Rect dng cha d liu ca mt hnh ch nht. Lp ny ngoi cc bin lu tr ta , kch thc v trng thi (selected) th cn mt phng thc dng kim tra xem mt ta [x,y] c nm bn trong n khng. Ta gi phng thc ny l isContain() v c kiu tr v l boolean. M ngun ca lp ny c dng:
function Rect() { this.isSelected = false; this.x = 0; this.y = 0; this.width = 1; this.height = 1; } Rect.prototype.isContain = function(x,y){ var right = this.x + this.width; var bottom = this.y + this.height;

34 | P a g e

Yin Yang
return x > this.x && x < right && y > this.y && y < bottom; }

HTML5 Canvas - Lp trnh Game 2D

Tip theo, ta to mt lp ShapeList dng cha cc i tng Rect trong mt kiu d liu mng. Ngoi ra, ShapeList s c thm mt bin dng ch ra i tng Rect ang c chn (selectedItem), v hai bin dng lu v tr ca chut khi click ln mt i tng Rect (offsetX, offsetY). Hai bin offset ny dng tnh ta chnh xc khi ngi dng s dng chut di chuyn i tng Rect. ShapeList cn c hai phng thc:
addItem: thm mt i tng Rect vo danh sch. selectAt: tm v chn i tng Rect cha ta [x,y]. Ta s duyt ngc t cui mng

m bo cc i tng nm sau s c chn trc trong trng hp nhiu Rect cng cha im [x,y]
function ShapeList(){ this.items = []; this.selectedItem = null; this.offsetX = -1; this.offsetY = -1; } ShapeList.prototype.addItem = function(x,y,width,height){ var rect = new Rect; rect.x = x; rect.y = y; rect.width = width; rect.height = height; this.items.push(rect); } ShapeList.prototype.selectAt = function(x,y){ if(this.selectedItem) this.selectedItem.isSelected = false; this.selectedItem = null; for (var i = 0; i < this.items.length; i++) { var rect = this.items[i]; if(rect.contains(x,y)) { this.selectedItem = this.items[i]; this.offsetX = x - this.items[i].x; this.offsetY = y - this.items[i].y; this.items[i].isSelected = true; break; } } }

2. Cc phng thc v bng context


function draw(){ clear();

35 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

for (var i = _list.items.length-1;i>=0; i--) { drawRect(_list.items[i]); } } function drawRect(rect){ _context.fillRect(rect.x,rect.y,rect.width,rect.height); if(rect.isSelected) { _context.save(); _context.strokeStyle = "red"; _context.strokeRect(rect.x,rect.y,rect.width,rect.height); _context.restore(); } }

3. Cc s kin chut ca Canvas


Trong cc s kin ny, ta s dng c _ismoving xc nh xem mt i tng c ang c chn hay khng v thc hin di chuyn i tng ShapeList.selectedItem trong mousemove. Gi tr _ismoving ny s c xc nh trong s kin mousedown v b hy khi mouseup.
function canvas_mousedown(e){ var x = e.pageX - _canvas.offsetLeft; var y = e.pageY - _canvas.offsetTop; _list.selectAt(x,y) if(!_list.selectedItem) _list.addItem(x-RECT_SIZE,yRECT_SIZE,RECT_SIZE*2,RECT_SIZE*2); _ismoving = true; draw(); } function canvas_mousemove(e){ if(_ismoving && _list.selectedItem){ var x = e.pageX - _canvas.offsetLeft; var y = e.pageY - _canvas.offsetTop; _list.selectedItem.x = x - _list.offsetX; _list.selectedItem.y = y - _list.offsetY; draw(); } } function canvas_mouseup(e){ _ismoving = false; }

Kt qu:

36 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

IV. S dng bn phm


Bn phm l thit b khng th thiu v l phng tin rt quan trng thc hin cc chc nng ca cc ng dng tng tc vi ngi dng. Trong bi vit ny, ta s hng dn cch bt s kin bn phm trong canvas v dng n iu khin gc xoay v hng di chuyn ca i tng ha.

1. Bt s kin bn phm
bt s kin ny, bn c th ng k trc tip cho i tng window, tuy nhin iu ny s gy ra nhng rc ri khi trang ca bn c qu nhiu thnh phn. Cch tt nht l ng k ring cho canvas cc hm x l. Tuy nhin, canvas c th focus c, bn cn xc nh thuc tnhTabIndex ca n:
<canvas id=canvas width=300 height=200 tabindex=1 style=border: 1px solid;></canvas>

Sau bn ng k cc s kin cn thit cho canvas. Khi chy trn trnh duyt, bn cn phi click chut vo canvas n nhn c focus trc khi thc hin cc thao tc bn phm.
_canvas.onkeydown = canvas_keyDown; function canvas_keyDown(e){ alert(e.keyCode); }

Tham s event truyn vo hm x l s cha cc thuc tnh cn thit bn xc nh c phm no c nhn. y, bn ch cn quan tm n thuc tnh keyCode lu m ca phm c nhn. Do cc gi tr keyCode c kiu s nn rt kh nh v kim tra, may mn l ta tm c 37 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

trang Javascript Keycode Enums lit k sn cc keyCode di dng enum ca mt i tng. Ta sa li mt cht tin s dng hn:
var Keys = { BACKSPACE: 8, TAB: 9, ENTER: 13, SHIFT: 16, CTRL: 17, ALT: 18, PAUSE: 19, CAPS_LOCK: 20, ESCAPE: 27, SPACE: 32, PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT_ARROW: 37, UP_ARROW: 38, RIGHT_ARROW: 39, DOWN_ARROW: 40, INSERT: 45, DELETE: 46, KEY_0: 48, KEY_1: 49, KEY_2: 50, KEY_3: 51, KEY_4: 52, // ... };

2. Kim tra trng thi ca nhiu phm


Mt kh khn ca cc s kin bn phm trong javascript l ch c th xc nh c duy nht mt phm nhn thng qua thuc tnh event.keyCode. c th kim tra c trng thi ca nhiu phm c nhn cng lc, ta phi lu trng thi ca chng li khi s kin keyDown xy ra v xa trng thi i trong s kin keyUp.
var _keypressed = {}; function canvas_keyDown(e){ _keypressed[e.keyCode] = true; } function canvas_keyUp(e){ _keypressed[e.keyCode] = false; }

3. Gii hn cc phm c bt
S dng phng php trn, bn cn lc cc phm cn s dng i tng _keypressed khng lu cc gi tr khng cn thit. Mt cch n gin nht l s dng mng lu keyCode ca cc phm ny v kim tra trong cc s kin bn phm:
const AVAILABLE_KEYS = [ Keys.UP_ARROW, Keys.DOWN_ARROW, Keys.LEFT_ARROW, Keys.RIGHT_ARROW

38 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

]; function canvas_keyDown(e){ if(AVAILABLE_KEYS.indexOf(e.keyCode)!=-1) { _keypressed[e.keyCode] = true; } } function canvas_keyUp(e){ if(_keypressed[e.keyCode]) { _keypressed[e.keyCode] = false; } }

V. Chuyn ng trong Canvas


Mt v d n gin khi lm quen vi ha v chuyn ng trong lp trnh l vit mt v d bng ny bn trong mt vng ca s (canvas). Mt qu bng s c v bn trong canvas v chuyn ng theo mt hng xc nh. Khi chm bt k thnh tng no, bng s i hng chuyn ng ty theo hng di chuyn.

1. C bn
Ta xc nh hai gi tr speedX v speedY tng ng vi tc di chuyn theo phng ngang v dc ca tri bng. Hng di chuyn ca bng ph thuc vo gi tr m hoc dng ca speedX v speedY. Trong v d ny, thnh tng l cc bin ca canvas v ch c hai phng l ngang v dc. Nguyn l hot ng rt n gin: khi bng tip xc vi bin dc ca canvas, ta s i chiu ca speedY v vi bin ngang ta s i chiu ca speedX. Trong lp Ball sau, ta s b sung thm cc thuc tnh right, bottom tin khi kim tra va chm. Hai thuc tnh cx v cy l v tr tm ca bng v s c khi to ngy nhin sao cho n lun nm hon ton bn trong canvas.
Ball.js:
function Ball(mapWidth, mapHeight){ this.mapWidth = mapWidth; this.mapHeight = mapHeight; this.radius = 20; this.speedX = 3; this.speedY = 3; this.cx this.radius; this.cy this.radius; = = Math.floor(Math.random()*(this.mapWidth-2*this.radius)) Math.floor(Math.random()*(this.mapHeight-2*this.radius)) + +

39 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

} Ball.prototype.draw = function(context){ context.beginPath(); context.fillStyle = "red"; context.arc(this.cx,this.cy,this.radius,0,Math.PI*2,true); context.closePath(); context.fill(); } Ball.prototype.move = function(){ this.cx += this.speedX; this.cy += this.speedY; this.left = this.cx - this.radius; this.top = this.cy - this.radius; this.right = this.cx + this.radius; this.bottom = this.cy + this.radius; } Ball.prototype.checkCollision = function(shapes) { if(this.left <= 0 || this.right >= this.mapWidth) this.speedX = this.speedX; if(this.top <= 0 || this.bottom >= this.mapHeight) this.speedY = this.speedY; }

Sample.HTML:
<HTML> <head> <script src="ball.js"></script> <script> var _canvas; var _context; var _ball; function draw(){ _context.clearRect(0,0,_canvas.width,_canvas.height); _ball.draw(_context); } function update(){ _ball.move(); _ball.checkCollision(); draw(); } window.onload = function(){ var interval = 10; _canvas = document.getElementById("canvas"); _context = _canvas.getContext("2d"); _ball = new Ball(_canvas.width,_canvas.height); setInterval("update()",interval); } </script> </head>

40 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

<body> <canvas id="canvas" width="400px" height="300px" style="border: 1px solid gray;"></canvas> </body> </HTML>

2. Thm hiu ng bng di chuyn


v d khng qu n iu, ta s thm cc nh bng m di chuyn pha sau tri bng chnh. Ta s lu cc v tr bng di chuyn qua vo mt mng c ti a 10 phn t v v ra canvas trong hm draw(). Phng thc Ball.draw() cn chnh sa mt cht cho php nhn tham s alpha xc nh m c. Tham s alpha ny c gi tr nm gia on 0 v 1:
Ball.prototype.draw = function(context,alpha){ if(!alpha) alpha = 255; context.beginPath(); context.fillStyle = "rgba(255, 100, 100," + alpha + ")"; context.arc(this.cx,this.cy,this.radius,0,Math.PI*2,true); context.closePath(); context.fill(); }

cc tri bng khng nm qu st nhau, ta ch thc hin lu v tr ca bng sau mi 5 ln bng di chuyn hay sau mi 5 ln phng thc update() c gi. Phng thc traceBall() sau s to ra mt i tng Ball mi vi hai gi tr cx v cy ly t tri bng chnh v lu vo mng _balls. Khi chiu di ca mng _balls vt qu 10, ta dng phng thc Array.splice() ct i phn t nm u mng:
function traceBall(ball){ var b = new Ball; b.cx = ball.cx; b.cy = ball.cy; _balls.push(b); if(_balls.length>10) _balls.splice(0,1); }

Kt qu:

41 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Kim tra va chm


Phn quan trng ca v d ny nm phng thc kim tra va chm ca tri bng. Phng thc ny s duyt qua tt c cc chng ngi vt v kim tra khong cch ca n so vi chng ngi vt theo hai phng dc v ngang. Vi v d ny, ta kim tra va chm mc rt n gin nn vic phn x c a tri bng cha hon ton chnh xc. Ta s gii thiu cc k thut kim tra va chm v di chuyn trong cc bi vit sau. Phng thc kim tra va chm ca lp Ball:
Ball.prototype.checkCollision = function(shapes) { if(this.left <= 0 || this.right >= this.mapWidth) this.speedX = this.speedX; if(this.top <= 0 || this.bottom >= this.mapHeight) this.speedY = this.speedY; for(var i = 0; i < shapes.items.length ; i++){ var item = shapes.items[i]; var hCollision = false; var vCollision = false; this.right >= item.left && this.left <= item.right && ((this.cy < item.top && this.bottom >= item.top) || (this.cy > item.bottom && this.top <= item.bottom))) // under the rectangle { this.speedY = -this.speedY; vCollision = true; } if(this.bottom >= item.top && this.top <= item.bottom && // the ball is in the ((this.cx < item.left && this.right >= item.left) || // left or (this.cx > item.right && this.left <= item.right))) { this.speedX = -this.speedX; hCollision = true; } if(

// the // on

// rig

42 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

if(hCollision || vCollision) break; } }

Minh ha:

43 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

D. K thut lp trnh Game C bn


I. Vng lp game (Game loop) hot ng th no?
Phn ct li ca hu ht cc game chnh l vng lp c dng cp nht v hin th trng thi ca game. Trong bi vit ny, ta s minh ha cc phng php to vng lp game vi ngn ng javascript.

1. Vng lp c bn
Mt vng lp game c bn bao gm cc vic c thc hin theo th t sau:
while(gameRunning) { processInput(); // keyboard, mouse,... updateGame(); draw(); // checkGameOver(); }

Minh ha:

44 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Trong javascript, thay v dng vng lp, ta s thay th bng setInterval() hoc setTimeout(). Thng thng bn ch cn xc nh mt gi tr interval thch hp theo tc ca game.
function gameLoop() { processInput(); updateGame(); draw(); setTimeout(gameLoop,100); // 10 fps }

Hp l hn khi bn mun xc nh r s khung hnh/giy (fps):


const FPS = 60; function gameLoop() { // } window.setInterval(gameLoop,1000/FPS);

2. Vng lp c tnh ton thi gian


Tuy nhin, khng phi lc no cng vic update v draw cng ho n thnh trc khi ln gi k tip c thc hin. Nh vy tc ca game s khng ng nht trn cc thit b c cu hnh khc nhau. gii quyt, ta s s dng n thi gian h thng so snh v quyt nh thi im update/draw.
const FPS = 60; const TICKS = 1000/FPS; var lastUpdateTime; function gameLoop() { var now = Date.now(); var diffTime = now - lastUpdateTime; if(diffTime >= TICKS) processInput(); updateGame(); lastUpdateTime = now; } draw(); var sleepTime = TICKS - diffTime; if(sleepTime<0) sleepTime = 0; setTimeout(gameLoop,sleepTime); }

Phng php trn chy n vi gi tr diffTime nh hn TICKS. Ngha l tc ca game khng vt qu gi tr TICKS cho php. Tuy nhin trong trng hp diffTime ln, vic cp nht s din ra chm.

45 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Gii php cui cng


Gii php ca ta l s thc hin update vi s ln da vo t l diffTime/TICKS trong mt ln lp ca game. S hiu qu hn nu ta b qua vic draw v thc hin update lin tip v s gip tng tc game b vo khong thi gian b tr hon.
const FPS = 60; const TICKS = 1000/FPS; var lastUpdateTime; function gameLoop() { var diffTime = Date.now() - lastUpdateTime; var numOfUpdate = Math.floor(diffTime/TICKS); for(var i = 0;i < numOfUpdate;i++){ processInput(); updateGame(); } if(diffTime >= TICKS) draw(); lastUpdateTime += TICKS * numOfUpdate; diffTime -= TICKS * numOfUpdate; var sleepTime = TICKS - diffTime; setTimeout(gameLoop,sleepTime); }

Nu bn s dng requestAnimationFrame cho vng lp game, bn s khng cn quan tm n vic tnh ton gi tr sleepTime.

4. V d hon chnh
Kim tra v d ny v so snh vi cc phng php trc , thc hin mt vi cng vic qu ti no trn trnh duyt v bn s thy khc bit:
const FPS = 6; const TICKS = 1000 / FPS; var startTime; var expectedCounter = 0; var lastUpdateTime; var actualCounter = 0; var output; function gameLoop() { var diffTime = Date.now() - lastUpdateTime; var numOfUpdate = Math.floor(diffTime/TICKS); for(var i = 0;i < numOfUpdate;i++){ updateGame(); } if(diffTime >= TICKS)

46 | P a g e

Yin Yang
draw(); lastUpdateTime += TICKS * numOfUpdate; diffTime -= TICKS * numOfUpdate; var sleepTime = TICKS - diffTime; setTimeout(gameLoop,sleepTime); } function updateGame() { actualCounter++; }

HTML5 Canvas - Lp trnh Game 2D

function draw() { var s = "Actual updates: "+actualCounter; s += "<br/>Expected updates: "+Math.floor((Date.now()-startTime)/TICKS); output.innerHTML = s; } // onLoad output = document.getElementById("output"); startTime = Date.now(); lastUpdateTime = startTime; gameLoop();

Output: Actual updates: 1323 Expected updates: 1323

II. Kim tra va chm: hnh trn v ch nht


Thng thng cc i tng trong game s c xc nh va chm bng cch a chng v mt dng hnh hc c bn nh hnh ch nht, hnh trn. Bi vit ny s gip bn cch tnh ton kim tra va chm gia hai loi hnh hc ny.

1. Gia hai hnh ch nht


Phng php: kim tra tng nh ca hnh ny c nm bn trong hnh kia khng.
Rect.prototype.collideWidthRect = function(rect) { return this.contains(rect.left,rect.top) || this.contains(rect.right,rect.top) || this.contains(rect.right,rect.bottom) || this.contains(rect.left,rect.bottom); }

Cch trn khng phi cch nhanh nht, v vy bn c th dng cch sau, n gin v hiu qu hn:
Rect.prototype.collideWidthRect = function(rect) { return !(this.left > rect.right ||

47 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D


this.right < rect.left || this.top > rect.bottom || this.bottom < rect.top);

2. Gia hai hnh trn


Phng php: Bi v mi im nm trn ng trn cch u tm, nn vic kim tra va chm gia hai hnh trn s c xc nh da vo khong cch tm gia chng. xc nh khong cch gia hai im, ta da vo nh l Pythagoras (Pythagorean theorem) . Ta coi khong cch gia hai im l ng cho ca mt tam gic vung. Vy ln ca ng cho ny l:
c = a + b => c = sqrt(a + b)

Circle.prototype.collideWithCircle = function(circle){ var dx = this.cx - circle.cx; var dy = this.cy - circle.cy; return Math.sqrt(dx*dx + dy*dy) <= this.radius+circle.radius; }

Trong minh ha di y, hai hnh trn c mu mc nh l xanh l, khi va chm nhau, chng s chuyn sang mu .

3. Gia hnh trn v hnh ch nht


Phng php: Gi C l tm v R l bn knh hnh trn. Ta s tm cch xc nh im A l im gn nht thuc hnh ch nht n tm C. Sau so snh ln ca CA vi R.

48 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Khong cch gia tm C hnh trn v im A ca hnh ch nht c minh ha nh hnh di y. Khi tm hnh trn nm bn trong hnh ch nht, th im C v A s trng nhau.

Gi rect l hnh ch nht cn xc nh va chm. Ta c thut ton xc nh im A nh sau: - B1: Gn A bng vi C. - B2: Nu C.X < rect.Left, t A.X = rect.Left. Ngc li nu C.X > rect.Right, t A.X = rect.Right. - B3: Nu C.Y < rect.Top, t A.Y = rect.Top. Ngc li nu C.Y > rect.Bottom, t A.Y = rect.Bottom. Khi c im A, ta li dng cng thc Pythagoras so snh vi bn knh ca hnh trn.
Circle.prototype.collideWithRect = function(rect){ var px = this.cx; var py = this.cy; if(px < rect.left) px = rect.left; else if(px > rect.right) px = rect.right; if(py < rect.top) py = rect.top; else if(py > rect.bottom) py = rect.bottom; var dx = this.cx - px; var dy = this.cy - py; return (dx*dx + dy*dy) <= this.radius*this.radius; }

49 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

III. Kim tra mt im nm trn on thng


C nhiu cch kim tra mt im c thuc ng thng (tng t vi on thng) hay khng: bng cch s dng cc cng thc hnh hc hoc thut ton v ng thng, Ngoi nhng cch trn, ta s gii thiu mt phng php n gin nht l s dng php so snh gc gii quyt vn ny. Trong demo sau, khi bn di chuyn chut ngang ln trn on thng, bn s on thng chuyn sang mu . tng: Ta c on thng AB to nn gc (so vi phng ngang hoc phng bt k), v mi im thuc AB u to nn gc so vi phng ngang. Hay ni cch khc, ta xem on thng AB l ng cho ca mt tam gic vung ABM. T l gia hai cnh gc vung ca tam gic ny s bng vi t l hai cnh gc vung to bi tam gic vung AXN. Minh ha nh hnh di y:

Nh vy vic xc nh mt im X c thuc AB hay khng ch cn da vo 2 yu t: (1) X phi nm trong vng hnh ch nht c to bi ng cho AB (ngoi tip tam gic ABM). (2) Gc XAN v BAM phi bng nhau. Ngoi ra, do vic so snh l kiu s thc v c th do rng ca on thng khc nhau nn ta cn chp nhn mt gi tr sai s EPSILON no . 50 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Mun chnh xc hn khi rng ca on thng thay i, bn c th tnh gc sai s cho php bng cch da vo rng on thng v khong cch AX tnh. Tuy nhin, iu ny khng quan trng lm v lm cho vic kim tra tn thm chi ph. n gin, ta s tnh t l (tan) thay v tnh gc :
Line.prototype.contains = function(x, y) { if( x < Math.min(this.handler1.cx,this.handler2.cx) || x > Math.max(this.handler1.cx,this.handler2.cx) || y < Math.min(this.handler1.cy,this.handler2.cy) || y > Math.max(this.handler1.cy,this.handler2.cy)) return false; var dx = this.handler1.cx-this.handler2.cx; var dy = this.handler1.cy-this.handler2.cy; var tan1 = Math.abs(dy/dx); var tan2 = Math.abs((y-this.handler1.cy)/(x-this.handler1.cx)); return Math.abs(tan1 - tan2) < EPSILON; }

IV. Vector 2D c bn
ng dng ca vector rt quan trng trong lnh vc lp trnh game v ha. Thng qua vector, ta c th m phng c cc chuyn ng, tnh ton lc, hng di chuyn sau khi va chm,

1. Khi nim
mt vect l mt phn t trong mt khng gian vect, c xc nh bi ba yu t: im u (hay im gc), hng (gm phng v chiu) v ln (hay di). (Wikipedia) T mt on thng AB ta c th xc nh c vector (m gi): u.root = A; u.x = B.x-A.x; u.y = B.y-A.y; u.length = sqrt(u.x*u.x+u.y*u.y); // |u|

2. Vector n v (Unit Vector, Normalized Vector)


Vector n v ca u l vector c chiu di bng 1 v k hiu l . Vector u sau c gi l vector n v ca v bng cch tnh (m gi): = u/|u| Nh || = 1 vy:

51 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Tch v hng (Dot product, Scalar product)


Php ton tch v hng ca hai vector c biu din du chm (nn c gi dot product) v c tnh nh sau: v.u = |v||u|cos = v1u1 + v2u2 + + vnun Vi (theta) l gc gia v, u v n l chiu ca khng gian. T cng thc trn, ta c th tnh c : cos = (v.u)/(|v||u|) = arccos(cos)

4. Php chiu (Projection)


Mt ng dng khc ca tch v hng l tnh php chiu ca mt vector ny ln vector khc. Tng t nh vic chiu mt vector v thnh 2 gi tr x v y ln trc Oxy. (Hnh t wikipedia)

Mt vector a c gi l vector chiu ca v ln u nu nh n c cng phng vi u v c ln: |a| = |v|cos 52 | P a g e

Yin Yang Tng qut hn vi hai vector bt k, xt biu thc: |a| = |v|cos Vi u l vector to vi v mt gc , t cng thc: cos = (v.u)/(|v||u|) Suy ra: |a| = |v|(v.u)/(|v||u|) = (v.u)/|v|

HTML5 Canvas - Lp trnh Game 2D

Vy ta tnh c ln ca vector v chiu trn vector u. T gi tr |x| ny, ta c th tnh c vector x bng cch nhn vi vector n v ca u: a = |a|

5. Hin thc vi javascript


Mt i tng Line c biu din bi 2 im u (p1) v cui (p2) ca mt on thng. T hai im ny, ta c phng thc getVector() ly v mt i tng vector ca on thng.
Line.prototype.getVector = function() { var x = this.p2.x-this.p1.x; var y = this.p2.y-this.p1.y; return { x: x, y: y, root: this.p1, length: Math.sqrt(x*x+y*y) }; }

Phng thc update() sau c gi mi khi mt on thng b thay i:


function update(){ var v1 = _line1.getVector(); var v2 = _line2.getVector(); // normalize vector v2 v2.dx = v2.x/v2.length; v2.dy = v2.y/v2.length; // dot product var dp = v1.x*v2.x + v1.y*v2.y; // length of the projection of v1 on v2 var length = dp/v2.length; // the projection vector of v1 on v2 var v3 = {

53 | P a g e

Yin Yang
x: length*v2.dx, y: length*v2.dy, }; // the projection line _line3.p2.x = _line3.p1.x+v3.x; _line3.p2.y = _line3.p1.y+v3.y;

HTML5 Canvas - Lp trnh Game 2D

// calculate the angle between v1 and v2 // and convert it from radians into degrees _angle = Math.acos(dp/(v1.length*v2.length))*(180/Math.PI); _angle = Math.round(_angle*100)/100; }

Trong phn demo sau, ta thc hin php chiu vector mu ln vector xanh l. Kt qu ca php chiu l vector mu xanh lam. Bn c th thay i hng v ln ca vector bng cch nhn nhn v r chut vo u mi tn.
Xem Demo.

V. Khong cch t im n on thng


Da vo php chiu t tch v hng (Dot product) ca hai vector, ta c th tnh c khong cch t mt im n mt ng thng, on thng. Bi ton: Tm khong cch t im C n on thng AB. Gii quyt: Ta s tnh vector chiu ca AC ln AB v gi l AH. V CH vung gc vi AB v khong cch t C n AB chnh l CH. Nh vy ta tnh c khong cch t mt im n mt ng thng cha AB. tm khong cch n on thng, ta cn xc nh H c thuc AB hay khng. Ta xem li mt cht v tch v hng ca hai vector. 54 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Kt qu ca tch v hng c 3 khong gi tr ta c th c lng c gc gia hai vector (b qua chiu m/dng): Case 1 (Dot product < 0): Gc gia hai vector ln hn 90 . im H nm ngoi AB. Case 2 (Dot product = 0): Hai vector vung gc vi nhau (90 ). im H trng vi A. Case 3 (Dot product > 0): Gc gia hai vector nh hn 90 . im H c th nm trong AB hoc khng. im H s nm ngoi AB nu nh di AH > AB.

M ngun:
function pointLineDistance(){ // v1: AC // v2: AB // v3: AH var v1 = _line1.getVector(); var v2 = _line2.getVector();

55 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

// normalize vector v2 v2.dx = v2.x/v2.length; v2.dy = v2.y/v2.length; // dot product var dp = v1.x*v2.x + v1.y*v2.y; // length of the projection of v1 on v2 var length = dp/v2.length; // the projection vector of v1 on v2 var v3 = { x: length*v2.dx, y: length*v2.dy, }; v3.length = Math.sqrt(v3.x*v3.x+v3.y*v3.y); // the projection line _line3.p2.x = _line3.p1.x+v3.x; _line3.p2.y = _line3.p1.y+v3.y; var d; // distance // d = -1 means H does not lie on AB if(dp < 0) { d = -1; } else { if(v3.length > v2.length) d = -1; else { var dx = v1.x-v3.x; var dy = v1.y-v3.y; d = Math.sqrt(dx*dx+dy*dy); } } return d; }

VI. Giao im ca hai ng thng


T hai on thng (hoc vector) trong mt phng 2D, ta c th tm c giao im ca chng tnh ton cc gc phn x v hng di chuyn.

1. To phng trnh ng thng t on thng


Ta c hai im A(x1,y1) v B(x2,y2) to thnh mt on thng, to c mt phng trnh ng thng t hai im ny, ta cn tnh c nghing ca ng thng (slope) theo cng thc: 56 | P a g e

Yin Yang a = (y2 y1)/(x2 x1) Thay th x2, y2 bng hai bin x,y: a = (y y1)/(x x1) => y y1 = a(x x1) Hay: y = ax + (y1 ax1) t b = y1 ax1, ta c: y = ax + b

HTML5 Canvas - Lp trnh Game 2D

2. Tnh giao im ca hai ng thng


Ta c hai phng trnh ng thng (1): y = a1x + b1 (2): y = a2x + b2 Ta c th tnh c giao im ca chng bng cch tm giao im x trc: a1x + b1 = a2x + b2; => x(a1 a2) = b2 b1 => x = (b2 b1)/(a1 a2) Khi c x, ta s th vo (1) hoc (2) tnh c y. kim tra hai on thng c ct nhau khng, ta ch cn kim tra im {x,y} thuc c hai on thng hay khng. Ngoi ra ta cn loi tr trng hp hai ng thng song song hoc trng nhau, khi gi tr slope ca chng s bng nhau.

57 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Minh ha vi HTML5 Canvas

(on m kh di nn c th xem trn trang yinyangit.wordpress.com).

VII. Va chm v phn x


tnh c hng phn x ca khi mt vt th va chm vo mt phng, ta c th da vo gc nghing ca mt phng v vector theo tng vng gi tr. Tuy nhin cch tng qut hn l s dng cc php ton trn vector thc hin.
Xem Demo

1. Kim tra hai on thng ct nhau


T bi vit trc v tm giao im ca hai ng thng, ta c th kim tra xem giao im tm c c phi l giao im ca hai on thng hay khng. Cch kim tra n gin l bn xem im ny c thuc c hai phn bao hnh ch nht ca hai on thng. Ta c phng thc kim tra nh sau:
// detect if a point is inside the rectangle bound Line.prototype.insideRectBound = function(x, y){ if( Math.min(this.p1.x,this.p2.x) - x > x - Math.max(this.p1.x,this.p2.x) > Math.min(this.p1.y,this.p2.y) - y > y - Math.max(this.p1.y,this.p2.y) > return false; return true; } of this line EPSILON || EPSILON || EPSILON || EPSILON)

// ... var intersected = _line1.insideRectBound(x,y) && _line2.insideRectBound(x,y);

58 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2. Phng php

Trong hnh minh ha sau, vector v l hng di chuyn ca vt th va chm vo u. Vector phn x ca v l b. T vector b ta phn tch ra hai vector thnh phn l a v c (nh vy ta c a + c = b). Trong : a: vector chiu ca v trn u. c: vector chiu ca v trn ng thng vung gc vi u. y l vector php tuyn ca u v c di bng khong cch t gc ca v n u. Nh vy tm c vector phn x b, ta ch cn theo 4 bc: 1. Tm giao im ca hai on thng (tng ng vi hai vector v v u). 2. Tm vector chiu a ca v trn u. 3. Tm vector php tuyn ca u c di bng khong cch t gc ca v n u. 4. Tnh tng vector a v c. Xem m ngun minh ha bng javascript ti trang sau thy chi tit hn: http://yinyangit.wordpress.com/2012/04/10/gamedev-vector2d-va-cham- va-phan- xa/

VIII. Va chm gia ng trn v on thng


Tm im va chm ca mt ng trn vi on thng v xc nh hng phn x ca di chuyn thng qua cc php ton trn vector.

1. Va chm
xc nh va chm, ta tnh ton khong cch t tm ng trn n on thng theo phng php Tnh khong cch t im n on thng v so snh vi bn knh ca ng trn.

59 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

V d trong phn kim tra khong cch ny cha xt trng hp va chm vi hai u ca on thng. Bi v vic kim tra phn x khi va chm vi u on thng s cn tnh ton thm mt vi bc nn ta s b qua. Phng thc sau s tr v im va chm ca tri bng vi on thng hoc null nu nh khng c.
Ball.prototype.findCollisionPoint = function(line) { // create a vector from the point line.p1 to the center of this ball. var v1= { x: this.cx - line.p1.x, y: this.cy - line.p1.y }; var v2 = line.getVector(); var v3 = findProjection(v1,v2); v3.length = Math.sqrt(v3.x*v3.x+v3.y*v3.y); var collisionPoint = null; if(v3.dp>0 && v3.length <= v2.length) { var dx = v1.x-v3.x; var dy = v1.y-v3.y; var d = Math.sqrt(dx*dx+dy*dy); if(d>this.radius) return null; collisionPoint = { x: line.p1.x + v3.x, y: line.p1.y + v3.y }; // don't overlap if(d < this.radius) { this.cx -= (this.movement.x/this.speed)*(this.radius-d); this.cy -= (this.movement.y/this.speed)*(this.radius-d); } } return collisionPoint; }

// distance

2. Phn x
Da vo vector chuyn ng ca tri bng v vector c to ra t on thng, ta c th tnh c vector chuyn ng mi ca bng (xem Vector2D: Va chm v phn x). 60 | P a g e

Yin Yang
Ball.prototype.bounceAgainst = function(line) { if(this.findCollisionPoint(line)) { var v1 = this.movement; var v2 = line.getVector(); var v3 = findProjection(v1,v2); // perpendicular vector of v2 var v4 = { x: v2.y, y: -v2.x }; v4 = findProjection(v1,v4); v4.x = -v4.x; v4.y = -v4.y; // bounce vector var v5 = { x: v3.x + v4.x, y: v3.y + v4.y };

HTML5 Canvas - Lp trnh Game 2D

v5.length = Math.sqrt(v5.x*v5.x+v5.y*v5.y); // normalize vector v5 = { x: v5.x/v5.length, y: v5.y/v5.length }; this.setMovement(v5); } }

i vi vic kim tra phn x khi tri bng va chm vi 1 im (nh hai u ca on thng), bn cn xc nh mt vector vung gc vi ng thng ni tm tri bng n im va chm v coi l mt phng va chm. Minh ha:

61 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

IX. Va chm gia nhiu ng trn


xc nh hng di chuyn ca hai qu cu c khi lng khc nhau sau khi va chm, ta s dng cng thc ca nh lut bo ton ng lng trong mt h c lp. Xt trng hp va chm trong khng gian mt chiu (1D cc vt di chuyn trn mt ng thng), ta gi m l khi lng v vn tc ca qu cu C, u l vn tc trc khi va chm v v l vn tc sau khi va chm. Ti thi im hai qu cu C1 v C2 va chm nhau, ta c cng thc: m1u1 + m2u2 = m1v1 + m2v2 Suy ra: v1 = (u1*(m1- m2) + 2*m2*u2)/(m1+m2) v2 = (u2*(m2- m1) + 2*m1*u1)/(m1+m2) Ta c th p dng cng thc ny trong khng gian hai chiu (2D) tnh vn tc theo mt phng xc nh. Bng cch chia vector vn tc thnh hai vector thnh phn, mt vector ux1 nm trn ng thng cha hai tm C1 v C2 (phng ngang), vector uy1 cn li vung gc vi vx1 (phng dc).ta chuyn khng gian 2 chiu thnh 1 chiu theo phng cha on thng ni hai tm ng trn.

62 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

var angle1 = Math.atan2(u1.y, u1.x); var ux1 = u1.length * Math.cos(angle1-angle); var uy1 = u1.length * Math.sin(angle1-angle); p dng cng thc bn trn, ta tnh c vector vn tc mi theo phng ngang l vx1. Do y l khng gian 1D nn vn tc uy1 s khng nh hng. var vx1 = ((ball1.mass-ball2.mass)*ux1+(ball2.mass+ball2.mass)*ux2)/(ball1.mass+ball2.mass); var vy1 = uy1; c hai vector thnh phn l vx1 v vy1, ta cn chuyn li cc vector mi ny sang khng gian 2D v hp thnh vector vector chuyn ng mi l v1. Do vector vx1 vung gc vi vy1 nn ta cn cng vi angle mt gc 90 hay PI/2. y, angle l gc to bi on thng ni hai tm ng trn. var v1 = {}; v1.x = Math.cos(angle)*vx1+Math.cos(angle+Math.PI/2)*vy1; v1.y = Math.sin(angle)*vx1+Math.sin(angle+Math.PI/2)*vy1;

1. X l va chm ca nhiu ng trn


Cch n gin nht v c phc tp tng i nh (s ln lp l n(n-1)/2) trong vic kim tra v x l va chm cho nhiu i tng l s dng hai vng lp lng nhau theo dng sau:
for(var i=0;i<_balls.length;i++) { for(var j=i+1;j<_balls.length;j++) checkCollision(_balls[i],_balls[j]); }

63 | P a g e

Yin Yang
Hm checkCo llision:
function checkCollision(ball1,ball2){ var dx = ball1.cx - ball2.cx; var dy = ball1.cy - ball2.cy;

HTML5 Canvas - Lp trnh Game 2D

// check collision between two balls var distance = Math.sqrt(dx*dx+dy*dy); if(distance > ball1.radius + ball2.radius) return; var angle = Math.atan2(dy,dx); var u1 = ball1.getVelocity(); var u2 = ball2.getVelocity(); var var var var var var angle1 = Math.atan2(u1.y, u1.x); angle2 = Math.atan2(u2.y, u2.x); ux1 = u1.length * Math.cos(angle1-angle); uy1 = u1.length * Math.sin(angle1-angle); ux2 = u2.length * Math.cos(angle2-angle); uy2 = u2.length * Math.sin(angle2-angle);

var vx1 = ((ball1.massball2.mass)*ux1+(ball2.mass+ball2.mass)*ux2)/(ball1.mass+ball2.mass); var vx2 = ((ball1.mass+ball1.mass)*ux1+(ball2.ma ssball1.mass)*ux2)/(ball1.mass+ball2.mass); var vy1 = uy1; var vy2 = uy2; // now var v1 v1.x = v1.y = we transform the 1D coordinate back to 2D = {}, v2 = {}; Math.cos(angle)*vx1+Math.cos(angle+Math.PI/2)*vy1; Math.sin(angle)*vx1+Math.sin(angle+Math.PI/2)*vy1;

v2.x = Math.cos(angle)*vx2+Math.cos(angle+Math.PI/2)*vy2; v2.y = Math.sin(angle)*vx2+Math.sin(angle+Math.PI/2)*vy2; ball1.velocity = v1; ball2.velocity = v2; }

X. Kim tra va chm da trn pixel


Cc i tng ha (hoc hnh nh) trong game thng c mt gii hn trong mt khung bao hnh ch nht c nn trong sut (pixel c alpha = 0). Nh vy i vi cc i tng phc tp v mun kim tra va chm chnh xc, ta cn kim tra cc pixel c alpha > 0 ca hai i tng ha c cng nm trn mt v tr hay khng.

64 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

1. Mt wrapper ca Image
tin x l cc hnh nh trong canvas di dng mt i tng trong game vi cc chc nng cn thit, ta to mt lp ImageObj cha bn trong mt i tng Image lu tr hnh nh. Phng thc quan trng m ImageObj phi c l draw(), tuy nhin vic np nh c th din ra kh lu v vy ta cn mt cch thc x l trng hp ny. Chng hn ta s vit ra mt dng thng bo thay th cho nh vi kch thc mc nh trong trng hp nh cha c ti xong:
function ImageObj(){ // ... this.draw = function(context){ if(ready){ context.drawImage(this.img,this.left,this.top); } else{ // image has not finished loading // draw something useful instead context.save(); context.fillText("Image is not ready",this.left+10,this.top+10); context.restore(); } context.strokeRect(this.left,this.top,this.width,this.height); context.stroke(); }; // ... }

Cha , i tng ImageObj c th t v li sau nh c np xong, ng thi ly c i tng ImageData (cha mng cc pixel), ta s vit mt s lnh x l trong s kin onload ca Image.
function ImageObj(){ // ... var self = this; this.img.onload = function(){ self.width = this.width; self.height = this.height; ready = true; // this image is ready to use // draw image after loading context.clearRect(self.left,self.top,self.width,self.height); self.draw(context); // get ImageData from this image self.data = context.getImageData(self.left,self.top,self.width,self.height).data; }; this.img.src = url; }

65 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Do vn bo mt, ta s khng ly c ImageData ca cc nh khng nm trong host hin ti (khc host m script c thc thi).

2. Xc nh vng giao hai hnh ch nht


Thay v lp qua ton b hai hnh nh v kim tra tng pixel ca chng. Ta s gii hn li phn nh cn kim tra bng cch xc nh vng giao gia hai hnh nh. Phn ny cng gip ta xc nh nhanh hai i tng c th xy ra va chm hay khng.
function findIntersectionRect(img1,img2){ var rect = { left: Math.max(img1.left,img2.left), top: Math.max(img1.top,img2.top), right: Math.min(img1.left+img1.width,img2.left+img1.width), bottom: Math.min(img1.top+img1.height,img2.top+img2.height) }; if(rect.left>rect.right || rect.top>rect.bottom) return null; return rect; }

Xem Demo.

66 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

3. Kim tra va chm


Nu tm hiu v i tng ImageData, bn bit rng cc pixel s c lu tr trong mt mng mt chiu. Mi pixel bao gm bn phn t ng lin nhau trong mng theo th t l [Red, Green, Blue, Alpha]. Nh vy mt nh c kch thc 2030 s c 600 pixel v c 6004=2400 phn t trong ImageData.
function checkPixelCollision(img1,img2){ if(!img1.data || !img2.data) return null; var rect = findIntersectionRect(img1,img2); if(rect) { // this array will hold all collision points of two images var points = []; for(var i=rect.left;i<=rect.right;i++){ for(var j=rect.top;j<=rect.bottom;j++){ var index1 = ((i-img1.left)+(jimg1.top)*img1.width)*4+3; var index2 = ((i-img2.left)+(jimg2.top)*img2.width)*4+3; if(img1.data[index1+3]!=0 && img2.data[index2+3]!=0) { points.push({x:i,y:j}); // you can exit here instead continue looping } } } return { rect: rect, points: points }; } return null; }

of

tng tc kim tra va chm, thay v lp qua tng pixel, bn c th lp ngt qung n pixel (theo c 2 chiu ngang v dc) ty theo mc yu cu chnh xc ca ng dng. Nh vy s ln lp kim tra s gim i 2n ln tng ng. Di y l nh minh ha vic thay i bc tng ca vng lp t 1 ln 3. Vng mu l cc pixel c alpha > 0 thuc c hai nh:

67 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

68 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

E. K thut lp trnh Game Nng cao


I. Cun nh nn v bn (Map Scrolling)
Cun bn l chc nng khng th thiu trong nhng game c bn ln vt qu kch thc khung nhn (viewport) ca mn hnh. Bi vit ny gip bn tm hiu mt s phng php to hiu ng, cun nh nn v bn trong game.

1. nh nn nhiu tng
Mt phng php n gin v to hiu ng p l s dng nh nn nhiu tng. Bng cch cho mi tng c tc cun khc nhau, khung cnh trong game tr nn c chiu su v tht hn. S lng tng ny thng ch gii hn t 2 n 3 v cc tng nm bn di s c tc cun chm hn.

69 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2. Cun gi
Bn c th thy nhiu game c bn rt ln nhng nh nn ch lp i lp li theo mt mu duy nht. iu ny c thc hin bng cch s dng mt nh nn c kch thc nh v c v lp i lp li trn viewport. Ty theo kch thc ca nh nn ny m ta s dng phng php v khc nhau. Cch thng thng l s dng mt nh nn c kch thc bng viewport. Sau ta chia nh nn ny thnh hai phn theo chiu dc da vo mt ng phn cch: - Ct phn nh nn t v tr ng phn cch n ht v v ln viewport ti v tr {0,0}. - Ct phn nh nn t v tr u tin n ng phn cch (phn cn li) v v ln viewport ti v tr tip ni vi phn lc ny.
// position that divide the background into two parts offsetX++; if(offsetX>width) offsetX = 0; // draw the first part ctx.drawImage(bgimg,offsetX,0,width-offsetX,height,0,0,width-offsetX,height); // the second part ctx.drawImage(bgimg,0,0,offsetX,height,width-offsetX,0,offsetX,height);

3. v cun tht
Vi mt bn ln, vic cun gi nhn vt chnh ca game lun gia mn hnh rt n gin. Ta c th xc nh c ta (left v top) trn bn s c dng lm viewport bng cch:
// inside Map object // obj = character this.offsetX = obj.left - viewWidth/2; this.offsetY = obj.top - viewHeight/2;

Tuy nhin vic thay i khung nhn lin tc c th khin cho ngi chi nhc mt, mt tp trung v nh hng n hiu sut. V vy ta p dng mt gii phi l to mt vng gii hn trong viewport gi l dead zone. Khi nhn vt di chuyn nhng vn nm trong vng ny, viewport s khng b thay i.
// inside Map object var dx = obj.left - _map.offsetX; var dy = obj.top - _map.offsetY; if(dx<this.deadzone.left)

70 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

this.offsetX = obj.left - this.deadzone.left; else if(dx+obj.size>this.deadzone.right) this.offsetX = obj.right - this.deadzone.right; if(dy<this.deadzone.top) this.offsetY = obj.top - this.deadzone.top; else if(dy+obj.size>this.deadzone.bottom) this.offsetY = obj.bottom - this.deadzone.bottom;

Xem Demo

II. To Amimated Sprite


Sprite l mt phng php to cc i tng chuyn ng t mt hnh nh duy nht. Bng cch sp xp nhiu i tng theo th t chuyn ng, sprite gip cho vic qun l ti nguyn v x l hiu qu hn so vi vic phi s dng nhiu tp tin nh ring l.
Xem Demo.

Mt nh c th gm nhiu sprite c cng kch thc hp li vi nhau. V d hnh di y ta c th thy mi hng l mt sprite hin th chuyn ng ca nhn vt theo phng khc nhau. Vy 71 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

vi mc ch l to lp Sprite linh ng, ta phi cho php n kt hp c nhiu sprite vi nhau v chuyn i qua li gia cc sprite d dng.

M ngun ca lp AnimatedSprite:
var AnimatedSprite = function(data) { this.init(data); this.isFinished = false; this.currentSprite = null; this.currentFrame = 0; this.lastTick = 0; }; AnimatedSprite.prototype = { start: function(){ this.isFinished = false; this.currentFrame = 0; } init: function(data) { if(data){ this.isLooping = data.isLooping; if(typeof this.isLooping!="boolean") this.isLooping = true; this.image = data.image; this.frameWidth = data.frameWidth; this.frameHeight = data.frameHeight || this.frameWidth; this.sprites = []; this.interval = data.interval; this.left = data.left; this.top = data.top; this.width = data.width || this.frameWidth; this.height = data.hegiht || this.frameHeight; this.onCompleted = data.onCompleted; } }, addSprite: function(data){ this.sprites[data.name]={

72 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

name : data.name, startFrame : data.startFrame || 0, framesCount : data.framesCount || 1, framesPerRow Math.floor(this.image.width/this.frameWidth) }; this.currentSprite = this.currentSprite this.sprites[data.name]; }, setSprite: function(name){ if(this.currentSprite != this.sprites[name]) { this.currentSprite = this.sprites[name]; this.currentFrame = 0; } }, update: function(){ if(this.isFinished) return; var newTick = (new Date()).getTime(); if(newTick-this.lastTick>=this.interval) { this.currentFrame++; if(this.currentFrame==this.currentSprite.framesCount) { if(this.isLooping) this.currentFrame=0; else { this.isFinished = true; if(this.onCompleted) this.onCompleted(); } } this.lastTick = newTick; } }, draw: function(context){ if(this.isFinished) return; var realIndex = this.currentSprite.startFrame+this.currentFrame; var row = Math.floor(realIndex/this.currentSprite.framesPerRow); var col = realIndex % this.currentSprite.framesPerRow;

||

context.drawImage(this.image,col*this.frameWidth,row*this.frameHeight, this.frameWidth,this.frameHeight,this.left,this.top,this.width,this.he ight);

73 | P a g e

Yin Yang
} }

HTML5 Canvas - Lp trnh Game 2D

s dng, ta c th to mt lp con ca AnimatedSprite cung cp cc chc nng di chuyn, kim tra va chm. y ta to mt lp Character tha k t AnimatedSprite:
function Character(data){ this.mapWidth = data.mapWidth; this.mapHeight = data.mapHeight; this.speedX = 0; this.speedY = 0; this.init(data); } Character.prototype = new AnimatedSprite(); Character.prototype.update = function(){ var var var var left = this.left+this.speedX; top = this.top+this.speedY; right = left+this.frameWidth; bottom = top+this.frameHeight;

if(left>0 && right<this.mapWidth) this.left = left; if(top>0 && bottom<this.mapHeight) this.top = top; AnimatedSprite.prototype.update.call(this); };

Sau to i tng t lp Character nh bn trn minh ha:


sprite = new Character({ mapWidth: canvas.width, mapHeight: canvas.height, image: image, frameWidth: 32, frameHeight: 48, interval: 100, left: 10, top: 10, }); sprite.addSprite({ name: "walk_down", startFrame: 0, framesCount: 4 }); sprite.addSprite({ name: "walk_left", startFrame: 4, framesCount: 4 });

74 | P a g e

Yin Yang
sprite.addSprite({ name: "walk_right", startFrame: 8, framesCount: 4 }); sprite.addSprite({ name: "walk_up", startFrame: 12, framesCount: 4 }); sprite.setSprite("walk_left"); setInterval(function(){ sprite.update(); canvas.width = canvas.width; sprite.draw(context); },1000/FPS);

HTML5 Canvas - Lp trnh Game 2D

III. Np trc hnh nh v ti nguyn


i vi nhng game s dng nhiu hnh nh (m thanh, video,), ta cn ph i np ton b cc nh cn thit trc khi vo game. Bi vit ny cung cp mt gii php n gin cho vic np trc cc hnh nh s dng trong mt canvas game. T v d trang HTML5 Canvas Image Loader Tutorial, ta b sung thm event cho php cp nht tin trnh np nh (onProgressChanged). Da vo cch ny, bn cng c th thay i gip vic np v qun l cc loi ti nguyn khc c thun tin:
function ImgLoader(sources,onProgressChanged,onCompleted) { this.images = {}; var loadedImages = 0; var totalImages = 0; // get num of sources if(onProgressChanged || onCompleted) for(var src in sources) { totalImages++; } var self = this; for(var src in sources) { this.images[src] = new Image(); this.images[src].onload = function() { loadedImages++; if(onProgressChanged) { var percent Math.floor((loadedImages/totalImages)*100); onProgressChanged(this,percent); } if(onCompleted && loadedImages >= totalImages) onCompleted(self.images); } this.images[src].src = sources[src]; } }

Cch s dng: 75 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

window.onload = function(images) { var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); var barWidth = 200; var barLeft = (canvas.width-barWidth)/2; context.fillRect(barLeft,10,barWidth,18); context.fillStyle = "blue"; var sources = { img1: "Spring/img (1).jpg", img2: "Spring/img (2).jpg", img3: "Spring/img (3).jpg", img4: "Spring/img (4).jpg", img5: "Spring/img (5).jpg", img6: "Spring/img (6).jpg", }; var left = 100; var foo = new ImgLoader(sources, function(image,percent) { context.drawImage(image, left, 55, 50,50); //context.clearRect(0,0,200,30); context.fillStyle = "blue"; context.fillRect(barLeft,12,percent*barWidth/100,12); context.fillStyle = "white"; context.fillText("Loading: "+percent+"%",barLeft+10,22); left+=60; }, function(images){ // completed } ); };

Minh ha:

IV. Phng to/thu nh game bng nt cun chut


thay i kch thc ni dung trong canvas, cch tt nht l s dng phng thc context.scale(double x, double y) thit lp mt t l co gin khi v bng context. Phng thc ny gip hnh nh trong canvas vn gi c nt nh vi cc nh vector (khng nh vic bn thay i kch thc ca canvas bng CSS hoc chc nng zoom ca trnh duyt).
Bi v cch trn qu n gin nn ta s dng li ti y v tp trung vo phn x l th cng. Qua , bn c th p dng cho nhng nn tng game khc khng h tr tranformation.

76 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Bn c th p dng cch lm trong v d ny cho nhng ng dng tng t, ch yu l thay i kch thc ca mt n v (CELL_SIZE), ca i tng v thay i ta .
Xem Demo

77 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

1. S kin Mouse Wheel trong javascript


Hot ng ca nt cun chut c xc nh bi mt gi tr delta ly c t tham s event ca s kin mousewheel (hoc DOMMouseScroll trn Firefox). Gi tr ny cho bi t chiu v ln vng quay ca bnh xe. Bn c th c mt bi hng dn c th ti Mouse wheel programming in JavaScript. Trong v d ny ta ch quan tm n chiu quay ca bnh xe: vi gi tr m, ta gim kch thc ni dung bn trong canvas i 1/2 v vi gi tr dng ta tng n ln 2 ln.
function canvas_mousewheel(e){ var delta = 0; if (!e) /* For IE. */ e = window.e; if (e.wheelDelta) { /* IE/Opera. */ delta = e.wheelDelta/120; } else if (e.detail) { /** Mozilla case. */ delta = -e.detail/3; } if (delta) { _map.changeZoom(delta); _ball.setZoom(_map.zoom); draw(); } if (e.preventDefault) e.preventDefault(); }

2. Thay i kch thc bn


Trong cc v d s dng bn , ta nh ngha mt hng CELL_SIZE quy nh kch thc ca mt theo pixel. Nh vy thay i kch thc bn khng c g phc tp. Trong v d ny ta to mt thuc tnh zoom=1 xc nh t l kch thc ban u. Gi tr ti thiu n c th nhn c l 0.5 v ln nht l 4:
Map.prototype = { changeZoom : function(zoom){ if(zoom this.zoom>=4)) return; this.zoom *= zoom < 0 ? 0.5 : 2; this.reset(); }, reset : function() { this.cellSize = CELL_SIZE*this.zoom; == 0 || (zoom<0 && this.zoom<=0.5) || (zoom>0 &&

78 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

this.width = MAP_WIDTH*this.cellSize ; this.height = MAP_HEIGHT*this.cellSize ; } // ... }

Phng thc reset() trn thc hin cp nht ba thuc tnh quan trng ca bn khi thay i t l kch thc.

3. V tng vng bn
Vi d liu ca bn c lu tr trong mt mng hai chiu. Ta cn xc nh c v tr, s lng dng v ct cn c hin th v ch v vng ny ln canvas.
// draw method var col = Math.floor(this.offsetX/this.cellSize); var row = Math.floor(this.offsetY/this.cellSize); ctx.fillStyle = "black"; for(var i=col;i<col+Math.floor(this.viewWidth/this.cellSize)+1;i++) { if(this.data[i]) for(var j=row;j<row+Math.floor(this.viewHeight/this.cellSize)+1;j++) { if(this.data[i][j]==1) ctx.fillRect(i*this.cellSize this.offsetX,j*this.cellSize -this.offsetY,this.cellSize ,this.cellSize ); } }

Nu s dng nh nn v, bn cn chia ta v ln ca vng nh cho t l zoom. Vi t l zoom cng ln, vng nh c v cng nh v ngc li:
ctx.drawImage(this.background,this.offsetX/this.zoom,this.offsetY/this.zoom,t his.viewWidth/this.zoom,this.viewHeight/this.zoom,0,0,this.viewWidth,this.vie wHeight);

4. p dng cho cc nhn vt trn bn


Mi nhn vt hay i tng c thm vo bn cng cn c thay i kc h thc v v tr tng ng vi t l zoom. Ta c th tnh c ta (left, top) mi ca i tng bng cch:
new_left = old_left/o ld_zoom*new_zoom new_top = old_top/old_zoom*new_zoom
this.setZoom = function(zoom){ if(this.zoom!=zoom) {

79 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D


this.size = BALL_SIZE*zoom; this.left = this.left/this.zoom*zoom; this.top = this.top/this.zoom*zoom; this.right = this.left + this.size; this.bottom = this.top + this.size; this.zoom = zoom;

} };

V. Thay i kch thc Canvas theo trnh duyt


Mt trong nhng yu cu thng thy ca game l thay i kch thc ca ca s game theo trnh duyt. Vic thay i ny cn m bo tc ca game khng b nh hng cng nh hnh nh khng b bin dng (gi nguyn t l chiu cao vo rng). Mt trong nhng li th ca cc trnh duyt hin i l h tr tnh nnghardware accelerated cho canvas. Vi cng mt pixel, trnh duyt c th hin th canvas nhiu kch thc khc nhau. V d nh bn gn canvas.width = 200 v canvas.height = 100, nh vy canvas c tt c 20000 pixel. V bn c th tng gp i kch thc ca canvas ln nhng lng pixel m bn thao tc vi canvas vn ch l 20000. Hay ni cch khc, vic x l v v canvas vi cc kch thc khc nhau c b x l ha (GPU) thc thi mt cch t ng. Ta phn bit kch thc thc v kch thc hin th ca canvas. Kch thc thc ca canvas c gn thng qua hai thuc tnh l width v height:
canvas.width = 200; canvas.height = 100; Kch thc hin th ca canvas c xc nh thuc tnh style.width v style.height (bng

javascript hoc CSS):


canvas.style.width = 400px; canvas.style.height = 200px;

nt ca canvas ph thuc vo kch thc thc ca n, v vy hy gi mt t l va phi gia hai loi kch thc ny.

1. iu chnh canvas thao kch thc trnh duyt


Mt v d n gin bn p dng khi cn thit. Khng ch cho canvas, bn c th s dng cch ny hin th hnh nh, video, (nh xem nh slideshow).

80 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

function fitSize(canvas){ var ratio = canvas.width/canvas.height;

81 | P a g e

Yin Yang
var width = window.innerWidth-5; var height = window.innerHeight-5; if(width/height>ratio) width = height*ratio; else height = width/ratio; canvas.style.width = width; canvas.style.height = height;

HTML5 Canvas - Lp trnh Game 2D

canvas.style.top = (window.innerHeight-height)/2; canvas.style.left = (window.innerWidth-width)/2; }

VI. S dng Full Screen API 1. Gii thiu


HTML5 cho php bn c th a mt thnh phn/th ca trang vo trng thi hin th fullscreen (khc vi ch fullscreen ca trnh duyt (F11)). Ngoi ra, bn c th s dng CSS thay i cch hin th ca thnh phn khi n trong trng thi fullscreen. API ny gi gn trong 5 mc sau: element.requestFullScreen(): Phng thc kch hot trng thi fullscreen ca mt thnh phn trong trang web. document.cancelFullScreen(): Phng thc hy b trng thi fullscreen. document.fullscreenchange : S kin c kch hot khi trng thi fullscreen thay i. document.fullScreen: Thuc tnh boolean dng kim tra trng thi fullscreen. :full-screen: Mt pseudo-class ca CSS dng nh ngha cch hin th ca thnh phn. Hin ti API ny ch mi c h tr trn Mozilla (Firefox) v WebKit (Chrome/Safari). Bn cn s dng cc tin t (vendor) l webkit v moz cho mi phng thc hay thuc tnh, style bn trn p dng cho tng loi trnh duyt. Nu cn thit, bn c th thm trc hai vendor ms v o chng c th hot ng c sau khi IE, Opera tch hp API ny: Phng thc ente rFullScreen():
function enterFullScreen(id){ var element = document.getElementById(id); element.requestFullscreen ? element.requestFullscreen() : element.mozRequestFullScreen ? element.mozRequestFullScreen() : element.webkitRequestFullScreen element.webkitRequestFullScreen() : alert("Fullscreen API is not supported in this browser"); ?

82 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Phng thc exitFullScreen():


function exitFullScreen(){ document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitCancelFullScreen document.webkitCancelFullScreen() : alert("Fullscreen API is not supported in this browser"); } ?

S kin fullscreenchange v thuc tnh fullScreen:


document.addEventListener("fullscreenchange", function (e) { console.log(document.fullscreen); }); document.addEventListener("mozfullscreenchange", function (e) { console.log(document.mozFullScreen); }); document.addEventListener("webkitfullscreenchange", function (e) { console.log(document.webkitIsFullScreen); });

CSS:
div:full-screen { background-color: gray; } div:-moz-full-screen { background-color: gray; } div:-webkit-full-screen { background-color: gray; }

83 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2. V d

<HTML> <head> <style> #mydiv { padding-top: 200px; display: none; height: 400px; background: black; } #mydiv:full-screen { display: block; } :full-screen h1 { color: wheat; } #mydiv:-moz-full-screen { display: block; } :-moz-full-screen h1{ color: wheat; } #mydiv:-webkit-full-screen { display: block; } :-webkit-full-screen h1{ color: wheat; } </style> <script type="text/javascript"> function enterFullScreen(id){ var element = document.getElementById(id); element.requestFullscreen ? element.requestFullscreen() : element.mozRequestFullScreen ? element.mozRequestFullScreen() : element.webkitRequestFullScreen element.webkitRequestFullScreen() : alert("Fullscreen API is not supported in this browser"); } function exitFullScreen(){ ?

84 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitCancelFullScreen ? document.webkitCancelFullScreen() : alert("Fullscreen API is not supported in this browser"); } document.addEventListener("fullscreenchange", function (e) { console.log(document.fullscreen); }); document.addEventListener("mozfullscreenchange", function (e) { console.log(document.mozFullScreen); }); document.addEventListener("webkitfullscreenchange", function (e) { console.log(document.webkitIsFullScreen); }); </script> </head> <body> <center> <div id="mydiv"> <h1>You are in fullscreen mode.</h1> <input type="button" value="Exit full screen" onclick="exitFullScreen('mydiv')" /> </div> <input type="button" value="Enter full screen" onclick="enterFullScreen('mydiv')"/> </center> </body> </HTML>

85 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

VII. To menu v chuyn i gia cc mn hnh Game


Mi game c lm ra u cn c mn hnh cho mng v cc menu gip ngi chi chuyn i gia cc mn hnh khc nhau nh: gii thiu, chi game, hng dn, ty chn. T yu cu ca mt bn, ta s hng dn cch thc hin phn ny mt cch n gin v nhanh chng.
Xem Demo

1. Lp MenuItem
Mi i tng MenuItem tng ng vi mt mc menu trn mn hnh. Mt i tng th ny c th ch cn 4 gi tr xc nh ta v kch thc. Tuy nhin d thay i v pht trin hn. Ta to thm mt s thuc tnh v cung cp mt s kin onclick cho n. Da vo thuc tnh isMouseOver, ta s thay i mu sc hin th ca MenuItem mi khi chut c hover. Phn ny kh n gin, ch cn coi y l mt cu trc d liu lu cc gi tr ca mt hnh ch nht cng vi phng thc v hin th n.
function MenuItem(data){ this.left = data.left || 0; this.top = data.top || 0; this.width = data.width || 100; this.height = data.height || 30; this.text = data.text || "Menu Item"; this.onclick = data.onclick; this.right = this.left+this.width; this.bottom = this.top+this.height; this.centerX = this.left+this.width/2; this.centerY = this.top+this.height/2; this.isMouseOver = false; this.update = function(){ }; this.draw = function(context){ context.font = "16px Arial"; context.textAlign = "center"; if(this.isMouseOver) context.fillStyle = "rgba(255,255,255,0.7)"; else context.fillStyle = "rgba(255,255,255,0.2)"; context.fillRect(this.left,this.top,this.width,this.height); context.fillStyle = "white"; context.fillText(this.text,this.centerX,this.centerY); context.strokeRect(this.left,this.top,this.width,this.height); };

86 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

this.contain = function(x,y){ return !(x<this.left || x>this.right y>this.bottom); }; } function MenuItem(data){ this.left = data.left || 0; this.top = data.top || 0; this.width = data.width || 100; this.height = data.height || 30; this.text = data.text || "Menu Item"; this.onclick = data.onclick; this.right = this.left+this.width; this.bottom = this.top+this.height; this.centerX = this.left+this.width/2; this.centerY = this.top+this.height/2; this.isMouseOver = false; this.update = function(){

||

y<this.top

||

}; this.draw = function(context){ context.font = "16px Arial"; context.textAlign = "center"; if(this.isMouseOver) context.fillStyle = "rgba(255,255,255,0.7)"; else context.fillStyle = "rgba(255,255,255,0.2)"; context.fillRect(this.left,this.top,this.width,this.height); context.fillStyle = "white"; context.fillText(this.text,this.centerX,this.centerY); context.strokeRect(this.left,this.top,this.width,this.height); }; this.contain = function(x,y){ return !(x<this.left y>this.bottom); }; } || x>this.right || y<this.top ||

2. Lp Screen
Lp ny l phn chnh ca to nn mt game. Mt game c th c to ra t mt hoc nhiu Screen v ngi chi c th chuyn qua li gia cc Screen bng mt vi nt bm no (trong v d ny l MenuItem). Lp Screen ny l ni qun l chnh v c th coi l mt game thu nh trong ng dng. Ging nh mi v d v mi i tng game ta tng thc hin, lp ny s gm hai phng thc chnh l update() v draw(). Bn cnh ta c th b sung cc phng thc bt u v kt thc

87 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

game. V d nh start() v stop(). V y l v d tp trung vo vic thit k menu v chuyn i gia cc mn hnh, cc i tng Screen ta to ch cha cc MenuItem. Ch : V mi lp Screen s ng k cc event onmousemove, onclick cho canvas, nn khi start() mt Screen, bn cn phi ng k cc event ny li cc event ny. Nu khng n s b overwrite bi event t cc Screen khc.
var var var var CELL_SIZE = 10; FPS = 10 ; WIDTH = 400; HEIGHT = 400;

function Screen(canvas){ var timer; var width = canvas.width; var height = canvas.height; var context = canvas.getContext("2d"); this.items = []; // this method/event is actived in the end of draw() method this.afterDraw = null; this.update = function(){ for(var i=0;i<this.items.length;i++){ this.items[i].update(); } }; this.draw = function(){ context.fillStyle = "black"; context.fillRect(0,0,width,height); for(var i=0;i<this.items.length;i++){ this.items[i].draw(context); } if(this.afterDraw) this.afterDraw(context); }; this.start = function(){ this.stop(); var self = this; // register events canvas.onclick = function(e){ // raise the onclick event of each MenuItem when it is clicked var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; for(var i=0;i<self.items.length;i++){ if(self.items[i].onclick self.items[i].contain(x,y)) self.items[i].onclick(x,y); } }; canvas.onmousemove = function(e){ // change the isMouseOver property of each MenuItem var x = e.pageX - this.offsetLeft;

&&

88 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

var y = e.pageY - this.offsetTop; canvas.style.cursor = 'default'; for(var i=0;i<self.items.length;i++){ self.items[i].isMouseOver self.items[i].contain(x,y); // change the cursor type to hand if(self.items[i].isMouseOver) canvas.style.cursor = 'pointer'; } }; timer = setInterval(function(){ self.update(); self.draw(); },1000/FPS); }; this.stop = function(){ if(timer) clearInterval(timer); timer = null; }; this.addItem = function(item){ this.items.push(item); }; }

3. Kim tra kt qu
Vy l xong hai lp chnh ca v d, bn to mt file HTML vi tn bt k test vi ni dung bn di.

89 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

F. AI trong game
I. Gii thiu
AI hay tr tu nhn to c s dng trong rt nhiu game, t n gin n phc tp. Ty theo tng trng hp m AI c th tnh ton v tr di chuyn, tm ng i, phn tch trng thi a ra quyt nh, Mt trong nhng game thuc loi AI n gin nht l tr chi Pong c pht hnh nm 1970. Dng game bng bn ny cho php ngi chi u vi my bng cch iu khin mt thanh paddle dc n v nh tr bng. V bn cng c th hnh dung c AI ca my hot ng nh th no: ch cn thay i v tr ca paddle ln xung theo tri bng.

Sau ny, nhng th loi game mi ra i i hi trnh AI phi nng ln mt tm mi. Thng thy nht l cc th loi game vi thut ton tm kim trn cu trc d liu dng cy tm ng i hay a ra quyt nh (decision tree). Trong cc thut ton duyt cy, ty theo trng hp v ln ca d liu, lp trnh vin c th thay i v chn la thut ton nh Hill climbing, Breadth First Search, Depth First Search, Best First Search, Iterative Depth First Search hay thm ch c th kt hp mt, hai loi thut ton vi nhau. Vi game Rn Sn Mi, mt tng ca ta l p dng AI trong game ny ngi chi c th u vi my. Nh vy bi ton t ra l p hi lm sao con rn m my iu khin c th tm c ng ngn nht n thc n m khng lao u vo tng hoc cn nhm thn ca n.

II. Phn tch la chn thut ton


1. Khng gian d liu nh:. 90 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

y chnh l kch thc ca bn , vi loi game ny th ch gii hn trong khong 5050 l . 2. Cn tm ra ng i ngn nht. Vi hai yu t ny, bn d dng nhn ra la chn gii thut tm kim theo chiu su (Breadth First Search) l hp l nht. Ta cng c th loi tr chn ra c thut gii ng: - Hill climbing hay Best First Search: khng kh thi do cn mt hm lng gi hay heuristic. Vi loi game m v tr hay trng thi nhn vt khng b nh hng nhiu bi cc yu t mi trng th iu ny khng cn thit, thm ch c th a ra kt qu sai. - Depth First Search hay Iterative Depth First Search: tm kim theo chiu su theo kiu may ri c th khin nhn vt i lc qu v lm chm thi gian tm thy con ng chnh xc. Hn na, kt qu tm c c th khng phi l ng i ngn nht.

III. Thut ton Breadth First Search


(Nu bn quen thuc vi thut ton Breadth First Search, c th b qua phn ny.) C ch lm vic ca thut ton tng t nh vt du loang, tm kim nhng im gn nht trc. Bn c th thy mt vi game s dng bn hay lin quan n AI cng c th s dng thut ton ny. Mt v d bn c th p dng thut ton ny l n-puzzle m ta ci t bng thut ton A* gii quyt. Trong gii thut ny ta cn nh ngha cc thnh phn sau: Open Close start goal n G(n) Danh sch cha cc v tr ch c xt Danh sch cha cc v tr xt. V tr bt u V tr kt thc v tr ang xt. Tp cc v tr c th n t v tr n.

Hnh minh ha (ngun http://artint.info/html/ArtInt_54.html):

91 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

Gii thut c m t bng m gi nh sau:


Begin Open := {start}; Close := ; While (Open <> ) do begin n:= Dequeue(Open); if (n=goal) then Return True; Open := Open + G(n); Close := Close + {n}; end; Return False; End;

Ta thy rng G(n) da vo tp Close kim tra cc v tr c cn c kim tra hay khng. Nu bn ci t hai tp ny bng mt collection th tc thc thi s tng i chm v phi thc hin tm kim phn t trong danh sch. Do v d ca ta c dng bn nn thay v dng collection, ta s s dng mng hai chiu c th truy xut trc tip n mt phn t da vo v tr. Khi ta c th kim tra thuc tnh ca phn t xem n c duyt cha.

IV. Cc quy tc trong game


Do c cch chi khc vi cc game cng loi nn ta cn t thm mt vi quy tc xy dng game: - Tc di chuyn ca (con rn) ngi chi v my phi bng nhau. - Khi c hai n n cng lc, u tin cho ngi chi ly c n.

92 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

- Hai con rn c th di chuyn xuyn qua nhau (nu khng chng c th cn nhau v con b cn s cht). - Khi di con rn ca my t n mt mc no , ngi chi s thua cuc. - gim mc kh, di con rn m my cn t c s cao hn ngi chi. Tm n, trong phn ti ta s thc hin vic ci t game ny trn HTML5-Canvas.

V. Xy dng mt lp Queue da trn mng


Vic s dng thut ton Breadth First Search (BFS) cn phi s dng mt cu trc d liu kiu hng i (Queue) lm tp Open. nh ngha: Hng i (ting Anh: queue) l mt cu trc d liu dng cha cc i tng lm vic theo c ch FIFO (vit tt t ting Anh: First In First Out), ngha l vo trc ra trc Trong hng i, cc i tng c th c thm vo hng i bt k lc no, nhng ch c i tng thm vo u tin mi c php ly ra khi hng i. Thao tc thm vo v ly mt i tng ra khi hng i c gi ln lt l enqueue v dequeue. Vic thm mt i tng lun din ra cui hng i v mt phn t lun c ly ra t u hng i. (Wikipedia); Trong javascript, ta c th d dng to mt lp Queue nh nhng phng thc sn c ca mng:
function Queue(){ var data = []; this.clear = function(){ data.length = 0; } this.getLength = function(){ return data.length; } this.isEmpty = function(){ return data.length == 0; } this.enqueue = function(item){ data.push(item); } this.dequeue = function(){ if (data.length == 0) return undefined; return data.shift(); } this.peek = function(){ return (data.length > 0 ? data[0] : undefined); } }

93 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

VI. Ci t thut ton Breadth First Search


Tc tm ng i trong game ny rt quan trng v cng ln level cao, vic di chuyn ca con rn c th ln ti 60 trong mt giy (tng ng FPS = 60) hay thm ch c th cao hn. Nu tc qu chm c th khin game b ng mi khi thut ton ny c s dng v t hn l con rn s lao u vo tng nh mt chic xe mt phanh. Nu khi test bn thy tc cha c ng , c bit trn cc my yu, hy th lm chm tc game li v tng thm phc tp ca bn . Mt cch khc na l gim kch thc bn gim khng gian tm kim. Tuy nhin bn khng cn qu lo lng v tc tm ng, theo th nghim ca ta th vi FPS = 1000 v di rn ln ti 100, game vn chy n v con rn khng mt mt vin ko no. ci t thut ton ny, trc tin ta to mt lp Node dng lu gi thng tin ca mt phn t trong mng hai chiu. Ta cn hai thuc tnh x,y lu li chnh v tr dng v ct ca Node trong mng. Nh vy ta c th xc nh c ngay v tr ca mt i tng Node trong mng m khng cn lp qua mng tm kim (do Node c lu trong Queue).
function Node(x,y,value){ this.x = x; this.y = y; this.value = value; this.visited = false; }

Mc d d hiu nhng cch ny s khin vic tm c cha t c tc m ta mong mun do phi so snh 2 thuc tnh value v visited xc nh mt Node c gh thm cha. V vy, ta s b i thuc tnh visited v tn dng thuc tnh value. Ta c lp Node mi:
var var var var BLANK = 0; WALL = 1; SNAKE = 2; VISITED = 3;

function Node(x,y,value){ this.x = x; this.y = y; this.value = value; }

Vng lp chnh ca thut ton:


// ... // add the start node to queue open.enqueue(start); // the main loop while(!open.isEmpty()) { node = open.dequeue(); if(node) { if(node.x==goal.x && node.y==goal.y)

94 | P a g e

Yin Yang
{

HTML5 Canvas - Lp trnh Game 2D

return getSolution(node); } genMove(node); } else break; } // ...

Phng thc sinh cc nc i tip theo ti v tr u rn:


// generate next states by adding neighbour nodes function genMove(node) { if (node.x < cols - 1) addToOpen(node.x + 1, node.y, node); if (node.y < rows - 1) addToOpen(node.x, node.y + 1, node); if (node.x > 0) addToOpen(node.x - 1, node.y, node); if (node.y > 0) addToOpen(node.x, node.y - 1, node); }

Phng thc thm mt nc i vo tp Open, ta ch cn thm cc node rng (BLANK). Khi thm vo, ta t li trng thi ca node l VISITED khng thm n vo ln th 2:
function addToOpen(x,y, previous) { var node = nodes[x][y]; if (node.value==BLANK) { // mark this node as visited to avoid adding it multiple times node.value = VISITED; // store the previous node // so that we can backtrack to find the optimum path // (by using the getSolution() method) node.previous = previous; open.enqueue(node); } }

Phng thc dng ly ng i sau khi tm c v tr ca node ch. Ta ch cn backtracking cc node da vo thuc tnh previous ca cc node:
function getSolution(p) { var nodes = []; nodes.push(p); while (p.previous) { nodes.push(p.previous); p = p.previous; }

95 | P a g e

Yin Yang
return nodes; }

HTML5 Canvas - Lp trnh Game 2D

Nh vy, khi c ng i n ch, ta ch cn cho rn di chuyn tng da theo ng i ny cho n ht di.

VII. Di chuyn i tng theo ng i


Trong lp Snake, ta to mt bin autoMoving xc nh quyn iu khin i tng thuc v ngi chi hay t ng (my tnh). Mi khi mt vin thc n mi to ra, ta s cp nht li ng i mi cho con rn. Ch cn thm mt dng lnh vo trong phng thc createFood().
function createFood() { var x = Math.floor(Math.random()*_cols); var y; do { y = Math.floor(Math.random()*_rows); } while(_walls[x][y] || _comSnake.contain(x, _playerSnake.contain(x, y));

y)

||

_food = {x: x, y: y}; // find new path for the com player _comSnake.setPath(_bfs.findPath(_comSnake.data,_comSnake.getHead(),_fo od)); }

Trong lp Snake, ta cn to mt phng thc mi gip rn di chuyn t ng. Bi v vic di chuyn ca rn da vo bn hng (do cn cho php ngi chi iu khin), ta c th xc nh hng di chuyn da vo v tr ca c v mi ca u rn:
// Snake this.move = function(){ if(this.stepIndex>0) { this.stepIndex--; var newPos = this.path[this.stepIndex]; if(newPos.x<this.data[0].x) this.direction = LEFT; else if(newPos.x>this.data[0].x) this.direction = RIGHT; else if(newPos.y<this.data[0].y) this.direction = UP; else if(newPos.y>this.data[0].y) this.direction = DOWN; } };

VIII. Vng lp chnh ca game


Phn quan trng nht gip game vn hnh, phn ny kh n gin v c ch thch nn ta cng khng cn gii thch thm. 96 | P a g e

Yin Yang
function update() { if(!_running) return;

HTML5 Canvas - Lp trnh Game 2D

_playerSnake.handleKey(_pressedKey); // player has priority to eat var ret =_playerSnake.update(_walls,_food); if(ret==1) // player eated the food { _scores += _level*2; createFood(); } else if(ret==2) // player collided with something { if(_scores>=0) { _scores -= _level*2; if(_scores<0) _scores = 0; } endGame(); return; }else{ if(!_comSnake.path) _comSnake.setPath(_bfs.findPath(_comSnake.data,_comSnake.getHead(),_fo od),_food); ret = _comSnake.update(_walls,_food); if(ret==1) // com player eated the food createFood(); } draw(); // Player's snake reached the maximum length // so the game will start the next level if(_playerSnake.data.length==MAX_PLAYER_LENGTH) { // go to next level _level++; _scores += _level*100; _running = false; _context.save(); _context.fillStyle = "rgba(0,0,0,0.2)"; _context.fillRect(0,0,WIDTH,HEIGHT); _context.restore(); _context.fillStyle = "red"; _context.textAlign = "center"; _context.fillText("Press Enter to level",WIDTH/2,HEIGHT/2); }else if(_comSnake.data.length==MAX_COM_LENGTH) { endGame(); return; } }

start

the

next

97 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

G. Mt nn tng game 2D side-scrolling


T phn Map Scrolling, ta c th thy y l mt sn game rt ph bin cho cc loi game s dng bn (nh Pac-Man, Battle City hay Mario,). Trong bi ny ta s thay i mt vi c im to mt demo dng game phiu lu mn hnh ngang.

I. C bn 1. To bn
Bn c dng trong loi game ny c th c xem nh mt li vi mi cha mt gi tr i din cho loi i tng (thng l vt cn nh tng, , cy, ). n gin, ta to mt bn ch gm duy nht mt loi vt cn v c phn b ngu nhin: map.js:
for(var i=1;i<MAP_WIDTH-1;i+=2) { this.data[i] = []; this.data[i+1] = []; for(var j=1;j<MAP_HEIGHT;j++) { this.data[i][j] = Math.floor(Math.random()*6); this.data[i+1][j] = this.data[i][j]; // create image buffer if(this.data[i][j]==BRICK) { context.fillRect(i*CELL_SIZE,j*CELL_SIZE,CELL_SIZE*2,CELL_SIZE); context.fill(); } } }

2. Kim tra va chm


Ta c th kim tra nhanh va chm ca nhn vt vi cc vt cn bng cch xc nh ta tng ng ca bn t v tr ca nhn vt. map.js:
this.contain = function(x,y){ var col = Math.floor(x/CELL_SIZE); var row = Math.floor(y/CELL_SIZE); if(!this.data[col]) return false; if(this.data[col][row]==BRICK) {

98 | P a g e

Yin Yang
var b = { left: col*CELL_SIZE, top: row*CELL_SIZE }; b.right = b.left+CELL_SIZE; b.bottom = b.top+CELL_SIZE; return b; } return false; }

HTML5 Canvas - Lp trnh Game 2D

i vi nhn vt, ta s dng 8 im bao quanh nhn vt kim tra (cc im mu trong hnh sau). Mun vic kim tra chnh xc hn, bn ch cn tng thm s im tuy nhin thi gian kim tra s lu hn. Da vo cc im ny ta c th xc nh c va chm v ngng vic di chuyn ca nhn vt theo cc trng hp cc im va chm l:

- R1 hoc R2: Va chm bn phi. Nu speedX>0, ta gn speedX = 0. - L1 hoc L2: Va chm bn tri. Nu speedX H1 hoc H2: Nhn vt nhy ln v ng u vo vt cn. Ta dt speedY = 0 v falling = true nhn vt dng li v bt u ri. - H1 hoc H2: Nhn vt nhy rt xung t hoc vt cn. Ta dt speedY = 0 v falling = false.
Player.prototype.update = function(){ if(this.isJumping) this.speedY += GRAVITY; var var var var vtop = this.top+this.speedY; vbottom = vtop+this.height; vleft = this.left+this.speedX; vright = vleft+this.width;

if(this.isJumping) vbottom -= 1;

99 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

var b; this.isJumping = true; if(vbottom >= this.map.height) { this.top = this.map.height-this.height; this.speedY = 0; this.isJumping = false; } else if(b = this.map.contain(this.left+2,vbottom) || this.map.contain(this.right-2,vbottom)) { this.top = b.top-this.height; this.speedY = 0; this.isJumping = false; } else if(b = this.map.contain(this.left+2,vtop) || this.map.contain(this.right-2,vtop)) { this.top = b.bottom; this.speedY = 0; } vtop = this.top+this.speedY; vbottom = vtop+this.height; if(this.left<=0 || (b = this.map.contain(vleft,vtop+6) || this.map.contain(vleft,vbottom-4))) { if(b) this.left = b.right; if(this.speedX<0) this.speedX = 0; }else if(this.right>=this.map.width || (b = this.map.contain(vright,vtop+6) || this.map.contain(vright,vbottom-4))) { if(b) this.left = b.left-this.width; if(this.speedX>0) this.speedX = 0; } this.top = vtop; this.bottom = vbottom; this.left += this.speedX; this.right = this.left + this.width; }

100 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

II. Thm cc chc nng v nhn vt 1. Lp Character


y l lp nn tng cho tt c c i tng chuyn ng (c th thay i v tr) trong game. Cc i tng c th l ngi chi, qui vt hay cc NPC (non-player character). Ta nh ngha kh nhiu thuc tnh trong lp ny xc nh v tr, tc , kch thc ca nhn vt. Bn cnh , ta thm mt s thuc tnh boolean hnh vi (hay kh nng) ca nhn vt: - canDestroyObstacles: kh nng ph hy cc chng ngi vt (bng cch dng u) ca nhn vt. Khi nhn vt nhy ln, nu u chm trng chng ngi vt c th ph hy (gch), ta s kim tra thuc tnh ny xc nh xem chng ngi vt c b ph hy hay khng. - isAutoMoving: Dng cho cc nhn vt khng b ngi chi (player) iu khin (qui vt). - canJump: Nhn vt c th nhy hay khng.
function Character(map,options){ if(!options) options = {}; this.map = map; this.left = options.left || 0; this.top = options.top || 300; this.height = options.height || 15; this.width = options.width || 15; this.jumpPower = options.jumpPower || 5; this.speed = options.speed || 2; this.speedX = (Math.random()<0.5? -this.speed: this.speed);

101 | P a g e

Yin Yang
this.speedY = 0; this.isJumping = true; this.isDead = false;

HTML5 Canvas - Lp trnh Game 2D

this.bottom = this.top+this.height; this.right = this.left+this.width; // behaviors this.canDestroyObstacles = options.canDestroyObstacles; this.isAutoMoving = options.isAutoMoving; this.canJump = options.canJump; }

Nhn chung phng thc chnh update() cng tng t nh trong bi part 0. Ngoi tr vic khi nhn vt nhy ln v ph gch, cc i th (trong game ny l cc Monster) bn trn s b tiu dit. V vy ta b sung on m ny vo phn kim tra va chm pha trn:
// top collision if(this.canDestroyObstacles) { // destroy all monsters that are standing on the brick for(m in this.map.monsters) { var mon = this.map.monsters[m]; if(!mon) continue; var cx = mon.left + mon.width/2; if(mon.bottom==b.top && cx>=b.left && cx<=b.right ) mon.die(); } this.top = b.bottom; this.speedY = 0; }

Thay i hng di chuyn ca nhn vt khi thuc tnh isAutoMoving c gi tr true v nhn vt b va chm pha tri hoc phi:
// update() method if(this.left<0 || (b = this.map.colllide(vleft,vtop+6,false) || this.map.colllide(vleft,vbottom-4,false,this.canEat))) // left { if(b && b!=true) this.left = b.right; if(this.speedX<0) this.speedX = this.isAutoMoving? this.speed: 0; }else if(this.right>=this.map.width || (b this.map.colllide(vright,vtop+6,false) || this.map.colllide(vright,vbottom-4,false))) // right { if(b && b!=true) this.left = b.left-this.width; if(this.speedX>0) this.speedX = this.isAutoMoving? -this.speed: 0; } =

102 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2. Lp Monster
Monster (hay Enemy) l cc i tng c kh nng hot ng v c th c tch hp AI nhm tiu dit hoc cn tr ngi chi. Trong bt k game no th cc loi i tng ny rt a dng v l thng l nguyn nhn chnh to ra s li cun ca game. V y ch l phn bt u nn ta ch to mt loi Monster duy nht c kh nng tiu dit ngi chi thng qua va chm.

Bi v c tha k t lp Character bn trn, lp ny ch cn mt cng vic chnh l hin thc phng thc draw() v chnh n:
function Monster(map,left,top){ // call the super-constructor Character.call(this,map,{ left: left, top: top, width: 20, height: 20, speed: 1, isAutoMoving: true }); } Monster.prototype = new Character(); Monster.prototype.draw = function(context){ context.save(); context.beginPath(); var left = this.left-this.map.offsetX; var top = this.top-this.map.offsetY; var right = left+this.width; var bottom = top+this.height; var hw = this.width/2; var cx = left+hw; context.fillStyle = "violet"; context.arc(cx,top+hw,hw-2,0,Math.PI*2,true); //context.rect(left,top,this.width,this.height); context.fill(); context.stroke();

103 | P a g e

Yin Yang
context.restore(); }

HTML5 Canvas - Lp trnh Game 2D

3. Lp Player
Cng tng t nh Monster, tuy nhin cng vic s phc tp hn v ta cn kim tra nhiu th v phi cung cp cc phm bm iu khin. Phng thc update ny mc nh tr v 0. Trng hp player hon thnh vng chi, tr v 1; v nu player cht, tr v 2:
Player.prototype.update = function(){ if(this.right>=this.map.width){ alert("Game Over!"); return 1; } if(this.isFalling) // die { this.speedY += GRAVITY; this.top += this.speedY; return (this.top>this.map.height)? 2 : 0 ; } Character.prototype.update.call(this); this.collide(this.map.monsters); }

Kim tra va chm vi cc monster, ta xem player v monster l cc hnh ch nht v ch cn kim tra xem hai hnh ny c ct nhau khng:
Player.prototype.collide = function(monsters){ for(m in monsters) { var mon = monsters[m]; if(!mon) continue; if(!(this.left > mon.right || this.right < mon.left || this.top > mon.bottom || this.bottom < mon.top)) { if(this.bottom<mon.bottom&& this.speedY>0) { mon.die(); } else { this.die(); break; } } } }

104 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

4. Lp Map
Nu coi lp trnh vin lp trnh vin l thng , th bn chnh l mt th gii thu nh ni m thng cho vn hnh nhng quy lut to ra cuc sng. Mc d bn c th rt n gin trong nhiu game, nhng i vi dng game phiu lu ny, n ng vai tr rt quan trng (c th hn so vi Monster). Mt th gii qu nh b s khin ngi chi nhanh kt thc vng chi v khng th khi ln s t m mun khm ph ca h. Khi mt vt th (chng ngi vt), ta s xa vng tng ng trn buffer (nh bn ) v gn gi tr li cho trong d liu l mc nh (0):
function clearCell(left,top,col,row) { data[col+row*COLS] = 0; context.save(); context.globalCompositeOperation = "destination-out"; context.fillStyle = "rgba(0,0,0,1)"; context.fillRect(left,top,CELL_SIZE,CELL_SIZE); context.restore(); }

kim tra va chm vi cc chng ngi vt, ta to phng thc collide() vi gi tr tr v l mt i tng lu gi cc gi tr v v tr, kch thc ca chng ngi vt :
this.colllide = function(x,y,canDestroy){ var b = this.contain(x,y); if(b) { if(canDestroy && b.type==BRICK) { clearCell(b.left,b.top,b.col,b.row); } return b; } return false; }; this.contain = function(x,y){ var col = Math.floor(x/CELL_SIZE); var row = Math.floor(y/CELL_SIZE); var val = data[col+row*COLS]; if(val>0) { var b = { left: col*CELL_SIZE, top: row*CELL_SIZE, col: col, row: row, type: val, }; b.right = b.left+CELL_SIZE; b.bottom = b.top+CELL_SIZE; return b; }

105 | P a g e

Yin Yang
return false; };

HTML5 Canvas - Lp trnh Game 2D

Trong game ny, lp Map cn l ni cha cc Monster. lm Monster ra lin tc nu s lng t hn mt gi tr no . Ta vit phng thc update() nh sau:
this.update = function(){ // generate random monsters if(this.monsters.length<MONSTER_IN_VIEW) this.monsters.push(new Monster(this,this.offsetX+Math.random()*this.viewWidth+50,1)); i = 0; var length = this.monsters.length; while(i<length){ if(this.monsters[i].isDead || this.monsters[i].left<this.offsetX) { this.monsters.splice(i,1); // remove this monster from array length--; }else { this.monsters[i].update(); i++; } } };

106 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

H. Mt s ng dng minh ha
Trong qu trnh thc hin bi bo co ny, ti thc hin mt vi d n nh minh ha cc kin thc trnh by. Cc d n ny hon ton c th c pht trin tr thnh nhng game online cung cp cho ngi chi trong thc t. Cc d n ny c thc hin bng thun HTML5 v khng s dng thm bt k th vin no.

I. Game ua xe 1. Cc thng s ca xe
Trong game ny, ta s s dng bn phm mi tn iu khin xe. Hai phm UP, DOWN di chuyn tin li v LEFT, RIGHT s dng quay hng xe. Mt xe ua c bn cn cc thuc tnh sau: - max/min speed: tc ti a/ti thiu ca xe. Nn tc ti a c gi tr tuyt i cao hn tc ti thiu. - acceleration: Kh nng tng tc ca xe. Gi tr cng ln th xe cng nhanh t vn tc ti a. - rotationAngle: Kh nng iu chnh gc quay ca xe. - friction: ma st ca xe trn tng loi a hnh. Gi tr ny s gip xe gim tc khi ngi chi khng gi phm di chuyn.

2. Di chuyn v quay xe
Vi mc ch kim tra va chm, ta s s dng mt mng cc im bao quanh xe hay xy ra tip xc nht. y, cc im m ta chn l 4 nh t vng bao hnh ch nht ca xe (c th coi nh 4 bnh xe). Khi xe xoay gc alpha v di chuyn, ta phi tnh li ta cc im ny tng ng. Cng thc tnh ta mi ca mt im sau khi xoay gc alpha l: x = cos(alpha) * x sin(alpha) * y y = sin(alpha) * x + cos(alpha) * y

107 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

V d ti gc 0 , vi gc ta nm tm hnh ch nht, im A c ta l {x: -width/2,y: height/2}. Vy vi gc xoay alpha, ta mi ca A l: x: cos(alpha)*(-width/2) sin(alpha)*(- height/2) y: sin(alpha)*(-width/2) + cos(alpha)*(- height/2)

3. Kim tra va chm (tip xc) vi a hnh


Vi bn l mt hnh nh, ta cn kim tra bng cch da vo pixel. Tuy nhin khng phi bng cch lp m da vo kim tra mt vi v tr xc nh. Cc v tr ny ta chnh l 4 im thuc cc gc ca xe m ta xc nh trong phn trc. - u tin ta cn ly i tng ImageData ca nh lm bn . - Vi mi im dng kim tra va chm ca xe, ta tnh v tr alpha ca chng trong ImageData ((x+y*width)*4+3) v so snh gi tr alpha vi 0 (tng ng vi mt ng). Thay v kim tra gi tr alpha, ta c th kim tra mu sc ti pixel cho tng loi a hnh khc nhau. - Tng, gim ma st ng vi tng loi a hnh. Trong v d ny, ta ch to bn vi hai loi a hnh l ng v bi c. ma st s tng dn theo s lng im (bnh xe) tip xc vi c:

108 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

4. Hn ch xe di chuyn v xoay khi b va chm


Sau khi bit c mt im va chm vi , ta s xc nh xem xe c th di chuyn hoc xoay c hay khng. Xem hnh v sau, ta xt tng trng hp im va chm ca xe l: - 0 hoc 3: khng cho php xe li. - 1 hoc 2: khng cho php xe tin. - 0 hoc 1: khng cho php xoay tri. - 2 hoc 3: khng cho php xoay phi.

5. To cc checkpoint
bit xe c i ng ng v ng hng, ta cn to ra cc im kim tra trn ng gi l checkpoint. Nu ngi chi mun i tt n checkpoint, hy m bo rng h s n chm hn so vi i trn ng chnh bng cch to cc vt cn hoc tng ma st. Vi bn trong game ny, ta ch to ra 4 checkpoint. Phng thc reachNextCheckPoint() s kim tra xem xe c chm checkpoint tip theo hay khng. Khi n checkpoint cui cng, ta s a bin currentCheckPoint v 0 v tng lap ln 1.

6. Kt qu
Online Demo.

109 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

II. Game bn i bc 1. Bn v a hnh


i vi dng game ny, a hnh ca bn c th nh hng rt ln n ngi chi. V d ngi chi c th ri xung mt h su v khng th bn hay thm ch thit mng. Tuy nhin phn 1 ny ta cha cn quan tm n nhng vn ny. Phn chnh m ta hng dn l lm sao ngi chi c th tng tc v chu tc ng ca a hnh nh di chuyn, bn ph. V vn kim tra va chm vi a hnh, khng c phng php no khc ngoi vic kim tra da trn pixel (do a hnh c hnh dng phc tp v bt k). V vy ta to mt ImageData t nh bn , sau thm mt phng thc kim tra mt im c nm trong vng ImageDa ta c alpha bng 0 hay khng.
this.contain = function(x,y){ if(!imageData) return false; var index = Math.floor((x+y*width)*4+3); return imageData.data[index]!=0; }

110 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

2. Ph hy mt phn a hnh
S dng phng thc contain bn trn, ta s kim tra c va chm khi n bn hoc ngi chi ri xung t. Vi trng hp n bn, ta phi ph hy vng a hnh ni n bay vo. Rt may l API ca Canvas cung cp mt phng php dng v ra cc vng c alpha bng 0, tng t vi vic xa b hon ton vng . Ta thc hin vic ny bng cch gn hai thuc tnh ca context canvas l globalCompositeOperation thnh destination-out v fillStyle thnh rgba(0,0,0,1). V ti v tr b n bn, ta s v mt hnh trn khoan vng a hnh ny. Bn nn lu v phc hi li context khi s dng thit lp ny.

3. Trng lc v Gi
Trong dng game ny, n khi c bn ra s chu tc ng cng lc ca 3 loi lc l: lc bn, trng lc v gi. Mi lc ny c th c minh ha bi mt vector (Lc bn c gii thiu trong phn trc). Ti mi thi im khi n bay trong khng gian, v tr mi ca n s c tnh bng cch dng v tr hin ti cng vi vector tng ca 3 lc ny. Lu : Bn s thy rng tc n bay qu nhanh c th khin cho vic kim tra va chm khng chnh xc (do trong game l n bin t ni ny n ni khc). V vy cn gim tc n li v tng FPS ln mt gi tr thch hp. to gi, ta s dng mt vector vi hai gi tr x,y thay i ngu nhin sau mt khong thi gian khong 20 giy.

4. Di chuyn Cannon
Do c a hnh phc tp, vic di chuyn cannon s tng i phc tp v cn ty thuc vo hnh dng ca n. Vic cn quan tm y l cch cannon c th i ln a hnh dc va phi. Mt mo nh m ta lm y l s dng cch nhy cc thay v i. Nh vy mi bc i theo chiu ngang ta cng ng thi nng cao v tr ca cannon hn mt cht. Nu cannon i xung dc, n s ri xung v tr thp hn (nh phng thc update()); nu cannon i ln dc, n s v tr cao hn. i vi dc c nghing ln, ta s kim tra mt ta bn tri (hoc phi ty theo hng di chuyn) xem n c chm vo mt a hnh khng. Nu c, ta s khng cho php cannon di chuyn theo hng .

5. St thng ca n
Mi khi n trng t hoc bt k cannon no, n s pht n m gy st thng cho cc cannon nm trong phm vi nht nh. Sc st thng ca n cn b nh hng bi tc ca n khi 111 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

trng mc tiu. Vy ta to mt thuc tnh lu tr nng lng ca vin n khi ang bay da vo cng thc ng lng (E = 1/2*m*v^2). Lng hp b tn tht ca cannon khi trng n s c tnh bng tng ca ng nng vin n v st thng khi pht n. Lc khi pht n ta s cho gi tr t 0 n 100 vi mi phm vi st thng khc nhau ca n. Vi cch tnh ny, bn c th m bo rng khi s dng mt loi n c phm vi st thng ln th mc st thng ca n cng ch tng ng vi loi c phm vi st thng nh hn (cn phn bit lc v phm vi st thng ca n).

6. H tr nhiu ngi chi


Bi v game khng chi qua mng nn nhiu ngi phi chia s cng mt mn hnh. Mi khi n pht n hoc bay ra khi bn , ta s thc hin chuyn lt chi n ngi tip theo. Nu nh ngi chi tip theo cht, tip tc gi quy vi iu kin dng l s ngi chi cn sng nh hn 1 (_alivePlayers<1). Ngoi nhim v chnh trn, phng thc changeTurn() di y cn c nhim v hin th hiu ng n ti v tr ca vin n, bi v y l thi im ngay sau khi n pht n.

7. Kt qu
Online Demo.

112 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

III. Game Mario


y l kt qu ca vic pht trin Mt nn tng game 2D side-scrollong t phn trc. Online Demo.

113 | P a g e

Yin Yang

HTML5 Canvas - Lp trnh Game 2D

I.

Li kt

Hin ti c rt nhiu sn phm game cng nh cc ng dng mang tnh ha tng tc cao c lm trn nn tng HTML5. Cc thit b di ng v h iu hnh mi nh Windows 8 cng tp trung vo h tr v s dng cng ngh HTML5. K nguyn ca HTML5 c th m ra mt tiu chun thng nht cho cc ng dng rich user experience v khng cn phi n o trong vic la chn cc th vin h tr. Cc ni dung trnh by trong sch ny cha tht s nng cao v tp trung vo vic pht trin cc d n thnh mt sn phm game thc s c th cnh tranh trn th trng. Tuy nhin y l bc khi u vng chc cho tng lai ca vic pht trin game trn mng vi cng ngh HTML5. Kt hp vi m hnh client-server, ta c th pht trin cc game nhiu ngi chi (MMO) v lu tr d liu trc tip ca ngi chi trn server. y l iu m ti cha cp ti trong bo co ny.

J.
1. 2. 3. 4. 5. 6. 7.

Ti liu tham kho


HTML 5 Tutorial (http://html5tutorial.net/). Dive Into HTML 5 (http://diveintohtml5.info/offline.html). HTML 5 Specification (http://www.w3.org/TR/2011/WD- html5-20110525/). HTML 5 Rocks (http://www.html5rocks.com/en/). HTML 5 Doctor (http://html5doctor.com/) HTML 5 Demos and Examples (http://html5demos.com/) Mozilla Development Netword HTML 5 ( https://developer.mozilla.org/en/html/html5/) 8. Google.com.

114 | P a g e

You might also like