最后更新于 .

此文之前首发于雷锋网,所以自己的博客上就晚了几天才放上来。跟大家分享一下自己开发手游的过程,希望对大家能有所帮助~


谨以此文献给与我同样有创业梦想的程序员们.

我相信像我一样的程序员一定大有人在,一个人、一身技术、一腔热血,想要涉足手游领域,却不清楚会投入多少。

所以,我把自己的这次游戏开发过程,完整记下来,给与我同样的程序员以参考。

4月1日

《保卫妞妞》正式立项,当然说是立项,其实就是我一个人而已 。

既然决定要做,就要调查一下可能用到的技术点,说下我的背景,有5年左右的c、c++开发经验,3年左右的python开发经验,多年web开发经验,但就是没有游戏开发经验.

之前也只是简单了解过一点objc,根本没有实战过。而更要命的时候我都不知道开发游戏需要什么库和工具. 所以大体搜了一下,貌似cocos2d很多人推荐,那就先看本介绍的书吧

4月1日~4月3日

将《learn cocos2d on iphone》这本书看完,不过这本书用的cocos2d版本是0.99,而我后来游戏中使用的是cocos2d 2.x,所以后来发现很多代码不能用还是很痛苦的.

之前说过objc也没怎么用过,所以看这本书的时候,就基本把主要例子都敲了一遍。因为之前也有c基础,所以倒也不是很困难。

看完这本书 ...

最后更新于 .

写在前面: 博客很久没有更新了,主要是事情实在太多,不过最近也确实做了些比较有价值的事情,后面和大家慢慢分享

笔者在腾讯主要负责开放平台openapi的工作,由于工作关系,这几天遍历了 百度、人人、新浪、淘宝 4个平台,研究了一下他们对于站内应用、网站登录、移动应用的整合方式,并开发了一个百度站内应用的demo。

百度站内应用demo: 体验地址(要体验的话,请先联系我开通白名单): http://app.baidu.com/app/enter?appid=385894&debug=1&is_from_dev=1&canvas_pos=platform

代码已经开源在github上: https://github.com/dantezhu/baidu_app_demo,里面封装了一个baidu的sdk,有需要的朋友可以直接拿去用。

开发语言用的是 python+flask 移动应用 和 网站接入,这两种接入都是走的oauth的方式,这个基本所有平台都是一样的。

而对于站内应用则和腾讯目前不太一样,所以着重说明一下在这里的处理,仅以百度举例:

百度的教程在这里: 百度站内应用开发文档

1. 当用户点击应用列表进入时 ...

最后更新于 .

离上一次写博有点久了,留言也回复的比较慢,主要事情确实有点多,今天想想还是把这篇给写了吧,可能有点乱。

先说说最近折腾了些啥 部分开源项目的代码从googlecode迁移到github,其实还是主要是svn和git的原因,因为公司一直是用svn,所以对svn会熟一些。

不过最近发现越来越多的项目都在使用github,所以免不了好奇起来,本着越是抵触越是要搞的心理,硬着头皮总算懂了些皮毛。

之前还对git的分布式代码管理没什么感觉,这几天恰巧去上海参加chinajoy,网络时好时坏,svn一直不能ci,这才怀念起git的好来。

所以目前的结论就是,两者都用着,新项目就统一往github上迁移了。

研究了一下bootstrap from twitter,这个号称能让开发人员写出漂亮页面的前端库真心不错,把页面用12个栅格来表示,之前从没想过页面可以这样规划(好吧,也可能是我孤陋寡闻。。),而且支持交互式布局,做出来的界面都iphone、ipad等移动设备都会自动适应,的确是后台开发写前端的一大利器,超赞!

OK,碎碎念结束,接下来还是分享一段代码吧。

关注本博的朋友应该会了解之前我在python的微框架使用flask还是bottle之间选择了很久,现在无论如何,事实就是我多的在用flask,原因就不扯了,反正也扯不清楚。

