先“上菜”:

 <!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. SQL查询 [SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY的区别(比较)] ---转载

    @@IDENTITY (Transact-SQL) 返回最后插入的标识值的系统函数. 备注 在一条 INSERT.SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含语句生成的 ...

  2. 我的Android进阶之旅------>Android关于Log的一个简单封装

    android.util.Log类,可以方便地用于在编码调试过程中打印日志.但是在发布后的产品中,如果有太多的日志打印,则会严重地影响性能.对android.util.Log类做一个简单的封装,当产品 ...

  3. Linux命令:grep,报错Binary file (standard input) matches

    在Linux使用grep命令,从文件中抓取显示特定的信息,如下: cat 文件名 | grep 特定条件 --->   cat xxxx | grep 12345 结果报错:Binary fil ...

  4. Docker容器部署tomcat出现中文乱码

    docker 容器部署tomcat后,日志文件中出现中文乱码,很多问号,中文的文件夹也是问好.先看看容器的locale: [root@docker1 ~]# docker exec -it 41de9 ...

  5. pinpoint-dubbo插件兼容泛化调用

    背景 dubbo插件中需要记录当前调用的接口和方法,但是在泛化调用的场景下,记录的接口和方法都变成了 com.alibaba.dubbo.rpc.service.GenericService:$inv ...

  6. [原创]java WEB学习笔记19:初识MVC 设计模式:查询,删除 练习(理解思想),小结 ,问题

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  7. 【leetcode刷题笔记】Unique Binary Search Trees II

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  8. Android 蓝牙实例【转】

    本文转自:http://www.yiibai.com/android/android_bluetooth.html 在很多方面,蓝牙是一种能够发送或接受两个不同的设备之间传输的数据. Android平 ...

  9. BZOJ 4650 [Noi2016]优秀的拆分:后缀数组

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4650 题意: 给你一个字符串s,问你s及其子串中,将它们拆分成"AABB&quo ...

  10. Android Studio Mac版快捷键

    mac上按键符号 ⌥ : option / alt ⇧ : shift ⌃ : control ⌘ : command ⎋ : esc (一)查找/查看相关 搜索任意内容 双击 sft 当前文件查找/ ...