请选择 进入手机版 | 继续访问电脑版

GA地精研究院

 找回密码
 立即注册
查看: 6011|回复: 19

[演示&系统] 随机迷宫——副本区域创建系统

[复制链接]
发表于 2009-9-27 23:16:03 | 显示全部楼层 |阅读模式
本帖最后由 疯人¢衰人 于 2013-6-27 21:58 编辑

[codes=galaxy]globals     
    integer array udg_Labyrinth //二进制0~7位为4个方向(下1、右下2、右4、右上8,上16,左上32,左64,左下128)是否相通,8~11位为四角(右下256、右上512、左上1024、左下2048)是否被对角连接占用,12位为是否为始点4096,13位为是否是终点8192,14位为是否为末端16384,15位为是否使用32768。(临时数据)
    integer array udg_UsedGrid //已使用格子(临时数据)
    integer array udg_UnableGrid //不可用格子(临时数据)
    integer array udg_EndWay//支路尽头点记录(临时数据)
    integer array udg_DestructableArray//可破坏物类型组(自定义数据)
    integer array udg_DestructableType//可破坏物类型对应的式样数目(固定数据)
    integer udg_UsedGridNum //已用格子总数(临时数据)
    integer udg_UnableGridNum //不可用格子总数(临时数据)
    integer udg_EndWayNum//支路尽头总数(临时数据)
    integer udg_DestructableNum//可破坏物类型总数(固定数据)
    integer udg_Length_X //X方向格子数,小于90(自定义数据)            
    integer udg_Length_Y //Y方向格子数,小于90 (自定义数据)
    integer udg_Start//起始点的位置,值为对应的Y*udg_Length_X+X-1(自定义数据)
    integer udg_End //终点的位置,值为对应的Y*udg_Length_X+X-1(自定义数据)  
    integer udg_FirstTimer//格子对应的timer数组的第一个timer的handle值(临时数据)
    integer udg_GridID//路径创建位置(临时数据)   
    integer udg_WayLength//当前路线长度(临时数据)               
    integer udg_WayLengthMin//当路线最小长度(自定义数据)     
    integer udg_WayLengthMax//当路线最大长度(自定义数据)
    integer udg_NewGroundType//可通行处的地面纹理类型(自定义数据)  
    integer udg_OldGroundType//不可通行处的地面纹理类型 (固定数据)
    integer udg_DoingOverNum//格子处理执行完毕数量(临时数据)
    real udg_DestructableRate//允许使用可破坏物上限(自定义数据)
    real udg_TopLeftCorner_X //左上角点X轴坐标(自定义数据)
    real udg_TopLeftCorner_Y //左上角点Y轴坐标(自定义数据)
    real udg_Density//迷宫最小使用密度(自定义数据)
    boolean udg_ReachEnd//已到达终点(临时数据)
endglobals

function H2I takes handle h returns integer//H2I函数
    return h
    return 0
endfunction

function I2T takes integer i returns timer//I2T函数
    return i
    return GetExpiredTimer()
endfunction

function Get01 takes integer GridID , integer I returns integer
    local integer TempGrid = udg_Labyrinth[GridID]
    loop
        exitwhen I == 0
        set I = I - 1
        set TempGrid = TempGrid / 2
    endloop
    return TempGrid - TempGrid / 2 * 2
endfunction

function Direction_0 takes nothing returns nothing //对下方向的处理
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 1
    set udg_GridID = udg_GridID - udg_Length_X
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32784
endfunction
   
function Direction_1 takes nothing returns nothing//对右下方向的处理
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 2   
    set udg_Labyrinth[udg_GridID - udg_Length_X] = udg_Labyrinth[udg_GridID - udg_Length_X] + 512
    set udg_Labyrinth[udg_GridID + 1] = udg_Labyrinth[udg_GridID + 1] + 2048
    set udg_GridID = udg_GridID - udg_Length_X + 1
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32800
endfunction

function Direction_2 takes nothing returns nothing//对右方向的处理
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 4
    set udg_GridID = udg_GridID + 1
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32832
endfunction

