Download as pdf or txt
Download as pdf or txt
You are on page 1of 114

HTML5 Canvas -

Lp Trnh Game 2D
v1.0

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


2012
http://vietgamedev.net/
http://yinyangit.wordpress.com/
1/7/2012
YIN YANG
Yin Yang HTML5 Canvas - Lp trnh Game 2D
2 | P a g e


Yin Yang HTML5 Canvas - Lp trnh Game 2D
3 | P a g e

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!

Yin Yang HTML5 Canvas - Lp trnh Game 2D
4 | P a g e

Mc lc

A. GII THIU .......................................................................................................................... 9
B. HTML5 v cc API mi....................................................................................................... 10
I. Web Storage (DOM Storage)............................................................................................. 10
1. Gii thiu .................................................................................................................... 10
2. Interface Storage ......................................................................................................... 10
3. Local Storage v Session Storage ............................................................................... 11
4. S dng ....................................................................................................................... 12
5. Storage event .............................................................................................................. 14
6. Thm cc phng thc vo Storage ........................................................................... 15
II. Web SQL Database ........................................................................................................ 16
1. Gii thiu .................................................................................................................... 16
2. Open Database ............................................................................................................ 16
3. Transaction ................................................................................................................. 17
4. Execute SQL ............................................................................................................... 17
III. Web Worker ................................................................................................................... 18
1. Gii thiu .................................................................................................................... 18
2. V d n gin nht: ................................................................................................... 19
3. Kt lun....................................................................................................................... 20
IV. To chuyn ng vi WindowAnimationTiming API................................................... 20
1. setTimeout v setInterval............................................................................................ 21
2. WindowAnimationTiming.......................................................................................... 21
3. Li ch v hiu qu ..................................................................................................... 22
4. S dng ....................................................................................................................... 23
C. Canvas 2D API ..................................................................................................................... 25
I. V nh v thao tc vi pixel............................................................................................... 25
1. Np v v nh ............................................................................................................. 25
2. Thao tc vi pixel ....................................................................................................... 26
II. V hnh bng chut ........................................................................................................ 30
1. Xc nh ta chut ................................................................................................. 30
2. Lu ni dung ca Canvas ........................................................................................... 31
III. Chn v di chuyn i tng ......................................................................................... 34
1. To cu trc d liu .................................................................................................... 34
2. Cc phng thc v bng context .............................................................................. 35
Yin Yang HTML5 Canvas - Lp trnh Game 2D
5 | P a g e

3. Cc s kin chut ca Canvas .................................................................................... 36
IV. S dng bn phm .......................................................................................................... 37
1. Bt s kin bn phm .................................................................................................. 37
2. Kim tra trng thi ca nhiu phm ............................................................................ 38
3. Gii hn cc phm c bt ........................................................................................ 38
V. Chuyn ng trong Canvas ............................................................................................ 39
1. C bn ......................................................................................................................... 39
2. Thm hiu ng bng di chuyn .................................................................................. 41
3. Kim tra va chm ........................................................................................................ 42
D. K thut lp trnh Game C bn ........................................................................................ 44
I. Vng lp game (Game loop) hot ng th no? .............................................................. 44
1. Vng lp c bn .......................................................................................................... 44
2. Vng lp c tnh ton thi gian .................................................................................. 45
3. Gii php cui cng .................................................................................................... 46
4. V d hon chnh......................................................................................................... 46
II. Kim tra va chm: hnh trn v ch nht ....................................................................... 47
1. Gia hai hnh ch nht................................................................................................ 47
2. Gia hai hnh trn ....................................................................................................... 48
3. Gia hnh trn v hnh ch nht ................................................................................. 48
III. Kim tra mt im nm trn on thng........................................................................ 50
IV. Vector 2D c bn .......................................................................................................... 51
1. Khi nim ................................................................................................................... 51
2. Vector n v (Unit Vector, Normalized Vector) ....................................................... 51
3. Tch v hng (Dot product, Scalar product)............................................................. 52
4. Php chiu (Projection)............................................................................................... 52
5. Hin thc vi javascript .............................................................................................. 53
V. Khong cch t im n on thng ............................................................................ 54
VI. Giao im ca hai ng thng ..................................................................................... 56
1. To phng trnh ng thng t on thng ............................................................ 56
2. Tnh giao im ca hai ng thng .......................................................................... 57
3. Minh ha vi HTML5 Canvas.................................................................................... 58
VII. Va chm v phn x ....................................................................................................... 58
1. Kim tra hai on thng ct nhau ............................................................................... 58
2. Phng php ............................................................................................................... 59
VIII. Va chm gia ng trn v on thng .................................................................... 59
Yin Yang HTML5 Canvas - Lp trnh Game 2D
6 | P a g e

