2009年6月19日

BUG-01 脚本引擎部分 --词法分析&语法树生成

     摘要: 感谢水王的大力支持感谢各位仁兄的支持下面入正题 本脚本语言的上下无关文法如下: Script                           ...  阅读全文

posted @ 2009-06-19 11:21 whitech 阅读(655) | 评论 (0)编辑 收藏

2009年6月6日

AMP, phplib template使用心得

主要讨论侧边栏

很多网站主体右侧,都会有一个侧边栏。譬如友情链接之类什么的,每个页面都有,而且重复。
这里讨论一个处理动态侧边栏的解决方法(动态就是会根据数据库更新的意思)。

主体方法如下:
 $tpl->set_file("link_link","link_link.html");
 $tpl->parse("link_area","link_link",true);
第一句是把侧边栏的页面读入,第二句是把侧边栏放到页面{link_area}处。

咋一看好像很简单,其实真的很简单。

这里贴一个刚做的网站的其中一个侧边栏的代码:


html页面最终侧边栏:

                <div class="cb_link" align="left">
                    
<table width="100%" cellspacing="0">
                        {link_area}                
                    
</table>
                
</div>

配对的php页面最终关于侧边栏的所有代码:

setLinkBlock($tpl);
setMovieBlock(
$tpl, $progid);
setMsgBlock(
$tpl, $progid);

这个页面的侧边栏共有三层,友情链接+movieblock+msgblock

经过服务器解析的侧边栏:

<div class="cb_link" align="left">
                    
<table width="100%" cellspacing="0">
                        
<tr height="8" bgcolor="#a11f25"><td colspan="2"></td></tr>
<tr><td align="left" height="28" colspan="2"><b><a>&nbsp;友情链接</a></b></td></tr>
<tr><td align="left" class="mt2" colspan="2"><a>&nbsp;1231321</a></td></tr>
<tr><td align="left" class="mt2" colspan="2"><a>&nbsp;那啥</a></td></tr>
<tr><td align="left" class="mt2" colspan="2"><a>&nbsp;还是那啥</a></td></tr>
<tr><td>&nbsp;</td></tr>
<!--last program block -->
<tr height="8" bgcolor="#a11f25"><td colspan="2"></td></tr>
<tr>
    
<td align="left" height="28"><b><a>&nbsp;近期节目</a></b></td>
    
<td align="right"><href="prog_list.php"><img src="./templates/images/more.png" /></a></td>
</tr>

<tr><td class="mt2" align="left" colspan="2">
    
<href="prog_article.php?issue=d9f17e4d8460bb463bddff33ad4075e0"><b>[第3期]</b>fffffffffffffffffffffffffffff</a>
</td></tr>

<tr><td class="mt2" align="left" colspan="2">
    
<href="prog_article.php?issue=8f274cca46324ceeb141e30d67d42488"><b>[第2期]</b>cccccccccccccccccccccccc</a>
</td></tr>

<tr><td class="mt2" align="left" colspan="2">
    
<href="prog_article.php?issue=f6cb2e20c5d965cefae00f52a44a6c27"><b>[第1期]</b>那个那个那个</a>
</td></tr>

<tr><td>&nbsp;</td></tr><!--this is the message blob -->
<tr height="8" bgcolor="#a11f25"><td colspan="2"></td></tr>
<tr>
    
<td align="left" height="28"><b><a>&nbsp;最新留言</a></b></td>
    
<td align="right"><href="message_list.php"><img src="./templates/images/more.png" /></a></td>
</tr>

<tr><td class="mt2" align="left" colspan="2"><a>&nbsp;123</a></td></tr>
<tr><td class="mt2" align="right" colspan="2"><a>--<style="color:black;">游客</b></a></td></tr>

<tr><td>&nbsp;</td></tr>
                    
</table>
                    
                
</div>



想象一下,每个页面就这样几行就已经把侧边栏弄好了,那是多么干净。。


这里讨论侧边栏的其中一段的实现方式:
link_prog.html文件:

<!--last program block -->
<tr height="8" bgcolor="#a11f25"><td colspan="2"></td></tr>
<tr>
    
<td align="left" height="28"><b><a>&nbsp;近期节目</a></b></td>
    
<td align="right"><href="prog_list.php"><img src="./templates/images/more.png" /></a></td>
</tr>
<!--  BEGIN link_progblob -->
<tr><td class="mt2" align="left" colspan="2">
    
<href="prog_article.php?issue={progid}"><b>[第{issue}期]</b>{intro}</a>
</td></tr>
<!--  END link_progblob  -->
<tr><td>&nbsp;</td></tr>

这里已经是整个文件了,不需要<html>之类的文件头,因为是直接内嵌在表格里面的


