Professional Documents
Culture Documents
2012
Yin Yang
2 |P age
Yin Yang
LI TA
Flash l mt cng ngh rt hiu qu, ph bin v cho php lp trnh vin c th to ra nhng ng dng vi y cc hiu ng hnh nh, m thanh c sc. Nhng cng ngh tng t nh Java Applet hay mt a con sng gi ca Microsoft l Silverlight cng khng th ng vng v cnh tranh c vi Flash. Nhng mt vn ny sinh y l kh nng tng tc gia cc cng ngh ny vi cc thnh phn xung quanh n (nh cc th HTML) dng nh khng th. Chng b c lp v hot ng c lp vi th gii bn ngoi. Gii php l quay tr li s dng thun HTML, Javascript v CSS, lp trnh vin vn c th to c ra ng dng vi hiu ng c bit v khng b cc gii hn m nhng cng ngh trn gp phi. Nhng tr ngi ln nht l khng c API to ra c nhng ng dng tng t nh trn Flash. V tc ca cc ng dng thun HTML kh chm, hu nh khng th chp nhn c vi mt game c yu cu cu hnh trung bnh. Nhng vi s ra i ca HTML5 cng vi cc thnh phn v API mi, gii hn trn b ph b v ang tng bc thay th dn cc cng ngh nh Flash. Vi cc ng dng cn nhng hiu ng ha v chuyn ng c bit, lp trnh vin c th s dng Canvas vi kiu bitmap hoc SVG vi kiu vector. Khng ch p dng cho vic thit k cc trang web trc quan, HTML5 cn c p dng to ra cc th vin ha gip to ra cc ng dng th, game trong c mi trng 2D v 3D nh nhng ng dng trn desktop. Mt iu ng mng na l HTML, Javascript v CSS khng cn b gii hn trn trnh duyt m c th c trin khai trn desktop di dng cc widget, trn cc thit b di ng v c th bt k thit b no. Nh vy, lp trnh vin khng cn s dng hay yu cu ngi dng ci t bt k th vin no c th chy c cc ng dng ca h. Mt li th rt ln m ch c HTML mi c th t c. Tuy nhin vic xy dng game trn trnh duyt c th l mt tri nghim kh khn v phi cn nhc gia vic chn la gia cc th vin hin i, y chc nng hay lm theo cc API cp thp ca HTML (thng qua Javascript). Qu trnh thc hin sch ny khng th trnh khi sai st, bn c c th gi phn hi ti http://vietgamedev.vn hoc blog http://yinyangit.wordpress.com hoc gi email trc tip cho ti (yinyang.it@gmail.com) thc mc, trao i cng nh gip ti sa i, cp nht nu cn thit. Xin cm n!
3 |P age
Yin Yang
Mc lc
A. B. I. GII THIU .......................................................................................................................... 9 HTML5 v cc API mi....................................................................................................... 10 Web Storage (DOM Storage)............................................................................................. 10 1. 2. 3. 4. 5. 6. II. 1. 2. 3. 4. III. 1. 2. 3. IV. 1. 2. 3. 4. C. I. Gii thiu .................................................................................................................... 10 Interface Storage ......................................................................................................... 10 Local Storage v Session Storage ............................................................................... 11 S dng ....................................................................................................................... 12 Storage event .............................................................................................................. 14 Thm cc phng thc vo Storage ........................................................................... 15 Web SQL Database ........................................................................................................ 16 Gii thiu .................................................................................................................... 16 Open Database ............................................................................................................ 16 Transaction ................................................................................................................. 17 Execute SQL ............................................................................................................... 17 Web Worker ................................................................................................................... 18 Gii thiu .................................................................................................................... 18 V d n gin nht: ................................................................................................... 19 Kt lun....................................................................................................................... 20 To chuyn ng vi WindowAnimationTiming API................................................... 20 setTimeout v setInterval............................................................................................ 21 WindowAnimationTiming.......................................................................................... 21 Li ch v hiu qu ..................................................................................................... 22 S dng ....................................................................................................................... 23
Canvas 2D API ..................................................................................................................... 25 V nh v thao tc vi pixel............................................................................................... 25 1. 2. II. 1. 2. III. 1. 2. Np v v nh ............................................................................................................. 25 Thao tc vi pixel ....................................................................................................... 26 V hnh bng chut ........................................................................................................ 30 Xc nh ta chut ................................................................................................. 30 Lu ni dung ca Canvas ........................................................................................... 31 Chn v di chuyn i tng ......................................................................................... 34 To cu trc d liu .................................................................................................... 34 Cc phng thc v bng context .............................................................................. 35 4 |P age
S dng bn phm .......................................................................................................... 37 Bt s kin bn phm .................................................................................................. 37 Kim tra trng thi ca nhiu phm ............................................................................ 38 Gii hn cc phm c bt ........................................................................................ 38 Chuyn ng trong Canvas ............................................................................................ 39 C bn ......................................................................................................................... 39 Thm hiu ng bng di chuyn .................................................................................. 41 Kim tra va chm ........................................................................................................ 42
K thut lp trnh Game C bn ........................................................................................ 44 Vng lp game (Game loop) hot ng th no? .............................................................. 44 1. 2. 3. 4. II. 1. 2. 3. III. IV. 1. 2. 3. 4. 5. V. VI. 1. 2. 3. VII. 1. 2. VIII. Vng lp c bn .......................................................................................................... 44 Vng lp c tnh ton thi gian .................................................................................. 45 Gii php cui cng .................................................................................................... 46 V d hon chnh......................................................................................................... 46 Kim tra va chm: hnh trn v ch nht ....................................................................... 47 Gia hai hnh ch nht................................................................................................ 47 Gia hai hnh trn ....................................................................................................... 48 Gia hnh trn v hnh ch nht ................................................................................. 48 Kim tra mt im nm trn on thng........................................................................ 50 Vector 2D c bn .......................................................................................................... 51 Khi nim ................................................................................................................... 51 Vector n v (Unit Vector, Normalized Vector) ....................................................... 51 Tch v hng (Dot product, Scalar product)............................................................. 52 Php chiu (Projection)............................................................................................... 52 Hin thc vi javascript .............................................................................................. 53 Khong cch t im n on thng ............................................................................ 54 Giao im ca hai ng thng ..................................................................................... 56 To phng trnh ng thng t on thng ............................................................ 56 Tnh giao im ca hai ng thng .......................................................................... 57 Minh ha vi HTML5 Canvas.................................................................................... 58 Va chm v phn x ....................................................................................................... 58 Kim tra hai on thng ct nhau ............................................................................... 58 Phng php ............................................................................................................... 59 Va chm gia ng trn v on thng .................................................................... 59 5 |P age
Va chm gia nhiu ng trn ..................................................................................... 62 X l va chm ca nhiu ng trn.......................................................................... 63 Kim tra va chm da trn pixel .................................................................................... 64 Mt wrapper ca Image .............................................................................................. 65 Xc nh vng giao hai hnh ch nht ........................................................................ 66 Kim tra va chm ........................................................................................................ 67
K thut lp trnh Game Nng cao .................................................................................... 69 Cun nh nn v bn (Map Scrolling) .......................................................................... 69 1. 2. 3. II. III. IV. 1. 2. 3. 4. V. 1. VI. 1. 2. VII. 1. 2. 3. nh nn nhiu tng ..................................................................................................... 69 Cun gi ...................................................................................................................... 70 v cun tht ............................................................................................................ 70 To Amimated Sprite ..................................................................................................... 71 Np trc hnh nh v ti nguyn .................................................................................. 75 Phng to/thu nh game bng nt cun chut ................................................................. 76 S kin Mouse Wheel trong javascript....................................................................... 78 Thay i kch thc bn ........................................................................................ 78 V tng vng bn ................................................................................................... 79 p dng cho cc nhn vt trn bn ........................................................................ 79 Thay i kch thc Canvas theo trnh duyt ................................................................ 80 iu chnh canvas thao kch thc trnh duyt .......................................................... 80 S dng Full Screen API................................................................................................ 82 Gii thiu .................................................................................................................... 82 V d ........................................................................................................................... 84 To menu v chuyn i gia cc mn hnh Game ....................................................... 86 Lp MenuItem ............................................................................................................ 86 Lp Screen .................................................................................................................. 87 Kim tra kt qu.......................................................................................................... 89
F. I. II.
AI trong game....................................................................................................................... 90 Gii thiu ........................................................................................................................... 90 Phn tch la chn thut ton .................................................................................... 90 Thut ton Breadth First Search ..................................................................................... 91 Cc quy tc trong game .................................................................................................. 92 Xy dng mt lp Queue da trn mng ....................................................................... 93 6 |P age
III. IV. V.
Ci t thut ton Breadth First Search.......................................................................... 94 Di chuyn i tng theo ng i................................................................................ 96 Vng lp chnh ca game ........................................................................................... 96
Mt nn tng game 2D side-scrolling .................................................................................. 98 C bn ................................................................................................................................ 98 1. 2. II. 1. 2. 3. 4. To bn .................................................................................................................. 98 Kim tra va chm ........................................................................................................ 98 Thm cc chc nng v nhn vt ................................................................................. 101 Lp Character ........................................................................................................... 101 Lp Monster ............................................................................................................. 103 Lp Player................................................................................................................. 104 Lp Map ................................................................................................................... 105
H. I.
Mt s ng dng minh ha ................................................................................................ 107 Game ua xe..................................................................................................................... 107 1. 2. 3. 4. 5. 6. II. 1. 2. 3. 4. 5. 6. 7. III. Cc thng s ca xe .................................................................................................. 107 Di chuyn v quay xe ............................................................................................... 107 Kim tra va chm (tip xc) vi a hnh ................................................................. 108 Hn ch xe di chuyn v xoay khi b va chm ......................................................... 109 To cc checkpoint ................................................................................................... 109 Kt qu ...................................................................................................................... 109 Game bn i bc ......................................................................................................... 110 Bn v a hnh .................................................................................................... 110 Ph hy mt phn a hnh ....................................................................................... 111 Trng lc v Gi ....................................................................................................... 111 Di chuyn Cannon .................................................................................................... 111 St thng ca n.................................................................................................... 111 H tr nhiu ngi chi............................................................................................ 112 Kt qu ...................................................................................................................... 112 Game Mario.................................................................................................................. 113
I. J.
7 |P age
Yin Yang
8 |P age
Yin Yang
A. GII THIU
HTML5 c h tr hu trn tt c trnh duyt. N l mt tp hp cc tnh nng c bit. nhng ta c th tm thy h tr cho mt s phn c trng nh canvas, video hoc nh v a l. Nhng c im k thut HTML5 cng xc nh lm th no nhng du ngoc nhn tng tc vi JavaScrip, thng qua cc ti liu thng qua cc ti liu Object Model (DOM) HTML5 khng ch xc nh mt tag <video>, cng l mt DOM API tng ng cho cc i tng video trong DOM. Bn c th s dng API ny tm kim h tr cho cc nh dng video khc nhau, nghe nhc, tm dng mt on video, mute audio , theo di bao nhiu video c ti v, v mi th khc bn cn phi xy dng mt tri nghim ngi dng phong ph xung quanh tag <video> . Khng cn phi vt b bt k th g: Ta khng th ph nhn rng HTML 4 l cc nh dng nh du thnh cng nht t trc n nay. HTML5 c xy dng da trn thnh cng . Bn khng cn phi b nhng nh du hin c. Bn khng cn phi hc li nhng iu bn bit. Nu ng dng web ca bn trc y s dng HTML 4, n vn s hot ng trong HTML5. By gi, nu bn mun ci thin cc ng dng web, bn n ng ni. V d c th: HTML5 h tr tt c cc hnh thc kim sot t HTML 4, nhng n cng bao gm iu khin u vo mi. Mt s trong s ny l qu hn b sung nh cc thanh trt v date pickkers, nhng thnh phn khc tinh t hn. V d, cc loi email input trng ging nh mt textbox, nhng cc trnh duyt linh ng s ty bin bn phm trn mn hnh ca h c th d dng hn khi nhp a ch email. Cc trnh duyt c khng h tr cc loi email input s xem n nh l mt vn bn thng thng, v hnh thc vn lm vic khng c thay i nh du hoc kch bn hack. iu ny c ngha l bn c th bt u ci thin cc hnh thc web ca bn ngy hm nay, ngay c khi mt s khch truy cp vo web ca bn. Rt d dng bt u: "Nng cp" ln HTML5 c th n gin ch bng vic thay i th DOCTYPE ca bn. DOCTYPE cn phi nm trong dng u tin ca tt c cc trang HTML. Cc phin bn trc ca HTML c nh ngha rt nhiu loi doctype, v la chn mt doctype ng rt rc ri. Trong HTML5 ch c mt DOCTYPE:
<!DOCTYPE html>
Nng cp ln DOCTYPE HTML5 s khng ph v cu trc ti liu ca bn, bi v cc th li thi trc y c nh ngha trong HTML 4 vn c v ra trong HTML5. Nhng n cho php bn s dng v xc nhn cc th mi nh <article> <section> , <header> , v <footer>
9 |P age
Yin Yang
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.
1. Gii thiu
Hin nay, mi cookie ch cho php lu tr ti a 4KB v vi chc cookie cho mt domain. V th cookie ch c dng lu tr nhng thng tin n gin v ngn gn nh email, username, gip ngi dng ng nhp t ng vo trang web. iu ny khin cho nhng trang web mun nng cao hiu sut lm vic bng cch cache d liu ti client hu nh khng th thc hin c. S xut hin ca Web Storage l mt im nhn cho vic ra i cc ng dng web c kh nng tng tc v np d liu tc th trn trnh duyt. Mt hiu q u na l dung lng truyn ti qua mng c th c gim thiu ng k. V d mt ng dng tra cu sch trc tuyn, cc sch c tra s c lu li trn my ca ngi dng. Khi cn tra li, my ngi dng s khng cn kt ni n server ti li nhng d liu c. Vi nhng ng dng web c c s d liu nh gn, lp trnh vin c th thc hin vic cache m thm c s d liu xung client v sau ngi dng c th thoi mi tra cu m khng cn request n server.
2. Interface Storage
interface Storage { readonly attribute unsigned long length; DOMString? key(unsigned long index); getter DOMString getItem(DOMString key); setter creator void setItem(DOMString key, DOMString value); deleter void removeItem(DOMString key); void clear(); };
10 | P a g e
Yin Yang
Nh bn thy, cc d liu lu tr trong Storage ch l kiu chui, vi cc loi d liu khc s nguyn, s thc, bool, bn cn phi thc hin chuyn i kiu. Mi i tng Storage l mt danh sch cc cp key/value, i tng ny bao gm cc thuc tnh v phng thc: length: s lng cp key/value c trong i tng. key(n): tr v tn ca key th n trong danh sch. getItem(key): tr v value c gn vi key. setItem(key,value): thm hoc gn mt cp key/value vo danh sc h. removeItem(key): xa cp key/value khi danh sch. clear: xa ton b d liu trong danh sch.
Bn cnh , i tng Storage cn c th c truy xut qua cc thuc tnh l cc key trong danh sch. V d:
localStorage.abc="123"; // equivalent to: // localStorage.setItem("abc","123");
Yin Yang
localStorage: c th truy xut ln nhau gia cc ca s trnh duyt. D liu s c lu tr khng gii hn thi gian. i vi localStorage:
Each domain and subdomain has its own separate local storage area. Domains can access the storage areas of subdomains, and subdomains can access the storage areas of parent domains. For example, localStorage['example.com'] is accessible to example.com and any of its subdomains. The subdomain localStorage['www.example.com'] is accessible to example.com , but not to other subdomains, such as mail.example.com . http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx
4. S dng
Bn c th to mt tp tin HTML vi ni dung pha di chy trn trnh duyt. y ta s dng Chrome v n cung cp sn ca s xem phn Resources trong Google Chrome Developer Tools (Ctrl + Shift + I). Ni dung ca tp tin HTML nh sau:
<!DOCTYPE html> <html> <body> <script type="text/javascript"> sessionStorage.myVariable="Hello. "; localStorage.myVariable="Nice to meet you!"; document.write(sessionStorage.myVariable); document.write(localStorage.myVariable); </script> </body> </html>
Kt qu hin th:
12 | P a g e
Yin Yang
Trong giao din xem Resources, bn c th m phn Console g cc lnh javascript tng tc vi trang web hin ti. V d y ta thm cc gi tr mi vo trong localStorage v dng alert() hin th chng ln.
13 | P a g e
Yin Yang
5. Storage event
i tng Window trong javascript cung cp mt event vi tn storage. Event ny c kch hot mi khi storageArea b thay i.
interface StorageEvent : Event { readonly attribute DOMString key; readonly attribute DOMString? oldValue; readonly attribute DOMString? newValue; readonly attribute DOMString url; readonly attribute Storage? storageArea; };
Event ny c th khng hot ng khi bn xem tp tin HTML my cc b v ch c kch hot nhng ca s/th khc. Tc l khi bn m nhiu ca s trnh duyt truy xut n cng domain, nu bn thay i mt i tng Storage bn ca s ny th cc ca s cn li s c kch hot event storage, cn ca s hin ti s khng xy ra g c.
<!DOCTYPE html> <html> <body> <button onclick="changeValue();">Change Value</button> <script type="text/javascript"> localStorage.clear(); console.log(localStorage); if (window.addEventListener) window.addEventListener('storage', storage_event, false); else if (window.attachEvent) // IE window.attachEvent('onstorage', storage_event, false); function storage_event(event){ console.log(event); } function changeValue() { localStorage.myValue=Math.random(); } </script> </body> </html>
14 | P a g e
Yin Yang
Phng thc trn s dng biu thc chnh quy tm kim theo hai ty chn g (tm kim ton b chui) v i (khng phn bit hoa thng). Phng thc string.search() tr v v tr ca k t u tin khp vi t kha tm kim, ngc li l -1 nu khng tm thy.
15 | P a g e
Yin Yang
1. Gii thiu
Li ch ca SQLite l c c tch hp vo cc ng dng vi mt th vin duy nht truy xut c database. Chnh v vy, bn c th s dng n lm c s d liu cho nhng ng dng nh v khng cn thit ci t bt k phn mm hoc driver no. Hin ti Web SQL Database c h tr trong cc trnh duyt Google Chrome, Opera v Safari. Trong javascript, bn s dng cc phng thc chnh sau lm vic vi Web SQL Database. openDatabase: m mt database c sn hoc to mi nu n cha tn ti. transaction / readTransaction: h tr thc hin cc thao tc vi database v rollback nu xy ra sai st. executeSql: thc thi mt cu lnh SQL.
2. Open Database
Phng thc ny c nhim v m mt database c sn hoc to mi nu n cha tn ti. Phng thc ny c khai bo nh sau:
Database openDatabase( in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback );
Tham s: name: tn ca database. version: phin bn. Hai database trng tn nhng khc phin bn th khc nhau. displayname: m t. estimatedSize: dung lng c tnh theo n v byte. creationCallback: phng thc callback c thc thi sau khi database m/to. V d to mt database vi tn mydb v dung lng l 5 MB:
var db = openDatabase("mydb", "1.0", "My First DB", 5 * 1024 * 1024);
16 | P a g e
Yin Yang
3. Transaction
Bn cn thc thi cc cu SQL trong ng cnh ca mt transactio n. Mt transaction cung cp kh nng rollback khi mt trong nhng cu lnh bn trong n thc thi tht bi. Ngha l nu bt k mt lnh SQL no tht bi, mi thao tc thc hin trc trong transaction s b hy b v database khng b nh hng g c. Interface Database h tr hai phng thc gip thc hin iu ny l transaction() v readTransaction(). im khc bit gia chng l transaction() h tr read/write, cn readTransaction() l read-only. Nh vy s dng readTransaction() s cho hiu sut cao hn nu nh bn ch cn c d liu.
void transaction( in SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback );
V d:
var db = openDatabase("mydb", "1.0", "My First DB", 5 * 1024 * 1024); db.transaction(function (tx) { // Using tx object to execute SQL Statements });
4. Execute SQL
executeSql() l phng thc duy nht thc thi mt cu lnh SQL trong Web SQL. N c s dng cho c mc ch c v ghi d liu
void executeSql( in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback );
Tuy nhin cch thc thi SQL trn khng c r rng v c th b cc vn v bo mt nh SQL injection. V vy tt hn bn nn cc tham s cn truyn cho cu SQL trong mt mng v t vo lm tham s th 2 ca phng thc executeSql(). Cc v tr trong cu SQL cha tham s s c thay th bi du ?: 17 | P a g e
Yin Yang
tx.executeSql("INSERT INTO CUSTOMERS (id, name) VALUES (?,?)", [1,"peter"]); tx.executeSql("INSERT INTO CUSTOMERS (id, name) VALUES (?,?)", [2,"paul"]);
1. Gii thiu
i tng Web Worker c to ra s thc thi trong mt thread c lp v chy ch nn nn khng nh hng n giao din tng tc ca trang web vi ngi dng. Vi c im ny, bn c th s dng Web Workert cc cng vic i hi thi gian x l lu np d liu, to cache, im hn ch ca Web Worker l khng th truy xut c thnh phn trn DOM, v c cc i tng window, document hay parent. M lnh cc cng vic cn thc thi cng phi c cch ly trong mt tp tin script. Vic to mt Web Worker s cn thc hin nh sau:
var worker = new Worker('mytask.js');
Tp tin script s c ti v v Worker ch c thc thi sau khi tp tin ny ti hon tt. Trong tp tin script ny, ta s x l s kin message ca Worker t cc d liu nhn c thng qua phng thc postMessage(). Phng thc ny chp nhn mt tham s cha thng ip cn gi n tp tin script x l. D liu ny s c ly thng qua thuc tnh data ca tham s event trong hm x l s kin message. Quy trnh ny c m t trong hnh sau:
18 | P a g e
Yin Yang
2. V d n gin nht:
To hai tp tin sau trong cng mt th mc: mytask.js:
this.onmessage = function (event) { var name = event.data; postMessage("Hello "+name); };
Test.html:
<!DOCTYPE html> <body> <input type="text" id="username" value="2" /> <br /> <button id="button1">Submit</button> <script> worker = new Worker("mytask.js"); worker.onmessage = function (event) { alert(event.data); }; document.getElementById("button1").onclick = function() {
19 | P a g e
Yin Yang
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:
20 | P a g e
Yin Yang
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);
frame mi thng qua tham s callback. Cc request ny s c lu trong i tng document vi cc cp <handle, callback> v c thc hin ln lt. Gi tr handle l mt s nh danh c to ra v tr v sau khi gi phng thc ny. cancelAnimationFrame: hy mt request c to ra requestAnimationFrame vi tham s l handle ca request. Ngoi ra cn c thuc tnh window.mozAnimationStartTime (ch mi c h tr trn Firefox) cha gi tr milisecond l khong cch t mc thi gian (1/1/1970) n thi im bt u ca request cui cng c thc hin. Gi tr ny tng ng vi gi tr tr v ca Date.now() hoc Date.getTime(), mc thi gian l bao nhiu khng quan trng nhng n gip bn bit c khong thi gian gia hai ln thc hin request.
21 | P a g e
Yin Yang
3. Li ch v hiu qu
Microsoft cho ta mt v d trc quan v hiu qu ca requestAnimationFrame() so vi setTimeout() ti trang requestAnimationFrame API. Qua v d ny, ta thy c s ln gi callback (update) thc t ca setTimeout() ln hn so vi d tnh. Ngoi ra cc kt qu cho thy hiu sut ca vic thc thi callback, CPU, mc tiu tn nng lng v nh hng n cc tc v nn ca requestAnimationFrame() hn hn so vi setTimeout():
22 | P a g e
Yin Yang
setTimeout Expected callbacks Actual callbacks Callback Efficiency Callback Efficiency Power Consumption Background Interference 40543 41584 59.70% Medium Medium High
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 || || || ;
V d hon chnh:
<HTML> <head> <script> const RADIUS = 20; var cx = 100; var cy = 100; var speedX = 2; var speedY = 2; var _canvas; var _context; var _reqAnimation; var _angle = 0; function update(time) { cx += speedX; cy += speedY;
23 | P a g e
Yin Yang
if(cx<0 || cx > _canvas.width) speedX = -speedX; if(cy<0 || cy > _canvas.height) speedY = -speedY;
// draw _context.clearRect(0, 0, _canvas.width, _canvas.height); _context.beginPath(); _context.arc(cx, cy, RADIUS, 0, Math.PI*2, false); _context.closePath(); _context.fill(); _reqAnimation(update); } window.onload = function(){ _canvas = document.getElementById("canvas"); _context = _canvas.getContext("2d"); _context.fillStyle = "red"; cx = _canvas.width/2; cy = _canvas.height/2; _reqAnimation = window.requestAnimationFrame || window.mozRequestAnimationFrame window.webkitRequestAnimationFrame window.msRequestAnimationFrame window.oRequestAnimationFrame || || || ;
if(_reqAnimation) update(); else alert("Your browser doesn't support requestAnimationFrame."); }; </script> </head> <body> <canvas id="canvas" width="400px" height="300px" style="border: 1px solid"></canvas> </body> </HTML>
24 | P a g e
Yin Yang
C. Canvas 2D API
HTML5 xc nh <canvas> nh mt bitmap ph thuc vo phn gii, c s dung v th, ha game hoc hnh nh trc quan khc. Canvas l hnh ch nht trn trang v c th s dng JavaScript v bt c iu g bn mun. HTML5 nh ngha mt tp cc chc nng ( canvas API) v hnh dng, xc nh ng dn, to gradient. HTML5 Canvas l mt JavaScript API m ha cc bn v. Canvas API cho php nh ngha mt i tng canvas nh l th <canvas> trn trang HTML ,chng ta c th v bn trong n. <canvas> l mt khi khng gian v hnh, mc nh l 300x250 pixels (trn tt c trnh duyt) Chng ta c th v c hnh 2D v 3D (WebGL). 2D c sn trong tt c cc trnh duyt Web hin i, IE9, v thng qua th vin excanvas.js trong cc phin bn IE hin ti. Canvas 2D cung cp mt API n gin nhng mnh m c th v mt cch nhanh chng trn b mt bitmap 2D. Khng c nh dng tp tin, v bn ch c th v bng cch s dng script. Bn khng c bt k cc nt DOM cho cc hnh khi bn v - bn ang v pixels, khng phi vect v ch l cc im nh c ghi nh. Mt s tnh nng c Canvas: V hnh nh T mu To hnh hc v cc kiu mu Vn bn Sao chp hnh nh, video, nhng canvas khc Thao tc im nh Xut ni dung ca mt th <canvas> sang tp tin nh tnh.
I. V nh v thao tc vi pixel
Mun to ra nhng hiu ng ha c bit khi s dng canvas, bn khng th ch s dng c thuc tnh v phng thc c sn ca i tng context. Chnh v vy, bi vit ny s gii thiu cho bn cch v nh v thao tc vi cc pixel t i tng ImageData.
1. Np v v nh
v mt nh ra canvas, ta to mt i tng image v thc hin phng thc context.drawImage() trong s kin load ca image. Nh vy m bo rng hnh nh ch c v sau khi c np hon tt. Ngoi ra, bn nn t s kin load trc khi gn ng dn cho nh. Nu khng image c th c load xong trc khi bn gn s kin load cho n. Phng thc drawImage() c ba overload sau: 25 | P a g e
V d:
window.onload = function(){ var canvas = document.getElementById("mycanvas"); var context = canvas.getContext("2d"); var img = new Image(); img.onload = function(){ context.drawImage(img, 10, 10,50,50); }; img.src = "foo.png"; };
2. Thao tc vi pixel
Mt nh bao gm mt mng cc pixel vi cc gi tr red, green, blue v alpha (RGBA). Trong alpha l gi tr xc nh m c (opacity) ca nh. Gi tr alpha cng ln th mu sc cng r nt v mu sc s tr nn trong sut nu alpha l 0. Trong Canvas 2D API, d liu nh c lu trong mt i tng ImageData vi 3 thuc tnh l width, height v data. Trong data l mt mng mt chiu cha cc pixel. Mi pixel cha 4 phn t tng ng l R,G,B,A. Nh vy vi mt nh c kch thc 1020 ta s c 200 pixel v c 200*4=400 phn t trong mng ImageData.data. 26 | P a g e
Yin Yang
imagedata = context.createImageData(sw, sh) Tr v mt i tng ImageData vi kch thc sw x sh. Tt c pixel ca i tng ny c mu en trong sut. imagedata = context.createImageData(imagedata) Tr v i tng ImageData vi kch thc bng vi i tng trong tham s. Tt c pixel c mu en trong sut. imagedata = context.getImageData(sx, sy, sw, sh) Tr v mt i tng ImageData cha d liu nh vng ch nht (xc nh bi cc tham s) ca canvas. Nm NotSupportedError exception nu nh c bt k tham s no khng phi l s hp l. Nm IndexSizeError exception nu width hoc height l zero. imagedata.width imagedata.height
Tr v kch thc tht ca i tng ImageData, tnh theo pixel. imagedata.data
Tr v mng mt chiu cha d liu dng RGBA, mi gi tr nm trong khong 0 n 255. context . putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])
27 | P a g e
Yin Yang
V d liu t i tng ImageData ln canvas ti v tr dx, dy. Nu nh hnh ch nht (t cc tham s dirtyX, dirtyY, dirtWidth, dirtyHeight) c xc nh, th phn d liu ca ImageData trong vng ch nht ny mi c v ln canvas.
Cc thuc tnh xc nh hiu ng v ca context s b b qua khi phng thc ny c gi. Cc pixel t canvas s c thay th hon ton bi ImageData m khng c cc s kt hp mu sc, hiu ng, vi cc d liu nh sn c trn canvas. Mt trong nhng v d thng gp v n gin nht l o ngc mu ca nh. iu ny c thc hin bng cch ly gi tr mu ti a (255) tr i gi tr ca mi knh mu RGB hin ti ca mi pixel. Gi tr alpha s gi tr ti a nh c r nt nht.
<HTML> <head> <script> window.onload = function(){ var img = new Image(); img.onload = function(){ invertColor(this); }; img.src="panda.jpg"; }; function invertColor(img){ var canvas = document.getElementById("mycanvas"); var context = canvas.getContext("2d"); // draw image at top-left corner context.drawImage(img,0,0); // draw original image right beside the previous image context.drawImage(img,img.width,0); // get ImageData object from the left image var imageData = context.getImageData(0, 0, img.width, img.height); var data = imageData.data;
28 | P a g e
Yin Yang
Kt qu:
Bn c th thm cc tham s to mt dirty rectangle trong phng thc putImageData() nu mun v ImageData ln mt vng ch nht xc nh ca canvas. V d ta chn cng mt vng ch nht trn ImageData v v ln hai vng ch nht khc nhau trn canvas c kt qu sau:
context.putImageData(imageData,0,0,0,0,img.width/2,img.height/2); context.putImageData(imageData,img.width,0,0,0,img.width/2,img.height/2);
29 | P a g e
Yin Yang
1. Xc nh ta chut
xc nh c ta chut trn canvas, ta s s dng tham s ca cc s kin nh mousedown, mousemove, Tham s ca cc s kin ny cha ta chut lu trong hai bin pageX v pageY. Ta s dng ta ny tr i ta ca canvas (canvas.offsetLeft v canvas.offsetTop) ly c v tr chnh xc ca chut trn canvas. u tin l vic m phng cng c Pen cho php v t do trong canvas:
<HTML> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> var preX; var preY; var paint; var canvas; var context; $(function(){ canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); $('#canvas').mousedown(function(e){ preX = e.pageX - this.offsetLeft; preY = e.pageY - this.offsetTop; paint = true; }); $('#canvas').mousemove(function(e){
30 | P a g e
Yin Yang
if(paint){ var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); preX = x; preY = y; } }); $('#canvas').mouseenter(function(e){ if(paint) { preX = e.pageX - this.offsetLeft; preY = e.pageY - this.offsetTop; } }); $("#canvas").mouseup(function(){ paint = false; }); $('#canvas').mouseleave(function(e){ paint = false; }); }); </script> </head> <body> <canvas id="canvas" width="500px" height="500px" style="border: 1px solid gray;"></canvas> </body> </HTML>
2. Lu ni dung ca Canvas
lu li d liu ca Canvas nhm phc hi khi cn thit (chng hn nh chc nng Undo, Redo), ta s s dng phng thc context.getImageData().Ta s s dng phng php ny thc hin chc nng v on thng trn Canvas. Trc k hi bt u v mt on thng, canvas cn c lu li ni dung v mi khi chut di chuyn, ta s phc hi li ni dung c lu ng thi v mt on thng t im bt u n v tr chut. Ta cng sa v d trn thnh mt jQuery plugin tin s dng:
<HTML> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> <script> (function( $ ) { var preX; var preY;
31 | P a g e
Yin Yang
var var var var var tool; canvas; context; imageData; paint; // pen, line
$.fn.makeDrawable = function() { canvas = this[0]; if( !$(canvas).is("canvas") ) throw "The target element must be a canvas"; context = canvas.getContext("2d"); $(canvas).mousedown(function(e){ preX = e.pageX - canvas.offsetLeft; preY = e.pageY - canvas.offsetTop; paint = true; if(tool=="line") { imageData = context.getImageData(0, canvas.height); } }); $(canvas).mousemove(function(e){ if(paint) { var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; if(tool=="pen") { context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); preX = x; preY = y; } else if(tool=="line") { canvas.width=canvas.width; content context.putImageData(imageData,0,0); context.moveTo(preX,preY); context.lineTo(x,y); context.stroke(); } } }); $(canvas).mouseup(function(e){ if(tool=="line") { var x = e.pageX - canvas.offsetLeft;
0,
canvas.width,
//
clear
canvas
32 | P a g e
Yin Yang
}); $(canvas).mouseleave(function(e){ paint = false; }); return $(canvas); }; $.fn.setTool = function(newTool) { tool=newTool; return $(canvas); } $.fn.clear = function() { canvas.width=canvas.width; return $(canvas); } })( jQuery ); $(function(){ $("#canvas").makeDrawable(); $("#button1").click(function(){ $("#canvas").clear(); }); $("#pen").change(function(){ if(this.value) $("#canvas").setTool("pen"); }); $("#line").change(function(){ if(this.value) $("#canvas").setTool("line"); }); $("#canvas").setTool("pen"); }); </script> </head> <body> <div> <button id="button1">Clear</button> <input name="tool" type="radio" id="pen" checked="true">Pen</input> <input name="tool" type="radio" id="line">Line</input> </div> <canvas id="canvas" width="500px" height="500px" style="border: 1px solid gray;"></canvas> </body> </HTML>
Kt qu:
33 | P a g e
Yin Yang
1. To cu trc d liu
u tin ta s to mt lp Rect dng cha d liu ca mt hnh ch nht. Lp ny ngoi cc bin lu tr ta , kch thc v trng thi (selected) th cn mt phng thc dng kim tra xem mt ta [x,y] c nm bn trong n khng. Ta gi phng thc ny l isContain() v c kiu tr v l boolean. M ngun ca lp ny c dng:
function Rect() { this.isSelected = false; this.x = 0; this.y = 0; this.width = 1; this.height = 1; } Rect.prototype.isContain = function(x,y){ var right = this.x + this.width; var bottom = this.y + this.height;
34 | P a g e
Yin Yang
return x > this.x && x < right && y > this.y && y < bottom; }
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; } } }
35 | P a g e
Yin Yang
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(); } }
Kt qu:
36 | P a g e
Yin Yang
1. Bt s kin bn phm
bt s kin ny, bn c th ng k trc tip cho i tng window, tuy nhin iu ny s gy ra nhng rc ri khi trang ca bn c qu nhiu thnh phn. Cch tt nht l ng k ring cho canvas cc hm x l. Tuy nhin, canvas c th focus c, bn cn xc nh thuc tnhTabIndex ca n:
<canvas id=canvas width=300 height=200 tabindex=1 style=border: 1px solid;></canvas>
Sau bn ng k cc s kin cn thit cho canvas. Khi chy trn trnh duyt, bn cn phi click chut vo canvas n nhn c focus trc khi thc hin cc thao tc bn phm.
_canvas.onkeydown = canvas_keyDown; function canvas_keyDown(e){ alert(e.keyCode); }
Tham s event truyn vo hm x l s cha cc thuc tnh cn thit bn xc nh c phm no c nhn. y, bn ch cn quan tm n thuc tnh keyCode lu m ca phm c nhn. Do cc gi tr keyCode c kiu s nn rt kh nh v kim tra, may mn l ta tm c 37 | P a g e
Yin Yang
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, // ... };
3. Gii hn cc phm c bt
S dng phng php trn, bn cn lc cc phm cn s dng i tng _keypressed khng lu cc gi tr khng cn thit. Mt cch n gin nht l s dng mng lu keyCode ca cc phm ny v kim tra trong cc s kin bn phm:
const AVAILABLE_KEYS = [ Keys.UP_ARROW, Keys.DOWN_ARROW, Keys.LEFT_ARROW, Keys.RIGHT_ARROW
38 | P a g e
Yin Yang
]; 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; } }
1. C bn
Ta xc nh hai gi tr speedX v speedY tng ng vi tc di chuyn theo phng ngang v dc ca tri bng. Hng di chuyn ca bng ph thuc vo gi tr m hoc dng ca speedX v speedY. Trong v d ny, thnh tng l cc bin ca canvas v ch c hai phng l ngang v dc. Nguyn l hot ng rt n gin: khi bng tip xc vi bin dc ca canvas, ta s i chiu ca speedY v vi bin ngang ta s i chiu ca speedX. Trong lp Ball sau, ta s b sung thm cc thuc tnh right, bottom tin khi kim tra va chm. Hai thuc tnh cx v cy l v tr tm ca bng v s c khi to ngy nhin sao cho n lun nm hon ton bn trong canvas.
Ball.js:
function Ball(mapWidth, mapHeight){ this.mapWidth = mapWidth; this.mapHeight = mapHeight; this.radius = 20; this.speedX = 3; this.speedY = 3; this.cx this.radius; this.cy this.radius; = = Math.floor(Math.random()*(this.mapWidth-2*this.radius)) Math.floor(Math.random()*(this.mapHeight-2*this.radius)) + +
39 | P a g e
Yin Yang
} Ball.prototype.draw = function(context){ context.beginPath(); context.fillStyle = "red"; context.arc(this.cx,this.cy,this.radius,0,Math.PI*2,true); context.closePath(); context.fill(); } Ball.prototype.move = function(){ this.cx += this.speedX; this.cy += this.speedY; this.left = this.cx - this.radius; this.top = this.cy - this.radius; this.right = this.cx + this.radius; this.bottom = this.cy + this.radius; } Ball.prototype.checkCollision = function(shapes) { if(this.left <= 0 || this.right >= this.mapWidth) this.speedX = this.speedX; if(this.top <= 0 || this.bottom >= this.mapHeight) this.speedY = this.speedY; }
Sample.HTML:
<HTML> <head> <script src="ball.js"></script> <script> var _canvas; var _context; var _ball; function draw(){ _context.clearRect(0,0,_canvas.width,_canvas.height); _ball.draw(_context); } function update(){ _ball.move(); _ball.checkCollision(); draw(); } window.onload = function(){ var interval = 10; _canvas = document.getElementById("canvas"); _context = _canvas.getContext("2d"); _ball = new Ball(_canvas.width,_canvas.height); setInterval("update()",interval); } </script> </head>
40 | P a g e
Yin Yang
<body> <canvas id="canvas" width="400px" height="300px" style="border: 1px solid gray;"></canvas> </body> </HTML>
cc tri bng khng nm qu st nhau, ta ch thc hin lu v tr ca bng sau mi 5 ln bng di chuyn hay sau mi 5 ln phng thc update() c gi. Phng thc traceBall() sau s to ra mt i tng Ball mi vi hai gi tr cx v cy ly t tri bng chnh v lu vo mng _balls. Khi chiu di ca mng _balls vt qu 10, ta dng phng thc Array.splice() ct i phn t nm u mng:
function traceBall(ball){ var b = new Ball; b.cx = ball.cx; b.cy = ball.cy; _balls.push(b); if(_balls.length>10) _balls.splice(0,1); }
Kt qu:
41 | P a g e
Yin Yang
// the // on
// rig
42 | P a g e
Yin Yang
Minh ha:
43 | P a g e
Yin Yang
1. Vng lp c bn
Mt vng lp game c bn bao gm cc vic c thc hin theo th t sau:
while(gameRunning) { processInput(); // keyboard, mouse,... updateGame(); draw(); // checkGameOver(); }
Minh ha:
44 | P a g e
Yin Yang
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 }
Phng php trn chy n vi gi tr diffTime nh hn TICKS. Ngha l tc ca game khng vt qu gi tr TICKS cho php. Tuy nhin trong trng hp diffTime ln, vic cp nht s din ra chm.
45 | P a g e
Yin Yang
Nu bn s dng requestAnimationFrame cho vng lp game, bn s khng cn quan tm n vic tnh ton gi tr sleepTime.
4. V d hon chnh
Kim tra v d ny v so snh vi cc phng php trc , thc hin mt vi cng vic qu ti no trn trnh duyt v bn s thy khc bit:
const FPS = 6; const TICKS = 1000 / FPS; var startTime; var expectedCounter = 0; var lastUpdateTime; var actualCounter = 0; var output; function gameLoop() { var diffTime = Date.now() - lastUpdateTime; var numOfUpdate = Math.floor(diffTime/TICKS); for(var i = 0;i < numOfUpdate;i++){ updateGame(); } if(diffTime >= TICKS)
46 | P a g e
Yin Yang
draw(); lastUpdateTime += TICKS * numOfUpdate; diffTime -= TICKS * numOfUpdate; var sleepTime = TICKS - diffTime; setTimeout(gameLoop,sleepTime); } function updateGame() { actualCounter++; }
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();
Cch trn khng phi cch nhanh nht, v vy bn c th dng cch sau, n gin v hiu qu hn:
Rect.prototype.collideWidthRect = function(rect) { return !(this.left > rect.right ||
47 | P a g e
Yin Yang
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 .
48 | P a g e
Yin Yang
Khong cch gia tm C hnh trn v im A ca hnh ch nht c minh ha nh hnh di y. Khi tm hnh trn nm bn trong hnh ch nht, th im C v A s trng nhau.
Gi rect l hnh ch nht cn xc nh va chm. Ta c thut ton xc nh im A nh sau: - B1: Gn A bng vi C. - B2: Nu C.X < rect.Left, t A.X = rect.Left. Ngc li nu C.X > rect.Right, t A.X = rect.Right. - B3: Nu C.Y < rect.Top, t A.Y = rect.Top. Ngc li nu C.Y > rect.Bottom, t A.Y = rect.Bottom. Khi c im A, ta li dng cng thc Pythagoras so snh vi bn knh ca hnh trn.
Circle.prototype.collideWithRect = function(rect){ var px = this.cx; var py = this.cy; if(px < rect.left) px = rect.left; else if(px > rect.right) px = rect.right; if(py < rect.top) py = rect.top; else if(py > rect.bottom) py = rect.bottom; var dx = this.cx - px; var dy = this.cy - py; return (dx*dx + dy*dy) <= this.radius*this.radius; }
49 | P a g e
Yin Yang
Nh vy vic xc nh mt im X c thuc AB hay khng ch cn da vo 2 yu t: (1) X phi nm trong vng hnh ch nht c to bi ng cho AB (ngoi tip tam gic ABM). (2) Gc XAN v BAM phi bng nhau. Ngoi ra, do vic so snh l kiu s thc v c th do rng ca on thng khc nhau nn ta cn chp nhn mt gi tr sai s EPSILON no . 50 | P a g e
Yin Yang
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|
51 | P a g e
Yin Yang
Yin Yang Tng qut hn vi hai vector bt k, xt biu thc: |a| = |v|cos Vi u l vector to vi v mt gc , t cng thc: cos = (v.u)/(|v||u|) Suy ra: |a| = |v|(v.u)/(|v||u|) = (v.u)/|v|
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|
53 | P a g e
Yin Yang
x: length*v2.dx, y: length*v2.dy, }; // the projection line _line3.p2.x = _line3.p1.x+v3.x; _line3.p2.y = _line3.p1.y+v3.y;
// 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.
Yin Yang
Kt qu ca tch v hng c 3 khong gi tr ta c th c lng c gc gia hai vector (b qua chiu m/dng): Case 1 (Dot product < 0): Gc gia hai vector ln hn 90 . im H nm ngoi AB. Case 2 (Dot product = 0): Hai vector vung gc vi nhau (90 ). im H trng vi A. Case 3 (Dot product > 0): Gc gia hai vector nh hn 90 . im H c th nm trong AB hoc khng. im H s nm ngoi AB nu nh di AH > AB.
M ngun:
function pointLineDistance(){ // v1: AC // v2: AB // v3: AH var v1 = _line1.getVector(); var v2 = _line2.getVector();
55 | P a g e
Yin Yang
// 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; }
Yin Yang a = (y2 y1)/(x2 x1) Thay th x2, y2 bng hai bin x,y: a = (y y1)/(x x1) => y y1 = a(x x1) Hay: y = ax + (y1 ax1) t b = y1 ax1, ta c: y = ax + b
57 | P a g e
Yin Yang
58 | P a g e
Yin Yang
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/
1. Va chm
xc nh va chm, ta tnh ton khong cch t tm ng trn n on thng theo phng php Tnh khong cch t im n on thng v so snh vi bn knh ca ng trn.
59 | P a g e
Yin Yang
V d trong phn kim tra khong cch ny cha xt trng hp va chm vi hai u ca on thng. Bi v vic kim tra phn x khi va chm vi u on thng s cn tnh ton thm mt vi bc nn ta s b qua. Phng thc sau s tr v im va chm ca tri bng vi on thng hoc null nu nh khng c.
Ball.prototype.findCollisionPoint = function(line) { // create a vector from the point line.p1 to the center of this ball. var v1= { x: this.cx - line.p1.x, y: this.cy - line.p1.y }; var v2 = line.getVector(); var v3 = findProjection(v1,v2); v3.length = Math.sqrt(v3.x*v3.x+v3.y*v3.y); var collisionPoint = null; if(v3.dp>0 && v3.length <= v2.length) { var dx = v1.x-v3.x; var dy = v1.y-v3.y; var d = Math.sqrt(dx*dx+dy*dy); if(d>this.radius) return null; collisionPoint = { x: line.p1.x + v3.x, y: line.p1.y + v3.y }; // don't overlap if(d < this.radius) { this.cx -= (this.movement.x/this.speed)*(this.radius-d); this.cy -= (this.movement.y/this.speed)*(this.radius-d); } } return collisionPoint; }
// distance
2. Phn x
Da vo vector chuyn ng ca tri bng v vector c to ra t on thng, ta c th tnh c vector chuyn ng mi ca bng (xem Vector2D: Va chm v phn x). 60 | P a g e
Yin Yang
Ball.prototype.bounceAgainst = function(line) { if(this.findCollisionPoint(line)) { var v1 = this.movement; var v2 = line.getVector(); var v3 = findProjection(v1,v2); // perpendicular vector of v2 var v4 = { x: v2.y, y: -v2.x }; v4 = findProjection(v1,v4); v4.x = -v4.x; v4.y = -v4.y; // bounce vector var v5 = { x: v3.x + v4.x, y: v3.y + v4.y };
i vi vic kim tra phn x khi tri bng va chm vi 1 im (nh hai u ca on thng), bn cn xc nh mt vector vung gc vi ng thng ni tm tri bng n im va chm v coi l mt phng va chm. Minh ha:
61 | P a g e
Yin Yang
62 | P a g e
Yin Yang
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;
63 | P a g e
Yin Yang
Hm checkCo llision:
function checkCollision(ball1,ball2){ var dx = ball1.cx - ball2.cx; var dy = ball1.cy - ball2.cy;
// check collision between two balls var distance = Math.sqrt(dx*dx+dy*dy); if(distance > ball1.radius + ball2.radius) return; var angle = Math.atan2(dy,dx); var u1 = ball1.getVelocity(); var u2 = ball2.getVelocity(); var var var var var var angle1 = Math.atan2(u1.y, u1.x); angle2 = Math.atan2(u2.y, u2.x); ux1 = u1.length * Math.cos(angle1-angle); uy1 = u1.length * Math.sin(angle1-angle); ux2 = u2.length * Math.cos(angle2-angle); uy2 = u2.length * Math.sin(angle2-angle);
var vx1 = ((ball1.massball2.mass)*ux1+(ball2.mass+ball2.mass)*ux2)/(ball1.mass+ball2.mass); var vx2 = ((ball1.mass+ball1.mass)*ux1+(ball2.ma ssball1.mass)*ux2)/(ball1.mass+ball2.mass); var vy1 = uy1; var vy2 = uy2; // now var v1 v1.x = v1.y = we transform the 1D coordinate back to 2D = {}, v2 = {}; Math.cos(angle)*vx1+Math.cos(angle+Math.PI/2)*vy1; Math.sin(angle)*vx1+Math.sin(angle+Math.PI/2)*vy1;
64 | P a g e
Yin Yang
1. Mt wrapper ca Image
tin x l cc hnh nh trong canvas di dng mt i tng trong game vi cc chc nng cn thit, ta to mt lp ImageObj cha bn trong mt i tng Image lu tr hnh nh. Phng thc quan trng m ImageObj phi c l draw(), tuy nhin vic np nh c th din ra kh lu v vy ta cn mt cch thc x l trng hp ny. Chng hn ta s vit ra mt dng thng bo thay th cho nh vi kch thc mc nh trong trng hp nh cha c ti xong:
function ImageObj(){ // ... this.draw = function(context){ if(ready){ context.drawImage(this.img,this.left,this.top); } else{ // image has not finished loading // draw something useful instead context.save(); context.fillText("Image is not ready",this.left+10,this.top+10); context.restore(); } context.strokeRect(this.left,this.top,this.width,this.height); context.stroke(); }; // ... }
Cha , i tng ImageObj c th t v li sau nh c np xong, ng thi ly c i tng ImageData (cha mng cc pixel), ta s vit mt s lnh x l trong s kin onload ca Image.
function ImageObj(){ // ... var self = this; this.img.onload = function(){ self.width = this.width; self.height = this.height; ready = true; // this image is ready to use // draw image after loading context.clearRect(self.left,self.top,self.width,self.height); self.draw(context); // get ImageData from this image self.data = context.getImageData(self.left,self.top,self.width,self.height).data; }; this.img.src = url; }
65 | P a g e
Yin Yang
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).
Xem Demo.
66 | P a g e
Yin Yang
of
tng tc kim tra va chm, thay v lp qua tng pixel, bn c th lp ngt qung n pixel (theo c 2 chiu ngang v dc) ty theo mc yu cu chnh xc ca ng dng. Nh vy s ln lp kim tra s gim i 2n ln tng ng. Di y l nh minh ha vic thay i bc tng ca vng lp t 1 ln 3. Vng mu l cc pixel c alpha > 0 thuc c hai nh:
67 | P a g e
Yin Yang
68 | P a g e
Yin Yang
1. nh nn nhiu tng
Mt phng php n gin v to hiu ng p l s dng nh nn nhiu tng. Bng cch cho mi tng c tc cun khc nhau, khung cnh trong game tr nn c chiu su v tht hn. S lng tng ny thng ch gii hn t 2 n 3 v cc tng nm bn di s c tc cun chm hn.
69 | P a g e
Yin Yang
2. Cun gi
Bn c th thy nhiu game c bn rt ln nhng nh nn ch lp i lp li theo mt mu duy nht. iu ny c thc hin bng cch s dng mt nh nn c kch thc nh v c v lp i lp li trn viewport. Ty theo kch thc ca nh nn ny m ta s dng phng php v khc nhau. Cch thng thng l s dng mt nh nn c kch thc bng viewport. Sau ta chia nh nn ny thnh hai phn theo chiu dc da vo mt ng phn cch: - Ct phn nh nn t v tr ng phn cch n ht v v ln viewport ti v tr {0,0}. - Ct phn nh nn t v tr u tin n ng phn cch (phn cn li) v v ln viewport ti v tr tip ni vi phn lc ny.
// position that divide the background into two parts offsetX++; if(offsetX>width) offsetX = 0; // draw the first part ctx.drawImage(bgimg,offsetX,0,width-offsetX,height,0,0,width-offsetX,height); // the second part ctx.drawImage(bgimg,0,0,offsetX,height,width-offsetX,0,offsetX,height);
3. v cun tht
Vi mt bn ln, vic cun gi nhn vt chnh ca game lun gia mn hnh rt n gin. Ta c th xc nh c ta (left v top) trn bn s c dng lm viewport bng cch:
// inside Map object // obj = character this.offsetX = obj.left - viewWidth/2; this.offsetY = obj.top - viewHeight/2;
Tuy nhin vic thay i khung nhn lin tc c th khin cho ngi chi nhc mt, mt tp trung v nh hng n hiu sut. V vy ta p dng mt gii phi l to mt vng gii hn trong viewport gi l dead zone. Khi nhn vt di chuyn nhng vn nm trong vng ny, viewport s khng b thay i.
// inside Map object var dx = obj.left - _map.offsetX; var dy = obj.top - _map.offsetY; if(dx<this.deadzone.left)
70 | P a g e
Yin Yang
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
Mt nh c th gm nhiu sprite c cng kch thc hp li vi nhau. V d hnh di y ta c th thy mi hng l mt sprite hin th chuyn ng ca nhn vt theo phng khc nhau. Vy 71 | P a g e
Yin Yang
vi mc ch l to lp Sprite linh ng, ta phi cho php n kt hp c nhiu sprite vi nhau v chuyn i qua li gia cc sprite d dng.
M ngun ca lp AnimatedSprite:
var AnimatedSprite = function(data) { this.init(data); this.isFinished = false; this.currentSprite = null; this.currentFrame = 0; this.lastTick = 0; }; AnimatedSprite.prototype = { start: function(){ this.isFinished = false; this.currentFrame = 0; } init: function(data) { if(data){ this.isLooping = data.isLooping; if(typeof this.isLooping!="boolean") this.isLooping = true; this.image = data.image; this.frameWidth = data.frameWidth; this.frameHeight = data.frameHeight || this.frameWidth; this.sprites = []; this.interval = data.interval; this.left = data.left; this.top = data.top; this.width = data.width || this.frameWidth; this.height = data.hegiht || this.frameHeight; this.onCompleted = data.onCompleted; } }, addSprite: function(data){ this.sprites[data.name]={
72 | P a g e
Yin Yang
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;
||
73 | P a g e
Yin Yang
} }
s dng, ta c th to mt lp con ca AnimatedSprite cung cp cc chc nng di chuyn, kim tra va chm. y ta to mt lp Character tha k t AnimatedSprite:
function Character(data){ this.mapWidth = data.mapWidth; this.mapHeight = data.mapHeight; this.speedX = 0; this.speedY = 0; this.init(data); } Character.prototype = new AnimatedSprite(); Character.prototype.update = function(){ var var var var left = this.left+this.speedX; top = this.top+this.speedY; right = left+this.frameWidth; bottom = top+this.frameHeight;
if(left>0 && right<this.mapWidth) this.left = left; if(top>0 && bottom<this.mapHeight) this.top = top; AnimatedSprite.prototype.update.call(this); };
74 | P a g e
Yin Yang
sprite.addSprite({ name: "walk_right", startFrame: 8, framesCount: 4 }); sprite.addSprite({ name: "walk_up", startFrame: 12, framesCount: 4 }); sprite.setSprite("walk_left"); setInterval(function(){ sprite.update(); canvas.width = canvas.width; sprite.draw(context); },1000/FPS);
Cch s dng: 75 | P a g e
Yin Yang
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:
76 | P a g e
Yin Yang
Bn c th p dng cch lm trong v d ny cho nhng ng dng tng t, ch yu l thay i kch thc ca mt n v (CELL_SIZE), ca i tng v thay i ta .
Xem Demo
77 | P a g e
Yin Yang
78 | P a g e
Yin Yang
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);
79 | P a g e
Yin Yang
} };
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.
80 | P a g e
Yin Yang
81 | P a g e
Yin Yang
var width = window.innerWidth-5; var height = window.innerHeight-5; if(width/height>ratio) width = height*ratio; else height = width/ratio; canvas.style.width = width; canvas.style.height = height;
82 | P a g e
Yin Yang
CSS:
div:full-screen { background-color: gray; } div:-moz-full-screen { background-color: gray; } div:-webkit-full-screen { background-color: gray; }
83 | P a g e
Yin Yang
2. V d
<HTML> <head> <style> #mydiv { padding-top: 200px; display: none; height: 400px; background: black; } #mydiv:full-screen { display: block; } :full-screen h1 { color: wheat; } #mydiv:-moz-full-screen { display: block; } :-moz-full-screen h1{ color: wheat; } #mydiv:-webkit-full-screen { display: block; } :-webkit-full-screen h1{ color: wheat; } </style> <script type="text/javascript"> function enterFullScreen(id){ var element = document.getElementById(id); element.requestFullscreen ? element.requestFullscreen() : element.mozRequestFullScreen ? element.mozRequestFullScreen() : element.webkitRequestFullScreen element.webkitRequestFullScreen() : alert("Fullscreen API is not supported in this browser"); } function exitFullScreen(){ ?
84 | P a g e
Yin Yang
document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitCancelFullScreen ? document.webkitCancelFullScreen() : alert("Fullscreen API is not supported in this browser"); } document.addEventListener("fullscreenchange", function (e) { console.log(document.fullscreen); }); document.addEventListener("mozfullscreenchange", function (e) { console.log(document.mozFullScreen); }); document.addEventListener("webkitfullscreenchange", function (e) { console.log(document.webkitIsFullScreen); }); </script> </head> <body> <center> <div id="mydiv"> <h1>You are in fullscreen mode.</h1> <input type="button" value="Exit full screen" onclick="exitFullScreen('mydiv')" /> </div> <input type="button" value="Enter full screen" onclick="enterFullScreen('mydiv')"/> </center> </body> </HTML>
85 | P a g e
Yin Yang
1. Lp MenuItem
Mi i tng MenuItem tng ng vi mt mc menu trn mn hnh. Mt i tng th ny c th ch cn 4 gi tr xc nh ta v kch thc. Tuy nhin d thay i v pht trin hn. Ta to thm mt s thuc tnh v cung cp mt s kin onclick cho n. Da vo thuc tnh isMouseOver, ta s thay i mu sc hin th ca MenuItem mi khi chut c hover. Phn ny kh n gin, ch cn coi y l mt cu trc d liu lu cc gi tr ca mt hnh ch nht cng vi phng thc v hin th n.
function MenuItem(data){ this.left = data.left || 0; this.top = data.top || 0; this.width = data.width || 100; this.height = data.height || 30; this.text = data.text || "Menu Item"; this.onclick = data.onclick; this.right = this.left+this.width; this.bottom = this.top+this.height; this.centerX = this.left+this.width/2; this.centerY = this.top+this.height/2; this.isMouseOver = false; this.update = function(){ }; this.draw = function(context){ context.font = "16px Arial"; context.textAlign = "center"; if(this.isMouseOver) context.fillStyle = "rgba(255,255,255,0.7)"; else context.fillStyle = "rgba(255,255,255,0.2)"; context.fillRect(this.left,this.top,this.width,this.height); context.fillStyle = "white"; context.fillText(this.text,this.centerX,this.centerY); context.strokeRect(this.left,this.top,this.width,this.height); };
86 | P a g e
Yin Yang
this.contain = function(x,y){ return !(x<this.left || x>this.right y>this.bottom); }; } function MenuItem(data){ this.left = data.left || 0; this.top = data.top || 0; this.width = data.width || 100; this.height = data.height || 30; this.text = data.text || "Menu Item"; this.onclick = data.onclick; this.right = this.left+this.width; this.bottom = this.top+this.height; this.centerX = this.left+this.width/2; this.centerY = this.top+this.height/2; this.isMouseOver = false; this.update = function(){
||
y<this.top
||
}; this.draw = function(context){ context.font = "16px Arial"; context.textAlign = "center"; if(this.isMouseOver) context.fillStyle = "rgba(255,255,255,0.7)"; else context.fillStyle = "rgba(255,255,255,0.2)"; context.fillRect(this.left,this.top,this.width,this.height); context.fillStyle = "white"; context.fillText(this.text,this.centerX,this.centerY); context.strokeRect(this.left,this.top,this.width,this.height); }; this.contain = function(x,y){ return !(x<this.left y>this.bottom); }; } || x>this.right || y<this.top ||
2. Lp Screen
Lp ny l phn chnh ca to nn mt game. Mt game c th c to ra t mt hoc nhiu Screen v ngi chi c th chuyn qua li gia cc Screen bng mt vi nt bm no (trong v d ny l MenuItem). Lp Screen ny l ni qun l chnh v c th coi l mt game thu nh trong ng dng. Ging nh mi v d v mi i tng game ta tng thc hin, lp ny s gm hai phng thc chnh l update() v draw(). Bn cnh ta c th b sung cc phng thc bt u v kt thc
87 | P a g e
Yin Yang
game. V d nh start() v stop(). V y l v d tp trung vo vic thit k menu v chuyn i gia cc mn hnh, cc i tng Screen ta to ch cha cc MenuItem. Ch : V mi lp Screen s ng k cc event onmousemove, onclick cho canvas, nn khi start() mt Screen, bn cn phi ng k cc event ny li cc event ny. Nu khng n s b overwrite bi event t cc Screen khc.
var var var var CELL_SIZE = 10; FPS = 10 ; WIDTH = 400; HEIGHT = 400;
function Screen(canvas){ var timer; var width = canvas.width; var height = canvas.height; var context = canvas.getContext("2d"); this.items = []; // this method/event is actived in the end of draw() method this.afterDraw = null; this.update = function(){ for(var i=0;i<this.items.length;i++){ this.items[i].update(); } }; this.draw = function(){ context.fillStyle = "black"; context.fillRect(0,0,width,height); for(var i=0;i<this.items.length;i++){ this.items[i].draw(context); } if(this.afterDraw) this.afterDraw(context); }; this.start = function(){ this.stop(); var self = this; // register events canvas.onclick = function(e){ // raise the onclick event of each MenuItem when it is clicked var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; for(var i=0;i<self.items.length;i++){ if(self.items[i].onclick self.items[i].contain(x,y)) self.items[i].onclick(x,y); } }; canvas.onmousemove = function(e){ // change the isMouseOver property of each MenuItem var x = e.pageX - this.offsetLeft;
&&
88 | P a g e
Yin Yang
var y = e.pageY - this.offsetTop; canvas.style.cursor = 'default'; for(var i=0;i<self.items.length;i++){ self.items[i].isMouseOver self.items[i].contain(x,y); // change the cursor type to hand if(self.items[i].isMouseOver) canvas.style.cursor = 'pointer'; } }; timer = setInterval(function(){ self.update(); self.draw(); },1000/FPS); }; this.stop = function(){ if(timer) clearInterval(timer); timer = null; }; this.addItem = function(item){ this.items.push(item); }; }
3. Kim tra kt qu
Vy l xong hai lp chnh ca v d, bn to mt file HTML vi tn bt k test vi ni dung bn di.
89 | P a g e
Yin Yang
F. AI trong game
I. Gii thiu
AI hay tr tu nhn to c s dng trong rt nhiu game, t n gin n phc tp. Ty theo tng trng hp m AI c th tnh ton v tr di chuyn, tm ng i, phn tch trng thi a ra quyt nh, Mt trong nhng game thuc loi AI n gin nht l tr chi Pong c pht hnh nm 1970. Dng game bng bn ny cho php ngi chi u vi my bng cch iu khin mt thanh paddle dc n v nh tr bng. V bn cng c th hnh dung c AI ca my hot ng nh th no: ch cn thay i v tr ca paddle ln xung theo tri bng.
Sau ny, nhng th loi game mi ra i i hi trnh AI phi nng ln mt tm mi. Thng thy nht l cc th loi game vi thut ton tm kim trn cu trc d liu dng cy tm ng i hay a ra quyt nh (decision tree). Trong cc thut ton duyt cy, ty theo trng hp v ln ca d liu, lp trnh vin c th thay i v chn la thut ton nh Hill climbing, Breadth First Search, Depth First Search, Best First Search, Iterative Depth First Search hay thm ch c th kt hp mt, hai loi thut ton vi nhau. Vi game Rn Sn Mi, mt tng ca ta l p dng AI trong game ny ngi chi c th u vi my. Nh vy bi ton t ra l p hi lm sao con rn m my iu khin c th tm c ng ngn nht n thc n m khng lao u vo tng hoc cn nhm thn ca n.
Yin Yang
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.
91 | P a g e
Yin Yang
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.
92 | P a g e
Yin Yang
- 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.
93 | P a g e
Yin Yang
Mc d d hiu nhng cch ny s khin vic tm c cha t c tc m ta mong mun do phi so snh 2 thuc tnh value v visited xc nh mt Node c gh thm cha. V vy, ta s b i thuc tnh visited v tn dng thuc tnh value. Ta c lp Node mi:
var var var var BLANK = 0; WALL = 1; SNAKE = 2; VISITED = 3;
94 | P a g e
Yin Yang
{
Phng thc thm mt nc i vo tp Open, ta ch cn thm cc node rng (BLANK). Khi thm vo, ta t li trng thi ca node l VISITED khng thm n vo ln th 2:
function addToOpen(x,y, previous) { var node = nodes[x][y]; if (node.value==BLANK) { // mark this node as visited to avoid adding it multiple times node.value = VISITED; // store the previous node // so that we can backtrack to find the optimum path // (by using the getSolution() method) node.previous = previous; open.enqueue(node); } }
Phng thc dng ly ng i sau khi tm c v tr ca node ch. Ta ch cn backtracking cc node da vo thuc tnh previous ca cc node:
function getSolution(p) { var nodes = []; nodes.push(p); while (p.previous) { nodes.push(p.previous); p = p.previous; }
95 | P a g e
Yin Yang
return nodes; }
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; } };
Yin Yang
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 level",WIDTH/2,HEIGHT/2); }else if(_comSnake.data.length==MAX_COM_LENGTH) { endGame(); return; } }
start
the
next
97 | P a g e
Yin Yang
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(); } } }
98 | P a g e
Yin Yang
var b = { left: col*CELL_SIZE, top: row*CELL_SIZE }; b.right = b.left+CELL_SIZE; b.bottom = b.top+CELL_SIZE; return b; } return false; }
i vi nhn vt, ta s dng 8 im bao quanh nhn vt kim tra (cc im mu trong hnh sau). Mun vic kim tra chnh xc hn, bn ch cn tng thm s im tuy nhin thi gian kim tra s lu hn. Da vo cc im ny ta c th xc nh c va chm v ngng vic di chuyn ca nhn vt theo cc trng hp cc im va chm l:
- R1 hoc R2: Va chm bn phi. Nu speedX>0, ta gn speedX = 0. - L1 hoc L2: Va chm bn tri. Nu speedX H1 hoc H2: Nhn vt nhy ln v ng u vo vt cn. Ta dt speedY = 0 v falling = true nhn vt dng li v bt u ri. - H1 hoc H2: Nhn vt nhy rt xung t hoc vt cn. Ta dt speedY = 0 v falling = false.
Player.prototype.update = function(){ if(this.isJumping) this.speedY += GRAVITY; var var var var vtop = this.top+this.speedY; vbottom = vtop+this.height; vleft = this.left+this.speedX; vright = vleft+this.width;
if(this.isJumping) vbottom -= 1;
99 | P a g e
Yin Yang
var b; this.isJumping = true; if(vbottom >= this.map.height) { this.top = this.map.height-this.height; this.speedY = 0; this.isJumping = false; } else if(b = this.map.contain(this.left+2,vbottom) || this.map.contain(this.right-2,vbottom)) { this.top = b.top-this.height; this.speedY = 0; this.isJumping = false; } else if(b = this.map.contain(this.left+2,vtop) || this.map.contain(this.right-2,vtop)) { this.top = b.bottom; this.speedY = 0; } vtop = this.top+this.speedY; vbottom = vtop+this.height; if(this.left<=0 || (b = this.map.contain(vleft,vtop+6) || this.map.contain(vleft,vbottom-4))) { if(b) this.left = b.right; if(this.speedX<0) this.speedX = 0; }else if(this.right>=this.map.width || (b = this.map.contain(vright,vtop+6) || this.map.contain(vright,vbottom-4))) { if(b) this.left = b.left-this.width; if(this.speedX>0) this.speedX = 0; } this.top = vtop; this.bottom = vbottom; this.left += this.speedX; this.right = this.left + this.width; }
100 | P a g e
Yin Yang
101 | P a g e
Yin Yang
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; } =
102 | P a g e
Yin Yang
2. Lp Monster
Monster (hay Enemy) l cc i tng c kh nng hot ng v c th c tch hp AI nhm tiu dit hoc cn tr ngi chi. Trong bt k game no th cc loi i tng ny rt a dng v l thng l nguyn nhn chnh to ra s li cun ca game. V y ch l phn bt u nn ta ch to mt loi Monster duy nht c kh nng tiu dit ngi chi thng qua va chm.
Bi v c tha k t lp Character bn trn, lp ny ch cn mt cng vic chnh l hin thc phng thc draw() v chnh n:
function Monster(map,left,top){ // call the super-constructor Character.call(this,map,{ left: left, top: top, width: 20, height: 20, speed: 1, isAutoMoving: true }); } Monster.prototype = new Character(); Monster.prototype.draw = function(context){ context.save(); context.beginPath(); var left = this.left-this.map.offsetX; var top = this.top-this.map.offsetY; var right = left+this.width; var bottom = top+this.height; var hw = this.width/2; var cx = left+hw; context.fillStyle = "violet"; context.arc(cx,top+hw,hw-2,0,Math.PI*2,true); //context.rect(left,top,this.width,this.height); context.fill(); context.stroke();
103 | P a g e
Yin Yang
context.restore(); }
3. Lp Player
Cng tng t nh Monster, tuy nhin cng vic s phc tp hn v ta cn kim tra nhiu th v phi cung cp cc phm bm iu khin. Phng thc update ny mc nh tr v 0. Trng hp player hon thnh vng chi, tr v 1; v nu player cht, tr v 2:
Player.prototype.update = function(){ if(this.right>=this.map.width){ alert("Game Over!"); return 1; } if(this.isFalling) // die { this.speedY += GRAVITY; this.top += this.speedY; return (this.top>this.map.height)? 2 : 0 ; } Character.prototype.update.call(this); this.collide(this.map.monsters); }
Kim tra va chm vi cc monster, ta xem player v monster l cc hnh ch nht v ch cn kim tra xem hai hnh ny c ct nhau khng:
Player.prototype.collide = function(monsters){ for(m in monsters) { var mon = monsters[m]; if(!mon) continue; if(!(this.left > mon.right || this.right < mon.left || this.top > mon.bottom || this.bottom < mon.top)) { if(this.bottom<mon.bottom&& this.speedY>0) { mon.die(); } else { this.die(); break; } } } }
104 | P a g e
Yin Yang
4. Lp Map
Nu coi lp trnh vin lp trnh vin l thng , th bn chnh l mt th gii thu nh ni m thng cho vn hnh nhng quy lut to ra cuc sng. Mc d bn c th rt n gin trong nhiu game, nhng i vi dng game phiu lu ny, n ng vai tr rt quan trng (c th hn so vi Monster). Mt th gii qu nh b s khin ngi chi nhanh kt thc vng chi v khng th khi ln s t m mun khm ph ca h. Khi mt vt th (chng ngi vt), ta s xa vng tng ng trn buffer (nh bn ) v gn gi tr li cho trong d liu l mc nh (0):
function clearCell(left,top,col,row) { data[col+row*COLS] = 0; context.save(); context.globalCompositeOperation = "destination-out"; context.fillStyle = "rgba(0,0,0,1)"; context.fillRect(left,top,CELL_SIZE,CELL_SIZE); context.restore(); }
kim tra va chm vi cc chng ngi vt, ta to phng thc collide() vi gi tr tr v l mt i tng lu gi cc gi tr v v tr, kch thc ca chng ngi vt :
this.colllide = function(x,y,canDestroy){ var b = this.contain(x,y); if(b) { if(canDestroy && b.type==BRICK) { clearCell(b.left,b.top,b.col,b.row); } return b; } return false; }; this.contain = function(x,y){ var col = Math.floor(x/CELL_SIZE); var row = Math.floor(y/CELL_SIZE); var val = data[col+row*COLS]; if(val>0) { var b = { left: col*CELL_SIZE, top: row*CELL_SIZE, col: col, row: row, type: val, }; b.right = b.left+CELL_SIZE; b.bottom = b.top+CELL_SIZE; return b; }
105 | P a g e
Yin Yang
return false; };
Trong game ny, lp Map cn l ni cha cc Monster. lm Monster ra lin tc nu s lng t hn mt gi tr no . Ta vit phng thc update() nh sau:
this.update = function(){ // generate random monsters if(this.monsters.length<MONSTER_IN_VIEW) this.monsters.push(new Monster(this,this.offsetX+Math.random()*this.viewWidth+50,1)); i = 0; var length = this.monsters.length; while(i<length){ if(this.monsters[i].isDead || this.monsters[i].left<this.offsetX) { this.monsters.splice(i,1); // remove this monster from array length--; }else { this.monsters[i].update(); i++; } } };
106 | P a g e
Yin Yang
H. Mt s ng dng minh ha
Trong qu trnh thc hin bi bo co ny, ti thc hin mt vi d n nh minh ha cc kin thc trnh by. Cc d n ny hon ton c th c pht trin tr thnh nhng game online cung cp cho ngi chi trong thc t. Cc d n ny c thc hin bng thun HTML5 v khng s dng thm bt k th vin no.
I. Game ua xe 1. Cc thng s ca xe
Trong game ny, ta s s dng bn phm mi tn iu khin xe. Hai phm UP, DOWN di chuyn tin li v LEFT, RIGHT s dng quay hng xe. Mt xe ua c bn cn cc thuc tnh sau: - max/min speed: tc ti a/ti thiu ca xe. Nn tc ti a c gi tr tuyt i cao hn tc ti thiu. - acceleration: Kh nng tng tc ca xe. Gi tr cng ln th xe cng nhanh t vn tc ti a. - rotationAngle: Kh nng iu chnh gc quay ca xe. - friction: ma st ca xe trn tng loi a hnh. Gi tr ny s gip xe gim tc khi ngi chi khng gi phm di chuyn.
2. Di chuyn v quay xe
Vi mc ch kim tra va chm, ta s s dng mt mng cc im bao quanh xe hay xy ra tip xc nht. y, cc im m ta chn l 4 nh t vng bao hnh ch nht ca xe (c th coi nh 4 bnh xe). Khi xe xoay gc alpha v di chuyn, ta phi tnh li ta cc im ny tng ng. Cng thc tnh ta mi ca mt im sau khi xoay gc alpha l: x = cos(alpha) * x sin(alpha) * y y = sin(alpha) * x + cos(alpha) * y
107 | P a g e
Yin Yang
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)
108 | P a g e
Yin Yang
5. To cc checkpoint
bit xe c i ng ng v ng hng, ta cn to ra cc im kim tra trn ng gi l checkpoint. Nu ngi chi mun i tt n checkpoint, hy m bo rng h s n chm hn so vi i trn ng chnh bng cch to cc vt cn hoc tng ma st. Vi bn trong game ny, ta ch to ra 4 checkpoint. Phng thc reachNextCheckPoint() s kim tra xem xe c chm checkpoint tip theo hay khng. Khi n checkpoint cui cng, ta s a bin currentCheckPoint v 0 v tng lap ln 1.
6. Kt qu
Online Demo.
109 | P a g e
Yin Yang
110 | P a g e
Yin Yang
2. Ph hy mt phn a hnh
S dng phng thc contain bn trn, ta s kim tra c va chm khi n bn hoc ngi chi ri xung t. Vi trng hp n bn, ta phi ph hy vng a hnh ni n bay vo. Rt may l API ca Canvas cung cp mt phng php dng v ra cc vng c alpha bng 0, tng t vi vic xa b hon ton vng . Ta thc hin vic ny bng cch gn hai thuc tnh ca context canvas l globalCompositeOperation thnh destination-out v fillStyle thnh rgba(0,0,0,1). V ti v tr b n bn, ta s v mt hnh trn khoan vng a hnh ny. Bn nn lu v phc hi li context khi s dng thit lp ny.
3. Trng lc v Gi
Trong dng game ny, n khi c bn ra s chu tc ng cng lc ca 3 loi lc l: lc bn, trng lc v gi. Mi lc ny c th c minh ha bi mt vector (Lc bn c gii thiu trong phn trc). Ti mi thi im khi n bay trong khng gian, v tr mi ca n s c tnh bng cch dng v tr hin ti cng vi vector tng ca 3 lc ny. Lu : Bn s thy rng tc n bay qu nhanh c th khin cho vic kim tra va chm khng chnh xc (do trong game l n bin t ni ny n ni khc). V vy cn gim tc n li v tng FPS ln mt gi tr thch hp. to gi, ta s dng mt vector vi hai gi tr x,y thay i ngu nhin sau mt khong thi gian khong 20 giy.
4. Di chuyn Cannon
Do c a hnh phc tp, vic di chuyn cannon s tng i phc tp v cn ty thuc vo hnh dng ca n. Vic cn quan tm y l cch cannon c th i ln a hnh dc va phi. Mt mo nh m ta lm y l s dng cch nhy cc thay v i. Nh vy mi bc i theo chiu ngang ta cng ng thi nng cao v tr ca cannon hn mt cht. Nu cannon i xung dc, n s ri xung v tr thp hn (nh phng thc update()); nu cannon i ln dc, n s v tr cao hn. i vi dc c nghing ln, ta s kim tra mt ta bn tri (hoc phi ty theo hng di chuyn) xem n c chm vo mt a hnh khng. Nu c, ta s khng cho php cannon di chuyn theo hng .
5. St thng ca n
Mi khi n trng t hoc bt k cannon no, n s pht n m gy st thng cho cc cannon nm trong phm vi nht nh. Sc st thng ca n cn b nh hng bi tc ca n khi 111 | P a g e
Yin Yang
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).
7. Kt qu
Online Demo.
112 | P a g e
Yin Yang
113 | P a g e
Yin Yang
I.
Li kt
Hin ti c rt nhiu sn phm game cng nh cc ng dng mang tnh ha tng tc cao c lm trn nn tng HTML5. Cc thit b di ng v h iu hnh mi nh Windows 8 cng tp trung vo h tr v s dng cng ngh HTML5. K nguyn ca HTML5 c th m ra mt tiu chun thng nht cho cc ng dng rich user experience v khng cn phi n o trong vic la chn cc th vin h tr. Cc ni dung trnh by trong sch ny cha tht s nng cao v tp trung vo vic pht trin cc d n thnh mt sn phm game thc s c th cnh tranh trn th trng. Tuy nhin y l bc khi u vng chc cho tng lai ca vic pht trin game trn mng vi cng ngh HTML5. Kt hp vi m hnh client-server, ta c th pht trin cc game nhiu ngi chi (MMO) v lu tr d liu trc tip ca ngi chi trn server. y l iu m ti cha cp ti trong bo co ny.
J.
1. 2. 3. 4. 5. 6. 7.
114 | P a g e