1. Va chm ...................................................................................................................... 59
2. Phn x........................................................................................................................ 60
IX. Va chm gia nhiu ng trn ..................................................................................... 62
1. X l va chm ca nhiu ng trn.......................................................................... 63
X. Kim tra va chm da trn pixel .................................................................................... 64
1. Mt wrapper ca Image .............................................................................................. 65
2. Xc nh vng giao hai hnh ch nht ........................................................................ 66
3. Kim tra va chm ........................................................................................................ 67
E. K thut lp trnh Game Nng cao .................................................................................... 69
I. Cun nh nn v bn (Map Scrolling) .......................................................................... 69
1. nh nn nhiu tng ..................................................................................................... 69
2. Cun gi ...................................................................................................................... 70
3. v cun tht ............................................................................................................ 70
II. To Amimated Sprite ..................................................................................................... 71
III. Np trc hnh nh v ti nguyn .................................................................................. 75
IV. Phng to/thu nh game bng nt cun chut ................................................................. 76
1. S kin Mouse Wheel trong javascript....................................................................... 78
2. Thay i kch thc bn ........................................................................................ 78
3. V tng vng bn ................................................................................................... 79
4. p dng cho cc nhn vt trn bn ........................................................................ 79
V. Thay i kch thc Canvas theo trnh duyt ................................................................ 80
1. iu chnh canvas thao kch thc trnh duyt .......................................................... 80
VI. S dng Full Screen API................................................................................................ 82
1. Gii thiu .................................................................................................................... 82
2. V d ........................................................................................................................... 84
VII. To menu v chuyn i gia cc mn hnh Game ....................................................... 86
1. Lp MenuItem ............................................................................................................ 86
2. Lp Screen .................................................................................................................. 87
3. Kim tra kt qu.......................................................................................................... 89
F. AI trong game....................................................................................................................... 90
I. Gii thiu ........................................................................................................................... 90
II. Phn tch la chn thut ton .................................................................................... 90
III. Thut ton Breadth First Search ..................................................................................... 91
IV. Cc quy tc trong game .................................................................................................. 92
V. Xy dng mt lp Queue da trn mng ....................................................................... 93
Yin Yang HTML5 Canvas - Lp trnh Game 2D
7 | P a g e

