修改vim-zencoding对sass的支持

目前使用的zencoding(git仓库版本)已经增加了对sass的支持,但支持不够完美,例如输入 pos:a ,展开以后是 position:absolute。这样的代码是无法编译通过的,sass中要求:(冒号)后面必须有空格,也就是position: absolute这样的结果。只需要很简单的修改就可以。

具体方法如下:
修改 autoload/zencoding/lang/sass.vim 在 let text = substitute(text, '\s*;\ze\(\${[^}]\+}\)\?\(\n\|$\)', '', 'g') Lline:60 行后面添加一行 let text = substitute(text, ':', ': ', '') 保存再次打开即可。

关于chrome浏览器移动web开发

之前预览移动页面,使用一款名为User-Agent Switcher的插件。这两天用chrome开发者工具修改设置时看到新版的chrome自带设置项可十分方便的预览移动页面。设置方法如下:

1. 打开chrome开发者工具,点右下角设置

2. 在设置页面切换到Overrides选项卡,设置User Agent和Device metrics两项即可。

还可以使用Chrome结合ADBPlugin调试安卓手机上的网页,具体信息参照:https://developers.google.com/chrome-developer-tools/docs/remote-debugging

玩家角度看《我叫MT》怎么做用户激励、付费激励

前段时间玩了下这款游戏,个人感觉游戏在用户活跃和付费激励方面设计得很好,从一个玩家的角度来说下这款游戏。

直接上图说明
1. 主界面

游戏主界面,大家能看到界面中两个红色中间带N的圆点。这两个点会一大一小的闪动,让你非常有想点击的欲望。

2. 用户激励
2.1 每天登陆送赠送

赠送的50符石(约相当于RMB 5元价值),体力用完后可点击恢复120点体力,8.8W金币,惊喜礼包一般是南瓜花或南瓜。

1.2 点斗积分

玩家达到35级以后,可以参加战斗系统,5场全胜,可以得230符石、若干金币,5场全输可以得160符石奖励。胜利以后声望增加,可以升级爵位,可以增加体力、领导力上限,每天可领取一定数量符石。

2.3活动副本

循环活动副本,出主角卡、南瓜、小金龙。主角卡用来升级打怪,南瓜可以给主角升级,小金龙可以卖金币。

3. 用户付费激励
3.1 体力购买

用户可用体力约为120点,副本每次消耗约6-8点,每隔几分钟可以回复1点,花费符石可1次购买120点体力,没有充值过的帐号每天仅可购买1次,充值后购买次数可增加,后期升级每天需大量体力,很多用户会充值。

3.2 战斗加速

左下角的"X2"代表当前游戏进行速度,默认是X1速度非常慢。X2后游戏进行速度会加快,可节省大量时间。普通用户可以X2,充值以后可以到X3。

3.3 月卡会员赠送

充值30块,你能得到什么,300符石?再送你3000符石(人民币300元),是不是感觉很超值?充30块钱月卡,一次获得等价符石,每天再送你100符石。刺激冲动型用户的付费欲望。

4. 卡牌进化系统

卡牌进化的过程如下:
1) 白色卡牌 升到25级 一套绿装  进化到绿色
2) 绿色卡牌 升到30级 一套蓝装  进化到蓝色
3) 蓝色卡牌 升到60级 一套精英蓝 进化到金边
4) 金边卡牌 此时不升级 一张蓝色卡牌 进化到金边+1
5) 金边卡牌+1 升到65级 两张蓝色卡牌 进化到金边+2
6) 金边卡牌+2 升级到70级 一张蓝色金边卡牌 进化到金边+3
7) 金边卡牌+3 升级到75级 一张紫色金边卡牌 进化到紫色
8) 紫色卡牌 此时不升级 一套紫装 进化到紫色金边
9) 依次+1 +2 +3,后面的没玩过。
说明:75级蓝卡+3升紫色,需要的金边卡牌是需要打副本掉落,或打碎片(掉率不高,且需要集齐80-120个)兑换到紫卡,升到75级,用一套紫装升到金边。一张紫卡的成本非常高,后期+1, +2, +3需要大量紫卡,如果玩家后期想要玩下去必须要充值。