function Direction_3 takes nothing returns nothing//对右上方向的处理
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 8  
    set udg_Labyrinth[udg_GridID + udg_Length_X] = udg_Labyrinth[udg_GridID + udg_Length_X] + 256
    set udg_Labyrinth[udg_GridID + 1] = udg_Labyrinth[udg_GridID + 1] + 1024
    set udg_GridID = udg_GridID + udg_Length_X + 1
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32896
endfunction

function Direction_4 takes nothing returns nothing//对上方向的处理
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 16
    set udg_GridID = udg_GridID + udg_Length_X
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32769
endfunction

function Direction_5 takes nothing returns nothing//对左上方向的处理  
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32   
    set udg_Labyrinth[udg_GridID + udg_Length_X] = udg_Labyrinth[udg_GridID + udg_Length_X] + 2048
    set udg_Labyrinth[udg_GridID - 1] = udg_Labyrinth[udg_GridID - 1] + 512
    set udg_GridID = udg_GridID + udg_Length_X - 1
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32770
endfunction

function Direction_6 takes nothing returns nothing//对左方向的处理  
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 64
    set udg_GridID = udg_GridID - 1
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32772
endfunction

function Direction_7 takes nothing returns nothing//对左下方向的处理   
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 128  
    set udg_Labyrinth[udg_GridID - udg_Length_X] = udg_Labyrinth[udg_GridID - udg_Length_X] + 1024
    set udg_Labyrinth[udg_GridID - 1] = udg_Labyrinth[udg_GridID - 1] + 256
    set udg_GridID = udg_GridID - udg_Length_X - 1
    set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 32776
endfunction  

function GetRandomDirection takes nothing returns integer//获得随机方向
    local integer array Random
    local integer RandomNum = 0   
    local integer i = 0
    if udg_GridID == udg_End then //当前点为终点   
        return -1
    endif
    if udg_GridID >= udg_Length_X then  
        if udg_Labyrinth[udg_GridID - udg_Length_X] - 32768 < 0 then
            set Random[RandomNum] = 0
            set RandomNum = RandomNum + 1
        endif
    endif
    if Get01(udg_GridID,8) == 0 and udg_GridID >= udg_Length_X and udg_GridID - udg_GridID / udg_Length_X * udg_Length_X != udg_Length_X - 1 then
        if udg_Labyrinth[udg_GridID - udg_Length_X + 1] - 32768 < 0 then
            set Random[RandomNum] = 1
            set RandomNum = RandomNum + 1
        endif
    endif
    if  udg_GridID - udg_GridID / udg_Length_X * udg_Length_X != udg_Length_X - 1 then
        if udg_Labyrinth[udg_GridID +1] - 32768 < 0 then
            set Random[RandomNum] = 2
            set RandomNum = RandomNum + 1
        endif
    endif
    if Get01(udg_GridID,9) == 0 and udg_GridID - udg_GridID / udg_Length_X * udg_Length_X != udg_Length_X - 1 and udg_GridID <= udg_Length_X * (udg_Length_Y - 1) - 1 then     
        if udg_Labyrinth[udg_GridID + udg_Length_X + 1] - 32768 < 0 then
            set Random[RandomNum] = 3
            set RandomNum = RandomNum + 1
        endif
    endif
    if udg_GridID <= udg_Length_X * (udg_Length_Y - 1) - 1 then   
        if udg_Labyrinth[udg_GridID + udg_Length_X] - 32768 < 0 then
            set Random[RandomNum] = 4
            set RandomNum = RandomNum + 1
        endif
    endif
    if Get01(udg_GridID,10) == 0 and udg_GridID <= udg_Length_X * (udg_Length_Y - 1) - 1 and udg_GridID - udg_GridID / udg_Length_X * udg_Length_X != 0 then         
        if udg_Labyrinth[udg_GridID+ udg_Length_X - 1] - 32768 < 0 then
            set Random[RandomNum] = 5
            set RandomNum = RandomNum + 1
        endif
    endif
    if udg_GridID - udg_GridID / udg_Length_X * udg_Length_X != 0 then   
        if udg_Labyrinth[udg_GridID - 1] - 32768 < 0 then   
            set Random[RandomNum] = 6
            set RandomNum = RandomNum + 1
        endif
    endif
    if Get01(udg_GridID,11) == 0 and udg_GridID - udg_GridID / udg_Length_X * udg_Length_X != 0 and udg_GridID >= udg_Length_X then   
        if udg_Labyrinth[udg_GridID - udg_Length_X - 1] - 32768 < 0 then
            set Random[RandomNum] = 7
            set RandomNum = RandomNum + 1
        endif
    endif   
    if RandomNum == 0 then
        set udg_UnableGrid[udg_UnableGridNum] = udg_GridID
        set udg_UnableGridNum = udg_UnableGridNum + 1  
        loop
            if udg_UsedGrid == udg_GridID then
                set udg_UsedGridNum = udg_UsedGridNum -1
                set udg_UsedGrid = udg_UsedGrid[udg_UsedGridNum]
            else
                set i = i + 1
            endif
            exitwhen i >= udg_UsedGridNum
        endloop   
        return -1
    else
        set udg_WayLength = udg_WayLength + 1
    endif   
    return Random[GetRandomInt(0,RandomNum - 1)]
