Archive for 十二月, 2012

利用JS+CSS去除网站绑定广告

星期日, 十二月 30th, 2012 76 views

应Eric同学邀请,出手帮忙去掉免费服务器的一个附带广告。广告如下,是一个右下角悬浮广告:

用火狐FireBug看了一下源码,该广告的代码如下:


(更多…)

cPanel主机500错误的解决方法

星期六, 十二月 29th, 2012 33 views

今天早上打开官网,出现如下字样:

The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, webmaster@flywin.cn and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

服务器500内部错误,第一反应是想要发邮箱给服务商让其重启。后来研究了下,怀疑是服务商更新了系统功能后产生了某些冲突。网上查了下基于cPanel的主机出现该错误的原因大致是权限问题。

进入cPanel->Legacy 文件管理器,看了下public_html的权限为750,于是修改成755,刷新一下还是500错误。怀疑是没有生效,于是修改为644之后,提示403错误浏览权限不足。再改回755后,网站成功访问。

具体原因不明,可能是服务器更新了新Mod安全规则而.htaccess未得到修改,网站出现500错误。
其他资料给出的建议大都是——文件夹权限要设置为755或者更低,文件权限要设置为644或者更低。
这里Mark一下,有朋友知道具体原因的可以留言讨论。

BeiTown
2012.12.29

Unity3D游戏开发之状态流框架

星期四, 十二月 27th, 2012 1,065 views

在制作Unity游戏时,通常我们可以充分利用其自身的特性来量身定做一系列开发框架。其中我们可以利用Unity中每一帧都会执行脚本中的一些默认函数如Update()、OnGUI()…的特性来设计一种针对Unity的框架——尚且称之为状态流框架。此类型框架在一些项目中都有见到身影,所以这里将其总结一下。

惯例,先上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public enum STATE
{
    START,PAUSE,OVER //枚举 开始,暂停,结束 三种状态
}

private STATE state = START;

void OnGUI()
{
    switch(state){
        case STATE.START:
            //此处添加游戏开始GUI绘制代码
            break;

        case STATE.PAUSE:
            //此处添加游戏暂停GUI绘制代码
            break;

        case STATE.OVER:
            //此处添加游戏结束GUI绘制代码
            break;
       
        default:
            break;
    }
}

我们可以利用枚举于switch结合来进行一个游戏状态的判断,脚本在游戏运行时会不断执行OnGUI()中的代码,此时只需要修改 state 的值即可针对不同的游戏状态绘制出不同的GUI界面。
(更多…)

Unity3D中Animation的初级使用方法及技巧

星期四, 十二月 27th, 2012 6,376 views

这一节说一下如何使用Unity的Animation编辑器控制GameObject的一些动画效果。并简述如何为Animation添加Event事件的方法。
首先,先创建一个Gameobject例子,这里我们还是Create 一个 Cube好了。


(更多…)

纯CSS右下角DIV浮动方法

星期五, 十二月 21st, 2012 85 views

做一个右下角浮动的DIV,之前考虑用JS来取浏览器高度,然后利用float:right; margin:浏览器.hight-DIV.height来做。但根本不需要这么复杂。

代码如下:

1
2
3
4
5
6
7
8
<div style="width:100px;
            height:100px;
            background-color:#fff;
            right:0px;
            bottom:0px;
            position:fixed;"
>
          TEST DIV
</div>

但此代码只在FireFox、Chrome及IE6以上浏览器下有效,要支持IE6则需要将position改成absolute

1
2
3
4
5
6
7
8
<div style="width:100px;
            height:100px;
            background-color:#fff;
            right:0px;
            bottom:0px;
            position:absolute;"
>
          TEST DIV
</div>

这个时候所有浏览器的效果都统一了,但是有一个弊端就是不会随着滚动条滚动。
所以如果需要精确控制DIV的位置,推荐的方案还是使用JS。

BeiTown
2012.12.21

Php页面header跳转的方法及错误矫正

星期五, 十二月 21st, 2012 44 views

因为准备架设双博客,所以把之前的技术博客移动到了网站根目录下的coder子文件夹,在WP后台修改了网站首页地址之后,Blog运行恢复正常。但是之前的一些外链比如 http://www.beitown.com/?p=420 此时无法链接到正确的文章页面。所以准备在根目录的index.php根据来路域名做一个判断及跳转。代码如下:

