先“上菜”:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>记忆方块</title>
<script src="randomNum.js"></script>
<script src="Card.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container"></div>
<script src="main.js"></script>
</body>
</html>

html

 #container{
width: 800px;
height: 600px;
background-color: orchid;
border: 3px solid orange;
position: relative;
}
.cardContainer{
width: 50px;
height: 50px;
overflow: hidden;
position: absolute;
}
.card{
width: 100%;
height: 100%;
margin: 0 auto;
}
.cardA{
background-color: red;
font-size: 32px;
line-height: 50px;
text-align: center;
color: aqua;
}
.cardB{
display: none;
background-color: blue;
}

css

 window.meng = window.meng || {};
(function () { function createRandom(N) {
var arr = [];
this._randomArr = [];
for (var i = 0; i < N; i++) {
arr[i] = i;
}
do {
var index = Math.floor(Math.random() * arr.length);
var flag = true;
this._randomArr.push(arr[index]);
arr.splice(index, 1);
if (arr.length == 0) {
flag = false;
}
} while (flag); } Object.defineProperty(createRandom.prototype, "randomArr", {
get: function () {
return this._randomArr;
}
});
meng.createRandom = createRandom;
})();
 /**
* Created by Administrator on 2016/8/26.
*/
window.meng = window.meng || {};
(function () { function Card(num) {
this._aVisible = true;
this._number=num;
this._htmlNode = document.createElement("div");
this._htmlNode.className = "cardContainer";
this._cardA = document.createElement("div");
this._cardA.className = "card cardA";
this._cardA.innerHTML=""+this._number;
this._htmlNode.appendChild(this._cardA);
this._cardB = document.createElement("div");
this._cardB.className = "card cardB";
this._htmlNode.appendChild(this._cardB); var self = this;
this._htmlNode.addEventListener("click", function (e) {
if (self.onclick) {
self.onclick(self);
// console.log(self);
}
});
//写这句话的意思以后,main里面的 Card.htmlNode.onclick=clickHandle;
//就可以了写成 Card.onclick=clickHandle;
// 因为这样写就保证了点击的都是Card的节点而不是,Card对象
} Object.defineProperties(Card.prototype, {
htmlNode: {
get: function () {
return this._htmlNode;
}
},
aVisible: {
get: function () {
return this._aVisible;
}
},
left: {
set: function (value) {
this._htmlNode.style.left = value + "px";
}
},
top: {
set: function (value) {
this._htmlNode.style.top = value + "px";
}
},
number: {
get: function () {
return this._number;
}
}
});
Card.prototype.showA = function () {
this._cardA.style.display = "block";
this._cardB.style.display = "none";
this._aVisible = true;
};
Card.prototype.showB = function () {
this._cardA.style.display = "none";
this._cardB.style.display = "block";
this._aVisble = false;
};
meng.Card = Card;
})();
 /**
* Created by Administrator on 2016/8/26.
*/
(function () { var N = 10;
var currentNumber = 1;
var cards = [];
var container = document.querySelector("#container"); function clickHandle(card) {
if (currentNumber == card.number) {
container.removeChild(card.htmlNode); var index = cards.indexOf(card);
if (index != -1) {
cards.splice(index,1);
if (currentNumber == 1) {
for (var i = 0; i < cards.length; i++) {
cards[i].showB();
}
}
if (cards.length <= 0) {
alert("yes");
}
}
currentNumber++;
} else {
alert("no");
}
// console.log(card.number); } function addCard() {
var randomLeft = new meng.createRandom(N);
var randomTop = new meng.createRandom(N); for (var i = 0; i < N; i++) {
var Card = new meng.Card(i+1);
cards.push(Card);
Card.left = randomLeft.randomArr[i] * 50;
Card.top = randomTop.randomArr[i] * 50;
container.appendChild(Card.htmlNode);
Card.onclick=clickHandle;
/*
*这里有个死循环:number是Card的属性,而onclick点击的应该是Card.htmlNode,
*而onclick只能接受一个单个功能,而不能带参数,所以就不能在clickHandle中设置
* card为Card.htmlNode了,它里面的card只能接受Card。
* 所以要在Card里面写上
* var self = this;
* this._htmlNode.addEventListener("click", function (e) {
* if (self.onclick) {
* self.onclick(self);
* }
* });
* 代码,原因在Card.js里面已经写明白了。
* */ }
} function init() {
currentNumber = 1;
addCard();
} init();
})();

“这道菜”的有个特别重要的一点,感觉还挺重要的,特此强行解释一波。╮(╯▽╰)╭

这个翻牌游戏中,我用了个Card函数去生产卡片,再在main函数里面去对个生产。

当点击的时候有个重大问题:点击的对象应该是Card.htmlNode这个div,不应该是Card对象。

而我代码中写的

  Card.onclick=clickHandle;
onclick接受的只能是function,顾function不能待参数,而clickHandle中必须对一个形参进行操作,而这个形参只能是Card。
这就出现了问题,onclick的行使对象"只能"是Card.htmlNode,而onclick实行的function只能用Card做参数。
这就不统一了,(Card.htmlNode与Card明显不同啊)。
所以应解决一遍问题,让这一边去符合另一边,引出了解决问题的思路就是:
  
   var self = this;