endfunction


function TerrainPathable takes real X, real Y,integer ID returns nothing // 地面通行状态处理
    local integer Random
    set X = X + I2R((ID- ID / 9 * 9) * 128 - 560)
    set Y = Y + I2R(ID / 9 * 128 - 544)
    if GetTerrainType(X,Y) != GetTerrainType(X + 128,Y) then   
        call SetTerrainPathable(X + 48,Y - 48,ConvertPathingType(1),false)   
        call SetTerrainPathable(X + 48,Y - 16,ConvertPathingType(1),false)
        call SetTerrainPathable(X + 48,Y + 16,ConvertPathingType(1),false)
        call SetTerrainPathable(X + 48,Y + 48,ConvertPathingType(1),false)
    endif                                   
    if GetTerrainType(X,Y) != GetTerrainType(X - 128,Y) then   
        call SetTerrainPathable(X - 48,Y - 48,ConvertPathingType(1),false)   
        call SetTerrainPathable(X - 48,Y - 16,ConvertPathingType(1),false)
        call SetTerrainPathable(X - 48,Y + 16,ConvertPathingType(1),false)
        call SetTerrainPathable(X - 48,Y + 48,ConvertPathingType(1),false)
    endif     
    if GetTerrainType(X,Y) != GetTerrainType(X,Y + 128) then   
        call SetTerrainPathable(X - 48,Y + 48,ConvertPathingType(1),false)   
        call SetTerrainPathable(X - 16,Y + 48,ConvertPathingType(1),false)
        call SetTerrainPathable(X + 16,Y + 48,ConvertPathingType(1),false)
        call SetTerrainPathable(X + 48,Y + 48,ConvertPathingType(1),false)
    endif     
    if GetTerrainType(X,Y) != GetTerrainType(X,Y - 128) then   
        call SetTerrainPathable(X - 48,Y - 48,ConvertPathingType(1),false)   
        call SetTerrainPathable(X - 16,Y - 48,ConvertPathingType(1),false)
        call SetTerrainPathable(X + 16,Y - 48,ConvertPathingType(1),false)
        call SetTerrainPathable(X + 48,Y - 48,ConvertPathingType(1),false)
    endif     
    if GetTerrainType(X,Y) == udg_OldGroundType and GetRandomReal(0,1) < udg_DestructableRate then
        set Random = GetRandomInt(0,udg_DestructableNum - 1)
        call CreateDestructable(udg_DestructableArray[Random],X +GetRandomReal(-40,40),Y +GetRandomReal(-40,40),GetRandomReal(0, 360),1,GetRandomInt(0,udg_DestructableType[Random] - 1))
    endif
endfunction

