zoukankan      html  css  js  c++  java
  • 【整理】HTML5游戏开发学习笔记(4)- 记忆力游戏

    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)考虑自适应大小的设置,如扑克牌的比例随着手机屏幕大小自适应

  • 相关阅读:
    【Matlab】把一年中的某一天(从1月1日起)换算成日期
    【工具】用hexo搭建博客
    【工具】文献分析工具histcite的简单使用
    【工具】用PPT排版打印海报时图片分辨率问题
    【工具】PPT插入高清图片保存后图片变模糊的解决方法
    【工具】排版软件TeX Live 2016的简单使用
    【工具】文字识别软件(OCR) ABBYY Finereader 11简单使用
    【Matlab】编程风格摘录
    【信号】用matlab实现一维信号的高斯滤波
    【GMT5】用GMT绘制测高卫星Topex_Poseidon_Jason的地面轨迹
  • 原文地址:https://www.cnblogs.com/Benoly/p/4056027.html
Copyright © 2011-2022 走看看