1
2
3
4
5
6
7
8
<?php
$url = $_SERVER['QUERY_STRING'];
if (stristr($url,"p="))
{
   //echo "url=:" . $url;
   header('Location:/coder/?'.$url);
}
?>

$_SERVER["QUERY_STRING"]表示查询(query)的字符串,浏览器通过http://www.beitown.com/?p=420地址访问index.php时,$_SERVER["QUERY_STRING"]的值为”?”之后的表达式,即p=420
通过stristr函数对url进行包含判断,如果含有表达式”p=”则进入相应的操作。
header函数意为跳转,使用方法参考demo

另外这里有一个错误介绍一下,如果在header前调用了echo会出现如下警告:

Warning: Cannot modify header information – headers already sent by….

解决办法是将echo去掉即可。
此时访问 http://www.beitown.com/?p=420将会跳转到新的文章页面即http://www.beitown.com/coder/?p=420中去。

BeiTown
2012.12.21

Unity3D自动匹配摄像机全方向公告板

星期三, 十二月 19th, 2012 125 views

项目需要在GUI上做一些特效,按道理应该是直接做2D序列帧动画,然后GUI播放的,但是介于美术实现的时间原因,决定用例子来做UI特效,但是目前遇到难题是GUI不能加载粒子。
所以决定运用公告板来虚拟一个UI,脚本代码如下:

FaceToCamera.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using UnityEngine;
using System.Collections;
using System;

public class FaceToCamera : MonoBehaviour
{
    public Camera _camera;
    public float _z = 5.0F;//纵深
    public float _x = 1.0F;//相对中心点x偏移
    public float _y = -1.0F;//相对中心点y偏移

    void Update()
    {

        _camera = Camera.current;//获取当前摄像机
        if (!_camera) return;

        transform.rotation = _camera.transform.rotation;//将对象角度与摄像机统一
        transform.position = _camera.transform.position;//将对象移动到摄像机当前位置

        transform.Translate(Vector3.forward * _z);//纵向推远,否则看不见
        transform.Translate(Vector3.right * _x);
        transform.Translate(Vector3.down * _y);

    }  
}

以上代码即可完成一个自动匹配摄像机的全方向公告板,即便摄像机来回切换Gameobject也会自动匹配上摄像机。唯一缺陷是该公告板不停刷新,可能会在某些极端情况下出现闪烁。

该Cube仅用于测试,此脚本适用于任意的Gameobject。

BeiTown
2012.12.19

Netty游戏服务器开发——利用Channel绑定机制 共享聊天服务器与逻辑服务器信息

星期二, 十二月 18th, 2012 2,702 views

因为工作原因,之前做的网游项目一直没有时间对其技术点做一个统一的整理,今天正好朋友问到了这个问题,所以顺便把之前项目中的方案贴出来供大家参考。
首先我们需要明白一些概念,我们所玩的网络游戏的服务器是一台大规模的收发兼处理工厂,与客户端交互的数据流如同一个个快递。
Netty的NIO机制保证了服务器与每一个客户端之间都有一条特快专线,即Channel,游戏中的各种交互性数据即是通过这个Channel进行收发的。

现在问题来了,我们假设玩家的战斗行走等信息都是一个个包裹,聊天喊话信息都是一封封信件,客户端与服务器交互时,这些数据都是在一条该客户端独有的Channel里的,无论服务器还是客户端对数据的读取都是顺序执行的,如果此时客户端在接受一个角色战斗信息(包裹)时,聊天窗口有大量的聊天信息(信件)发来,那么客户端需要先读取完排在角色战斗信息(包裹)之前的聊天信息(信件)然后再读取战斗信息,接着才进行相应动画处理,这样就会产生一个delay,影响战斗的流畅感。反之服务器的接收也是如此。

所以为了保证在聊天信息大量收发的同时,战斗及其他游戏信息能够快速被相应,我们需要为每一个客户端再开辟一个收发聊天信息的Channel,把聊天信息通道分离出来。因此需要另外开始一个Netty服务器,即聊天服务器。
架设完成之后你将会看到,每个客户端与服务器之间都产生了2个Channel,分别为包裹专线,和信件专线。并且这两个服务器的Port是不一样的,需要客户端分别进行2次的连接。