VI. Ci t thut ton Breadth First Search.......................................................................... 94
VII. Di chuyn i tng theo ng i................................................................................ 96
VIII. Vng lp chnh ca game ........................................................................................... 96
G. Mt nn tng game 2D side-scrolling .................................................................................. 98
I. C bn ................................................................................................................................ 98
1. To bn .................................................................................................................. 98
2. Kim tra va chm ........................................................................................................ 98
II. Thm cc chc nng v nhn vt ................................................................................. 101
1. Lp Character ........................................................................................................... 101
2. Lp Monster ............................................................................................................. 103
3. Lp Player................................................................................................................. 104
4. Lp Map ................................................................................................................... 105
H. Mt s ng dng minh ha ................................................................................................ 107
I. Game ua xe..................................................................................................................... 107
1. Cc thng s ca xe .................................................................................................. 107
2. Di chuyn v quay xe ............................................................................................... 107
3. Kim tra va chm (tip xc) vi a hnh ................................................................. 108
4. Hn ch xe di chuyn v xoay khi b va chm ......................................................... 109
5. To cc checkpoint ................................................................................................... 109
6. Kt qu ...................................................................................................................... 109
II. Game bn i bc ......................................................................................................... 110
1. Bn v a hnh .................................................................................................... 110
2. Ph hy mt phn a hnh ....................................................................................... 111
3. Trng lc v Gi ....................................................................................................... 111
4. Di chuyn Cannon .................................................................................................... 111
5. St thng ca n.................................................................................................... 111
6. H tr nhiu ngi chi............................................................................................ 112
7. Kt qu ...................................................................................................................... 112
III. Game Mario.................................................................................................................. 113
I. Li kt ................................................................................................................................ 114
J. Ti liu tham kho .............................................................................................................. 114

Yin Yang HTML5 Canvas - Lp trnh Game 2D
8 | P a g e



Yin Yang HTML5 Canvas - Lp trnh Game 2D
9 | P a g e

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>

Yin Yang HTML5 Canvas - Lp trnh Game 2D
10 | P a g e

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 qu 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();
};
Yin Yang HTML5 Canvas - Lp trnh Game 2D
11 | P a g e

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 sch.
- 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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
12 | P a g e

- 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
subdomainlocalStorage['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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
13 | P a g e


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.

Yin Yang HTML5 Canvas - Lp trnh Game 2D
14 | P a g e

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>

Yin Yang HTML5 Canvas - Lp trnh Game 2D
15 | P a g e

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.

Yin Yang HTML5 Canvas - Lp trnh Game 2D
16 | P a g e

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 javascript 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);
Yin Yang HTML5 Canvas - Lp trnh Game 2D
17 | P a g e

3. Transaction
Bn cn thc thi cc cu SQL trong ng cnh ca mt transaction. 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) {
tx.executeSql("CREATE TABLE IF NOT EXISTS CUSTOMERS(id unique, name)");
tx.executeSql("INSERT INTO CUSTOMERS (id, name) VALUES (1, 'peter')");
tx.executeSql("INSERT 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 ?:

Yin Yang HTML5 Canvas - Lp trnh Game 2D
18 | P a g e

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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
19 | P a g e


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() {
Yin Yang HTML5 Canvas - Lp trnh Game 2D
20 | P a g e

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 API
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().
Yin Yang HTML5 Canvas - Lp trnh Game 2D
21 | P a g e

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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
22 | P a g e

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():


Yin Yang HTML5 Canvas - Lp trnh Game 2D
23 | P a g e


setTimeout requestAnimationFrame
Expected callbacks 40543 40544
Actual callbacks 41584 40544
Callback Efficiency 59.70% 100.00%
Callback Efficiency Medium High
Power Consumption Medium Low
Background Interference High 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;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
24 | P a g e

if(cx<0 || cx > _canvas.width)
speedX = -speedX;

if(cy<0 || cy > _canvas.height)
speedY = -speedY;

// 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>

Yin Yang HTML5 Canvas - Lp trnh Game 2D
25 | P a g e

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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
26 | P a g e

- V image ti mt v tr destX, destY:
context.drawImage(image,destX,destY);
- 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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
27 | P a g e


Bn c th tham kho thng tin v cc API ny ti: http://www.whatwg.org/specs/web-
apps/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 ])
Yin Yang HTML5 Canvas - Lp trnh Game 2D
28 | P a g e

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;

Yin Yang HTML5 Canvas - Lp trnh Game 2D
29 | P a g e

for (var i = 0; i < data.length; i += 4) {

data[i] = 255 - data[i]; // red
data[i + 1] = 255 - data[i+1]; // green
data[i + 2] = 255 - data[i+2]; // blue
data[i + 3] = 255; // alpha
}

context.putImageData(imageData,0,0);

}
</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);
Yin Yang HTML5 Canvas - Lp trnh Game 2D
30 | P a g e



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){
Yin Yang HTML5 Canvas - Lp trnh Game 2D
31 | P a g e

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 khi 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;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
32 | P a g e

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

$.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, 0, canvas.width,
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; // clear canvas
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;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
33 | P a g e

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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
34 | P a g e


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;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
35 | P a g e

return x > this.x && x < right &&
y > this.y && y < bottom;
}
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();
Yin Yang HTML5 Canvas - Lp trnh Game 2D
36 | P a g e

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,y-
RECT_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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
37 | P a g e




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
Yin Yang HTML5 Canvas - Lp trnh Game 2D
38 | P a g e

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
Yin Yang HTML5 Canvas - Lp trnh Game 2D
39 | P a g e

];
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 = Math.floor(Math.random()*(this.mapWidth-2*this.radius)) +
this.radius;
this.cy = Math.floor(Math.random()*(this.mapHeight-2*this.radius)) +
this.radius;