function GroundMade takes nothing returns nothing//地面类型处理
    local integer GridID = H2I(GetExpiredTimer()) - udg_FirstTimer
    local real Center_X = udg_TopLeftCorner_X + I2R((GridID- GridID / udg_Length_X * udg_Length_X) * 1152 + 576)   
    local real Center_Y = udg_TopLeftCorner_Y + I2R(GridID / udg_Length_X * 1152 + 576)
    local integer Labyrinth = udg_Labyrinth[GridID]
    if udg_Labyrinth[GridID] - 32768 > 0 then
        call SetTerrainType( Center_X,Center_Y, udg_NewGroundType, -1, 4, 0 )
        call SetTerrainType( Center_X - 384,Center_Y, udg_OldGroundType, -1, 1, 0 )
        call SetTerrainType( Center_X + 384,Center_Y, udg_OldGroundType, -1, 1, 0 )
        call SetTerrainType( Center_X,Center_Y - 384, udg_OldGroundType, -1, 1, 0 )
        call SetTerrainType( Center_X,Center_Y + 384, udg_OldGroundType, -1, 1, 0 )
        if Labyrinth - Labyrinth / 2 * 2 == 1 then//下
            call SetTerrainType( Center_X,Center_Y - 256, udg_NewGroundType, -1, 3, 1 )  
        endif
        if Labyrinth - Labyrinth / 4 * 4 >= 2 then//右下                    
            call SetTerrainType( Center_X + 384,Center_Y - 384, udg_NewGroundType, -1, 3, 0 )  
            call SetTerrainType( Center_X + 512,Center_Y - 512, udg_NewGroundType, -1, 3, 0 )  
        endif      
        if Labyrinth - Labyrinth / 8 * 8 >= 4 then//右            
            call SetTerrainType( Center_X + 256 ,Center_Y, udg_NewGroundType, -1, 3, 1 )  
        endif
        if Labyrinth - Labyrinth / 16 * 16 >= 8 then//右上      
            call SetTerrainType( Center_X + 384,Center_Y + 384, udg_NewGroundType, -1, 3, 0 )  
            call SetTerrainType( Center_X + 512,Center_Y + 512, udg_NewGroundType, -1, 3, 0 )
        endif
        if Labyrinth - Labyrinth / 32 * 32 >= 16 then//上   
            call SetTerrainType( Center_X,Center_Y + 256, udg_NewGroundType, -1, 3, 1 )  
        endif
        if Labyrinth - Labyrinth / 64 * 64 >= 32 then//左上  
            call SetTerrainType( Center_X - 384,Center_Y + 384, udg_NewGroundType, -1, 3, 0 )  
            call SetTerrainType( Center_X - 512,Center_Y + 512, udg_NewGroundType, -1, 3, 0 )  
        endif
        if Labyrinth - Labyrinth / 128 * 128 >= 64 then//左  
            call SetTerrainType( Center_X - 256,Center_Y, udg_NewGroundType, -1, 3, 1 )  
        endif
        if Labyrinth - Labyrinth / 256 * 256 >= 128 then//左下  
            call SetTerrainType( Center_X - 384,Center_Y - 384, udg_NewGroundType, -1, 3, 0 )  
            call SetTerrainType( Center_X - 512,Center_Y - 512, udg_NewGroundType, -1, 3, 0 )  
        endif
    else
        //未使用
    endif
    set udg_DoingOverNum = udg_DoingOverNum + 1      
endfunction  

function TerrainPathableMake takes nothing returns nothing//单格地面通行处理     
    local integer i = 0  
    local integer GridID = H2I(GetExpiredTimer()) - udg_FirstTimer
    local real Center_X = udg_TopLeftCorner_X + I2R((GridID- GridID / udg_Length_X * udg_Length_X) * 1152 + 576)   
    local real Center_Y = udg_TopLeftCorner_Y + I2R(GridID / udg_Length_X * 1152 + 576)  
    call DestroyTimer(GetExpiredTimer())         
    loop
        call TerrainPathable(Center_X,Center_Y,i)
        set i = i + 1
        exitwhen i == 81  
    endloop   
    set udg_DoingOverNum = udg_DoingOverNum + 1   
endfunction


