php 网页游戏开发入门教程一(webgame+design) |
本文标签:php,网页游戏开发 一、简单的程序框架 。 复制代码 代码如下: class Map//地图类 { var $Map_ID; function Map_bg_css($Map_ID) { $this->Map_ID = $Map_ID; mysql_select_db($db_name,$link); $sql="select * from map where Map_ID=".$this->Map_ID." limit 1"; $result=mysql_query($sql,$link); echo "<style type="."text"."/"."css>"; $rs=mysql_fetch_array($result); echo "#map{"; echo "position:absolute;"; echo "width:".$rs[X坐标]."px;"; echo "height:".$rs[Y坐标]."px;"; echo "z-index:0;"; echo "left:0px;top:0px;}"; } function Map_bg($Map_ID){ $this->Map_ID = $Map_ID; $sql="select * from map where Map_ID=".$this->Map_ID.""; $result=mysql_query($sql,$link); while($rs=mysql_fetch_array($result)) { echo "<div id=Layer_bg_".$rs[X坐标]."_".$rs[Y坐标].">"; echo "<img src=".$rs[Map_bg]." border=0 title=".$rs[ID]."></div>"; } } } 上面是一个很简单的地图类 。代码可能不太正确,意思是正确的 。就是根据map表中的坐标,生成了一组div层,以及这一组层的css 。 你可以改为table的 。你可以也把坐标放到一个字段里,用数组的形式取 。 使用的时候,用 new map; map(N); 其中N是map表里的地图Map_ID. 城市内的建筑也类似 。如果要显示出来的话 。 关于地图,现在我采用的方式更为简单 。通过坐标来判断需要哪些图,然后直接显示出来 。当然没有碰撞什么的,因为暂时不需要 。至于人物走动什么的,不在本文讨论范围 。 有了地图和城市后 。涉及到的问题就是城市里资源的产生 。 这时候,City表里需要有可供判断的时间和数量的字段 。 比如:产生资金量Money,产生资金花费的时间Action_Time,上次产生资金时间Money_time 。 这两个字段的数值应该在City_base表里出现 。(即城市基础表,不同等级,不同类型城市的对应数值 。这是给策划填数据用的,建好表后就等策划去头痛吧 。如果你身兼数职 。 。 。) 如何自动产生资源呢? 我们可以在城市所有人改变的时候,写入一个时间 。或者在城市初始化的时候写入一个时间 。 $Now_Time=date(Y-m-d H:i:s); (说明:$开头是变量的意思 。php里特有的 。如果是asp的话可以写成 。Now_Time=Now() ) 把$Now_Time写入到Money_time里 。 update("UPDATE City SET Money_time=$Now_Time WHERE City_ID=$City_ID LIMIT 1;"); $City_ID是你自己定义的 。指某一个城市 。如:$City_ID=1; 我们假定当前城市产生资金量为100 。即$Money=100;(具体的数值,应该是由City_base表里取出的 。) 假设间隔时间为$Action_Time,我们再假定是每小时执行一次 。即$Action_Time=3600;(具体的数值,是根据你的初始化表里取得的 。也可以根据城市等级或者用户等级取得 。反正随便你自己怎么设定 。) 这时候,有基础时间了 。有基础资金产量了 。有间隔时间了 。让它循环执行起来就行了 。 上面说过,服务端用C语言定时器 。客户端用javascript 。 服务端,资源定时器设定为5分钟执行一次 。那么我们的误差就是5分钟 。对网页游戏来说,可以接受 。(战斗的定时器得1分钟吧 。当然服务器够牛的话,几秒钟都可以 。) 当然,可以完全php写,然后配置php的corn 。现在我在做的程序就是直接用php写了 。包括任意长时间的定时器类,专门控制抽象事件用的 。C的定时器暂时没用 。 每次执行什么代码呢? 首先得新建一个定时器任务的表 。目的就是让定时器知道需要执行哪些程序和数据的更新 。表内容比如:城市资源更新 。当然,这个表可要可不要 。建立的好处是方便处理类似保护状态不产生资源之类的问题 。 服务端程序: 获得当前服务器时间 。 获得当前需要更新城市 。 判断服务器时间与$Money_time的时间差 。(时间戳,具体的时间戳网上资料满多的 。) 判断时间差是否大于$Action_Time 。 大于,则更新资源 。同时更新$Money_time 。 小于,则无操作 。 客户端程序: 获得当前服务器时间 。 获得当前城市的$Money,$Money_time,$Action_Time 。 使用javascript显示剩余时间的倒计时,以及增加的资源量 。 客户端特殊情况触发: 因为客户端显示的资源情况是伪同步,所以当客户端使用该资源的时候 。需要服务端将当前的实际资源更新,属于定时器处理的时间也需要更新 。 即,当客户端触发涉及资源的情况时,立即更新当前资源 。同时更新定时器中会用到的$Money_time 。这样才不会造成,看的资源用不到,或者定时器重复产生资源 。 总体来说 。这部分程序都很简单 。难点在C语言定时器的制作,以及前台javascipt倒计时的写法上 。 C语言定时器,找个C语言程序员,超简单;前台的javascipt,网上有很多倒计时的代码,找个来改改就能用 。 Code 复制代码 代码如下: <SCRIPT LANGUAGE="JavaScript"> var maxtime = 这里是你的时间差///一个小时,按秒计算,自己调整! function CountDown(){ if(maxtime>=0){ minutes = Math.floor(maxtime/60); seconds = Math.floor(maxtime%60); msg = "你的文字说明"+minutes+"分"+seconds+"秒";//动态显示剩余时间 。 document.all["timer"].innerHTML=msg; //if(maxtime == 3) document.all["timer"].innerHTML=只剩3秒!; --maxtime; } else{ clearInterval(timer); document.all["timer"].innerHTML=时间到; } } timer = setInterval("CountDown()",1000); </SCRIPT> <div id=timer></div> 这个是网上找的代码 。稍微修改就可以用的 。这里只是显示了倒计时 。也可以改为显示资源的增加情况 。 C语言里操作mysql数据库 。 Code 复制代码 代码如下: // TODO: Add your control notification handler code here bool bRes = m_dbConn.Connect("数据库ip地址", 3306 , "用户名", "密码", "数据库名"); if(!bRes) { AfxMessageBox("connect fail"); return; } string strSql = "select * from city limit 1";//所有显示或取值类的都用这段 。中间的sql语句可以自己构造 。 ResultSet* rs = m_dbConn.ExecuteQuery(strSql); while(rs->Next()) { string str = rs->GetString("username"); AfxMessageBox(str.c_str()); } /* strSql = "update city set money=money +100 where City_ID=xxx";//所有的增加、删除、更新都用这段,中间的sql语句可以自己构造 。 bRes = m_dbConn.ExecuteUpdate(strSql); if(!bRes) { AfxMessageBox("ExecuteUpdate fail"); } */ m_dbConn.Close(); 定时器的主函数 。 void CBeiLiDlg::Go() { while(true) { // AfxMessageBox("go"); Sleep(5*1000);//毫秒 。定时器刷新时间 。 } } 当然 。这里的C的代码不能直接用 。只是一部分 。 新的方法是,通过php定时器类负责前台、时间到后,调用ajax执行完成 。后台通过定时执行php定时器类的专用处理函数,处理前台掉线,前台未正常执行等情况 。 如果我们的新游戏今年年底能正常上线的话 。我可以公开这个类,没技术含量,但是很巧妙 。 地图、城市、基本上算是有了 。 接下来是城市里的建筑 。 上面讲的资源增加,其实定位在建筑上更准确 。不过建筑的分类和数值会复杂很多 。那是策划考虑的问题 。 建筑上,只讲一个前台的修建效果 。 当然,这个效果是可有可无 。你可以直接给个类似新闻列表的显示,再加个倒计时就行 。 显示的效果就是,点修建后 。不刷新页面,调入一张动画图片 。并在时间到后自动转换为其他图片 。 Code 复制代码 代码如下: <script language=javascript> function xiujian() { top.abc.document.getElementById(前台建筑位置所在图片的id).src=修建后建筑的图片地址; //显示修建后的建筑图片 。可以加上后台时间判断 。其中abc,是建筑所在层的id, } function xiujian1() { setTimeout(xiujian(),5000);//动画时间5秒 。这里也可以加入时间判断 。当时间不到的完成的时候,继续调用动画 。 } function donghua() { top.abc.document.getElementById(前台建筑位置所在图片的id).src=建筑动画所在的地址;//显示修建动画 。 } donghua(); xiujian1(); </script> 附带讲一下 。如果要考虑多浏览器兼容,那么用prototype.js 。如果只需要ff和ie 。那么用而jqury.js 或尽量自己写 。因为120k的prototype.js不算小 。 后台部分,把时间到,增加资源的代码,改为时间到,增加或更新建筑就行了 。又是增加N个表 。 。 新的方法是,增加事件子类 。 建筑基础表:产出,类型,图片等等 。 。 建筑详细表:属于哪个城市,可以在城市表里关联 。关联的方式不同会对程序有很大的影响 。各种关联方式都行,但是一旦关联方式确定后,最好别改动 。 现在建筑也有了 。用类似的定时方式,打工,征兵等等都可以实现 。 战斗, 兵的参数:兵种,数量,攻击,防御等等 。 战斗的临时表:谁的兵,打谁,出发时间,战斗时间,战斗结果 。 这里的几个字到是简单 。实际的表会复杂一些 。 webgame中,战斗的过程分两种,一种是给出双方参数,时间到,就根据公式计算结果 。一种是半即时或者即时的战斗,可以边打边喝药边用技能的那种 。 第一种流程 。 点出兵 。这时候,兵的参数,出发时间,到达时间,都记录进战斗临时表 。 定时器中,处理战斗的部分,判断时间是否到开打的时候 。到开打的时间了,则取得被攻击方的兵的参数 。然后通过几个公式计算结果 。处理结果,比如谁的兵挂了多少,战场掉落了多少钱,城市被谁抢到了 。一大堆判断以及updata 。(这里的定时器处理和获得资源的定时器处理是很类似的 。) 最后把结果分别发给双方 。(又涉及到一个短信息系统 。) 第二种流程 。 点攻击 。马上就处理数据 。打打npc好做 。玩家之间对战,也可以把被攻击的玩家当成npc来处理 。 两个人或两人以上即时战斗 。需要用到ajax了 。目前在技术上和理论上是没问题的,还没实际写代码,所以不好讲 。 现在,技术上已经确定可以很好的实现了 。 很简单的公式,两种战斗都可以用到: intval(sqrt($User_B_AP)-sqrt($User_A_DP)); 根号下攻击-根号下防御=伤害 。 具体写的时候,公式肯定会复杂不少,不过这头痛的事,还是交给策划去做吧 。 战斗的具体参数,其实已经不是程序考虑的了 。 程序只需要考虑从数据表A取得数据,存入临时表B 。然后当时间到了后(通过定时器实现),再从数据表C取得数据,通过公式计算,最后删除临时表B或者把临时表B存到另外一个地方备份 。 这里的思路其实就是定时器类 。 数据是哪些?找策划要 。有几个表?找策划要 。战斗公式?找策划要 。 有地图、城市、建筑、士兵、战斗后,道具的出现就有必要了 。 为什么呢? 有了城市能做什么?产生资源,产生钱,产生兵 。 有了士兵做什么?可以抢资源,抢钱 。 资源和钱做什么?买道具 。 买道具做什么?更好的抢资源和抢钱 。 (同时,抢资源,抢钱的时候,资源会被消耗) 这是一个很简单的循环 。就是绕成了一个圈,虽然这个圈很小 。有部分策划想得非常好,就是绕不成圈,那样没任何意义 。 首先,需要一个道具的基础表 。自动ID,道具类型,道具属性,说明 。在道具的处理上,可以在玩家表里增加更多字段,道具跟随玩家 。也可以单独建一个道具的详细表 。用类似背包的方式实现 。 背包的方式有两种,一是用数组存储,二是用横向表存储 。都挺麻烦的 。不过从道具流通和买卖上考虑 。用背包的方式是值得的 。接下来的功能 。 商店 。拍卖行 。基本上跟一般的网站应用很类似 。只不过产品变为了游戏里的道具 。货币是游戏币 。 三、总结 上面的小例子,思路上是基本完善,没问题的 。程序代码上只给了一小部分,能真正理解这一小部分 。其他部分的程序应该不是问题 。 webgame重要的还是数据流的绕成圈,以及可玩性 。 现在讲为:程序的健壮和数据流的清晰 。 上面的功能,真的做出来,是不够玩的 。就是没什么可玩性,做出来都没意义 。 但是,仅仅是做出来,仍然是一件困难的事情 。 游戏里涉及的东西太多 。即使是很简单的游戏,即使webgame看上去很简单,甚至实际也很简单;做出来,非常困难 。 没有过开发webgame经验的人,来策划webgame或者说开发webgame 。会觉得很简单 。大功能其实就那么几个 。思路上也容易绕成圈 。 实际情况是,一个非常简单的功能,当它需要绕圈的时候;当它需要交互的时候 。这个功能就不再简单,而是复杂,相当的复杂 。 这是当你不太明白设计模式的时候,如果你精通设计模式,那么功能就会简单起来 。 特别是你想制作一款有足够的可玩性,能面向市场的产品,即使是初期思路非常简单,功能也很单纯 。但你实际策划的时候,实际编程的时候 。大量的数据、数值需要你去处理,大量的交互需要你去处理 。这时候,开始的简单,已经变得复杂了 。虽然从程序的角度讲,技术含量不高 。 更准确的讲,是繁琐,非常繁琐 。 优秀的策划是可以把数据表列出来,把数据走向清晰的列出来,放在你面前 。这样的策划不多的 。 当然,他不一定列得很准确,但是程序员能比较准确的理解他的意思 。 |