php函数:

function setProgBlock($tpl) {
    
$tpl->set_file("link_prog","link_prog.html");
    
$proglist = listProgram($page, 5);
    
$tpl->set_block("link_prog", "link_progblob", "pb");
    
$tpl->set_var("mb");
    
while(!$proglist->EOF) {
        
$tpl->set_var("progid", $proglist->fields['PROGRAM_ID']);
        
$tpl->set_var("issue", $proglist->fields['PROGRAM_ISSUE']);
        
$tpl->set_var("intro", substr($proglist->fields['PROGRAM_INTRODUCTION'],0,64));
        
$proglist->moveNext();
        
$tpl->parse("pb", "link_progblob", true);
    }
    
$tpl->parse("link_area","link_prog",true);
}



有了以上的基础,就可以在php页面里面调用 setProgBlock($tpl) 来设置侧边栏了

假如侧边栏有几层(友情链接+最新留言+。。。),一样调用

其实这里还有个问题懒得改,就是把html里面的侧边栏区域{link_area}也作为变量输入setXxxBlock,这样才比较好看。

注意:每个php函数里面,
 $tpl->set_file("link_prog","link_prog.html");处变量名需要设置为不同,否则会出错。
于是就搞定了

有了很nnd干净的侧边栏html页面和php页面,最最重要,侧边栏修改时不再需要每个页面改了。






posted @ 2009-06-06 17:27 whitech 阅读(203) | 评论 (0)编辑 收藏

2009年5月7日

关于三维场景八叉树的初步想法

今天建冰跟我提起了一个很有意思的东西:八叉树

把一个立方体切三刀,横一刀,竖两刀(按坐标轴的方向切),就变成8个边长为一半的立方体。再切一次小立方体,在分成8块。。。
一直往下递归,这就可以使用一个八叉树储存。

八叉树储存的好处:
1.在没有东西的立方体,就不用再往下切,能节省储存空间,运算资源
2.管理方便,搜索某一个小方块的时候,能很方便的使用二分法查找
3.深度到一定层次以后,基本可以拟合所有的三维模型。

对八叉树的使用的初步想法:
        首先,对一个三维游戏的空间来说,z维的使用远比x、y维少。若x、y维使用范围是0-1024,z维用到128就足够了(当然这是在地面游戏的基础上,不包括空战)。
        所以,为了减少八叉树的层次,我们可以对八叉树做一点点扩充:第一层不作为八叉树的分叉储存,储存一个平面。这是一个由立方体拼成的平面。大家可以想象一下平面拼起来的麻将。从第二层开始,就是真正意义上的八叉树,第一层平面上的每一个立方体,都是八叉树的根节点,然后往下细分。假如场景需要为1024*1024*128,这只需要第一层4*4的立方体,然后每个立方体对应7层的八叉树即可。对比起全八叉树,只能形成1024*1024*1024的空间,需要10层的八叉树,节约了3层。

         其次,对于场景里面的物体操作。
         物体可以用一个小八叉树储存(八叉树again),当然这个八叉树的层次会少很多,最多不过5层。在场景中,以某一个元点(譬如八叉树的最左叶节点)作为场景的定位,然后判断与场景相交,只需要一个矩阵的乘法运算即可。效率很高
        
         当然,八叉树的相交会存在一定问题。在我暂时能想到的范围里,由于八叉树的储存不完全是以元点为单位的,会有很多节点没有延伸到最底层(当然这个最底层是必须为定义好的有限层),取相交矩阵的时候,必须把其延伸到最底层,才能取出这个矩阵(或者用一些特殊算法取)。这还是在一个物体的情况下。当有多个物体的时候,两种解决方法:其一,把物体的占用空间存进场景八叉树,这样每个物体的占用空间场景都知道,只要在场景空间里面判断是否有交集即可。其二,以相对坐标的形式,遍历两个物体相交的元点是否有重叠占用。



posted @ 2009-05-07 13:51 whitech 阅读(1941) | 评论 (1)编辑 收藏

2009年4月8日

继续物理引擎--问题暴露

搁置了一段时间,想了不少东西,也发现了不少问题。

第一:只扫描一遍,功能有所欠缺。解决方案一,使用两遍扫描,第一遍扫描只做碰撞检测,记录状态。第二遍扫描才计算其速度、更新位置等

第二:运动的冗余。当前运动的方式写在BPhyBall里,当我尝试添加BPhyTriangle时,发觉线性运动的大部分函数都是可以直接从BPhyBall里面照搬过来,这是设计模式上的缺陷。

暂时到这里。陆续更新。

posted @ 2009-04-08 00:15 whitech 阅读(193) | 评论 (0)编辑 收藏

