二月, 2005 的文章
[FALCOM]新作イース-フェルガナの誓い- THE OATH IN FELGHANA!!!

![]()
イース-フェルガナの誓い- THE OATH IN FELGHANA
介绍几本 PHP 书籍和一些 PHP 相关资源链接
本文链接:
http://www.openphp.cn/index.php/article/13/167/index.html
Programming PHP
原书名:Web Database Applications with PHP&MySQL
原书名:PHP Developer’s Cookbook
原书名:Core MySQL:The Serious Developer’s Guide
原书名:JavaScript:The Definitive Guide,Fourth EditionPHP Blog
Personal Blog
Aaron Wormus : http://www.wormus.com/aaron/
Adam Trachtenberg : http://www.trachtenberg.com
Andrei Zmievski : http://www.gravitonic.com
Avenger : http://blog.phpe.net
Bitflux : http://blog.bitflux.ch
Binzy Wu : http://0926.net/blog/
Chris Shiflett : http://shiflett.org
David Sklar : http://www.sklar.com/blog/
Derick Rethans : http://derickrethans.nl
George Schlossnagle : http://www.schlossnagle.org/~george/blog/
EasyChen : http://blog.ibkmk.com
Harry Fuecks : http://www.sitepoint.com/blog-view.php?blogid=9
HaoHappy : http://blog.csdn.net/haohappy2004/
Ilia Alshanetsky : http://ilia.ws
James Cox : http://imajes.info
John Coggeshall : http://blog.coggeshall.org
Justin Wu : http://www.phpsalon.com
Marco Tabini : http://blogs.phparch.com/mt/
Martin Fowler : http://martinfowler.com/bliki/
Miguel de Icaza : http://primates.ximian.com/~miguel/activity-log.php
phpComplete : http://phpcomplete.com/
Rasmus Lerdorf : http://lerdorf.com/
sebastian : http://www.sebastian-bergmann.de/blog/
ShenKong : http://blog.csdn.net/countstars/
Sterling Hughes : http://www.edwardbear.org/serendipity/
Wez Furlong : http://netevil.org
PHP Website
PHP Official Site: http://www.php.net
Online Manual: http://www.php.net/manual/zh/
Smarty Template Engine: http://smarty.php.net
PEAR: http://pear.php.net
PECL: http://pecl.php.net
PHP Snapshots: http://snaps.php.net
PHP-GTK: http://gtk.php.net
DataBase Site
MySQL Official Site: http://www.mysql.com
SQLite Official Site: http://www.sqlite.org
PostgreSQL Official Site: http://www.postgresql.com
PostgreSQL Chinese Site: http://www.pgsqldb.org
Scripts Site
PHP Classes: http://www.phpclasses.org
PHP code exchange: http://px.sklar.com
Softwares Download
PHP: http://www.php.net/downloads.php
PHP Manual: http://www.php.net/download-docs.php
Apache: http://httpd.apache.org/download.cgi
MySQL: http://dev.mysql.com/downloads/
SQLite: http://www.sqlite.org/download.html & http://pecl.php.net/package/SQLite
Other Resource
Sitepoint: http://www.sitepoint.com
PHP Hub: http://www.phphub.com
Zend: http://www.zend.com
Open Source Web Development: http://www.devshed.com
PHP Freaks: http://www.phpfreaks.com
PHP Builder: http://www.phpbuilder.com
WeberDev: http://www.weberdev.com
PHP Editor Review: http://www.php-editors.com
本文链接:
http://www.openphp.cn/index.php/article/13/167/index.html
[仓木麻衣]Love,needing…
What’ up!
皆さんこんにちは☆倉木麻衣です!
ついにNew Singleをリリースしましたぁ~(^O^)/
約8ヵ月振りのSINGLEなのですが、久々にLoveSongを歌いました。今回は《愛》がテーマなのですが、最近本当に周りの方々の《愛》に支えられているなぁ(∪o∪)。。。と思っています。《愛》というのは、単に恋愛だけでは無く、家族を想いやる気持ちや、友達を想う気持ち。職場での協力も《愛》だと思っています。タイトルでもある『Love,needing』は『愛が必要』という意味ですが、皆さんの心の中での《愛》や、大切な人との《愛》などを、今回の楽曲から感じて頂けたら嬉しいp(^ ^)qです。
沢山の感想を
剧场版 网球王子!
劇場版「テニスの王子様 二人のサムライ THE FIRST GAME」