这里主要是分享一点,无论是django,flask,bottle 都有一个通过 endpoint 生成 url的函数,在django中是reverse(模板中是url),flask是url_for,bottle中是url ...

最后更新于 .

这篇文章写的比较晚,主要也是要真正用起来才会发现,django1.4的这次升级在项目目录结构,配置文件上都有比较多的调整,恰好这次也受这样的困扰,所以就拿出来和大家分享一下。 django1.4增加了一个很重要的目录: static,在之前,django的所有静态文件都是放在media目录下的,但是同时用户在后台主动上传的文件也会放到这里,所以会引起一些不必要的混乱. 而且在之前的版本种,django的admin会霸占/media的路径,导致我之前不得不在配置里面强制修改一下:

ADMIN_MEDIA_PREFIX = '/admin_media/'

或者让网站自己的静态文件路径使用的别的前缀:

MEDIA_URL = '/site_media/'

对应的nginx.conf也要做一些相应的配置,对于之前版本相关的内容,这篇文章就不做赘述了,有兴趣的朋友可以去我之前写的博文看一下: linux下nginx+python+fastcgi部署总结(django版),PS:当时还没用uwsgi,大家将就一下。。 回到我们说的django1.4的变更,增加的static目录用来存放网站需要的静态文件,如css,img等,而/media目录用来存放用户上传的文件,admin使用的静态文件是放到/static/admin下。 这样的调整是要比原来合理很多,但同时nginx.conf的配置也需要做响应的变更,如:

