网页游戏开发七武器Word文档格式.docx
《网页游戏开发七武器Word文档格式.docx》由会员分享,可在线阅读,更多相关《网页游戏开发七武器Word文档格式.docx(29页珍藏版)》请在冰豆网上搜索。
![网页游戏开发七武器Word文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/29/64d7a52e-a34e-408e-bbd8-d516b274905c/64d7a52e-a34e-408e-bbd8-d516b274905c1.gif)
生命最大值100
体力最大值50
可加点数0
已加点数10
获得角色信息。
$user=getUser
(1);
这时候
$user[‘ap’]==10;
$user[‘dp’]==10;
$user[‘hp’]==100;
$user[‘sp’]==50;
已经可以开始打怪了。
好了,这时候问题来了。
如果角色穿上了装备。
装备对角色属性的加成,怎么处理呢?
装备
首先,构造一个装备基础表。
假设装备可以增加以下属性。
这样么:
装备id
id
装备名称
name
增加力量
pg
增加敏捷
增加攻击
增加防御
增加生命
增加体力
这样的后果就是很难扩展。
假如装备是物品的一种,那么这时候,表就很难构造了。
简化为:
增加类型addtype
增加点数addpoint
比如
装备名称
木棍
增加类型
ap|pg
增加点数
10|3
意思是木棍增加攻击10点,增加力量3点。
假设我们获取了id为1的装备的信息
$equip=getEquipInfo
(1);
然后开始展示装备。
Echo$equip[‘name’].”<
br/>
”;
$addtype=explode("
|"
$equip['
addtype'
]);
$addpoint=explode("
$equip['
addpoint'
foreach($addtypeas$key=>
$value)
{
echo$addtype[$k]."
+"
.$addpoint[$k]."
<
"
;
}
显示出来为:
ap+10
pg+3
这时候装备是装备,角色是角色,他们是分离开的。
为了让角色与装备关联起来。
需要新增加一个userequip表。
即玩家装备表。
假设一个角色只能拿3件装备。
那么
userequip:
装备一
equipid_1
装备二
equipid_2
装备三
equipid_3
这时候,当角色装备上木棍后。
数据为
获得角色的装备id
$userequipid=getUserEquip
(1)
获得角色的装备
functiongetEquip($id)
$equip=getEquipInfo($id);
$userequip[$addtype[‘ap’]]=$userequip[$addtype[‘ap’]]+$addpoint[$key][‘addpoint’];
$userequip=getEquip($userequipid[‘equipid_1’])
增加角色的属性
$user[‘ap’]=$user[‘ap’]+$userequip[‘ap’];
$user[‘dp’]=$user[‘dp’]+$userequip[‘dp’];
这样,角色与装备的联系就搞定了。
当然,有更多的巧妙的方式,让角色与装备变得更简单和更强大。
实际运用中,建立一个角色类,装备什么的,通过类似组合的方式放进去。
(实际上不算组合,就是函数)
类似:
classUser
public$user;
functiongetUserBase()
//获得角色基础数据
functiongetUserInfo()
//获得角色数据
functiongetUserEquip()
//获得角色装备数据,这里可以直接调用装备类里的方法。
//最后
functiongetUser()
$this->
user[‘base’]=getUserBase();
user[‘info’]=getUserInfo();
user[‘equip’]=getUserEquip();
//角色数据与装备数据组合
//调整角色数据,因为可能会有角色状态
return$this->
user;
背包:
背包有两种方式。
一种是纵表,一种是横表。
如果需要从背包上获得盈利点,就用横表吧。
userbeibao:
栏位一
itemid_1
数量
num_1
是否开启ifopen
道具类型type
栏位二
itemid_2
num_2
栏位三
itemid_3
num_3
栏位N
itemid_N
num_N
跟装备表很类似。
略有不同的是,多了数量、类型、是否空闲等等字段。
那么如何新增背包和购买背包呢?
假设有5个背包栏位。
对应5个表
userbeibao_1
userbeibao_2
userbeibao_3
userbeibao_4
userbeibao_5
新增背包就是对某个表插入一段数据。
背包位置有多少。
就是某个表开启的空位有多少。
背包表的栏位字段的数量,要按最大值算。
比如最大的背包有30格,那么字段就是30*4个。
比如用户获得1个8格包包。
那么,
userbeibao_2中。
可用的位置就只开启8个。
通过初始化时,’ifopen’来控制。
纵表的话,相对简单。
userid
itemid
itemtype
num
道具id道具类型数量
都放到一个表里就行。
场景部分(地图、城市、场所)
地图
《网页游戏开发七武器(二、前台展示)》里面的地图部分吗?
里面有一句。
map.php的功能。
根据获得的x,y显示相应的一小块图块。
一开始,我是从数据库里调用对应的数据。
后来觉得效率低了,缓存了一下。
(如何缓存见《网页游戏开发七武器(一、高负载)》)
后来一想,不对。
为什么要缓存呢?
数据有变化吗?
地图背景没变化。
城池有变化,不过变化很慢。
那么只需要缓存城池就行了。
地图呢?
很简单了。
根据坐标,获得对应的图片。
关键部分代码:
//m代表地图横着需要放几块。
//n代表地图竖着需要放几块。
for($m=1;
$m<
=5;
$m++)
for($n=1;
$n<
=4;
$n++)
//根据坐标获得地图块的编号。
这里的200,是因为地图块的大小是200*200像素。
$x=ceil($mapy/200);
$y=ceil($mapx/200);
if($x>
=1
and$x<
=15and$y>
=1and$y<
=25)
//获得具体的图片名
$url="
images/map/map_r"
.$x."
_c"
.$y."
.jpg"
$left=($y-1)*200-$mapx1;
$top=($x-1)*200-$mapy1;
echo"
<
divstyle=\"
position:
absolute;
z-index:
11;
left:
.$left."
px;
top:
.$top."
width:
200px;
height:
background-image:
url("
.$url."
);
\"
>
/div>
//$mapx=$mapx+200;
$mapy=$mapy+200;
$mapy=$mapy1;
$mapx=$mapx+200;
图片的命名怎么处理呢?
用firework打开一张完整的背景图,用切图导出的功能。
将图片切割成多个小方块后同时导出。
这时候,再加上具体的城池什么的。
这个就自由发挥了。
如果是修房子游戏,地图是自动生成的,就相当于没背景这个概念。
全部数据库里调就行,记得加缓存。
城市
城市需要显示在地图上,
城市作为玩家角色所处位置的参数之一。
城市作为NPC所处位置的参数之一。
城市作为场所的承载地。
City:
城市名name
城市类型type
城市图标image
城市坐标x
城市坐标y
其他参数。
总体上说,城市本身就是简单的一个表、一些数据。
关键的问题是
1)如何简单的处理多种类型的城市(或者就是地图上的某个石头、水池什么的)
2)如何简单的处理玩家角色在同一个城市中的位置转换。
第一个问题,
首先给City表增加一个字段type。
代表是什么城市类型。
比如
主城
关卡
大城
小城
等等。
这时候,会遇到另一个问题。
如何知道某个类型的城市,有些什么内部场景和内部建筑呢?
主城A有
城外
内城
商店
拍卖行
主城C有
(没有拍卖行)
类型都是“主城”
但是目前的表里,并没有对城池拥有场景的描述。
因此增加1个字段sence
主城A
sence字段的内容就是1|1|1|1
主城B
sence字段的内容就是1|1|1|0
很简单吧。
也就是城市内的场景通过一个0101表获得。
0就没有对应的场景。
1就有对应的场景。
至于对应的场景和01的位置,可以自行确定。
那么,针对场景来说,可能还会有一个变化。
比如主城A的城外的背景图是chengwai_A.jpg
主城B的城外的背景图是chengwai_B.jpg
也就是说同类型的城市,同样的场景。
但是背景有差异。
多个文件?
根据编号读不同的图?
那么最好的办法,还是把重担丢给填表的策划。
差异化的地方,毕竟不会太多(美术资源有限),所以可以考虑把同类型城市,但是有差异的场景背景图;
放到一个字段里。
还是sence字段。
sence字段的内容就是chengwai_A.jpg|1|1|1
sence字段的内容就是chengwai_B.jpg|1|1|0
伪代码如下:
if($sence[0]==1)
//获得默认背景。
elseif($sence[0]==0)
//没有这个场景,进入处理错误流程。
else
//有数据,又不为0或1。
那么就说明是一张有差异的背景图片。
//获得有差异的背景图。
$sence[0]
第二个问题,
假设世界结构是这样的
大地图->
城市->
场景->
建筑
那么,玩家表里需要增加三个字段。
cityid玩家所在城市id
sence玩家所在场景编号(或名称)
build玩家所在建筑编号(或名称)
好了。
玩家点城市里的对应按钮。
更新玩家表里的3个字段。
确定好了?
当然没有。
这时候,数据库会相当繁忙的。
因为玩家切换场景是比较频繁的操作。
如果用前台脚本来处理玩家所在位置,那么一些功能,比如声望不够,不能进入内城,就不太好实现了。
假设玩家在城市间移动,是需要一定时间的(10秒到几千秒)
那么,可以认为cityid的变化是不太快的。
数据库能轻松胜任。
而sence和build的变化是相当频繁的。
问题就集中在如何高效率的处理sence和build的转换。
还是很简单。
用session存储sence和build
同时,当玩家在场景发生某个事件时,再更新数据表。
这样处理效率很高。
不过会出现一个小bug。
就是玩家如果没有执行任何事件,刷新或者重登陆的时候,会出现在城市的默认位置。
(一般不会有玩家在意的。
一年多了,都没人提这个)
简单交互部分(与npc战斗、与玩家战斗、军团战斗)
首先,需要有一个清晰的概念。
战斗的流程是什么?
1)获得攻击方A的数据。
2)获得被攻击方B的数据。
3)根据战斗公式以及回合流程。
反馈战斗结果、战斗过程。
4)根据反馈的数据,更新对应数据。
攻击方A,被攻击方B。
可能是任何对象。
即,可能是玩家角色、武将、宠物、NPC等等。
(注:
军团战斗,可以分开,也可以合并到一起。
因为算法和流程可能会有比较大的不同。
)
战斗的算法公式也可能根据双方对象的不同而不同。
简单的说分为3个部分。
1、战斗对象(根据类型不同,二获得不同的对象)
2、战斗流程(一个虚类,输入战斗对象,获得结果及需要的数据)
3、算法(即战斗公式,属于战斗流程中的一部分)
1、战斗对象。
classFight($id,$type)
switch($type)
case“角色”:
returngetUserInfo($id);
break;
case“武将”:
returngetWJInfo($id);
case“NPC”:
returngetNPC($id);
2、战斗流程。
classFightProcess
public
$A;
$B;
$type;
//获得初始数据。
即获得两个Fight对象。
functionsetFight($A,$B,$type)
A=$A;
B=$B;
type=$type;
//这里的$type是声明A、B分别是什么对象。
也可以不用。
因为A、B自己也会申明自己的类型。
functionbeginFight()
//开始战斗。
一般有一个循环。
functionendFight()
//结束战斗。
获得胜负数据。
回合数据。
对应的消息发送。
3、执行的时候。
$A=newFight($id,$type);
$B=newFight($id,$type);
$type=xxx;
$Fight=newFightProcess();
$Fight->
setFight($A,$B,$type);
doBegin();
doEnd();
军团战斗的时候。
只是A、B对象的初始化不同。
以及beginFight()
和endFight()有不同。
其他功能(拍卖、闯关、国战、屠龙)
这类功能相对简单。
没太多说的。
主要就是服务器需要有一个定时执行。
每1分钟执行一次。
需要一个表来记录列表信息。
有人误会是每个玩家都需要定时执行。
实际上是服务器在固定时间内只需要执行一次。
因为每个玩家的信息都会进入到需要执行的列表中。
执行的是列表。
例如拍卖:
A卖出itemiditmenum个。
到期时间是endtime。
竞标人
jingbiao
B卖出itemid_Bitemnum_B个。
到期时间是endtime_B。
竞标人jingbiao
他们的数据都存在表sale里。
假设某一时刻。
A、B都到期了。
其中A有人竞标。
竞标人C
服务器执行的函数类似:
functiondoSale()
//获得所有sale里到期的数据。
//循环所有数据。
(一般不会超过100条。
不同担心负载)
//判断是否有人竞标。
(即jingbiao是否有数据)
//有则执行竞标人获得物品。
A获得资金、消息。
//无则A获得物品。
消息。
}网页游戏开发七武器(四、数据同步)
网页游戏的数据同步,涉及到
1)soap
2)socket
Soap
这是一小段与后台通讯的soap代码。
$login_url="
http:
//xxx.xxxxx.xxx/xxx.asmx?
WSDL"
$client=newSoapClient($login_url);
$ip=get_client_ip();
//这是一个自定义的获得客户端ip的函数。
$param=array("
ID"
=>
$id,"
Key"
$key,"
IP"
$ip);
$result=$client->
__soapCall('
Key'
array('
param'
$param));
$result=$result->
KeyResult;
__soapCall
KeyResult
都是服务端提供的标准接口。
能看出什么来吗?
这一段其实是facebook的登录接口代码。
关键部分就只有这么多。
Socket
这是一小段php前台发送socket包的代码。
$serverArea后台服务ip
$city需要发送的城市id
$forceName需要发送的势力名称(或公会名称)
$nicknam玩家昵称
$type自定义的类型
$content发送的内容。
整个代码就是构造一个符合后台要求的数据包格式。
chr
(1)代表1个空字符。
每段数据包的大小是370个字节。
其中每1个段表示不同的数据。
没有数据的地方都用空字符填满了。
functiongetChat($serverArea,$city,$forceName,$nickname,$type,$content)
$len=strlen($serverArea);
if($len<
50)
$len_add=50-$len;
for($i=0;
$i<
$len_add;
$i++)
$serverArea=$serverArea.chr
(1);
$len=strlen($city);
20)
$len_add=20-$len;
$city=$city.chr
(1);
$len=strlen($forceName);
$forceName=$forceName.chr
(1);
$len=strlen($nickname);
$nickname=$nickname.chr
(1);
$len=strlen($type);
10)
$len_add=10-$len;
$type=$type.chr
(1);
$len=strlen($content);
230)
$len_add=230-$len;
$content=$content.chr
(1);
$buf=$serverArea.$city.$forceName.$nickname.$type.$target.$content;
$len=strlen($buf);
370)
$len_add=370-$len;
$buf=$buf.chr
(1);
return$buf;
配合上