Yin Yang HTML5 Canvas - Lp trnh Game 2D
40 | P a g e

}
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>
Yin Yang HTML5 Canvas - Lp trnh Game 2D
41 | P a g e

<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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
42 | P a g e


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 ca 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;

if( this.right >= item.left && this.left <= item.right && // the ball is
((this.cy < item.top && this.bottom >= item.top) || // on or
(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))) // right side of the rectangle
{
this.speedX = -this.speedX;
hCollision = true;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
43 | P a g e


if(hCollision || vCollision)
break;
}

}
Minh ha:


Yin Yang HTML5 Canvas - Lp trnh Game 2D
44 | P a g e

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:

Yin Yang HTML5 Canvas - Lp trnh Game 2D
45 | P a g e


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 hon 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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
46 | P a g e

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)
Yin Yang HTML5 Canvas - Lp trnh Game 2D
47 | P a g e

draw();

lastUpdateTime += TICKS * numOfUpdate;
diffTime -= TICKS * numOfUpdate;
var sleepTime = TICKS - diffTime;
setTimeout(gameLoop,sleepTime);
}

function updateGame() {
actualCounter++;
}

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 ||
Yin Yang HTML5 Canvas - Lp trnh Game 2D
48 | P a g e

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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
49 | P a g e

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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
50 | P a g e

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 .
Yin Yang HTML5 Canvas - Lp trnh Game 2D
51 | P a g e

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 vy:
|| = 1
Yin Yang HTML5 Canvas - Lp trnh Game 2D
52 | P a g e

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
Yin Yang HTML5 Canvas - Lp trnh Game 2D
53 | P a g e

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|
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 = {
Yin Yang HTML5 Canvas - Lp trnh Game 2D
54 | P a g e

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;

// 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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
55 | P a g e



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();
Yin Yang HTML5 Canvas - Lp trnh Game 2D
56 | P a g e


// 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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
57 | P a g e

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
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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
58 | P a g e

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 of this line
Line.prototype.insideRectBound = function(x, y){
if( Math.min(this.p1.x,this.p2.x) - x > EPSILON ||
x - Math.max(this.p1.x,this.p2.x) > EPSILON ||
Math.min(this.p1.y,this.p2.y) - y > EPSILON ||
y - Math.max(this.p1.y,this.p2.y) > EPSILON)
return false;
return true;
}

// ...
var intersected = _line1.insideRectBound(x,y) && _line2.insideRectBound(x,y);
Yin Yang HTML5 Canvas - Lp trnh Game 2D
59 | P a g e

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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
60 | P a g e

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); // distance

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;
}
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).
Yin Yang HTML5 Canvas - Lp trnh Game 2D
61 | P a g e

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
};

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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
62 | P a g e


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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
63 | P a g e


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]);
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
64 | P a g e

