先“上菜”:

 <!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. Python菜鸟之路:前端HTML基础

    前面的章节中,Python的基本知识已经差不多介绍完了.本节介绍HTML相关的知识.需要着重声明的是,前端知识是非常非常重要的知识,以我实际项目经验来看,一个项目的瓶颈在设计和前端.设计就先不说了,前 ...

  2. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之实现游戏逻辑(五)

    在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的 ...

  3. 记一次Net软件逆向的过程(经典)

    查壳 1.先看下目录结构: 2.查下,是什么语言 ==> Net的,那不用说了,肯定能破解(毕竟是老本行嘛~) 混淆与反混淆 3.dnSpy打开后发现很多变量是乱码 4.用de4dot跑一波 5 ...

  4. 在网页中显示PDF文件及vue项目中弹出PDF

    1.<embed width="800" height="600" src="test_pdf.pdf"> </embed ...

  5. UIImageView 获取图片的 宽 高

    该文章纯属这两天开发的经验之谈 并且也是平常没注意 这回发现的一个小方法 并且很实用 在开发中 提高了很大的效率 更加符合高保真的要求 通常 美术 切的一些图片 需要 :1还原的 现在 我们一般支持i ...

  6. 【六】MongoDB管理之副本集

    一.复制介绍 所谓的复制就是在多个主机之间同步数据的过程. 1.数据冗余及可用性 复制技术提供数据冗余及可用性,在不同的数据库服务器上使用多个数据副本,复制技术防止单个数据库服务器出现数据故障而出现数 ...

  7. python中reduce()函数

    reduce()函数也是Python内置的一个高阶函数.reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收 ...

  8. 常量池、perm(持久代)、方法区、栈

      常量池.perm(持久代).方法区.栈 常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据. 除了包含代码中所定义的各种基本类型(如:int.long等等)和对象型(如St ...

  9. vim配置与使用

    Vim 是一个上古神器,本篇文章主要持续总结使用 Vim 的过程中不得不了解的一些指令和注意事项,以及持续分享一个前端工作者不得不安装的一些插件,而关于 Vim 的简介,主题的选择,以及为何使用 vi ...

  10. Oracle可能会遇到问题和解决方法

    1.plsql developer查询一列用中文,出现乱码 添加环境变量NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK->软件重启 2.ORA-1251 ...