this._htmlNode.addEventListener("click", function (e) {
if (self.onclick) {
self.onclick(self);
// console.log(self);
}
});
先用self接受this(也就是Card对象)。
设置当htmlNode被点击的时候,执行self.onclick,也就是Card.onclick
这里巧妙地把htmlNode的点击引到了Card的点击上。
归结一句话:当Card.htmlNode点击的时候行使的功能变成了Card点击行使改功能。

js之翻牌游戏中的一个深刻感悟的更多相关文章

  1. JavaScript游戏中的面向对象的设计

    简介: 从程序角度考虑,许多 JavaScript 都基于循环和大量的 if/else 语句.在本文中,我们可了解一种更聪明的做法 — 在 JavaScript 游戏中使用面向对象来设计.本文将概述原 ...

  2. Unity优化方向——优化Unity游戏中的图形渲染(译)

    CPU bound:CPU性能边界,是指CPU计算时一直处于占用率很高的情况. GPU bound:GPU性能边界,同样的是指GPU计算时一直处于占用率很高的情况. 原文:https://unity3 ...

  3. 可在 html5 游戏中使用的 js 工具库

    可在 html5 游戏中使用的 js 工具库 作者: 木頭 时间: September 21, 2014 分类: Utilities,Game 使用 cocos2d-js 3.0 开发游戏项目两三个月 ...

  4. 在VS中让一个JS文件智能提示另一个JS文件中的成员

    “在VS中如何让一个JS文件智能提示另一个JS文件中的成员” 有时候会有这种情况:当我的一个Web页面引用了两个JS文件(假如分别叫common.js和JScript1.js),如果JScript1. ...

  5. Visual Studio中让一个JS文件智能提示另一个JS文件中的成员

    当一个Web页面引用了两个JS文件(假如分别叫common.js和JScript1.js),如果JScript1.js中需要调用大量的common.js中的方法,这时候在JScript1.js中智能提 ...

  6. php中向前台js中传送一个二维数组

    在php中向前台js中传送一个二维数组,并在前台js接收获取其中值的全过程方法: (1),方法说明:现在后台将数组发送到前台 echo json_encode($result); 然后再在js页面中的 ...

  7. Js 日期选择,可以的一个页面中重复使用本JS日历,兼容IE及火狐等主流浏览器,而且界面简洁、美观,操作体验也不错。

    <html> <head> <title>Js日期选择器并自动加入到输入框中</title> <meta http-equiv="con ...

  8. GOOGLE VR SDK开发VR游戏,VR播放器之中的一个

    近期一年来,VR虚拟现实和AR增强现实技术的宣传甚嚣尘上.事实上VR,AR技术非常早就有了,一直没有流行开来.不可否认价格是影响技术推广的最大壁垒. 谷歌对VR最大的贡献是提供了便宜的谷歌眼镜,依照G ...

  9. jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?

    1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自 ...

随机推荐

  1. Linux使用yum安装rpm包

    1.yum其实管理的也是rpm包,只不过依赖什么的都自己做了2.yum在有的linux版本是收费的,但是CentOS是免费的3.yum一般意义上是需要联网的,即:使用网络yum源 a.yum源配置文件 ...

  2. Tensorflow 初级教程(二)

    一.Tensorflow 扩展功能 1.自动求导 2.子图的执行 3.计算图控制流 4.队列/容器 Tensorflow 自动求导 当计算tensor C关于tensor W的梯度时,会先寻找从W到C ...

  3. Ubuntu 13.04 可以使用的源

    以下为收集的Ubuntu 13.04 可以使用的源 #中科大源deb http://mirrors.ustc.edu.cn/ubuntu/ saucy main restricted universe ...

  4. onclick事件表示方法

    onclick事件表示方法                                                            1.第一种是直接在html中插入onclick事件 & ...

  5. R语言图形base系统(三)

     本篇介绍R语言base系统绘制散点图.条形图.直方图.箱线图.饼图,还将简单介绍点图.核密度图.折线图. 散点图: attach(mtcars) plot(wt, mpg, main="B ...

  6. C#线程使用学习

    线程的入口函数可以不带输入参数,也可以带输入参数: form1.cs using System; using System.Collections.Generic; using System.Comp ...

  7. php函数指定默认值的方法

    发布:JB02   来源:脚本学堂     [大 中 小] 本文介绍下,在php编程中,指定函数的默认值的方法,分享二个例子,供大家学习参考下.本文转自:http://www.jbxue.com/ar ...

  8. 通过socket和Udp协议简单实现一个群体聊天工具(控制台)

    编写一个聊天程序.有收数据的部分 和 发数据的部分.这两个部分需要同时执行,这就用到多线程技术,一个线程负责收,一个现象负责发. 因为收和发动作是不一致的,所以要定义两个run方法而且这两个方法要封装 ...

  9. Python 3 mysql 数据类型

    Python 3 mysql 数据类型 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 详细参考: http://www.runoob.com/m ...

  10. Python 运算符(算术运算符(+,-,*,**,/,//),逻辑运算符(not , or ,and),比较运算符(>,<,>=,=<),复合运算符(+=,-=,*=,/=,**=,//=))

    # 一.算术运算符(+,-,*,**, /, //, %) # 加法运算符+ print(1 + 2) # 字符串相连 ") # 重载 print([1,2] + [3,4]) # 幂运算* ...