function Main_StartF takes nothing returns nothing//全部完成提示  
    if udg_DoingOverNum >= udg_Length_X * udg_Length_Y then
        call DestroyTimer(GetExpiredTimer())         
    else
        return
    endif
    call BJDebugMsg("全部完成")   
endfunction

function Main_StartE takes nothing returns nothing //地面通行处理
    local integer GridID = 0   
    if udg_DoingOverNum >= udg_Length_X * udg_Length_Y then
        call DestroyTimer(GetExpiredTimer())         
    else
        return
    endif   
    call BJDebugMsg("地面纹理处理完成")
    set udg_DoingOverNum = 0
    loop
        call TimerStart(I2T(udg_FirstTimer + GridID),0,false,function TerrainPathableMake)
        set GridID = GridID + 1
        exitwhen GridID >= udg_Length_X * udg_Length_Y
    endloop      
    call TimerStart(CreateTimer(),0.01,true,function Main_StartF)
endfunction

function Main_StartD takes nothing returns nothing//地面纹理处理
    local integer GridID = 0   
    call DestroyTimer(GetExpiredTimer())
    loop  
        if Get01(GridID,14) == 1 then
            set udg_EndWay[udg_EndWayNum] = GridID
            set udg_EndWayNum = udg_EndWayNum + 1
        endif
        call TimerStart(I2T(udg_FirstTimer + GridID),0,false,function GroundMade)
        set GridID = GridID + 1
        exitwhen GridID >= udg_Length_X * udg_Length_Y
    endloop
    set udg_EndWayNum = udg_EndWayNum - 1
    call TimerStart(CreateTimer(),0.01,true,function Main_StartE)
endfunction

function Main_StartC takes nothing returns nothing//迷宫分配
    local integer RandomNum = 0
    local integer TempGridID = 0
    call DestroyTimer(GetExpiredTimer())
    set TempGridID = GetRandomDirection()
    if (TempGridID == -1) then
        if (I2R(udg_UsedGridNum + udg_UnableGridNum - 2) / I2R(udg_Length_X * udg_Length_Y) >= udg_Density) and (udg_ReachEnd == true) then //迷宫创建结束判断
            call TimerStart(CreateTimer(),0,false,function Main_StartD)
            call BJDebugMsg("迷宫创建完成")
            return   
        endif   
        if udg_WayLength != 0 then
            set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 16384
        endif
        set udg_WayLength = 0
        set udg_GridID = udg_UsedGrid[GetRandomInt(0,udg_UsedGridNum - 1)]
        if Get01(udg_GridID,14) == 1 then     
            set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] - 16384     
        endif
        call TimerStart(CreateTimer(),0,false,function Main_StartC)
        return
    endif     
    if TempGridID == 0 then//方向设置   
        call Direction_0()
    elseif TempGridID == 1 then
        call Direction_1()
    elseif TempGridID == 2 then
        call Direction_2()
    elseif TempGridID == 3 then
        call Direction_3()
    elseif TempGridID == 4 then
        call Direction_4()
    elseif TempGridID == 5 then
        call Direction_5()
    elseif TempGridID == 6 then
        call Direction_6()
    elseif TempGridID == 7 then
        call Direction_7()
    endif   
    set udg_UsedGrid[udg_UsedGridNum] = udg_GridID
    set udg_UsedGridNum = udg_UsedGridNum + 1         
    if udg_GridID == udg_End then //当前点为终点
        set udg_ReachEnd = true
    endif
    if GetRandomInt(udg_WayLengthMin,udg_WayLengthMax) <= udg_WayLength then
        if (I2R(udg_UsedGridNum + udg_UnableGridNum - 2) / I2R(udg_Length_X * udg_Length_Y) >= udg_Density) and (udg_ReachEnd == true) then //迷宫创建结束判断
            call TimerStart(CreateTimer(),0,false,function Main_StartD)
            call BJDebugMsg("迷宫创建完成")
            return   
        endif   
        set udg_WayLength = 0  
        set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] + 16384
        set udg_GridID = udg_UsedGrid[GetRandomInt(0,udg_UsedGridNum - 1)]
        if Get01(udg_GridID,14) == 1 then
            set udg_Labyrinth[udg_GridID] = udg_Labyrinth[udg_GridID] - 16384         
        endif
    endif
    call TimerStart(CreateTimer(),0,false,function Main_StartC)  
