cccty1l 发表于 2010-2-18 17:06:09

[袋子系统] 模仿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)。

再就是单位位置的计算了,我发到沙发上,当然还是请感兴趣的同学看原链接的代码,我演示里面的代码真是惨不忍睹啊。

放上截图一张,话说这东西老早就弄出来了,放在那里一直都忘掉了,而且现在也没有做完,具体用途大家自己摸索吧。
哦,还得唠叨一句,这个系统不怎么浪费系统资源的,至少我的老爷机都没觉得卡。

cccty1l 发表于 2010-2-18 17:12:38

代码是使用的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

小明的左手 发表于 2010-2-19 10:47:09

主要就是位置 难弄

cccty1l 发表于 2010-2-19 11:02:40

恩,是这样的,相比原版的演示,现在的这个在移动镜头的时候,面板总是跟不上(跟击退系统一样,跨度大了就会不连贯),我也很无奈,本人无法解决。

还有一个问题就是,对物品栏双击会有Bug,双击任意物品栏会选中同行最后一列的物品栏(因为单位之间的距离太近了),这个情况可以通过调整单位距离镜头的距离来缓解一下,但是没办法解决,所以我只好在演示里面对“响应左键”增加了0.5秒的延迟,同样是无奈之举。

eff 发表于 2010-2-20 13:17:31

实用性为0

intelligentcode 发表于 2010-2-28 07:23:56

Znic哪里有中文教程?????急需

cccty1l 发表于 2010-2-28 10:08:51

http://bbs.islga.org/read-htm-tid-35995.html

socool2008 发表于 2010-3-7 21:53:49

回 3楼(cccty1l) 的帖子

模型里的单位选取体积不能自动对准镜头呀,点的时候的确容易点错

flavor 发表于 2010-6-16 17:56:37

唉!再接再厉

jescal 发表于 2011-5-7 22:29:21

好强大阿~~~好强大阿~~~

q496163428 发表于 2011-5-8 17:12:35

YDWE迟早会出这个功能 - -

-9- 发表于 2011-6-4 19:24:35

正,多謝分享!!!

w511487414 发表于 2011-7-10 17:24:23

学习了 ....

qq1316567457 发表于 2011-7-14 11:10:55

我喜欢

qq1093425950 发表于 2022-6-14 21:27:10

不会用,,用了代码游戏也进不去
页: [1]
查看完整版本: [袋子系统] 模仿WOW的背包.改