|
選ばれし者たちだけの銀幕(ステージ)! 絶賛公開中 リョーマの兄!?「越前リョーガ」出現! 青学テニス部メンバーが,豪華客船を舞台にした陰謀に巻き込まれる!! 洋上を進む,豪華客船.バカンスを楽しむ世界中のセレブ達にまじって,楽しそうな青学メンバーたちの姿.なんと,テニス好きの大富豪・桜吹雪彦麻呂の主催する船上特設コートでのエキシビジョンマッチに出場するため,招待されたのである. 翌日の試合に備えて,練習試合を終えた青学メンバーたちに,対戦相手となる桜吹雪自らが集めたスペシャル・チームの選手たちが歩み寄る.いつものように素っ気ないリョーマ.しかし,そんなリョーマに親しげに話しかける少年がいた.彼は”越前リョーガ”と名乗り,「リョーマの兄だ」と微笑みかけるのであった! 驚く青学メンバー.さすがにリョーマも,戸惑いを隠せなかった…. その夜,手塚と大石は桜吹雪の部屋に呼ばれ,明日の試合はわざと負けろという話を持ちかけられる.用意されたエキジビジョンマッチは,金持ち招待客たちが選手たちに大金を賭けて勝負させる闇のイベントだったのだ!掛け金を総取りし,大儲けするために協力しろと脅かす桜吹雪.当然,きっぱりと断る手塚だが・・・しかし,ここは海の上.桜吹雪の罠に,逃げ場のないリョーマたち青学メンバーが選んだ手段は…!? 作品紹介
映画情報関連リンク
|
推荐好书Windows游戏编程大师技巧(第二版)
| Windows游戏编程大师技巧(第二版) Tricks of the Windows Game Programming Gurus,2nd |
||||
![]() 评级: 阅读数:16267 |
作者:[美]André LaMothe 译者:沙鹰 出版社:中国电力出版社 图书分类: 程序设计 > Visual C++ 销售榜 版别版次:2004年2月第1版第1次印刷 ISBN书号:7-5083-1827-7
|
|||
内容简介:
本书是著名游戏程序设计类书籍作者André LaMothe的两卷本《Windows游戏编程大师技巧》中的第一卷的第二版。和作者撰写的其他畅销书一样,在书中随处可见许多有趣但又有一定难度的源程序。作者循循善诱地从程序设计的角度介绍了在Windows环境下进行游戏开发所需的全部知识,包括Win32编程以及DirectX中所有主要组件(包括DirectDraw、DirectSound、DirectInput和DirectMusic)。书中还用单独的章节详细讲授了2D图形学和光栅化技术、游戏算法、多线程编程、文本游戏和解析、人工智能(包括模糊逻辑、神经网络和遗传算法)、物理建模(完全碰撞反应、动量传递和正反向运动学)及实时模拟等游戏程序开发中的关键技术。光盘上带有两套完整的在线电子版书籍,内容涉及General 3D图形和算法以及Direct3D直接模式;此外,还有大量其他特约作者所著的关于游戏编程内容的文章。
光盘内容:
本书中所有程序的代码,还包括一个新的16位引擎
关于Direct3D和General 3D的文章和在线书籍
通用游戏编程工具以及3D引擎的评定版本
免费素材
完整的Microsoft DirectX SDK
Microsoft Visual C++入门版
RPG中游戏精灵的移动问题
作 者:胡海星
版权说明
[1] 此文章原刊载于2001年《程序员》— 第11期 — 编程擂台。
[2] 该文版权所有,未经《程序员》编辑部允许不得任意转载或摘编。
[3] 我们转载此文,已征得《程序员》编辑部及作者的允许。
1、问题描述
在RPG游戏中,经常要设计精灵的移动路线。例如,地图上有若干障碍物,游戏精灵在坐标(X0, Y0)。游戏玩家希望用鼠标点击了地图上坐标(X1, Y1),电脑应该自动控制游戏精灵走到点(X1, Y1)。玩家希望精灵能尽快的移动到目标点,所以电脑应该计算出发点(X0, Y0)绕过所有的障碍物到达点(X1, Y1)的最短路线。
现在我们将问题简化一下。在地图上有n个障碍物,这些障碍物都是水平或竖直放置的矩形,他们的左上角和右上角坐标已知,矩形障碍物之间可能重叠。游戏精灵看作一个半径为r的圆,其圆心坐标(X0, Y0)已知。现在要让精灵移动到点(X1, Y1),即让它的圆心和点(X1, Y1)重合。请编程计算出最短路径长度。
1.1、输入
输入文件名:rpg.in
第一行是6个整数:n、X0、Y0、r、X1, Y1,后面的n行每行有四个整数a、b、c、d,分别代表一个矩形障碍物的左上角X坐标,左上角Y坐标,右下角X坐标,右下角Y坐标。
1.2、输出
输出文件名:rpg.out
输出最短路径长度,精确到小数点后两位。
数据规模限制:
0 <= n <= 5000, 坐标点范围在[ -100000,100000 ]之间。
程序可执行文件名:rpg.exe
2、问题分析
这个问题是一个有着广泛的实际应用背景的问题,该问题来源于机器人学领域,在计算几何学中称为算法的运动规划问题。
为了解决问题,我们先考虑问题的一种的简单情形:障碍物是已知的若干矩形,但是要移动的精灵是一个点P,要将该点P从S移动到T,找出最短路径。可以看出,从S到T的最短路径应该是一条由线段组成的折线,如图1所示。折线的两端点或者是S,T,或者是障碍物的顶点。因此我们可以把出发点S和目标点T以及所有矩形的顶点看成无向图的顶点,如果从某个点可以“看到”另一个点,则在这两个顶点之间连一条边,边的长度就等于两个点的距离。然后采用单源最短路径的Dijkstra算法求解。
| 图1 |
下面考虑我们的这个问题。本题要移动的是一个圆,它和点不同之处在于圆心与障碍物之间的距离不可能超过圆半径r,否则就会出现重合现象。我们因此可以把圆收缩成一个点,把所有障碍物边界向外扩展r,这样就本题就转化成为同样是求点到点之间的最短路径问题了。
每个障碍物扩展后的边界就相当于把圆环绕该矩形移动一周后圆心所留下的轨迹,如图2所示。
| 图2 |
我们把任何一条出发点到目标点的路径看成一根线,那么对应于最短路径的这根线显然应该是“绷紧”的,如图3所示。“绷紧”的线有什么特点呢?
- 由于障碍物不存在“角”,所以这根线应该可以分解为圆弧和线段,且两者交替出现。
- 所有的圆弧都是紧贴障碍物的边。
- 任何一条线段必然与它两端的两个圆弧相切(见图3)
| 图3 |
由上述分析,我们有了这样一个想法:先求出所有的切线,包括出发点和目标点到所有圆弧的切线以及所有圆弧与圆弧之间的公切线,然后把这些切线看成是图中的顶点,给这些顶点赋一个等于切线长度的权值。如果某两条切线的两个顶点连一条边,边上的权值等于两个切点之间的劣弧长度。最后给这张地图加上一个源点和一个终点。在所有代表出发点到其他圆弧的切线的顶点与源点之间连一条边,边上的权值为0;同样地,在所有代表目标点到其他圆弧的切线的顶点与终点之间连一条边,边上的权值为0。这样,本题就转化为求源点到终点的最短路径问题了,这里的最短路径指的是经过所有顶点和边的权值之和最小。可用经典的Dijkstra算法求最短路径。
| 图4 |
由于我们求切线的过程中有可能碰到切点处于障碍物内部的情况,因此要判断每条切线段是否合法。首先检验线段的两个端点是否处于障碍物内部;其次检验该线段是否与原来正方形的顶点,到线段的距离是否小于R;三者中有一者成立就可判定该切线段不合法。
另外还有如图4所示的一种特殊情况。在图4中,两个大小相同的障碍物在同一竖直位置上。它们有2条内公切线,8条外公切线,但是其中有6条外公切线是重复的。因此我们作如下规定:如果一条切线与某段圆弧相切且切点不在端点上,则该线段为不合法线段,应删去。
下面估计一下这个算法的时间复杂度。假设有n个矩形障碍物,则圆弧之间的公切线有4?Cn2O(n2)条,也就是说图的顶点数为O(n2);求最短路径的时间复杂度为O(V2),其中V为顶点数目;整个算法的复杂度为O(n4)。
算法的实现细节,包括求点到圆的切线、圆与圆的公切线、点到线段距离、圆弧上两点间距离等,请读者自行参考解析几何的相关资料。
到此这个问题已经全部解决。这个问题在图论建模和算法实现上提出了较高要求,尤其是算法实现部分特别繁琐。这需要我们在编程时不急不躁,仔细地考虑每个环节,这同时也是对我们算法实现的基本功的考验。
深入A*算法 -浅析A*算法在搜索最短路径中的应用
目 录
1 A*算法的程序编写原理
2 用A*算法实现最短路径的搜索
在这里我将对A*算法的实际应用进行一定的探讨,并且举一个有关A*算法在最短路径搜索的例子。值得注意的是这里并不对A*的基本的概念作介绍,如果你还对A*算法不清楚的话,请看姊妹篇《初识A*算法》。
这里所举的例子是参考AMIT主页中的一个源程序,你可以在AMIT的站点上下载也可以在我的站点上下载。你使用这个源程序时,应该遵守一定的公约。
1、A*算法的程序编写原理
我在《初识A*算法》中说过,A*算法是最好优先算法的一种。只是有一些约束条件而已。我们先来看看最好优先算法是如何编写的吧。如图有如下的状态空间(起始位置是A,目标位置是P,字母后的数字表示节点的估价值):
![]() |
||
| 图1 状态空间图 |
![]() |
||
| 图2 节点图 |
先看搜索主函数:
void AstarPathfinder::FindPath(int sx, int sy, int dx, int dy)
{
NODE *Node, *BestNode;
int TileNumDest;
//得到目标位置,作判断用
TileNumDest = TileNum(sx, sy);
//生成Open和Closed表
OPEN=( NODE* )calloc(1,sizeof( NODE ));
CLOSED=( NODE* )calloc(1,sizeof( NODE ));
//生成起始节点,并放入Open表中
Node=( NODE* )calloc(1,sizeof( NODE ));
Node->g = 0;
//这是计算h值
Node->h = (dx-sx)*(dx-sx) + (dy-sy)*(dy-sy); // should really use sqrt().
//这是计算f值,即估价值
Node->f = Node->g+Node->h;
Node->NodeNum = TileNum(dx, dy);
Node->x = dx;
Node->y = dy;
OPEN->NextNode=Node; // make Open List point to first node
for (;;)
{
//从Open表中取得一个估价值最好的节点
BestNode=ReturnBestNode();
//如果该节点是目标节点就退出
if (BestNode->NodeNum == TileNumDest) // if we’ve found the end, break and finish
break;
//否则生成子节点
GenerateSuccessors(BestNode,sx,sy);
}
PATH = BestNode;
}
再看看生成子节点函数 GenerateSuccessors:
void AstarPathfinder::GenerateSuccessors(NODE *BestNode, int dx, int dy)
{
int x, y;
//依次生成八个方向的子节点,简单!
// Upper-Left
if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y-TILESIZE) )
GenerateSucc(BestNode,x,y,dx,dy);
// Upper
if ( FreeTile(x=BestNode->x, y=BestNode->y-TILESIZE) )
GenerateSucc(BestNode,x,y,dx,dy);
// Upper-Right
if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y-TILESIZE) )
GenerateSucc(BestNode,x,y,dx,dy);
// Right
if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y) )
GenerateSucc(BestNode,x,y,dx,dy);
// Lower-Right
if ( FreeTile(x=BestNode->x+TILESIZE, y=BestNode->y+TILESIZE) )
GenerateSucc(BestNode,x,y,dx,dy);
// Lower
if ( FreeTile(x=BestNode->x, y=BestNode->y+TILESIZE) )
GenerateSucc(BestNode,x,y,dx,dy);
// Lower-Left
if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y+TILESIZE) )
GenerateSucc(BestNode,x,y,dx,dy);
// Left
if ( FreeTile(x=BestNode->x-TILESIZE, y=BestNode->y) )
GenerateSucc(BestNode,x,y,dx,dy);
}
看看最重要的函数GenerateSucc:
void AstarPathfinder::GenerateSucc(NODE *BestNode,int x, int y, int dx, int dy)
{
int g, TileNumS, c = 0;
NODE *Old, *Successor;
//计算子节点的 g 值
g = BestNode->g+1; // g(Successor)=g(BestNode)+cost of getting from BestNode to Successor
TileNumS = TileNum(x,y); // identification purposes
//子节点再Open表中吗?
if ( (Old=CheckOPEN(TileNumS)) != NULL ) // if equal to NULL then not in OPEN list,
// else it returns the Node in Old
{
//若在
for( c = 0; c <8; c++)
if( BestNode->Child[c] == NULL ) // Add Old to the list of BestNode’s Children
// (or Successors).
break;
BestNode->Child[c] = Old;
//比较Open表中的估价值和当前的估价值(只要比较g值就可以了)
if ( g g ) // if our new g value is Parent = BestNode;
Old->g = g;
Old->f = g + Old->h;
}
}
else //在Closed表中吗?
if ( (Old=CheckCLOSED(TileNumS)) != NULL ) // if equal to NULL then not in OPEN list
// else it returns the Node in Old
{
//若在
for( c = 0; c<8; c++)
if ( BestNode->Child[c] == NULL ) // Add Old to the list of BestNode’s
// Children (or Successors). break;
BestNode->Child[c] = Old;
//比较Closed表中的估价值和当前的估价值(只要比较g值就可以了)
if ( g g ) // if our new g value is Parent = BestNode;
Old->g = g;
Old->f = g + Old->h; //再依次更新Old的所有子节点的估价值
PropagateDown(Old); // Since we changed the g value of Old, we need
// to propagate this new value downwards, i.e.
// do a Depth-First traversal of the tree!
}
}
else //不在Open表中也不在Close表中
{
//生成新的节点
Successor = ( NODE* )calloc(1,sizeof( NODE ));
Successor->Parent = BestNode;
Successor->g = g;
Successor->h = (x-dx)*(x-dx) + (y-dy)*(y-dy); // should do sqrt(), but since we
don’t really
Successor->f = g+Successor->h; // care about the distance but just which branch
looks Successor->x = x; // better this should suffice. Anyayz it’s faster.
Successor->y = y;
Successor->NodeNum = TileNumS;
//再插入Open表中,同时排序。
Insert(Successor); // Insert Successor on OPEN list wrt f
for( c =0; c <8; c++)
if ( BestNode->Child[c] == NULL ) // Add Old to the list of BestNode’s
Children (or Successors).
break;
BestNode->Child[c] = Successor;
}
}
哈哈。A*算法我懂了。当然,我希望你有这样的感觉。不过我还要再说几句。仔细看看这个程序,你会发现,这个程序和我前面说的伪程序有一些不同,在GenerateSucc函数中,当子节点在Closed表中时,没有将子节点从Closed表中删除并放入Open表中。而是直接的重新的计算该节点的所有子节点的估价值(用PropagateDown函数)。这样可以快一些。另当子节点在Open表和Closed表中时,重新的计算估价值后,没有重新的对Open表中的节点排序,我有些想不通,为什么不排呢?会不会是一个小小的BUG。你知道告诉我好吗?
好了。主要的内容都讲完了,还是完整仔细的看看源程序吧。希望我所的对你有一点帮助,一点点也可以。如果你对文章中的观点有异议或有更好的解释都告诉我。
本文附带的源程序(34KB)
SLG游戏之路径寻找
作 者:吴进
SLG游戏类的游戏可谓“棋盘式游戏”,如《三国志》一、四、五,机器人大战,梦幻模拟战等都是典型的SLG游戏。该游戏的一大特点就是:走格子。移动,攻击范围都是以格子为攻击单位。其实SLG游戏的特点远不止这些。在这里,实现一个给出移动力(MP),寻找可达路径程序。先看看我们要达到的效果:
![]() |
| 图1 |
在该地图中,画黄色框的为得到的移动范围。浅绿色的为草地,对NPC移动力影响为1,深绿色的为树林,对移动力影响为2;灰色的为山地,对移动力影响为3;蓝色的为河流,对移动力影响为9;这些都是在程序中定义的,可以自行修改。如水军就可以将河流的移动力影响设置为1,等等,这涉及到地图机制,现在不加讨论。现在关键的,就是这个移动范围是如何得来的,请继续看。
|
|
| 表1 |
为了显示该地图,我定义了一个地图文件,用文本编辑器打开看,它其实是一个数组形式(表1)。每一个数值对应该点消耗的移动力(MP)值,绘制地图也是以该表为依据。我将NPC的标记定义为b,看,标记b的点就是NPC人物所处的位置。而经过寻找路径的语句后,要导出一个输出范围表(表2),该表不仅要反映出NPC可以到达的范围,还要反映到达每点经过的路径。在该表每点数值的含义为:NPC到达该点后剩余的移动力点数。实际这就已经指出了到达每一点的最短路径(耗最少移动力)。不信,你按照这样的方法:
|
|
| 表2 |
将要到达的点作为当前点,找相邻的4个点中最大数值的点,将该点存如路径数组的第一单元,再以找出的点为当前点,找4个点中不在路径数组中的最大点,如此循环,直到找到数值最大的点为止。这时该路径数组存放的就是到达指定点的最短路径。
要生成该输出范围表,要用到计算机算法的广度优先搜索,我对标准的搜索程序做了一个变形,得到了范围表的生成方案,用文字描叙为:
开始第一轮遍历…
将探索方向值设置为0。
遍历导出序列所有点非0点,依次尝试走方向:左、右、上、下。如果当前点MP值-探索点耗移动力值>=0,说明该点可达,查找导出序列,如果存在该点,判断按照从当前点出发计算的MP值是否大于导出序列,如果大于,说明从当前点出发更省移动力,将该点加入导出序列,并赋值为当前点MP值-尝试点MP值,并加大探索方向值,探索完所有点后,检查探索方向值,如果探索方向值为0,说明已再无探索点,即已达到最大范围,输出导出序列。否则进入下一轮遍历。