Hm checkCollision:
function checkCollision(ball1,ball2){

var dx = ball1.cx - ball2.cx;
var dy = ball1.cy - ball2.cy;

// 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 angle1 = Math.atan2(u1.y, u1.x);
var angle2 = Math.atan2(u2.y, u2.x);
var ux1 = u1.length * Math.cos(angle1-angle);
var uy1 = u1.length * Math.sin(angle1-angle);
var ux2 = u2.length * Math.cos(angle2-angle);
var uy2 = u2.length * Math.sin(angle2-angle);

var vx1 = ((ball1.mass-
ball2.mass)*ux1+(ball2.mass+ball2.mass)*ux2)/(ball1.mass+ball2.mass);
var vx2 = ((ball1.mass+ball1.mass)*ux1+(ball2.mass-
ball1.mass)*ux2)/(ball1.mass+ball2.mass);
var vy1 = uy1;
var vy2 = uy2;

// now we transform the 1D coordinate back to 2D
var v1 = {}, v2 = {};
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;

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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
65 | P a g e

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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
66 | P a g e

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.

Yin Yang HTML5 Canvas - Lp trnh Game 2D
67 | P a g e

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)+(j-
img1.top)*img1.width)*4+3;
var index2 = ((i-img2.left)+(j-
img2.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 of
continue looping
}
}
}

return {
rect: rect,
points: points
};
}
return null;
}
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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
68 | P a g e



Yin Yang HTML5 Canvas - Lp trnh Game 2D
69 | P a g e

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.

Yin Yang HTML5 Canvas - Lp trnh Game 2D
70 | P a g e

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)
Yin Yang HTML5 Canvas - Lp trnh Game 2D
71 | P a g e

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
Yin Yang HTML5 Canvas - Lp trnh Game 2D
72 | P a g e

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]={
Yin Yang HTML5 Canvas - Lp trnh Game 2D
73 | P a g e

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);

Yin Yang HTML5 Canvas - Lp trnh Game 2D
74 | P a g e

}
}
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 left = this.left+this.speedX;
var top = this.top+this.speedY;
var right = left+this.frameWidth;
var 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
});
Yin Yang HTML5 Canvas - Lp trnh Game 2D
75 | P a g e

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);
III. Np trc hnh nh v ti nguyn
i vi nhng game s dng nhiu hnh nh (m thanh, video,), ta cn phi 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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
76 | P a g e

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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
77 | P a g e

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

Yin Yang HTML5 Canvas - Lp trnh Game 2D
78 | P a g e

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 bit 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 == 0 || (zoom<0 && this.zoom<=0.5) || (zoom>0 &&
this.zoom>=4))
return;

this.zoom *= zoom < 0 ? 0.5 : 2;

this.reset();
},
reset : function()
{
this.cellSize = CELL_SIZE*this.zoom;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
79 | P a g e


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 kch 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/old_zoom*new_zoom
new_top = old_top/old_zoom*new_zoom
this.setZoom = function(zoom){
if(this.zoom!=zoom)
{
Yin Yang HTML5 Canvas - Lp trnh Game 2D
80 | P a g e

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).
Yin Yang HTML5 Canvas - Lp trnh Game 2D
81 | P a g e



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

Yin Yang HTML5 Canvas - Lp trnh Game 2D
82 | P a g e

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;

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 enterFullScreen():
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");
Yin Yang HTML5 Canvas - Lp trnh Game 2D
83 | P a g e


}
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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
84 | P a g e

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(){
Yin Yang HTML5 Canvas - Lp trnh Game 2D
85 | P a g e


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>

Yin Yang HTML5 Canvas - Lp trnh Game 2D
86 | P a g e

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);
};
Yin Yang HTML5 Canvas - Lp trnh Game 2D
87 | P a g e

