【整理】HTML5游戏开发学习笔记(1)-骰子游戏
《HTML5游戏开发》,该书出版于2011年,似乎有些老,可对于我这样没有开发过游戏的人来说,却比较有吸引力,选择自己感兴趣的方向来学习html5,css3,相信会事半功倍。不过值得注意的是,该书的游戏是些小的游戏,内容相对比较基础,而且html5标准已经正式发布,可能会和书中所描述有少许出处。当然了,书中的小游戏还是比较不错的,适合我这样的前端开发不咋地的来练手,学习方式是在以自己的思路实现之后,再来看书中的实现思路,因为每个人有自己的开发习惯。
1.预备知识
在做第一个骰子游戏开发前,必须知道在html5中,如何绘制矩形和圆形
/*获取2d绘图上下文 var ctx = document.getElementById(‘diceCanvas‘).getContext(‘2d‘) */ /*绘制矩形 ctx.lineWidth = 1 ctx.strokeStyle = ‘#000‘ ctx.strokeRect(100,50,100,100) ctx.fillStyle = ‘#f00‘ ctx.fillRect(100,50,100,100) */ /*绘制圆形或弧形.关闭路径,如果不关闭,这绘制的是不闭合的半圆 ctx.lineWidth = 1 ctx.strokeStyle = ‘#000‘ ctx.beginPath() ctx.arc(200,200,50,0,2*Math.PI*90/360,false) ctx.closePath() ctx.stroke() */
2.实现思路
设计和思考整个游戏中涉及的对象,包括骰子和游戏玩法。
为了简化在绘制每个圆点的时候对坐标的定位计算,我选择九宫格的布局,所以增加了个九宫格坐标对象
3.代码
/*九宫格坐标图*/ function NineBlockBoxMap(squareSize){ var size = squareSize/3, maps = [[],[],[]], x,y, n = 3 for(x=0; x<n; x++){ for(y=0; y<n; y++){ maps[x][y] = {x : x*size + size/2, y : y*size + size/2} //alert(maps[x][y].x+‘|‘+maps[x][y].y) } } this.maps = maps } NineBlockBoxMap.prototype.locate = function(x,y,offsetX,offsetY){ var map = this.maps[x][y] return {x:map.x+offsetX,y:map.y+offsetY} } /*骰子*/ function Dice(){ var opts, ctx, maps function clearCanvas(){ //WARNNING : 不能清除整个Canvas画布,而是要清除当前骰子尺寸的部分画布,因为整个画布有多个骰子 //ctx.clearRect(0,0,opts.canvasWidth,opts.canvasHeight) ctx.clearRect(opts.diceX,opts.diceY,opts.diceWidth+2*opts.diceLineWidth,opts.diceHeight+2*opts.diceLineWidth) } function dotRandom(){ return Math.floor(Math.random()*6+1) } function drawDots(num){ var doDraw = function(points){ var point,i for(i=0; i<points.length; i++){ point = points[i] ctx.beginPath() ctx.arc(point.x,point.y,opts.dotRadius,0,Math.PI*2,false) ctx.closePath() ctx.fill() } } var points = [] //根据1-6的骰子点数在九宫格图中绘制1-6个圆点 switch(num){ case 1 : points.push(maps.locate(1,1,opts.diceX,opts.diceY)) break case 2 : points.push(maps.locate(0,1,opts.diceX,opts.diceY)) points.push(maps.locate(2,1,opts.diceX,opts.diceY)) break case 3 : points.push(maps.locate(2,0,opts.diceX,opts.diceY)) points.push(maps.locate(1,1,opts.diceX,opts.diceY)) points.push(maps.locate(0,2,opts.diceX,opts.diceY)) break case 4 : points.push(maps.locate(0,0,opts.diceX,opts.diceY)) points.push(maps.locate(0,2,opts.diceX,opts.diceY)) points.push(maps.locate(2,0,opts.diceX,opts.diceY)) points.push(maps.locate(2,2,opts.diceX,opts.diceY)) break case 5 : points.push(maps.locate(0,0,opts.diceX,opts.diceY)) points.push(maps.locate(0,2,opts.diceX,opts.diceY)) points.push(maps.locate(1,1,opts.diceX,opts.diceY)) points.push(maps.locate(2,0,opts.diceX,opts.diceY)) points.push(maps.locate(2,2,opts.diceX,opts.diceY)) break case 6 : points.push(maps.locate(0,0,opts.diceX,opts.diceY)) points.push(maps.locate(0,2,opts.diceX,opts.diceY)) points.push(maps.locate(0,1,opts.diceX,opts.diceY)) points.push(maps.locate(2,1,opts.diceX,opts.diceY)) points.push(maps.locate(2,0,opts.diceX,opts.diceY)) points.push(maps.locate(2,2,opts.diceX,opts.diceY)) break default : alert(num + ‘ num must be 1~6‘) break } ctx.fillStyle = opts.dotFillStyle doDraw(points) } function drawDice(){ //绘制骰子矩形 ctx.lineWidth = opts.diceLineWidth ctx.strokeStyle = opts.diceStrokeStyle ctx.strokeRect(opts.diceX,opts.diceY,opts.diceWidth,opts.diceHeight) //绘制骰子上的圆点 var num = dotRandom() drawDots(num) return num } function extend(opt1,opt2){ var name opt1 = opt1||{} opt2 = opt2||{} for(name in opt2){ opt1[name] = opt1[name]||opt2[name] } return opt1 } return { init : function(options){ opts = extend(options,{ canvasId : ‘diceCanvas‘, canvasWidth : 400, canvasHeight : 400, diceWidth : 90, diceHeight : 90, diceX : 50, diceY : 50, diceLineWidth : 5, diceStrokeStyle : ‘#000‘, dotFillStyle : ‘#000‘, dotRadius : 10 }) var canvas = document.getElementById(opts.canvasId) if(canvas==null||canvas.tagName !== ‘CANVAS‘){ alert(‘element must be canvas tag.‘) return } ctx = canvas.getContext(‘2d‘) maps = new NineBlockBoxMap(opts.diceWidth) return this }, throwDice : function(onThrow){ //清除当前骰子的绘图区域 clearCanvas() var num = drawDice() if(typeof onThrow === ‘function‘){ onThrow(num) } return this } } }//end-Dice /*游戏规则 2个骰子之和(2-12) 第一次(7,11) 胜 第一次(2,3,12 )输 第一次 (4,5,6,8,9,10),继续 (第二次(7)输,如果正好和之前相同的点数则 胜,否则继续) */ var GameResult = {Lose:-1,Unknown:0,Win:1} var rule = function GameRule(){ var throwCount = 0 var continual = false var previousSum = 0 return { getResult : function(sum){ var result = GameResult.Unknown, sum = parseInt(sum) throwCount++ if( throwCount==1 ){ if( sum==7||sum==11 ){ result = GameResult.Win } else if( sum==2||sum==3||sum==12 ){ result = GameResult.Lose } } else if(throwCount>1 && continual){ if(throwCount==2&&sum==7){ result = GameResult.Lose } else if(sum==previousSum){ result = GameResult.Win } } previousSum = sum continual = ( result==GameResult.Unknown ) return result }, reset : function(result){ if(result==GameResult.win||result==GameResult.Lose){ throwCount = 0 continual = false previousSum = 0 } } } }() /*app*/ var throwDiceButton = document.getElementById(‘throwDiceButton‘) var dice1TextBox = document.getElementById(‘dice1TextBox‘) var dice2TextBox = document.getElementById(‘dice2TextBox‘) var resultTextBox = document.getElementById(‘resultTextBox‘) var dice1 = new Dice().init() var dice2 =new Dice().init({diceX : 200,diceY : 50,}) throwDiceButton.onclick = function(){ var result = GameResult.Unknown sum = 0 //投掷骰子1 dice1.throwDice(function(num){ dice1TextBox.value = num sum += num }) //投掷骰子2 dice2.throwDice(function(num){ dice2TextBox.value = num sum += num }) result = rule.getResult(sum) rule.reset(result) if(result==GameResult.Win){ resultTextBox.value = ‘You Win : ‘ + sum } else if(result==GameResult.Lose){ resultTextBox.value = ‘You Lose : ‘ + sum } else{ resultTextBox.value = ‘Play again : ‘ + sum } }
4.优化和完善
精简代码和抽象,增加记录得分,初始一定金额等效功能,使其更像是个赌博游戏。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。