《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.优化和完善
精简代码和抽象,增加记录得分,初始一定金额等效功能,使其更像是个赌博游戏。

【整理】HTML5游戏开发学习笔记(1)- 骰子游戏的更多相关文章

  1. 【整理】HTML5游戏开发学习笔记(5)- 猜谜游戏

    距上次学习笔记已有一个多月过去了,期间由于新项目赶进度,以致该学习计划给打断,十分惭愧.书本中的第六章的例子相对比较简单.所以很快就完成. 1.预备知识html5中video标签的熟悉 2.实现思路对 ...

  2. HTML5移动开发学习笔记之Canvas基础

    1.第一个Canvas程序 看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子. 效果图为: 代码如下: <!DOCTYPE html> < ...

  3. [游戏开发-学习笔记]菜鸟慢慢飞(四)-Camera

    游戏开发中,主相机应该是最重要的GameObject之一,毕竟游戏呈现给玩家,就是通过它. 相机的使用,在不同的游戏中,有很大的不同.这里总结一下自己学到的一些相关知识. 固定位置-游戏过程中相机的T ...

  4. cocos2d-x 3.x游戏开发学习笔记(1)--mac下配置cocos2d-x 3.x开发环境

    打开用户文件夹下.bash_profile文件,配置环境 vim ~/.bash_profile //按键i,进行插入编辑(假设输错d进行删除一行) 环境配置过程例如以下: 1.首先配置下androi ...

  5. 【Visual C++】游戏编程学习笔记之三:游戏循环的使用

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44208419 作者:Zee ...

  6. 【整理】HTML5游戏开发学习笔记(2)- 弹跳球

    1.预备知识(1)在画布上绘制外部图片资源(2)梯度(gradient):HTML5中的对象类型,包括线性梯度和径向梯度.如createLinearGradient,绘制梯度需要颜色组http://w ...

  7. 【整理】HTML5游戏开发学习笔记(4)- 记忆力游戏

    1.预备知识(1)Canvas绘制多边形(2)Canvas绘制文字 2.实现思路涉及的对象  (1)场景Scene  场景代表了画布上的一块区域,场景里的每个物体都是场景里的一个元素,其绘制统一由场景 ...

  8. 【整理】HTML5游戏开发学习笔记(3)- 抛物线运动

    1.预备知识(1)Canvas旋转的实现过程 window.onload = function(){ var ctx = document.getElementById('canvas1').getC ...

  9. [Android游戏开发学习笔记]View和SurfaceView

    本文为阅读http://blog.csdn.net/xiaominghimi/article/details/6089594的笔记. 在Android游戏中充当主要角色的,除了控制类就是显示类.而在A ...

随机推荐

  1. JSPatch 原理

    原理 JSPatch用iOS内置的JavaScriptCore.framework作为JS引擎,但没有用它JSExport的特性进行JS-OC函 数互调,而是通过Objective-C Runtime ...

  2. 详解Android微信登录与分享

    Android 使用微信登录.分享功能 具体的文档详情微信官网上介绍(微信官网文档),本人直接按照项目部署步骤进行讲解: 第一步:申请你的AppID: 第二步:依赖 dependencies { co ...

  3. 字符串经过base64编码后的长度与原字符串的长度是什么关系呀?

    beforeEncode为Encode之前的字符串 那么Encode后的字符串长度为: 1.如果beforeEncode.length()是3的整数倍,那么长度为  (beforeEncode.len ...

  4. 【转】SQL SERVER 中 sp_rename 用法

    因需求变更要改表的列名,平常都是跑到Enterprise manager中选取服务器->数据库->表,然后修改表,这样太麻烦了,查了一下,可以用script搞定,代码如下: EXEC sp ...

  5. JMeter性能测试基础 (2) - 变量的使用

    在使用JMeter进行性能测试时,一般情况下要保证样本容量尽可能大,这样才能得到一个比较合理的结果.也就是说,我们不能只对同一个URL进行多次访问,而是要对统一模块下尽可能多的URL进行访问,以取得相 ...

  6. mysql group by分组查询

    分组的SQL语句有2个: group by 和分组聚合函数实现 partition by (oracle和postgreSQL中的语句)功能 group by + having 组合赛选数据 注意:h ...

  7. linux 负载均衡配置 keepalive lvs 使用nginx转发 CentOS7 搭建LVS+keepalived负载均衡

    最近希望能够配置一下负载均衡,在虚拟机上面,但是网上找了很多资料很零散,对于不了解的人,很多不够详细,最近终于做好了,把具体的步骤写下来,方便各位网友查阅学习 这个实验需要安装nginx如果没有安装过 ...

  8. springboot学习笔记-3 整合redis&mongodb

    一.整合redis 1.1 建立实体类 @Entity @Table(name="user") public class User implements Serializable ...

  9. nowcoder 202F-平衡二叉树

    题目链接 题目描述 平衡二叉树,顾名思义就是一棵“平衡”的二叉树.在这道题中,“平衡”的定义为,对于树中任意一个节点,都满足左右子树的高度差不超过 d. 空树的高度定义为0,单个节点的高度为1,其他情 ...

  10. Luogu 5108 仰望半月的夜空(后缀数组)

    如果是要求左端点最大,直接求出SA,找前缀名次最小值就可以了.虽然现在要左端点最小,但我们已经知道了这个字典序最小的串是什么,找到名次数组上的合法区间求最小值即可.我也不知道为什么我会弃掉这个题,可能 ...