ng2048源码阅读

Tutorial: http://www.ng-newsletter.com/posts/building-2048-in-angularjs.html

Github: https://github.com/fullstackio/ng2048.git

本地不部署项目一直卡在node-sass不成功的问题上,需要的css文件没办法生成,我的目的是弄清设计原理,学习ng的用法,所以直接用sass编译sass文件为css文件,丢到项目文件夹下跑起来。

sass编译css文件

npm install node-sass -g
sass D:\GitHub\ng2048\app\styles\main.scss D:\GitHub\ng2048\app\styles\main.css

启动项目

这个项目是grunt构建的, 使用--force忽略sass编译的错误继续执行

grunt serve --force

这个列子有些小复杂,看看能学到啥

1. 数据传递,指令的使用,ng-if的使用

grid的使用,通过ng-model传递到指令内部的独立scope

<!-- 显示格子 -->
<div grid ng-model='ctrl.game' class="row"></div>

Grid中包含tile,tile指令也是通过ng-model传递到指令内部的独立scope,注意这里的ng-repeat迭代的对象的传递

<div id="game-{{ ngModel.gameSize }}">
<div class="grid-container">
<div class="grid-cell" ng-repeat="cell in ngModel.grid track by $index"></div>
</div> <div class="tile-container">
<div tile
ng-model='tile'
ng-repeat='tile in ngModel.tiles track by $id(tile.id || $index)'></div>
</div>
</div>

tile的模板

<div ng-if='ngModel' class="tile position-{{ ngModel.x }}-{{ ngModel.y }} tile-{{ ngModel.value }}"
ng-class="{ 'tile-merged': ngModel.merged}">
<div class="tile-inner">
{{ ngModel.value }}
</div>
</div>

2. 通用的游戏键盘控制服务

服务init的时候这个keydown什么也不做,通过on订阅事件,将自己的处理程序加到服务的keyEventHandlers列表中完成事件的定制。这个服务就通用的了,你只需要写好自己的控制程序,然后通过on订阅就可以了。这也算是一种设计技巧了。

'use strict';

angular.module('Keyboard', [])
.service('KeyboardService', function($document) { var UP = 'up',
RIGHT = 'right',
DOWN = 'down',
LEFT = 'left'; var keyboardMap = {
37: LEFT,
38: UP,
39: RIGHT,
40: DOWN
}; this.init = function() {
var self = this;
this.keyEventHandlers = [];
$document.bind('keydown', function(evt) {
var key = keyboardMap[evt.which]; if (key) {
// An interesting key was pressed
evt.preventDefault();
self._handleKeyEvent(key, evt);
}
});
}; this.on = function(cb) {
this.keyEventHandlers.push(cb);
}; this._handleKeyEvent = function(key, evt) {
var callbacks = this.keyEventHandlers;
if (!callbacks) {
return;
} evt.preventDefault(); if (callbacks) {
for (var x = 0; x < callbacks.length; x++) {
var cb = callbacks[x];
cb(key, evt);
}
}
}; });
//初始化
KeyboardService.init();
//订阅事件
KeyboardService.on(function(key) {
self.game.move(key);
});

3. 设计思路和实现思路

代码看完了,游戏的思路和我设想的差不多,但是在实现上跟我想的有些不一样,大致也就是两层循环挨个的处理格子,但是实现上感觉还是有些技巧的。

3.1 根据方向确定坐标的偏移量
    var vectors = {
'left': { x: -1, y: 0 },
'right': { x: 1, y: 0 },
'up': { x: 0, y: -1 },
'down': { x: 0, y: 1 }
};
3.2 根据方向确定两层循环的索引序列,[0,1,2,3]还是[3,2,1,0]
    this.traversalDirections = function(key) {
var vector = vectors[key];
var positions = {x: [], y: []};
for (var x = 0; x < this.size; x++) {
positions.x.push(x);
positions.y.push(x);
} if (vector.x > 0) {
positions.x = positions.x.reverse();
}
if (vector.y > 0) {
positions.y = positions.y.reverse();
} return positions;
};
3.3 一次性拿到可以直接移动到的位置和紧跟的进行碰撞的位置
    this.calculateNextPosition = function(cell, key) {
var vector = vectors[key];
var previous; do {
previous = cell;
cell = {
x: previous.x + vector.x,
y: previous.y + vector.y
};
} while (this.withinGrid(cell) && this.cellAvailable(cell));
//没有越界,并且cell是空的 return {
newPosition: previous,
next: this.getCellAt(cell)
};
};

ng2048源码阅读的更多相关文章

  1. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  2. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  3. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  4. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  5. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  6. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  7. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  8. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  9. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. iOS 真机测试时报错:Provisioning profile "iOS Team Provisioning Profile: XXX” doesn't include the currently selected device “XXX”.

    这几天因工作需要,去给客户演示iOS项目打包的过程.之前演示都是顺利的,但后来客户自己操作时打电话说遇到了问题,出现报错. 就过去看了一下,发现一个很陌生的错误提示: The operation co ...

  2. Java基础加强之集合篇(模块记忆、精要分析)

    千里之行,始于足下.把别人的变成自己,再把自己的分享给别人,这也是一次提升的过程.本文的目的是以一篇文章从整体把握集合体系又不失一些细节上的实现,高手路过. 集合的作用与特点 Java是一门面向对象语 ...

  3. 使用Git的Push出现rejected - non-fast-forward错误

    通过查阅资料,发现是文件冲突问题,即本地和远程的Repository中的文件出现了冲突所致,重新检查了一下,发现是在建立Repository时,添加了ReadMe.txt文件,导致和本地得项目分支不一 ...

  4. java基础-注释

    注释是一种形式的元数据,提供了非程序自身的数据,注释对于被注释的代码没有直接的影响. 本文主要概括注释的使用,java平台(SE)预定义的注释,类型注释是如跟可插入类型系统连用达到更强的类型检查的,以 ...

  5. 前馈网络求导概论(一)·Softmax篇

    Softmax是啥? Hopfield网络的能量观点 1982年的Hopfiled网络首次将统计物理学的能量观点引入到神经网络中, 将神经网络的全局最小值求解,近似认为是求解热力学系统的能量最低点(最 ...

  6. ITree诞生啦!

    经过一个月的码码码,一个面向OIer的ITree终于来辣! ... (似乎把OI遗弃在了某个角落了........... 一个月里,从只会py到写出ITree,真是不容易呢(其实就是两个多礼拜而已= ...

  7. notepad++崩溃后文件内容变为NUL的解决方法

    毫无疑问,notepad++是一款非常优秀的文本编辑器,但是notepad++有时候会崩溃,之后文件内容就会全部变成NUL 当你打文件看到自己辛辛苦苦的成果全都变成NUL是不是有想哭的感觉?" ...

  8. 安卓端360度全景图的html5实现

    这里是一款旅游相关的安卓应用,其中虚拟旅游的功能采用html5的360度全景图技术实现,使用户能够身临其境的感受旅游景点的风光. 此处引入了ddpanorama插件,它的原理是在canvas上绘制全景 ...

  9. tableViewCell嵌套collectionView,动态高度

    方法有很多,有通过内容高度,经过代理回调,刷新的,甚至还有计算cell个数,然后根据cell大小计算的,这里推荐iOS 8新特性,通过AutoLayout,利用内容将cell撑起来; 关键代码: vi ...

  10. 2016huasacm暑假集训训练五 F - Monkey Banana Problem

    题目链接:http://acm.hust.edu.cn/vjudge/contest/126708#problem/F 题意:求至上而下一条路径的所经过的值得和最大值,这题比赛时就出了 但当时看不懂题 ...