HTML 5游戲制作之五彩連珠(設(shè)計(jì))
在看了幾篇Canvas相關(guān)的文章后,發(fā)現(xiàn)前兩節(jié)的代碼實(shí)現(xiàn)還是有問(wèn)題,因?yàn)橹赖纳?,所以只能在自己已知的知識(shí)上做實(shí)現(xiàn)。不過(guò)還好,這是一個(gè)發(fā)現(xiàn)的過(guò)程,也是一個(gè)糾錯(cuò)和完善的過(guò)程。我第一次嘗試一邊學(xué)習(xí)一遍寫博客,我想這也有助我的學(xué)習(xí),可以把知識(shí)掌握的牢固些,起碼忘的慢一些吧:)。
前兩節(jié)學(xué)習(xí)了幾個(gè)基本繪制的方法,lineTo moveTo和arc,也了解坐標(biāo)的情況,但寫的比較傻,只是單純的實(shí)現(xiàn)。 比如棋盤的起始坐標(biāo)如果有偏移量,我們還要計(jì)算他的具體開始坐標(biāo)和結(jié)束坐標(biāo),實(shí)際上Canvas有現(xiàn)有的方法提供偏移的功能。 他叫 translate,另外還有縮放scale、旋轉(zhuǎn)rotate,他們都可以用transform代替。所以,在代碼方面還會(huì)有些調(diào)整。不過(guò)這個(gè)的學(xué)習(xí)恰巧也讓我知道如何實(shí)現(xiàn)動(dòng)畫效果。如果多個(gè)元素在一個(gè)Canvas上,實(shí)現(xiàn)動(dòng)畫,必然會(huì)需要擦除重繪的情況,如果元素之間有覆蓋的情況,擦除就需要多考慮了。當(dāng)然,簡(jiǎn)單的辦法就是把整個(gè)畫布根據(jù)當(dāng)然所有元素的位置重新繪制一遍。所以在代碼設(shè)計(jì)方面,需要把不同的元素獨(dú)立出來(lái),每個(gè)元素都有自己的draw方法,并且要依照次序繪制Canvas。
分析一下游戲所需的元素:1、棋盤(地圖)2、泡泡 3、等待區(qū)域(新的3個(gè)即將進(jìn)入棋盤的泡泡)4、獎(jiǎng)勵(lì)區(qū)域(白搭星、超級(jí)百搭星、炸彈)5、統(tǒng)計(jì)信息 6、按鈕
所以在對(duì)象的設(shè)計(jì)方面起碼要有幾類 棋盤(map)、新泡泡區(qū)(ready)、獎(jiǎng)勵(lì)區(qū)(awards)、泡泡(bubble)、星星1(star1) 、星星2(star2) 、炸彈(boom)、統(tǒng)計(jì)積分(score),還要包括游戲背后的數(shù)據(jù)(data)。 OK,先這么規(guī)劃,挨個(gè)的去實(shí)現(xiàn)。先把map和bubble重寫了。
之前把map寫成了類,顯然是不合適的,因?yàn)檫@個(gè)游戲不可能會(huì)有多個(gè)map,所以直接定義為對(duì)象更方便。而泡泡顯然需要很多,所以需要寫成類比較方便。游戲里面所有對(duì)象需要訪問(wèn)的全局變量和常量需要定義在一個(gè)game對(duì)象里,游戲開始則是調(diào)用game.start()的方法。所以先看下game的定義:
- var game = {
- canvas: document.getElementById("canvas"),
- ctx: this.canvas.getContext("2d"),
- cellCount: 9,
- cellWidth: 30,
- lineCount: 5,
- mode: 7,
- colors: ["red", "#039518", "#ff00dc", "#ff6a00", "gray", "#0094ff", "#d2ce00"],
- over: function () {
- alert("GAME OVER");
- },
- getRandom: function (max) {
- return parseInt(Math.random() * 1000000 % (max));
- },
- };
cellCount就是格子的總數(shù),cellwidth是每個(gè)格子的寬度,因?yàn)椴还鈓ap里需要這個(gè),所以就定義在了這里,mode 是游戲模式 5是簡(jiǎn)單 7是困難。
再看下map的代碼:
- game.map = {
- startX: 40.5,
- startY: 60.5,
- width: game.cellCount * game.cellWidth,
- height: game.cellCount * game.cellWidth,
- bubbles: [],
- init: function () {
- for (var i = 0; i < game.cellCount; i++) {
- var row = [];
- for (var j = 0; j < game.cellCount; j++) {
- row.push(new Bubble(i, j, null));
- }
- this.bubbles.push(row);
- }
- },
- draw: function () {
- var ctx = game.ctx;
- ctx.save();
- ctx.translate(this.startX, this.startY);
- ctx.beginPath();
- for (var i = 0; i <= 9; i++) {
- var p1 = i * game.cellWidth;;
- ctx.moveTo(p1, 0);
- ctx.lineTo(p1, this.height);
- var p2 = i * game.cellWidth;
- ctx.moveTo(0, p2);
- ctx.lineTo(this.width, p2);
- }
- ctx.strokeStyle = "#555";
- ctx.stroke();
- //繪制子元素(所有在棋盤上的泡)
- this.bubbles.forEach(function (row) {
- row.forEach(function (bubble) {
- bubble.draw();
- });
- });
- ctx.restore();
- },
- addBubble: function (bubble) {
- var thisBubble = this.bubbles[bubble.x][bubble.y];
- thisBubble.color = bubble.color;
- },
- getBubble: function (x, y) {
- var thisBubble = this.bubbles[x][y];
- if (!thisBubble.color) {
- return null;
- }
- else {
- return thisBubble;
- }
- }
- };
map的init初始化方法里我先把所有的泡泡部署好了,但是都沒(méi)有染色,我并沒(méi)有在ui的背后維護(hù)一個(gè)數(shù)組,因?yàn)槲矣X(jué)得泡泡有沒(méi)有顏色就代表 0,1了,所以就這樣也行。
draw方法不再想之前那樣把起始坐標(biāo)計(jì)算進(jìn)去了,而是使用了translate方法,這樣就很方便寫代碼了。
addBubble其實(shí)就是染色而已,接收參數(shù)是一個(gè)泡泡對(duì)象,這個(gè)對(duì)象來(lái)自ready區(qū)域的泡泡。
Ready區(qū)域其實(shí)就像俄羅斯方塊那樣,有三個(gè)預(yù)備的泡泡即將進(jìn)入map區(qū)域。
- game.ready = {
- startX: 40.5,
- startY: 20.5,
- width: game.cellWidth * 3,
- height: game.cellWidth,
- bubbles: [],
- init: function () {
- this.genrate();
- var me = this;
- me.flyin();
- },
- genrate: function () {
- for (var i = 0; i < 3; i++) {
- var color = game.colors[game.getRandom(game.mode)];
- this.bubbles.push(new Bubble(i, 0, color));
- }
- },
- draw: function () {
- var ctx = game.ctx;
- ctx.save();
- ctx.translate(this.startX, this.startY);
- ctx.beginPath();
- ctx.strokeStyle = "#555";
- ctx.strokeRect(0, 0, this.width, this.height);
- ctx.stroke();
- //繪制準(zhǔn)備的泡
- this.bubbles.forEach(function (bubble) {
- bubble.draw();
- });
- ctx.restore();
- },
- };
ready.init 初始化3個(gè)泡泡,并且把這3個(gè)泡泡“飛入”到map里,ready.draw很簡(jiǎn)單就是繪制一個(gè)小矩形和3個(gè)泡泡。
哦,對(duì)了,我們的泡泡的繪制代碼也稍作了修改,現(xiàn)在的樣子不是之前的純色了,有了水晶效果。。。不妨看看:
- Bubble.prototype.draw = function () {
- if (!this.color) {
- return;
- }
- var ctx = game.ctx;
- ctx.beginPath();
- //console.log("x:" + px + "y:" + py);
- var gradient = ctx.createRadialGradient(this.px - 5, this.py - 5, 0, this.px, this.py, this.light);
- gradient.addColorStop(0, "white");
- gradient.addColorStop(1, this.color);
- ctx.arc(this.px, this.py, 11, 0, Math.PI * 2);
- ctx.strokeStyle = this.color;
- ctx.fillStyle = gradient;
- ctx.fill();
- ctx.stroke();
- };
createRadialGradient方法是畫一個(gè)放射性的圓,起始在左上角,這樣就有個(gè)光照效果,還是不錯(cuò)的。 看下效果圖吧

原文鏈接:http://www.cnblogs.com/mad/archive/2012/03/17/2392632.html
【編輯推薦】
- HTML 5游戲制作之五彩連珠(預(yù)覽)
- HTML 5游戲制作之五彩連珠(畫圖)
- HTML 5游戲制作之五彩連珠(動(dòng)畫)
- HTML 5游戲制作之五彩連珠(尋路)
- HTML 5游戲制作之五彩連珠(試玩)






