5. 不定期活动
不定期会开放各种活动,上线送金币、符石,增加活动副本次数,增加卡牌掉率。你是玩家遇上这样的机会,还不得泡在线上。体力用完了,普通帐户只能买1次怎么办?亲,考虑下掏钱吧!

6. 总结:
6.1 这款游戏在吸引用户付费方面做了很多设计,原本与人民币等价兑换的符石,在游戏中普通玩家也可大量获得。针对普通玩家,使用购买体力、加速等方式让用户掏小钱(5块15块的)。针对想深入一点的玩家,月卡只需30块就可以多得300块钱的符石。让用户付出很少的代价就可以获得极大的心理价值反馈。针对高端玩家,后期紫卡升级可是无底洞,几千上万都填不满,煤老板有地方消费了。

6.2 游戏中金币系统设计存在比较大的问题,没有一个很明显的获取方式。活动副本的小金龙掉率低,而且掉的钱很快消耗掉。大量金币基本靠活动赠送,不知是有意为之还是存在bug。后期可以减少活动赠送,在商城里加一个符石购买金币,让用户掏钱。哈哈!

6.3 因为不存在用户关系,用户基本处于单人游戏环境。当进行到后期需要大量充值情况下,游戏对玩家吸引力减弱,缺乏一个长期可持续的游戏模式。

6.4 装备系统刚出来,自己还没刷出来过,冒似没掉率很低,不知又是一个吸金大坑还是鸡肋设计。

关于截图的一点总结

1. 去除滚动条
aau创建webform可以去掉滚动条,但测试的时候发现如果网页中对html设置了overflow-y:scroll;滚动条还是会显示出来,页面的doctype好象也可以影响滚动条的显示。最终使用代码将所以滚动条显示出来,在截图的时候裁掉滚动条。
计算滚动条代码:

var js = /**
    document.documentElement.style.overflowY='scroll';
**/
wb.doScript(js);

var scrollWidth = wb.document.documentElement.offsetWidth  - wb.body.clientWidth;

2. 触发layzload加载的图片
很多网站对图片使用了懒加载,图片显示不全,强制设置滚动条到底部可以解决大部份情况。
js添加一行
window.scrollTo(0, 100000);

3. 多用win.delay
最开始在使用setPos修改webform的宽度之后,因为我设置的宽度大于body的宽度截图出现头部居中主体内容未居中的情况,尝试在调用setPos以后调用win.delay(20)问题就解决了。在设置scroll的值触发图片懒加载以后也需要暂停一下让图片加载完成,不过要根据实际网页的情况去设置。

批量截图软件webmonitor

