1.预备知识
(1)Canvas绘制多边形
(2)Canvas绘制文字

2.实现思路
涉及的对象
  (1)场景Scene
  场景代表了画布上的一块区域,场景里的每个物体都是场景里的一个元素,其绘制统一由场景来调用绘制
 (2) 扑克牌Card
  包括翻开,关闭,移除等操作
 (3)一副扑克牌Deck
  包括洗牌
 (4)游戏玩法PlayingRule
 每次选择2张扑克进行比较,相等则消除(移除),不相等,则进行下一次的2张牌的选择 ,在进行比较

3.主要代码

			/*场景*/
function Scene(canvasId){
var canvas = document.getElementById(canvasId)
var ctx = canvas.getContext('2d')
var width = canvas.width
var height = canvas.height //场景里所有的元素
var elements = [] function initEvents(){
canvas.addEventListener('click',function(e){
for(var i=0;i<elements.length;i++){
if( typeof elements[i].onEvent == 'function' ){
elements[i].onEvent(e)
}
}
},false)
} return { addElement : function(element){
elements.push(element)
}, init : function(){ for(var i=0;i<elements.length;i++){
if( typeof elements[i].init == 'function' ){
elements[i].init(ctx)
}
} initEvents()
} }
} /*
扑克牌
德国扑克牌(一付55/54/32张)规格:9x5.7cm 8.7x5.7cm
*/
function Card(x,y,value,index){
this.x = x
this.y = y
this.value = value
this.index = index
this.status = this.StatusType.Closed this.ctx = null
} Card.prototype = { constructor : Card,
width : 60,
height : 90,
ratio : 1,
StatusType : {Closed:0,Opened:1,Removed:2},
timeout : 300, init : function(ctx){
this.ctx = ctx
this.draw()
}, draw : function(){
var ctx = this.ctx
ctx.clearRect(this.x,this.y,this.width,this.height) switch(this.status){
case 2 :
ctx.fillStyle = '#ccc'
ctx.fillRect(this.x,this.y,this.width*this.ratio,this.height*this.ratio)
break
break
case 1 :
ctx.fillStyle = '#36f'
ctx.fillRect(this.x,this.y,this.width*this.ratio,this.height*this.ratio)
//添加文字
ctx.fillStyle = '#fff'
ctx.font = 'bold 50px Verdana'
ctx.fillText(this.value,this.x+this.width*.5-17,this.y+this.height*.5+17)
break
case 0 :
default :
ctx.fillStyle = '#f60'
ctx.fillRect(this.x,this.y,this.width*this.ratio,this.height*this.ratio)
break
}
}, onEvent : function(e,cardPicked){
var x = e.offsetX,
y = e.offsetY //牌被选中,显示该牌的value值
if(this.x<=x&&x<=this.x+this.width&&this.y<=y&&y<=this.y+this.height){
this.open()//翻开扑克 var self = this
cardPicked(self) setTimeout(function(){
self.close()//关闭扑克牌
},self.timeout) } cardPicked(null)
}, open : function(){
if(this.status == this.StatusType.Closed){
this.status = this.StatusType.Opened
this.draw()
}
}, close : function(){
if(this.status == this.StatusType.Opened){
this.status = this.StatusType.Closed
this.draw()
}
}, remove : function(){
this.status = this.StatusType.Removed
this.draw()
} } /*整付扑克牌 52张*/
function Deck(){
this.cards = []
this.rule = new PlayingRule()
} Deck.prototype = {
constructor : Deck,
opts : {},
//cards : 52,
margin : 10,//牌之间的间距 init : function(ctx){
this.opts.ctx = ctx this.draw()
this.shuffle()
}, draw : function(){
var ctx = this.opts.ctx
var x = this.margin,
y = this.margin,
i = 3,
index = -1 for(i=3;i<9;i++){
var card1 = new Card(x,y,i,++index)
var card2 = new Card(x,y+card1.height+this.margin,i,++index) card1.init(ctx)
card2.init(ctx) //console.log(card1.x+','+card1.y)
//console.log(card2.x+','+card2.y) this.cards.push(card1)
this.cards.push(card2) x += card1.width+this.margin
y = y
}
}, //洗牌
shuffle : function(){
var length = this.cards.length
var r1
var r2
var i
var value for(i=0;i<length;i++){
r1 = Math.floor(Math.random()*length)
r2 = Math.floor(Math.random()*length) value = this.cards[r1].value
this.cards[r1].value = this.cards[r2].value
this.cards[r2].value = value
} /*debug*/
for(i=0;i<length;i++){
console.log(this.cards[i].index+' : '+this.cards[i].value)
}
}, onEvent : function(e){
var cards = this.cards
var length = cards.length
var i
var card
var self = this for(i=0;i<length;i++){
card = cards[i] if(typeof card.onEvent == 'function'){
card.onEvent(e,function(card){
if(card==null||card.status==card.StatusType.Removed){
return
} //有扑克牌被选中
var isMatch = self.rule.pushCard(card).isMatch()
var cards = self.rule.getCards()
var length = cards.length if(isMatch){
for(var i=0;i<length;i++){
var card = cards[i]
alert(card.index)
card.remove()
}
}
else{
//如果不匹配,当前选中的扑克牌会自动定时关闭
//DONOTHING
} //如果有2张扑克,则清除玩法中的选中的2张扑克牌
self.rule.refresh()
})
}
}
} } /*玩法规则*/
function PlayingRule(){
var cards = [] return { pushCard : function(card){
if(cards.length<2){
cards.push(card) console.log('push:'+card.value)
} return this
}, isMatch : function(){
if(cards.length==2){
return cards[0].value === cards[1].value
} return false
}, refresh : function(){
if(cards.length==2){
cards.length = 0
}
}, getCards : function(){
return cards;
} }
} //app
window.onload = function(){ var scene = new Scene('canvas1')
var deck = new Deck() scene.addElement(deck)
scene.init() }