这个时候又产生了一个问题,如果此时玩家要发送消息给周围的玩家或是自己的好友,而这些人物的列表并不在聊天服务器上,而是在逻辑服务器上。那么怎样将信息传达到对应人的Channel上呢。
传统的方法可能是在聊天服务器上再复制一份好友列表,甚至周围玩家列表,并且两个服务器之间时刻进行通信,以保证数据的同步性;或者每次发送聊天信息时,调用缓存区的数据,通过目标ID遍历寻找到目标的Channel。

我们来简单分析下这两种方案的运算开销:

方案一中,同步包的心跳最长不得超过1s,否则可能会出现玩家体验上的不同步。那么每1s同步一次,OK,我们设1000个玩家,每1s需要同步1000个玩家的各种信息,当然这显然不现实。所以继续优化方案一,改为触发型同步,即当逻辑服务器上的数据更新后,立即发送该更新数据的同步包给聊天服务器。此时1000个玩家如果聚集在主城附近来回跑动,最频繁的更新当属周围玩家列表的更新,或者采用的是九宫格灯塔AOI(此区域管理算法另外开篇说明)机制不需要周围玩家列表,但仍旧需要不停的更新自己的区域坐标——仍旧是大量的同步包。
(更多…)

Unity3D粒子系统的使用

星期二, 十二月 18th, 2012 305 views

先从最简单的粒子特效做起,点击[GameObject]->[Create Other]->[Particle System],此时在场景中创建一个粒子系统。如下图所示:

选中场景中的粒子系统,点击[Component]->[Effects]->[Legacy Particles]->[Ellipsoid Particle Emitter] 以及 [Particle Animator] 为粒子系统实例分别添加粒子发射器和粒子动画器。
如下图:
(更多…)

大话人工智能(2)——“中文房间”理论以及AI的“看上去挺智能”

星期二, 十二月 18th, 2012 105 views

上篇文字说道AI的信息堆积,之后朋友提出了“中文房间”理论,这里科普一下,以下两段是摘录:

“中文房间”最早由美国哲学家John Searle于20世纪80年代初提出。这个实验要求你想象一位只说英语的人身处一个房间之中,这间房间除了门上有一个小窗口以外,全部都是封闭的。他随身带着一本写有中文翻译程序的书。房间里还有足够的稿纸、铅笔和橱柜。写着中文的纸片通过小窗口被送入房间中。根据Searle的理论,房间中的人可以使用他的书来翻译这些文字并用中文回复。虽然他完全不会中文,Searle认为通过这个过程,房间里的人可以让任何房间外的人以为他会说流利的中文。

解读:
Searle 创造了“中文房间”思想实验来反驳电脑和其他人工智能能够真正思考的观点。房间里的人不会说中文;他不能够用中文思考。但因为他拥有某些特定的工具,他甚至可以让以中文为母语的人以为他能流利的说中文。根据Searle,电脑就是这样工作的。它们无法真正的理解接收到的信息,但它们可以运行一个程序,处理信息,然后给出一个智能的印象。

类似理论的实践产品比如苹果的Siri就相当于本实验中封闭的房间,iPhone的话筒就相当于本实验中的小窗口,你对iPhone说的话相当于本实验中的写有中文的纸片,Siri程序虽然完全不懂中文,但是通过其内部程序,会让我们使用iPhone的人以为Siri领悟了我们的指令,并能和我们进行人性化的交流与沟通。

而实际上确实目前的人工智能并不能脱离这套理论。上一篇文字的信息堆积只不过将房间里的内置信息库变成了后天添加的内容——因为人类社会的信息量相当之庞大,我们不可能预先知道房间外面世界的改变并预先将所有信息存储进信息库(书柜)中。

但另一方面,这样的信息堆积是没有自主的联想机制的。比如你告诉机器1+1=2,它记住了,但它并没有1+2等于多少的信息。怎样才能通过1+1=2来推导出1+2=3呢?当然这个问题已经上升到数学界,著名的哥德巴赫猜想就一直致力于解释清楚这个问题。所以目前来说,人类世界的1+2=3也是通过后天强硬灌输的。只不过我们掌握了某一种规律,可以知道1+2=3,1+3=4以此类推。这种规律即是一种经验类信息源。
(更多…)