endfunction

function Main_StartB takes nothing returns nothing  //第二个执行的触发,用于初始化udg_Labyrinth、udg_UsedGridNum、udg_UnableGridNum
    local integer i = 0      
    local integer AllGridNum = udg_Length_X * udg_Length_Y
    set udg_WayLength = 0
    set udg_EndWayNum = 0  
    set udg_UsedGridNum = 0
    set udg_UnableGridNum = 2
    set udg_DoingOverNum = 0
    set udg_UnableGrid[0] = udg_Start  
    set udg_UnableGrid[1] = udg_End
    set udg_ReachEnd = false   
    set udg_GridID = udg_Start
    set udg_TopLeftCorner_X = I2R(R2I(udg_TopLeftCorner_X - 64) / 128 * 128 +64)  //X位置偏移
    set udg_TopLeftCorner_Y = I2R(R2I(udg_TopLeftCorner_Y - 64) / 128 * 128 +64)  //Y位置偏移
    set udg_Labyrinth[udg_Start] = udg_Labyrinth[udg_Start] + 36864//2^15+2^12 ,
    set udg_Labyrinth[udg_End] = udg_Labyrinth[udg_End] + 8192 //2^13   
    call TimerStart(CreateTimer(),0,false,function Main_StartC)
    call BJDebugMsg("数据初始化完成")  
endfunction
   
function Main_StartA takes nothing returns nothing //执行的初始函数,创建游戏时执行 ,用于创建连续handle的timer
    local integer i = 0
    local integer  AllGridNum = udg_Length_X * udg_Length_Y
    local timer TempTimer = CreateTimer()
    set udg_FirstTimer = H2I(TempTimer)  
    loop
        set TempTimer = CreateTimer()
        set udg_Labyrinth = 0
        set i = i + 1
        exitwhen i == AllGridNum
    endloop
    call TimerStart(TempTimer,0,false,function Main_StartB)
    set TempTimer = null
    call BJDebugMsg("Timer初始化完成")
endfunction

function GetGridIDLocation takes integer GridID returns location//根据位直ID获得点   
    return Location(udg_TopLeftCorner_X + I2R((GridID- GridID / udg_Length_X * udg_Length_X) * 1152 + 576),udg_TopLeftCorner_Y + I2R(GridID / udg_Length_X * 1152 + 576))
endfunction

function FaceAngle takes integer GridID returns real//根据位直ID获得面向角度
    local real Angle
    local integer Labyrinth = udg_Labyrinth[GridID]
    if Labyrinth - Labyrinth / 2 * 2 == 1 then//下
        set Angle = 270
    endif
    if Labyrinth - Labyrinth / 4 * 4 >= 2 then//右下
        set Angle = 315              
    endif      
    if Labyrinth - Labyrinth / 8 * 8 >= 4 then//右   
        set Angle = 0         
    endif
    if Labyrinth - Labyrinth / 16 * 16 >= 8 then//右上  
        set Angle = 45     
    endif
    if Labyrinth - Labyrinth / 32 * 32 >= 16 then//上   
        set Angle = 90
    endif
    if Labyrinth - Labyrinth / 64 * 64 >= 32 then//左上  
        set Angle = 135
    endif
    if Labyrinth - Labyrinth / 128 * 128 >= 64 then//左   
        set Angle = 180
    endif
    if Labyrinth - Labyrinth / 256 * 256 >= 128 then//左下   
        set Angle = 225
    endif                  
        return Angle      
endfunction[/codes]

说明图片

