您的位置:首页 > Web前端 > HTML5

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

2014-10-28 09:38 471 查看
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)考虑自适应大小的设置,如扑克牌的比例随着手机屏幕大小自适应
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: