js之翻牌游戏中的一个深刻感悟
先“上菜”:
<!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之翻牌游戏中的一个深刻感悟的更多相关文章
- JavaScript游戏中的面向对象的设计
简介: 从程序角度考虑,许多 JavaScript 都基于循环和大量的 if/else 语句.在本文中,我们可了解一种更聪明的做法 — 在 JavaScript 游戏中使用面向对象来设计.本文将概述原 ...
- Unity优化方向——优化Unity游戏中的图形渲染(译)
CPU bound:CPU性能边界,是指CPU计算时一直处于占用率很高的情况. GPU bound:GPU性能边界,同样的是指GPU计算时一直处于占用率很高的情况. 原文:https://unity3 ...
- 可在 html5 游戏中使用的 js 工具库
可在 html5 游戏中使用的 js 工具库 作者: 木頭 时间: September 21, 2014 分类: Utilities,Game 使用 cocos2d-js 3.0 开发游戏项目两三个月 ...
- 在VS中让一个JS文件智能提示另一个JS文件中的成员
“在VS中如何让一个JS文件智能提示另一个JS文件中的成员” 有时候会有这种情况:当我的一个Web页面引用了两个JS文件(假如分别叫common.js和JScript1.js),如果JScript1. ...
- Visual Studio中让一个JS文件智能提示另一个JS文件中的成员
当一个Web页面引用了两个JS文件(假如分别叫common.js和JScript1.js),如果JScript1.js中需要调用大量的common.js中的方法,这时候在JScript1.js中智能提 ...
- php中向前台js中传送一个二维数组
在php中向前台js中传送一个二维数组,并在前台js接收获取其中值的全过程方法: (1),方法说明:现在后台将数组发送到前台 echo json_encode($result); 然后再在js页面中的 ...
- Js 日期选择,可以的一个页面中重复使用本JS日历,兼容IE及火狐等主流浏览器,而且界面简洁、美观,操作体验也不错。
<html> <head> <title>Js日期选择器并自动加入到输入框中</title> <meta http-equiv="con ...
- GOOGLE VR SDK开发VR游戏,VR播放器之中的一个
近期一年来,VR虚拟现实和AR增强现实技术的宣传甚嚣尘上.事实上VR,AR技术非常早就有了,一直没有流行开来.不可否认价格是影响技术推广的最大壁垒. 谷歌对VR最大的贡献是提供了便宜的谷歌眼镜,依照G ...
- jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?
1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自 ...
随机推荐
- Delphi 对话框实现源码分析
Delphi 对话框实现源码分析 简介 在这篇文章中,我将大概的从Delphi XE2 的Dialogs单元入手,分析ShowMessage,MessageBox等对话框运行原理,希望能帮助你理解 ...
- JVM指令重排
指令重排的基本原则: a.程序顺序原则:一个线程内保证语义的串行性 b.volatile规则:volatile变量的写,先发生于读 c.锁规则:解锁(unlock)必然发生在随后的加锁(lock)前 ...
- 安装了包,pycharm却提示找不到包
这段时间,我爬虫爬到了一个论坛的数据,有个分析需要知道他的字符编码,因此使用到了 chardet,我在终端很顺利的安装了这个,但是在pycharm里使用的时候老是提示有错误,向下面这样: 其实这个是因 ...
- Linux基础系列:常用命令(6)_nfs服务与nginx服务
NFS介绍: NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统 ...
- LeetCode:移除K位数字【402】
LeetCode:移除K位数字[402] 题目描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. nu ...
- 用cocos2d-html5做的消除类游戏《英雄爱消除》——概述
在bbs.html5china.com论坛学习了MV和老马的小熊蘑菇后我也自己模仿他们做了这样子一个游戏,权当技术交流学习,现在附上游戏截图和源码. 游戏截图: 1.系统菜单界面: 2.游戏界面 3. ...
- 解决编译caffe2遇到的坑
首先我们要从源码克隆caffe2的库: git clone --recursive https://github.com/caffe2/caffe2.git 执行下载过程会报这样的错: Cloning ...
- Oracle数据库体系结构(2)数据库实例
Oracle实例的概念: 实例(Instance):就是数据库管理系统,处于用户与物理数据库之间的一个中间层软件,由一系列内存结构和后台进程组成. 用户操作数据库的过程实质上与数据库实例建立连接,然后 ...
- leetcode 901. Online Stock Span
Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of ...
- python 3 封装
python 3 封装 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小鱼,小虾,小王八,一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的. 先看如何隐藏 在 ...