说明图片

                        系统使用说明
         这个系统虽然被我称为随机迷宫,但是它更像是一个副本区域创建系统。因为这个系统的作用是在一个给定的矩形空白区域内创建带有迷宫性质通路以及周边的简单装饰物。也就是说你可以通过使用这个系统,将一片区域制作成一个副本地图。
         具体效果你可以参考演示地图。


         系统使用方法很简单,复制到自定义函数中。然后根据注释来设置参数。游戏初始化调用Main_StartA即可。迷宫的起点和终点没有设置通向外界的通道,你可以自行创建(注意处理地面通行状态)或者用传送(传送门或移动单位)的方法进入离开区域。
         
         每个支路的尽头的ID都放到了udg_EndWay数组之中。其总数为udg_EndWayNum个。你可以使用系统中的附带函数GetGridIDLocation来获得每个尽头对应的中心点。特别要说的是,所有的区域(也就是被使用了的格子的中间部分,说明图中的红色部分)的大小都是一样的。你可以根据说明图来计算大小。图中每个小方格的边长都是128(游戏距离)。


         每个格子的状态都在udg_Labyrinth数组中对应ID的元素里。存储方式是16位二进制。每一位的含义可以看注释。


         参数说明:
                   具体的参数说明请看注释,不明白的可以参考演示。特别要说明的是注释中的最后又如下三种标注:(临时数据)、(自定义数据)、(固定数据)。临时数据是指函数中临时使用的数据,不需要设置值。自定义数据是只我们自己来设置值的,这些值将影响创建出的效果。固定数据也是需要我们设置的,与自定义数据不同的是,这个值我们是无法选择的。固定数据的类型只有三个变量:udg_DestructableTypeudg_DestructableNum两个是根据udg_DestructableArray来确定的;udg_DestructableType是对应每个udg_DestructableArray的可破坏物的样式总数,比如演示中的冰封皇冠树木的样式总数为10udg_DestructableNumudg_DestructableArray的元素总数。另外一个固定数据的变量是udg_OldGroundType,也就是未处理时的区域的地面纹理类型,演示中为雪地。


         整个系统式游戏初始化时运行的。当然并非必须这样,只是我使用了一个十分简化了的TimerHash系统来传递参数。所以必须初始化运行。如果你想要在其他时候运行,那么请先去掉Main_StartA过程中的   call TimerStart(TempTimer,0,false,function Main_StartB)  这一行,并在游戏初始化时运行Main_StartA。然后当你需要创建区域时,你再调用Main_StartB


         理论上来说,这个系统可以创建多片区域。或者重建一片区域。但是你需要对整个系统进行处理之后才能实现。具体如下:
1、  创建多片区域。那么设置udg_Length_X udg_Length_Y为最大区域的对应值,然后去掉Main_StartA过程中的   call TimerStart(TempTimer,0,false,function Main_StartB)  这一行,并在游戏初始化时运行Main_StartA。最后对应创建的区域设好参数,执行Main_StartB即可。
2、  重建某片区域。这个有些麻烦。方法简单来说就是还原成初始状态后再次创建。具体方法我就不多说了。只是注意,因为不是初始化立即执行系统,所以也要做创建多片区域那样的修改。

随机迷宫1.2.w3x

217 KB, 下载次数: 1167

 楼主| 发表于 2009-9-27 23:22:06 | 显示全部楼层
先发一张效果图!
昨天是半夜弄完的,于是很多说明不是很清楚。我这里多说几句。
首先解释一下那张带颜色的格子图。
那个是说明如何连接通路的。
具体来说就是每个小格代表一个地面纹理(128*128)
红色是指必然使用的区域,也就是如果联通了这个大格,那么这里必然可通行。
黄色是指没有使用的原始部分,会被装饰物覆盖
绿色是上下左右通路的纹理控制,蓝色是斜向的。
根据这个你可以知道每个大格(1152*1152)中哪里是可以通行的,哪里不可以。
参考udg_Labyrinth的对应值可以很方便的了解这个格子的状况。
因而添加各种东西。

参数中注意这两个实数型参数:udg_DestructableRate、udg_Density。
udg_Density是迷宫最小密度,其值是这个迷宫使用的格子数占总数的最小百分比,不过很多时候实际形成的结果是远远大于它的。这个值最大值是1,不过不建议大于0.9,因为这样需要更多的运算。
udg_DestructableRate这个是每个小格子(128*128)存在可破坏物的概率。因为存在可破坏物上限,所以如果你的使用范围很大,udg_Density很小的话,建议减小udg_DestructableRate的值,这个值也是最大为1