4.优化和完善
(1)有bug,可以作弊,选择的拥有比较的2张牌可以为同一张,需添加判断
(2)简化了书中的例子,图形图片绘制改为了数字文字的现实
(3)可以进行图形绘制,使扑克牌逼真些
(4)考虑自适应大小的设置,如扑克牌的比例随着手机屏幕大小自适应

【整理】HTML5游戏开发学习笔记(4)- 记忆力游戏的更多相关文章

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

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

  2. 【整理】HTML5游戏开发学习笔记(1)- 骰子游戏

    <HTML5游戏开发>,该书出版于2011年,似乎有些老,可对于我这样没有开发过游戏的人来说,却比较有吸引力,选择自己感兴趣的方向来学习html5,css3,相信会事半功倍.不过值得注意的 ...

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

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

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

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

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

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

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

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

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

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

  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. 关于OBS获取显示器黑屏的解决办法

    近来看到许多人说OBS获取显示器源的时候黑屏,下面介绍下相关处理办法. 第一种,先尝试把OBS程序的兼容性设置成Win 7和管理员身份,具体操作: 设置成这样,如果能够获取到显示器,那么问题解决,否则 ...

  2. L2-031 深入虎穴(BFS)

    著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报.已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门.每一扇门背后或者是一个房间,或者又有很多条路,同样是每条 ...

  3. [转载] JVM 内存结构

    转载自:http://gityuan.com/2015/10/17/java-memory/

  4. FUNMVP:几张图看懂区块链技术到底是什么?(转载)

    几张图看懂区块链技术到底是什么? 本文转载自:http://www.cnblogs.com/behindman/p/8873191.html “区块链”的概念可以说是异常火爆,好像互联网金融峰会上没人 ...

  5. PAT甲级题解-1057. Stack (30)-树状数组

    不懂树状数组的童鞋,正好可以通过这道题学习一下树状数组~~百度有很多教程的,我就不赘述了 题意:有三种操作,分别是1.Push key:将key压入stack2.Pop:将栈顶元素取出栈3.PeekM ...

  6. Linux内核分析作业 NO.5

    拔掉系统调用的三层皮(下) 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 ...

  7. 求二维数组联通子数组和的最大值 (联通涂色) beta!

    算法十分臃肿,效率捉鸡,不知用了多少循环,还有bug...任重道远,编程之美. 思想:按行遍历,找出每行的最大子数组.若行间都联通,行最大子数组相加后,再加上独立的正数.若行间不连通,找出较大子路径, ...

  8. 从零开始学Kotlin-基础语法(1)

    从零开始学Kotlin基础篇系列文章 注释 //单行注释 /* 多行注释 */ /** * 多行注释 */ 定义变量/常量 变量定义:var 关键字 var <标识符> : <类型& ...

  9. _stdcall 和 _cdecl

    今天遇到一个问题用C++编写一个动态链接库生成的文件为dll.dll,用在visual stdio 2010调用这个dll 调用形式:[DllImport("dll.dll")] ...

  10. beta圆桌2!

    031602111 傅海涛 1.今天进展 文档转换差不多完成 2.存在问题 无 3.明天安排 增加新功能和完善之前的功能 4.心得体会 接口真难 031602115 黄家雄 1.今天进展 考了六级 2 ...