this.contain = function(x,y){
return !(x<this.left || x>this.right || y<this.top ||
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(){

};
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 || x>this.right || y<this.top ||
y>this.bottom);
};
}
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
Yin Yang HTML5 Canvas - Lp trnh Game 2D
88 | P a g e

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 CELL_SIZE = 10;
var FPS = 10 ;
var WIDTH = 400;
var 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;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
89 | P a g e

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.

Yin Yang HTML5 Canvas - Lp trnh Game 2D
90 | P a g e

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 phi 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:.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
91 | P a g e

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 Danh sch cha cc v tr ch c xt
Close Danh sch cha cc v tr xt.
start V tr bt u
goal V tr kt thc
n v tr ang xt.
G(n) Tp cc v tr c th n t v tr n.
Hnh minh ha (ngun http://artint.info/html/ArtInt_54.html):
Yin Yang HTML5 Canvas - Lp trnh Game 2D
92 | P a g e


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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
93 | P a g e

- 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);
}
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
94 | P a g e

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 BLANK = 0;
var WALL = 1;
var SNAKE = 2;
var 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)
Yin Yang HTML5 Canvas - Lp trnh Game 2D
95 | P a g e

{
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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
96 | P a g e

return nodes;
}
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, y) ||
_playerSnake.contain(x, 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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
97 | P a g e

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

_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 start the next
level",WIDTH/2,HEIGHT/2);
}else if(_comSnake.data.length==MAX_COM_LENGTH)
{
endGame();
return;
}
}

Yin Yang HTML5 Canvas - Lp trnh Game 2D
98 | P a g e

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)
{
Yin Yang HTML5 Canvas - Lp trnh Game 2D
99 | P a g e

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;
}
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 vtop = this.top+this.speedY;
var vbottom = vtop+this.height;
var vleft = this.left+this.speedX;
var vright = vleft+this.width;

if(this.isJumping)
vbottom -= 1;
Yin Yang HTML5 Canvas - Lp trnh Game 2D
100 | P a g e


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;
}



Yin Yang HTML5 Canvas - Lp trnh Game 2D
101 | P a g e



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);
Yin Yang HTML5 Canvas - Lp trnh Game 2D
102 | P a g e

this.speedY = 0;

this.isJumping = true;
this.isDead = false;

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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
103 | P a g e

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();
Yin Yang HTML5 Canvas - Lp trnh Game 2D
104 | P a g e

context.restore();
}

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;
}
}
}

}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
105 | P a g e

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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
106 | P a g e

return false;
};
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++;
}
}
};

Yin Yang HTML5 Canvas - Lp trnh Game 2D
107 | P a g e

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

Yin Yang HTML5 Canvas - Lp trnh Game 2D
108 | P a g e


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:
Yin Yang HTML5 Canvas - Lp trnh Game 2D
109 | P a g e

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.
Yin Yang HTML5 Canvas - Lp trnh Game 2D
110 | P a g e


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 ImageData 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;
}
Yin Yang HTML5 Canvas - Lp trnh Game 2D
111 | P a g e

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
Yin Yang HTML5 Canvas - Lp trnh Game 2D
112 | P a g e

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.

Yin Yang HTML5 Canvas - Lp trnh Game 2D
113 | P a g e

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

Online Demo.


Yin Yang HTML5 Canvas - Lp trnh Game 2D
114 | P a g e

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. Ti liu tham kho
1. HTML 5 Tutorial (http://html5tutorial.net/).
2. Dive Into HTML 5 (http://diveintohtml5.info/offline.html).
3. HTML 5 Specification (http://www.w3.org/TR/2011/WD- html5-20110525/).
4. HTML 5 Rocks (http://www.html5rocks.com/en/).
5. HTML 5 Doctor (http://html5doctor.com/)
6. HTML 5 Demos and Examples (http://html5demos.com/)
7. Mozilla Development Netword HTML 5 (
https://developer.mozilla.org/en/html/html5/)
8. Google.com.

You might also like