系统有两个附加函数,GetGridIDLocation,FaceAngle,第一个前面已经解释,第二个是后加的,这里说一下。
FaceAngle是获得单位面向角度的。也就是保证单位的面向角度是面向通路的。这个函数只用在支路的尽头上,也就是udg_EndWay,这个数组里的ID。
无标题.jpg
回复 支持 反对

使用道具 举报

发表于 2009-9-27 23:31:48 | 显示全部楼层
强 膜拜之
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-27 23:41:49 | 显示全部楼层
忘了说……
为了效果请先将地面的高度处理下

还有,那个能量之书是为了标注支路末端的
回复 支持 反对

使用道具 举报

发表于 2009-9-28 07:52:32 | 显示全部楼层
虽然看不懂J
但是我是否可以理解成‘在256*256的空白地形里无限创建自己想要的地形’?
(可破坏物可以删除,那么‘重置副本’时就删除可破坏物,使之空地用来做其他的副本?)
当然,还要考虑可破坏物上限
如果我理解正确的话,是不是可以用这个系统做‘局域网版的战役’?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-28 08:25:37 | 显示全部楼层
引用第4楼蟋有的蟀于2009-09-28 07:52发表的  :
虽然看不懂J
但是我是否可以理解成‘在256*256的空白地形里无限创建自己想要的地形’?
(可破坏物可以删除,那么‘重置副本’时就删除可破坏物,使之空地用来做其他的副本?)
当然,还要考虑可破坏物上限
如果我理解正确的话,是不是可以用这个系统做‘局域网版的战役’?
能够处理的很有限
比如悬崖就无法处理
另外如果你这么做了的话
因为计算量过大
我不保证不会掉线……
回复 支持 反对

使用道具 举报

发表于 2009-9-28 08:37:46 | 显示全部楼层
1.24想要移植也是泪流满面
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-28 08:56:31 | 显示全部楼层
稍微修改即可
唯一需要修改的就是H2I和I2T
这两个改了就行了
回复 支持 反对

使用道具 举报

发表于 2009-9-28 09:03:07 | 显示全部楼层
可否放出算法的版本
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-28 09:23:49 | 显示全部楼层
算法版本?
迷宫算法么?
回复 支持 反对

使用道具 举报

发表于 2009-9-28 18:59:34 | 显示全部楼层
话说,当时给竹子做地形时我只用悬崖和饰物就做了一个类似阵法的迷宫,很有意思的说。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-28 22:45:57 | 显示全部楼层
引用第11楼玄影阁于2009-09-28 18:59发表的  :
话说,当时给竹子做地形时我只用悬崖和饰物就做了一个类似阵法的迷宫,很有意思的说。
放上来吧
回复 支持 反对

使用道具 举报

发表于 2009-9-29 14:01:20 | 显示全部楼层
引用第12楼疯人¢衰人于2009-09-28 22:45发表的  :

放上来吧
要经过竹子(551155)同意的
回复 支持 反对

使用道具 举报

发表于 2009-9-29 20:19:32 | 显示全部楼层
看下原理
回复 支持 反对

使用道具 举报

发表于 2012-2-9 05:33:52 | 显示全部楼层
板大的文章 看了 必回~

頂~~
回复 支持 反对

使用道具 举报

发表于 2012-2-9 12:44:56 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2012-3-5 19:00:39 | 显示全部楼层
这个好。
回复 支持 反对

使用道具 举报

发表于 2012-3-5 20:18:18 | 显示全部楼层
希瓦是坏人
回复 支持 反对

使用道具 举报

发表于 2012-3-9 07:15:20 | 显示全部楼层
好文章 頂~~~
回复 支持 反对

使用道具 举报

发表于 2012-3-9 23:22:03 | 显示全部楼层
第六个
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2019-10-21 13:45 , Processed in 0.323497 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表