server {
    listen ...

最后更新于 .

前段时间有朋友在微博上@我推荐了一款vim的插件,用来显示对齐线,感觉效果不错,就给大家推荐一下.

下载链接: Indent Guides

截图如下:

1

一. 安装

不用多说,直接解压放到vimfiles or .vim下

二. 配置

基本可以不用配置,不过由于默认的对齐线宽度太宽,不太美观,所以我改成1了,如下

let g:indent_guides_guide_size=1

详细的配置,可以参看他的文档,这里不再多说

三. 使用

默认的键盘映射是

<mapleader>ig

OK,插件就介绍到这里,其实如果只是单纯的介绍插件,就不用写这篇文章了。

我在用这个插件的时候,又发现了另一个需求,即标尺的功能。vim7.3里面默认提供了colorcolumn,例如执行:

:set cc=80

就可以高亮第80列,效果如下:

1

但是有时候我们想看一下几行的字符是不是在同一列上时,手工去输入列数实在太麻烦了,所以我就单独写了一个函数,来满足这个需求:

map ,ch :call ...

最后更新于 .

不是第一次写nginx的自定义模块了,之前有写过根据POST数据转发请求的模块(参见nginx自定义模块编写-根据post参数路由到不同服务器),不过上次写的是处理模块,而这次写的是过滤模块,还是有一些区别的。 在正式开始前,先说一下写nginx自定义模块要注意的几个点:

  1. 上次的文章提到,在函数里用r-connection.log打印log会core,今天发现是ngx头文件和lua头文件引用顺序的问题,把ngx的头文件放在最前面即可解决
  2. nginx的一个字符串类型 ngx_str_t 有两个参数, len 和 data,这两个参数一定要一起使用,因为data的\0结尾,不一定是len的长度,这一点千万要注意
  3. 需要和cpp文件联合编译是,在ngx的编译参数里面加上--with-ld-opt="-lstdc++"

OK,废话不多说,开始正式说我这次写的统计模块吧 需求背景呢,就是现在已经在nginx后面挂了很多服务器,需要用nginx来统计成功率,响应时间等等参数,在网上翻了半天,大部分居然是用access_log,然后用程序扫描$request_time来实现的,这对一个每秒几千次访问的服务器是不可忍受的,所以最终没办法,那就自己写一个呗~ 重新看了nginx自定义模块的开发文档,整个调用过程如下:

1

但是实在是没找到请求整个结束时的回调函数,最接近的也就是用filter模块了(即过滤模块),当然这样统计出来的请求时间,可能会比实际时间短一些。 OK,定了要写那种模块后,我们来考虑一下具体的实现

  1. 为了性能最大话 ...

最后更新于 .

之前对bottle做过不少的介绍,也写过一些文章来说明bottle的缺点,最近发现其实之前有些地方说的不太公平,所以趁此机会也来更正一下。

  • bottle是支持类似flask url_for的语法的,具体使用方法在下文介绍
  • bottle的request.query之类的参数默认是str类型,也是有原因的,比如我在给google做代理的时候,编码就不一定是utf8的,如果强制转化utf8就会报错
  • 之前的bug也得到了修正,比如mount('/x',app)之后,/x/和/x都可以访问到

OK,现在正式进入主题,我们来介绍一些bottle的一些高级使用

一. 智能创建url

这部分在bottle的文档上是没有介绍的(其实bottle明明实现了很多贴心的功能,不知道为啥都不写在文档上)。 在Bottle类里,有一个成员函数:

def get_url(self, routename, **kargs):
    """ Return a string that matches a named route """
    scriptname = request.environ.get('SCRIPT_NAME', '' ...

最后更新于 .

还是和往常一样,没啥主题,就是记录下这段时间遇到的技术问题,分享一下。

1. 在javascript中实现简单的模板替换

最近搞了一下js,最不习惯的就是字符串生成都要用字符串拼装或者join的方式,所以尝试一下看能否实现简单的模板替换,效果还不错。

function str_format(str, obj) {
    return str.replace(/\{\s*(\w+)\s*\}/g, function(_i, _1) {
        return obj[_1] != null ? obj[_1] : '';
    });
};

很多朋友会说性能差一些,可能确实如此,不过对我来说,相比编写的舒适来说,这点性能差别实在无足轻重了。

2. uwsgi报readv() faild

用uwsgi+nginx搭建的server,发现当用post请求时,会返回数据超时。查了一下uwsgi的error.log:

9825#0: *745262 readv() failed (104: Connection reset by peer ...

最后更新于 .

前段时间有博友在群里问了一个关于vim排序的问题,因为时间问题一直没帮忙解决,今天时间正好空出来,就帮忙搞了一下。 原文的问题如下:

vimuser 说:
2012年03月1日 于 5:04 下午  (编辑)
今天折腾了一下午,研究vim的排序,看了教程和搜索了一些文档,还是没弄明白,vim的正则表达式跟一般的又不一样,来请教下博主。

|1 | 11 | 111| 1111|
|2 | 22 | 222| 2222|
要根据第3个|和第4个|之间的列进行排序该如何写命令呢?

其实之前也只是简单的用过vim的sort命令,没有想过vim是否能完成如此复杂的排序,不过抱着试试看的态度,我看了一下sort的描述(:h :sort),其中一段话如下:

:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]

When /{pattern}/ is specified and there is no ...

最后更新于 .

nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器,然而当我们需要根据http包体来进行请求路由时,nginx默认的配置规则就捉襟见肘了,但是没关系,nginx提供了强大的自定义模块功能,我们只要进行需要的扩展就行了。 我们来理一下思路,我们的需求是:

nginx根据http包体的参数,来选择合适的路由

在这之前,我们先来考虑另一个问题: 在nginx默认配置的支持下,能否实现服务器间的跳转呢?即类似于状态机,从一个服务器执行OK后,跳转到另一台服务器,按照规则依次传递下去。 答案是可以的,这也是我之前写bayonet之后,在nginx上特意尝试的功能。 一个示例的配置如下:
server {
    listen       8080;
    server_name  localhost;

    location / {
        proxy_pass http://localhost:8888;

        error_page 433 = @433;
        error_page 434 = @434;
    }
    location @433 {
        proxy_pass http://localhost:6788;
    }
    location @434 {
        proxy_pass http://localhost:6789;
    }

    error_page ...