2009年3月10日

试验性物理引擎(续)

今天主要记录一些跟物理性质关系比较大的细节问题,有时候细节问题是很重要的,很多bug就在这些问题里。

首先一个,reflash函数内部的处理次序问题,究竟是先算速度,还是先算力
 1void CBall::reflash()
 2{
 3    velocity.positivation();
 4    /*
 5    if(velocity.degree > maxVelocity)
 6    {
 7        velocity.degree = maxVelocity;
 8    }
 9    */

10    /*
11    else if(velocity.degree < 0.01)
12    {
13        velocity.degree = 0;
14    }
15    */

16    if(velocity.degree > 0)
17    {
18        CVector griftForce(velocity.x * (-1), velocity.y * (-1), 1);
19        griftForce = griftForce * (gravity * Qgrift * Qgroundgrift);
20        griftForce.degree += velocity.degree * velocity.degree / 1000;
21        //force = force + griftForce;
22        velocity.degree -= griftForce.degree/gravity;
23        if(velocity.degree < 0)
24        {
25            velocity.degree = 0;
26        }

27    }

28    if(fabs(force.degree) > 0)
29    {
30        velocity = velocity + force/gravity;
31    }
    
32    velocity.positivation();
33    if(velocity.degree > maxVelocity)
34    {
35        velocity.degree = maxVelocity;
36    }

37    velocity.standarlization();
38    double tx = x;
39    x += velocity.degree * velocity.x;
40    y += velocity.degree * velocity.y;
41    force.reset();
42}
这是最新版的ball->reflash函数。是经过了几次轮回尝试得来的。来之不易啊。。。
在这里,每一帧先算摩擦,然后是受力,最后才是速度。这样,每一帧结束后,球所保存的速度就是当前速度。上一个版本忘了怎样的顺序,出了个当速度很小的时候(应该是受力平衡而且运动很慢的时候),每一帧结束后速度总为0,但又总是能动的错误。

接下来是一个关于重叠的问题。
计算机是离散的,只能模拟连续,这是问题的根源。
举个例子,当在某一帧里,两球的距离为2,但径向的相对速度为8的时候,你应该怎样判断?假如判断为不碰,下一帧两球将会有6个像素的重叠区域,判为碰,两球其实还没碰到。
问题提出来了,我的解法是,当距离小于径向相对速度的一半判为碰。否则不碰。原因比较简单,也比较复杂,反正用起来是不错。
当然需要一个重叠的修正函数,参考水王的话“重叠的时候,用一种看起来正常的方法分开就可以了”,于是,我就直接把两个球的坐标重置。往径向位移一点就行了,根据重叠的程度。在运动中,这是看不出来的重置。

还有问题,是两球相对速度为0时候的碰撞。严格说这不算碰撞,但这里有一个力传递的概念。假如不管这个力,如果某球在下一帧受到作用力,在碰撞检测的时候,两球无速度,但到刷新的时候,速度出现了!就会产生一个重叠至穿越的bug。也许会说把刷新和碰撞检测的顺序调换,没试过,从逻辑上讲,我觉得行不太通,说不明白。

说实话,穿越这个bug我到现在还没能完全修正。由于出现几率较小,还是放着先吧。

再来一个细节,牵引力的问题。
把代码贴出来就行了。
void CBall::tract(CVector d)
{
    
if(fabs(velocity.degree) > 0)
    
{
        CVector rg 
= velocity & d;
        d.degree 
= (1 + rg.degree / velocity.degree) * gravity * Qgrift * Qgroundgrift;
    }

    
else
    
{
        d.degree 
= gravity * Qgrift * Qgroundgrift;
    }

    push(d);
}
看到了,不是单纯的使用摩擦力推进就可以。要先把牵引力方向的摩擦力中和掉。。

posted @ 2009-03-10 16:22 whitech 阅读(269) | 评论 (0)编辑 收藏

2009年3月8日

试验性物理引擎(未完成版)

     摘要: 花了差不多一个星期写的试验性的碰撞物理引擎还是试验性阶段,只有球和线段首先为了统一接口,定义一个 物理实体类 CEntity,存些最简单关键的东西譬如坐标,碰撞系数,可动性等等,还有一个比较重要的参数,是实体类型(球,线段,或者以后加上的什么东西)接下来就是球和线段的实现了。当然,有了实体类,球和线段就要继承实体了。在这个引擎里面,由于线段基本都被当障碍使用,所以线段暂时是不可动的,只存几个参数:...  阅读全文

posted @ 2009-03-08 22:18 whitech 阅读(350) | 评论 (1)编辑 收藏

仅列出标题  
<2024年10月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(1)

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