[袋子系统] 模仿WOW的背包.改
原帖在这里http://bbs.islga.org/read-htm-tid-33038-fpage-2.html
我把演示的代码粗略看了一下,提取出了对我有用的一部分,做了一个可以多人的版本。
其实这么说不准确,其实演示中的玩家视角是锁定了,它本身已经可以支持多人了,而我做的是不锁定屏幕的版本,用到了一些小技巧,大概说一下吧。
说先我们得知道,一个单位,在不和其他单位或可破坏物交互(意思就是发布命令或者阻碍其行走之类的)的前提下,下面所有的情况是可以不同步的:
1,单位的播放动画
2,单位的透明度和颜色
3,单位的模型大小
4,单位的位置和飞行高度(主要的这一点,上面的3点不需要刚才的那个前提也可以)
然后说说链接中演示的原理
1,模型,用到了一个始终会面向玩家镜头的模型
2,物品栏响应左键,是注册了一个“玩家选取单位”的事件
3,物品栏响应右键,是注册了一个“单位发布命令”的事件,也就是当玩家的单位跟随“物品栏单位”等一类的情况
4,物品栏单位纹理变化,就是吃树
上面3点和4点存在“和其他单位或可破坏物交互”的情况,但是3点可以通过对单位发布stop命令来解决、4点保证了物品栏单位吃树的时候位置非不同步就可以了。
还有一个要注意的地方,就是单位A位置不同步的情况下,单位B路过它的时候,会由于单位A有碰撞体积而使得单位B绕路,但是在其他玩家看来,单位B可能没有经过单位A,由此会导致掉线。解决办法是给单位A添加技能‘Amrf’‘Aeth’(抱歉之前说错了,‘Amrf’是乌鸦形态,用于改变单位高度的,‘Aeth’是不死的幽灵(可见的)技能,它有一个“不妨碍建造“的选项,有了之后就不会有碰撞体积了--2010-4-21)。
再就是单位位置的计算了,我发到沙发上,当然还是请感兴趣的同学看原链接的代码,我演示里面的代码真是惨不忍睹啊。
放上截图一张,话说这东西老早就弄出来了,放在那里一直都忘掉了,而且现在也没有做完,具体用途大家自己摸索吧。
哦,还得唠叨一句,这个系统不怎么浪费系统资源的,至少我的老爷机都没觉得卡。
代码是使用的Znic,我把需要展示的一段代码给翻出来,大家凑合看看吧。
function BagSys__Camera_get takes nothing returns integer
local integer x=BagSys__Cameranum
if ( x < 8191 ) then
if ( BagSys__Camerasto != 0 ) then
set BagSys__Cameranum=BagSys__Camerasto
else
set BagSys__Cameranum=x + 1
endif
return x
endif
return 0
endfunction
function BagSys__Camera_del takes integer this returns nothing
if ( this > 0 ) then
set BagSys__Camerasto=BagSys__Cameranum
set BagSys__Cameranum=this
endif
endfunction
这个函数是给玩家p创建一个镜头的数据,用来计算物品栏的位置用的。
function BagSys__CreateCamera_ForPlayer takes integer p returns integer
local integer x=BagSys__Camera_get()
set BagSys__Camera_p=x
set BagSys__Camera_At=BagSys__Camera_get()
set BagSys__Camera_Eye=BagSys__Camera_get()
set BagSys__Camera_AxisX=BagSys__Camera_get()
set BagSys__Camera_AxisY=BagSys__Camera_get()
set BagSys__Camera_AxisZ=BagSys__Camera_get()
return x
endfunction
function BagSys__GetTerrainZ takes real x,real y returns real
call MoveLocation(BagSys__GL, x, y)
return GetLocationZ(BagSys__GL)
endfunction
function BagSys__Approximately takes real v1,real v2,real s returns boolean
return ( v2 - s < v1 ) and ( v1 < v2 + s )
endfunction
function BagSys__Vec3Normalize takes integer Output,integer v returns integer
local real len=SquareRoot(BagSys__Camera_x * BagSys__Camera_x + BagSys__Camera_y * BagSys__Camera_y + BagSys__Camera_z * BagSys__Camera_z)
set BagSys__Camera_x=BagSys__Camera_x / len
set BagSys__Camera_y=BagSys__Camera_y / len
set BagSys__Camera_z=BagSys__Camera_z / len
return Output
endfunction
function BagSys__Vec3Subtract takes integer Output,integer v1,integer v2 returns integer
set BagSys__Camera_x=BagSys__Camera_x - BagSys__Camera_x
set BagSys__Camera_y=BagSys__Camera_y - BagSys__Camera_y
set BagSys__Camera_z=BagSys__Camera_z - BagSys__Camera_z
return Output
endfunction
function BagSys__Vec3Cross takes integer Output,integer v1,integer v2 returns integer
set BagSys__Camera_x=BagSys__Camera_y * BagSys__Camera_z - BagSys__Camera_z * BagSys__Camera_y
set BagSys__Camera_y=BagSys__Camera_z * BagSys__Camera_x - BagSys__Camera_x * BagSys__Camera_z
set BagSys__Camera_z=BagSys__Camera_x * BagSys__Camera_y - BagSys__Camera_y * BagSys__Camera_x
return Output
endfunction
function BagSys__Vec3Transform_1 takes integer Output,integer v returns integer
local integer a=BagSys__VECTOR3_mat
local integer b=a + 1
local integer c=b + 1
set BagSys__Camera_x=BagSys__Camera_x * BagSys__Camera_x + BagSys__Camera_y * BagSys__Camera_x + BagSys__Camera_z * BagSys__Camera_x
set BagSys__Camera_y=BagSys__Camera_x * BagSys__Camera_y + BagSys__Camera_y * BagSys__Camera_y + BagSys__Camera_z * BagSys__Camera_y
set BagSys__Camera_z=BagSys__Camera_x * BagSys__Camera_z + BagSys__Camera_y * BagSys__Camera_z + BagSys__Camera_z * BagSys__Camera_z
return Output
endfunction
function BagSys__Matrix3RotationAxis takes integer v,real a returns nothing
local real cosa=Cos(a)
local real sina=Sin(a)
local real cos_a=1 - cosa
local real x=BagSys__Camera_x
local real y=BagSys__Camera_y
local real z=BagSys__Camera_z
local integer mat=BagSys__VECTOR3_mat
set BagSys__Camera_x=cosa + cos_a * x * x
set BagSys__Camera_y=cos_a * x * y - sina * z
set BagSys__Camera_z=cos_a * x * z + sina * y
set mat=mat + 1
set BagSys__Camera_x=cos_a * y * x + sina * z
set BagSys__Camera_y=cosa + cos_a * y * y
set BagSys__Camera_z=cos_a * y * z - sina * x
set mat=mat + 1
set BagSys__Camera_x=cos_a * z * x - sina * y
set BagSys__Camera_y=cos_a * z * y + sina * x
set BagSys__Camera_z=cosa + cos_a * z * z
endfunction
function BagSys__Camera_Win2World takes integer p,real X,real Y,real Range returns integer
local integer axisx=BagSys__Camera_AxisX
local integer axisy=BagSys__Camera_AxisY
local integer axisz=BagSys__Camera_AxisZ
local integer eye=BagSys__Camera_Eye
local integer Output=BagSys__Camera_Pos
set BagSys__Camera_x=BagSys__Camera_x + BagSys__Camera_x * Range + X * BagSys__Camera_x * BagSys__WidthScreen * Range + Y * BagSys__Camera_x * BagSys__HeightScreen * Range
set BagSys__Camera_y=BagSys__Camera_y + BagSys__Camera_y * Range + X * BagSys__Camera_y * BagSys__WidthScreen * Range + Y * BagSys__Camera_y * BagSys__HeightScreen * Range
set BagSys__Camera_z=BagSys__Camera_z + BagSys__Camera_z * Range + X * BagSys__Camera_z * BagSys__WidthScreen * Range + Y * BagSys__Camera_z * BagSys__HeightScreen * Range
return Output
endfunction
function BagSys__Camera_UpdateAxisMatrix takes integer this,real ex,real ey,real ez,real tx,real ty,real tz returns nothing
local integer axisx=BagSys__Camera_AxisX
local integer axisy=BagSys__Camera_AxisY
local integer axisz=BagSys__Camera_AxisZ
local integer eye=BagSys__Camera_Eye
local integer at=BagSys__Camera_At
set BagSys__Camera_x=tx
set BagSys__Camera_y=ty
set BagSys__Camera_z=tz
set BagSys__Camera_x=ex
set BagSys__Camera_y=ey
set BagSys__Camera_z=ez
call BagSys__Vec3Normalize(axisz , BagSys__Vec3Subtract(axisz , at , eye))
call BagSys__Matrix3RotationAxis(axisz , - GetCameraField(CAMERA_FIELD_ROLL))
call BagSys__Vec3Normalize(axisx , BagSys__Vec3Cross(axisx , axisz , BagSys__VECTOR3_oneZ))
call BagSys__Vec3Transform_1(axisy , BagSys__Vec3Cross(axisy , axisx , axisz))
call BagSys__Vec3Transform_1(axisx , axisx)
endfunction
从这里往上看,就是每一段间隔更新下数据。
总的来说不是很复杂,不过让我自己来写我可写不出来,全是从链接里面的演示偷出来的。
function BagSys__CameraUpdate_ForPlayer takes integer p returns boolean
local real tx
local real ty
local real tz
local real X
local real Y
local real Z
local integer this
local integer at
local integer eye
if ( Lpid == p ) then
set X=GetCameraEyePositionX()
set Y=GetCameraEyePositionY()
set Z=GetCameraEyePositionZ()
set tx=GetCameraTargetPositionX()
set ty=GetCameraTargetPositionY()
set tz=GetCameraTargetPositionZ()
set this=BagSys__Camera_p
set at=BagSys__Camera_At
set eye=BagSys__Camera_Eye
if ( ( not ( BagSys__Approximately(X , BagSys__Camera_x , 1) and BagSys__Approximately(Y , BagSys__Camera_y , 1) and BagSys__Approximately(Z , BagSys__Camera_z , 1) and BagSys__Approximately(tx , BagSys__Camera_x , 1) and BagSys__Approximately(ty , BagSys__Camera_y , 1) and BagSys__Approximately(tz , BagSys__Camera_z , 1) ) ) ) then
call BagSys__Camera_UpdateAxisMatrix(this , X , Y , Z , tx , ty , tz)
return true
endif
endif
return false
endfunction
这个函数就是用来摆放单位的位置的。
function BagSys__ButtonUpdate takes unit u,integer p returns nothing
local integer x=GetUnitUserData(u)
set x=BagSys__Camera_Win2World(BagSys__Camera_p , BagSys__Button_centerx , BagSys__Button_centery , BagSys__ZSlot)
call SetUnitX(u, BagSys__Camera_x)
call SetUnitY(u, BagSys__Camera_y)
call SetUnitFlyHeight(u, BagSys__Camera_z - BagSys__GetTerrainZ(BagSys__Camera_x , BagSys__Camera_y), 0)
endfunction
主要就是位置 难弄 恩,是这样的,相比原版的演示,现在的这个在移动镜头的时候,面板总是跟不上(跟击退系统一样,跨度大了就会不连贯),我也很无奈,本人无法解决。
还有一个问题就是,对物品栏双击会有Bug,双击任意物品栏会选中同行最后一列的物品栏(因为单位之间的距离太近了),这个情况可以通过调整单位距离镜头的距离来缓解一下,但是没办法解决,所以我只好在演示里面对“响应左键”增加了0.5秒的延迟,同样是无奈之举。 实用性为0 Znic哪里有中文教程?????急需 http://bbs.islga.org/read-htm-tid-35995.html
回 3楼(cccty1l) 的帖子
模型里的单位选取体积不能自动对准镜头呀,点的时候的确容易点错 唉!再接再厉 好强大阿~~~好强大阿~~~ YDWE迟早会出这个功能 - - 正,多謝分享!!! 学习了 .... 我喜欢 不会用,,用了代码游戏也进不去
页:
[1]