自己开发了一款批量截图软件,用来对一组url批量截图。当web项目修改后,运行软件,重新截图一遍,查看是否有样式错乱。使用aau开发(http://www.aau.cn),在此特别推荐一下aau,一款国人研发的开发语言。

webmonitor源码地址:git://gitcafe.com/lcc/WebMonitor.git
webmonitor项目页面:https://gitcafe.com/lcc/WebMonitor

说明:1. git获取项目源代码 2. 从www.aau.cn上下载aau开发工具,用开发工具打开项目点击“运行”试用程序,或者点击“发布”生成应用程序。

使用截图:

创建项目

添加url

截的图片

解决ftplugin/ruby.vim Line 83 E484错误

自己用的vim是从源上获取的代码自行编译的x64位版本,版本号是7.3-712。在编辑haml、rb等文件时就报出ftplugin/ruby.vim E484错误。看了下ruby.vim是调用system命令取ruby路径时报错。解决方法,在vimrc中添加一行:
let g:ruby_path = ""
当检测到有g:ruby_path这个变量时,就不会调用system命令取ruby路径。ruby.vim 中仅 72-94行用到了s:ruby_path,暂时没发现修改后有什么问题。

错误截图:

兼容ie6的fixed布局(非js、expression)

时代的脚本向前,ie6也快走出历史舞台了,只是现在还折腾着某些人(仰天长笑三声 哈!哈!哈!)。分享一个兼容fixed的小方法,传统的js侦听scroll事件以及expression的方法页面经常出现卡顿,用了一个取巧的方案来实现类似fixed的效果。直接上代码:

<!DOCTYPE html>
<html>
<!--[if lt IE 7]> <html class="ie6"> <![endif]-->
<!--[if IE 7]> <html class="ie7"> <![endif]-->
<!--[if IE 8]> <html class="ie8"> <![endif]-->
<!--[if gte IE 9]> <html class="ie9"> <![endif]-->
<head>
  <meta charset="UTF-8">
  <title></title>
  <style type="text/css">
    html, body {
      padding: 0;
      margin: 0;
    }
    .ie6, .ie6 body {
      height: 100%;
      overflow-y: hidden;
    }
    .ie6 .contentWrap {
      overflow-y: auto;
      width: 100%;
      height: 100%;
    }
    .popLayer {
      width: 400px;
      height: 400px;
      position: fixed;
      top: 50%;
      left: 50%;
      margin-top: -200px;
      margin-left: -200px;
      background-color: #F0F0F0;
      border: 1px solid #DDD;
    }
    .ie6 .popLayer {
      position: absolute;
    }
  </style>
</head>
<body>
  <!--[if lt IE 7]><div id="contentWrap" class="contentWrap"><![endif]-->
  <p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p><p>这是一行文字</p>
  <!--[if lt IE 7]></div><![endif]-->
  <div id="popLayer" class="popLayer">
    <p>这是弹出层的内容</p>
    <button onclick="document.getElementById('popLayer').style.display='none';">关闭弹出层</button>
  </div>
</body>
</html>

ThinkPHP中关于Widget的小问题

又折腾了下Widget,纪录下遇到的两个小问题。

1. Layout中嵌入Widget,Widget未显示声明NOLAYOUT时,出现循环调用。
例:Lib/Tpl/_layout.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <h1>这是layout</h1>
  <div>
    {__CONTENT__}
  </div>

  <div>
    {:W('Test')}
  </div>
</body>
</html>

Lib/Widget/Test/test.html

<ul>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
</ul>

这个时候,编译出来的Widget模板大概是这样

<?php if (!defined('THINK_PATH')) exit();?><!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <h1>这是layout</h1>
  <div>
    <ul>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
  <li><a href="javascript:;">这是Widget中的内容</a></li>
</ul>

  </div>

  <div>
    <?php echo W('Test');?>
  </div>
</body>
</html>

Widget模板编译的时候被填充在了Layout的{__CONTENT__}中,下面W('test')的Widget调用依然存在。于是发生死循环没有报错页面一片空白,逐行调试了好久才找到问题。
解决方法:在 Lib/Widget/Test/test.html 开头添加一行{__NOLAYOUT__}

2. Widget的调用方式和传参。
我参考的是官方3.1.2的手册,手册上的示例是{:W('ShowComment')},大意是调用ShowComment得到返回的内容。在 Action 中使用 $widgetContent = W('ShowComment'); $this->assign('widgetContent',$widgetContent);但是$widgetContent的内容没有出现在模板变量{$widgetContent}出现的位置,查看函数时才看到W函数在默认情况下是echo出widget的内容。模板中正确的调法是{~W('ShowComment')},如果只是要取到Widget的内容应该使用W('ShowComment',array(),true);。

ThinkPHP用Behavior扩展Layout

ThinkPHP新版的模板引擎添加了layout试用了下layout功能还是蛮强大的,但还是用法还不太灵活需要在配置文件中手动指定。自己用Behavior做了一个小功能来扩展layout,在Action类中指定$layout属性的值即可自动启用layout,也可以在单个Action方法中设置layout的值,设置为空值时不启用layout。

1. 创建ActionEx
文件:Lib/Model/ActionEx.class.php

<?php
  class ActionEx extends Action {
    public $layout;
    public $_runViewAssist;

    // 初始化动作绑定
    public function _initialize() {
      ActionEx::action($this);
      add_tag_behavior('view_begin','ViewAssist');
    }

    // 暂存action
    static public $_action;
    // 获取action
    static function action(&$action = false) {
      if ($action) {
        self::$_action = $action;
      }
      return self::$_action;
    }

  }
?>

2. 配置自动加载路径
在Conf/config.php中添加 'APP_AUTOLOAD_PATH' => '@.Model', 将Model添加到自动加载路径。

3. 添加Behavior
Lib/Behavior/ViewAssistBehavior.class.php

<?php
  class ViewAssistBehavior extends Behavior {
    protected $options = array();

    public function run(&$params) {
      $act = ActionEx::action();
      if (!$act->_runViewAssist) {
        $act->_runViewAssist = true;
        if ($act->layout) {
          C('LAYOUT_ON', 1);
          C('LAYOUT_NAME', $act->layout);
          // var_dump($act->layout);exit;
        }
      }
    }
  }
?>

4. 测试Layout
Lib/Action/TestAction.class.php

<?php
  class TestAction extends ActionEx {
    public $layout = '_layout';
    public function index() {
      $this->display();
    }

    public function test2() {
      // 禁用layout
      $this->layout = '';
      $this->display();
    }
  }
?>

Tpl/_layout.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <h1>这是layout</h1>
  <div>
    {__CONTENT__}
  </div>
</body>
</html>

Tpl/Test/index.html

<h3>这是action中的内容</h3>

Tpl/Test/test2.html

<h3>test2</h3>

分别访问localhost/Test/index和localhost/Test/test2可以看到启用layout和未启用layout界面。

附:
文件目录

| | |~Common/
| | |~Conf/
| | | `-config.php
| | |~Lang/
| | |~Lib/
| | | |~Action/
| | | | |-IndexAction.class.php
| | | | `-TestAction.class.php
| | | |~Behavior/
| | | | `-ViewAssistBehavior.class.php
| | | |~Model/
| | | | `-ActionEx.class.php
| | | `~Widget/
| | |+Runtime/
| | |~Tpl/
| | | |~Test/
| | | | |-index.html
| | | | `-test2.html
| | | `-_layout.html
| | `-index.php

启用Layout和禁用Layout的截图


相关链接
ThinkPHP官网:http://www.thinkphp.cn/
 

自用的两个vim函数Tab/Space互转和Tab键补全

1. Tab和Space转换函数,expandtab和rettab的组合运用。命令:ToTab,:ToSpace分别转换当前文件到tab缩进和space缩进。

" --------------------------------------------------
" [空格与制表切换] {{{
" --------------------------------------------------
fu! ToggleTab(t)
    if a:t == 'tab'
        setl noet
        ret!
    elsei a:t == 'space'
        setl et
        ret
    en
endf
com! -nargs=0 ToSpace call ToggleTab('space')
com! -nargs=0 ToTab call ToggleTab('tab')
" }}}

2. Tab键补全,这个是以前网上的配置里面摘出来的。用惯了Tab键补全,C-p、C-n实在不习惯。函数做了简单的判断,在字母后面为补全,其它地方为Tab键。后面了加一个Shift+Tab的强制Tab键映射,在任何情况下都能键入tab。

" --------------------------------------------------
" [自动完成函数] {{{
" --------------------------------------------------
" 自动完成
fu! InsertTabWrapper()
    let col=col('.')-1
    return (!col || getline('.')[col-1] !~ '\k') ? "\<TAB>" : "\<C-P>"
endf
" 映射键
ino <TAB> <C-R>=InsertTabWrapper()<CR>
" 强制TAB键
ino <S-TAB> <C-R>="\<TAB>"<CR>
" }}}