|
随机迷宫
其实这个东西好多人都做过………………
不过都是经典迷宫。
就是只有一条通路,整个迷宫都只有路。没有其余的东西。
从起点到终点只有一条通路……
复杂度很高。
推荐小呆ACG的迷宫闯关
我的是复杂度很低……而且很容易懂……
就是在矩形区域中随机选择N个点,顺次用最短路径连接这些点、起点和终点。
然后一个迷宫就出来了………………
还没有刷怪什么的…………
主要是路径的围墙出了问题。
一开始是创建路径时就一步步建造围墙。
前几天发现这样太不稳定(因为可破坏物是有碰撞的,不能重叠,清除时会比较麻烦)
所以变成了标识+扫描创建。
然后又修改了一些小地方…………
不过总算是把以前弄的东西终结了~~
心情高兴~~
代码:
[jass]
globals
//Const Globals Values
gamecache rmgc = null
constant real rmDesGene = 2
//Setting Globals Values
real rmDistanceBetweenTwoLocs = 256.0
real rmHalf = rmDistanceBetweenTwoLocs / 2.0
integer rmXs = 0
integer rmYs = 0
real rmFirstLocX = 0.0
real rmFirstLocY = 0.0
real rmStartLocX = 0.0
real rmStartLocY = 0.0
real rmEndLocX = 0.0
real rmEndLocY = 0.0
integer rmTerrainType = 0
integer rmAroundTerrainType = 0
//Temp Globals Values
real rmNextLocX = 0.0
real rmNextLocY = 0.0
integer rmNextX = 0
integer rmNextY = 0
integer array rmDesType
integer array rmDesTypeVariation
real array rmDesTypeMinZ
real array rmDesTypeMaxZ
real array rmDesTypeMinSize
real array rmDesTypeMaxSize
integer rmDesTypeNumber = 0
integer array rmTreeType
integer array rmTreeTypeVariation
real array rmTreeTypeMinZ
real array rmTreeTypeMaxZ
real array rmTreeTypeMinSize
real array rmTreeTypeMaxSize
integer rmTreeTypeNumber = 0
integer rmNumberTreesInLoc = 0
integer array rmGoto
integer rmOldGoto = -1
rect rmCleanRect = null
//No.1 Way Globals Values
integer rmXsBetweenLocAndEnd = 0
integer rmYsBetweenLocAndEnd = 0
integer rmLastLoc_X = -1
integer rmLastLoc_Y = -1
integer rmLastGoto = -1
integer rmPointNumber = 0
endglobals
constant function rmH2I takes handle h returns integer
return h
return 0
endfunction
function rmInit takes nothing returns nothing
call FlushGameCache( InitGameCache( "TheRandomMapGC.w3x" ) )
set rmgc = InitGameCache( "TheRandomMapGC.w3x" )
set rmGoto[0] = 0
set rmGoto[1] = 1
set rmGoto[2] = 2
set rmGoto[3] = 3
endfunction
constant function rmLoc2X takes integer locx returns real
return locx * rmDistanceBetweenTwoLocs + rmFirstLocX
endfunction
constant function rmLoc2Y takes integer locy returns real
return locy * rmDistanceBetweenTwoLocs + rmFirstLocY
endfunction
function rmX2Loc takes real x returns integer
return R2I( ( x - rmFirstLocX ) / rmDistanceBetweenTwoLocs )
endfunction
function rmY2Loc takes real y returns integer
return R2I( ( y - rmFirstLocY ) / rmDistanceBetweenTwoLocs )
endfunction
constant function rmOutX takes integer x returns boolean
return x >= 1 and x <= rmXs - 1
endfunction
constant function rmOutY takes integer y returns boolean
return y >= 1 and y <= rmYs - 1
endfunction
function rmSetFace takes integer x, integer y, integer face returns nothing
call StoreBoolean( rmgc, "face" + I2S( face ), I2S( x ) + "," + I2S( y ), true )
endfunction
function rmGetFace takes integer x, integer y, integer face returns boolean
return GetStoredBoolean( rmgc, "face" + I2S( face ), I2S( x ) + "," + I2S( y ) )
endfunction
function rmFlushFace takes integer x, integer y, integer face returns nothing
call FlushStoredBoolean( rmgc, "face" + I2S( face ), I2S( x ) + "," + I2S( y ) )
endfunction
constant function rmGetBack takes integer i returns integer
if i == 0 then
return 1
elseif i == 1 then
return 0
elseif i == 2 then
return 3
elseif i == 3 then
return 2
endif
return -1
endfunction
function rmSetRightRoad takes integer x, integer y returns nothing
call StoreInteger( rmgc, I2S(x), I2S(y), GetStoredInteger( rmgc, I2S(x), I2S(y) ) + 1 )
endfunction
function rmIsRightRoad takes integer x, integer y returns boolean
return GetStoredInteger( rmgc, I2S(x), I2S(y) ) >= 1
endfunction
function rmGetRandomDesType takes nothing returns integer
return GetRandomInt( 0, rmDesTypeNumber - 1 )
endfunction
function rmGetRandomDesVariation takes integer id returns integer
return GetRandomInt( 0, rmDesTypeVariation[id] - 1 )
endfunction
function rmGetRandomDesZ takes integer id returns real
return GetRandomReal( rmDesTypeMinZ[id], rmDesTypeMaxZ[id] )
endfunction
function rmGetRandomDesSize takes integer id returns real
return GetRandomReal( rmDesTypeMinSize[id], rmDesTypeMaxSize[id] )
endfunction
function rmCreateDestructable takes real x, real y, real facing returns nothing
local integer id = rmGetRandomDesType()
local integer variation = rmGetRandomDesVariation(id)
local real z = rmGetRandomDesZ(id)
local real size = rmGetRandomDesSize(id)
call CreateDestructableZ( rmDesType[id], x, y, z, facing, size, variation )
endfunction
function rmCreateDestructable0 takes real x, real y returns nothing
call rmCreateDestructable( x - rmHalf, y + rmHalf / rmDesGene, 180.0 )
call rmCreateDestructable( x - rmHalf, y - rmHalf / rmDesGene, 180.0 )
endfunction
function rmCreateDestructable1 takes real x, real y returns nothing
call rmCreateDestructable( x + rmHalf, y + rmHalf / rmDesGene, 0.0 )
call rmCreateDestructable( x + rmHalf, y - rmHalf / rmDesGene, 0.0 )
endfunction
function rmCreateDestructable2 takes real x, real y returns nothing
call rmCreateDestructable( x + rmHalf / rmDesGene, y + rmHalf, 270.0 )
call rmCreateDestructable( x - rmHalf / rmDesGene, y + rmHalf, 270.0 )
endfunction
function rmCreateDestructable3 takes real x, real y returns nothing
call rmCreateDestructable( x + rmHalf / rmDesGene, y - rmHalf, 90.0 )
call rmCreateDestructable( x - rmHalf / rmDesGene, y - rmHalf, 90.0 )
endfunction
function rmCreateDestructable01 takes integer x, integer y returns nothing
//call rmCreateDestructable( x + rmHalf / rmDesGene, y + rmHalf, 270.0 )
//call rmCreateDestructable( x - rmHalf / rmDesGene, y + rmHalf, 270.0 )
//call rmCreateDestructable( x + rmHalf / rmDesGene, y - rmHalf, 90.0 )
//call rmCreateDestructable( x - rmHalf / rmDesGene, y - rmHalf, 90.0 )
call rmSetFace( x, y, 0 )
call rmSetFace( x, y, 1 )
endfunction
function rmCreateDestructable23 takes integer x, integer y returns nothing
//call rmCreateDestructable( x + rmHalf, y + rmHalf / rmDesGene, 0.0 )
//call rmCreateDestructable( x + rmHalf, y - rmHalf / rmDesGene, 0.0 )
//call rmCreateDestructable( x - rmHalf, y + rmHalf / rmDesGene, 180.0 )
//call rmCreateDestructable( x - rmHalf, y - rmHalf / rmDesGene, 180.0 )
call rmSetFace( x, y, 2 )
call rmSetFace( x, y, 3 )
endfunction
//直道创建
function rmCreateDestructable_LeftUp takes integer x, integer y returns nothing
//call rmCreateDestructable( x + rmHalf / rmDesGene - 1.0, y + rmHalf, 270.0 )
//call rmCreateDestructable( x - rmHalf / rmDesGene + 1.0, y + rmHalf, 270.0 )
//call rmCreateDestructable( x - rmHalf, y + rmHalf / rmDesGene - 1.0, 180.0 )
//call rmCreateDestructable( x - rmHalf, y - rmHalf / rmDesGene + 1.0, 180.0 )
call rmSetFace( x, y, 1 )//这里要对开
call rmSetFace( x, y, 3 )
endfunction
function rmCreateDestructable_RightUp takes integer x, integer y returns nothing
//call rmCreateDestructable( x + rmHalf / rmDesGene, y + rmHalf, 270.0 )
//call rmCreateDestructable( x - rmHalf / rmDesGene, y + rmHalf, 270.0 )
//call rmCreateDestructable( x + rmHalf, y + rmHalf / rmDesGene, 0.0 )
//call rmCreateDestructable( x + rmHalf, y - rmHalf / rmDesGene, 0.0 )
call rmSetFace( x, y, 0 )
call rmSetFace( x, y, 3 )
endfunction
function rmCreateDestructable_LeftDown takes integer x, integer y returns nothing
//call rmCreateDestructable( x + rmHalf / rmDesGene, y - rmHalf, 90.0 )
//call rmCreateDestructable( x - rmHalf / rmDesGene, y - rmHalf, 90.0 )
//call rmCreateDestructable( x - rmHalf, y + rmHalf / rmDesGene, 180.0 )
//call rmCreateDestructable( x - rmHalf, y - rmHalf / rmDesGene, 180.0 )
call rmSetFace( x, y, 1 )
call rmSetFace( x, y, 2 )
endfunction
function rmCreateDestructable_RightDown takes integer x, integer y returns nothing
//call rmCreateDestructable( x + rmHalf / rmDesGene, y - rmHalf, 90.0 )
//call rmCreateDestructable( x - rmHalf / rmDesGene, y - rmHalf, 90.0 )
//call rmCreateDestructable( x + rmHalf, y + rmHalf / rmDesGene, 0.0 )
//call rmCreateDestructable( x + rmHalf, y - rmHalf / rmDesGene, 0.0 )
call rmSetFace( x, y, 0 )
call rmSetFace( x, y, 2 )
endfunction
//弯道创建
function rmRemoveDestructable takes nothing returns nothing
call RemoveDestructable( GetEnumDestructable() )
endfunction
function rmDesDestructable takes real x, real y returns nothing
call SetRect( rmCleanRect, x - rmHalf, y - rmHalf, x + rmHalf, y + rmHalf )
call EnumDestructablesInRect( rmCleanRect, null, function rmRemoveDestructable )
endfunction
function rmCleanGoto takes nothing returns nothing
local integer i = 0
loop
set rmGoto[ i ] = i
set i = i + 1
exitwhen i > 3
endloop
endfunction
function rmCleanDesXY takes real minx, real miny, real maxx, real maxy returns nothing
call SetRect( rmCleanRect, minx, miny, maxx, maxy )
call EnumDestructablesInRect( rmCleanRect, null, function rmRemoveDestructable )
endfunction
function rmStoreRandomLoc takes nothing returns nothing
set rmNextX = GetRandomInt( 1, rmXs - 1 )
set rmNextY = GetRandomInt( 1, rmYs - 1 )
set rmNextLocX = rmLoc2X( rmNextX )
set rmNextLocY = rmLoc2Y( rmNextY )
endfunction
function rmCreateDestructables takes integer new, integer old, integer locx, integer locy, real x, real y returns nothing
if old == -1 then
if new == 0 or new == 1 then
call rmCreateDestructable01( rmX2Loc( x ), rmY2Loc( y ) )
else
call rmCreateDestructable23( rmX2Loc( x ) , rmY2Loc( y ) )
endif
return
endif
if new == 0 then
if old == 0 or old == 1 then
call rmCreateDestructable01( rmX2Loc( x ), rmY2Loc( y ) )
elseif old == 2 then
call rmCreateDestructable_LeftUp( rmX2Loc( x ), rmY2Loc( y ) )
elseif old == 3 then
call rmCreateDestructable_LeftDown( rmX2Loc( x ), rmY2Loc( y ) )
endif
elseif new == 1 then
if old == 0 or old == 1 then
call rmCreateDestructable01( rmX2Loc( x ), rmY2Loc( y ) )
elseif old == 2 then
call rmCreateDestructable_RightUp( rmX2Loc( x ), rmY2Loc( y ) )
elseif old == 3 then
call rmCreateDestructable_RightDown( rmX2Loc( x ), rmY2Loc( y ) )
endif
elseif new == 2 then
if old == 2 or old == 3 then
call rmCreateDestructable23( rmX2Loc( x ) , rmY2Loc( y ) )
elseif old == 1 then
call rmCreateDestructable_LeftDown( rmX2Loc( x ), rmY2Loc( y ) )
elseif old == 0 then
call rmCreateDestructable_RightDown( rmX2Loc( x ), rmY2Loc( y ) )
endif
elseif new == 3 then
if old == 2 or old == 3 then
call rmCreateDestructable23( rmX2Loc( x ) , rmY2Loc( y ) )
elseif old == 1 then
call rmCreateDestructable_LeftUp( rmX2Loc( x ), rmY2Loc( y ) )
elseif old == 0 then
call rmCreateDestructable_RightUp( rmX2Loc( x ), rmY2Loc( y ) )
endif
endif
endfunction
//连接 近的2点
function rmLinkPoint takes integer X, integer Y, real x, real y, integer new, integer old returns nothing
local integer right = GetStoredInteger( rmgc, I2S(X), I2S(Y) )
if right < 1 then
call rmDesDestructable( x, y )
return
endif
if right >= 1 then
//call rmCleanDestructables( x, y, new, old )
//else
// call TerrainDeformCrater( x, y, rmDistanceBetweenTwoLocs, -64.0, 0, false )
call SetTerrainType( x, y, rmTerrainType, -1, R2I( rmDistanceBetweenTwoLocs / 128.0 ), 1 )
call rmCreateDestructables( new, old, X, Y, x, y )
endif
endfunction
//连接 远的2点
function rmLinkLoc takes integer X, integer Y, real x, real y, integer X2, integer Y2, real x2, real y2 returns nothing
local integer walkx = 0
local integer walky = 0
local integer walk = 0
local integer tx1 = X
local integer ty1 = Y
local integer tx2 = tx1
local integer ty2 = ty1
local integer goto = 0
local integer oldgoto= rmLastGoto
local boolean b = false
if X2 < X then
set walkx = -1
elseif X2 > X then
set walkx = 1
else
set walkx = 0
endif
if Y2 < Y then
set walky = -1
elseif Y2 > Y then
set walky = 1
else
set walky = 0
endif
loop
if tx1 == X2 and ty1 == Y2 then
exitwhen true // break
elseif tx1 == X2 then
set walk = 1
elseif ty1 == Y2 then
set walk = 0
else
set walk = GetRandomInt( 0, 1 )
endif
if walk == 0 then
set tx2 = tx1 + walkx
elseif walk == 1 then
set ty2 = ty1 + walky
endif
if tx2 > tx1 then
set goto = 0
elseif tx2 < tx1 then
set goto = 1
elseif ty2 > ty1 then
set goto = 2
elseif ty2 < ty1 then
set goto = 3
endif
//tx1 = 上一次的点的X坐标点
//ty1 = 上一次的点的Y坐标点
//tx2 = 这一次的点的X坐标点
//ty2 = 这一次的点的Y坐标点
call rmSetRightRoad( tx1, ty1 )
call rmLinkPoint( tx1, ty1, rmLoc2X(tx1), rmLoc2Y(ty1), goto, oldgoto )
//call AddLightning( "DRAB", true, rmLoc2X(tx1), rmLoc2Y(ty1), rmLoc2X(tx2), rmLoc2Y(ty2) )
if b == false then
if oldgoto == rmGetBack( goto ) then
if goto == 0 or goto == 1 then
call rmFlushFace( rmX2Loc( x ), rmY2Loc( y ), goto )
elseif goto == 2 or goto == 3 then
call rmFlushFace( rmX2Loc( x ), rmY2Loc( y ), rmGetBack( goto ) )
endif
endif
set b = true
endif
set oldgoto = goto
set tx1 = tx2
set ty1 = ty2
endloop
set rmLastGoto = oldgoto
endfunction
function rmMakeRandomLoc takes integer X, integer Y, real x, real y returns nothing
call rmStoreRandomLoc()
call rmLinkLoc( X, Y, x, y, rmNextX, rmNextY, rmNextLocX, rmNextLocY )
endfunction
//连接 终点和起点
function rmMakeRandomMapWithLocs takes integer number returns nothing
local integer i = 0
local integer X = rmNextX
local integer Y = rmNextY
local real x = rmNextLocX
local real y = rmNextLocY
call rmMakeRandomLoc( X, Y, x, y )
loop
set i = i + 1
exitwhen i > number
call rmMakeRandomLoc( rmNextX, rmNextY, rmNextLocX, rmNextLocY )
endloop
call rmLinkLoc( rmNextX, rmNextY, rmNextLocX, rmNextLocY, rmX2Loc(rmEndLocX), rmY2Loc(rmEndLocY), rmEndLocX, rmEndLocY )
endfunction
function rmInitMap takes integer Xs, integer Ys returns nothing
local integer i = 0
local integer j = 0
local real x = 0.0
local real y = 0.0
loop
set i = i + 1
exitwhen i >= Xs
set j = 0
loop
set j = j + 1
exitwhen j >= Ys
set x = rmFirstLocX + i * rmDistanceBetweenTwoLocs
set y = rmFirstLocY + j * rmDistanceBetweenTwoLocs
call SetTerrainType( x, y, rmAroundTerrainType, -1, R2I( rmDistanceBetweenTwoLocs / 128.0 ), 1 )
endloop
endloop
call rmCleanDesXY( rmFirstLocX - 100.0, rmFirstLocY - 100.0, rmFirstLocX + rmLoc2X( Xs ) + 100.0, rmFirstLocY + rmLoc2Y( Ys ) )
endfunction
function rmCreateCond takes integer x, integer y, integer face returns boolean
if not rmIsRightRoad( x, y ) then
return true
else
if not rmGetFace( x, y, face ) then
return false
endif
endif
return true
endfunction
function rmCreateDestructableAtLoc takes integer x, integer y returns nothing
if not rmGetFace( x, y, 0 ) and rmCreateCond( x - 1, y, 1 ) then
call rmCreateDestructable0( rmLoc2X( x ), rmLoc2Y( y ) )
endif
if not rmGetFace( x, y, 1 ) then
call rmCreateDestructable1( rmLoc2X( x ), rmLoc2Y( y ) )
endif
if not rmGetFace( x, y, 2 ) and rmCreateCond( x, y + 1, 3 ) then
call rmCreateDestructable2( rmLoc2X( x ), rmLoc2Y( y ) )
endif
if not rmGetFace( x, y, 3 ) then
call rmCreateDestructable3( rmLoc2X( x ), rmLoc2Y( y ) )
endif
endfunction
function rmPlantDes takes nothing returns nothing
local integer i = 0
local integer j = 0
loop
set i = i + 1
exitwhen i >= rmXs
set j = 0
loop
set j = j + 1
exitwhen j >= rmYs
if GetStoredInteger( rmgc, I2S(i), I2S(j) ) > 0 then
call rmCreateDestructableAtLoc( i, j )
endif
endloop
endloop
endfunction
function rmGetRandomTreeType takes nothing returns integer
return GetRandomInt( 0, rmTreeTypeNumber - 1 )
endfunction
function rmGetRandomTreeVariation takes integer id returns integer
return GetRandomInt( 0, rmTreeTypeVariation[id] - 1 )
endfunction
function rmGetRandomTreeZ takes integer id returns real
return GetRandomReal( rmTreeTypeMinZ[id], rmTreeTypeMaxZ[id] )
endfunction
function rmGetRandomTreeSize takes integer id returns real
return GetRandomReal( rmTreeTypeMinSize[id], rmTreeTypeMaxSize[id] )
endfunction
function rmCreateTree takes real x, real y returns nothing
local integer id = rmGetRandomTreeType()
local integer variation = rmGetRandomTreeVariation(id)
local real z = rmGetRandomTreeZ(id)
local real size = rmGetRandomTreeSize(id)
call CreateDestructableZ( rmTreeType[id], x, y, z, GetRandomReal( 0.0, 360.0 ), size, variation )
endfunction
function rmCreateTreeAtLoc takes integer X, integer Y returns nothing
local integer i = 0
local real x = rmLoc2X( X )
local real y = rmLoc2Y( Y )
loop
exitwhen i >= rmNumberTreesInLoc
call rmCreateTree( x + GetRandomReal( -rmHalf / 2, rmHalf / 2 ), y + GetRandomReal( -rmHalf / 2, rmHalf / 2 ) )
set i = i + 1
endloop
endfunction
function rmPlantTree takes nothing returns nothing
local integer i = 0
local integer j = 0
loop
set i = i + 1
exitwhen i >= rmXs
set j = 0
loop
set j = j + 1
exitwhen j >= rmYs
if GetStoredInteger( rmgc, I2S(i), I2S(j) ) <= 0 then
call rmCreateTreeAtLoc( i, j )
endif
endloop
call FlushStoredMission( rmgc, I2S( i ) )
endloop
call FlushStoredMission( rmgc, "face0" )
call FlushStoredMission( rmgc, "face1" )
call FlushStoredMission( rmgc, "face2" )
call FlushStoredMission( rmgc, "face3" )
endfunction
function rmCreateRandomRoad takes nothing returns nothing
call rmMakeRandomMapWithLocs( rmPointNumber )
call rmPlantDes()
set rmLastLoc_X = -1
set rmLastLoc_Y = -1
call RemoveRect( rmCleanRect )
set rmCleanRect = null
call TimerStart( GetExpiredTimer(), 0.0, false, function rmPlantTree )
endfunction
function rmMakeRandomMap takes integer number returns nothing
local integer Xs = rmXs
local integer Ys = rmYs
local real FirstX = rmFirstLocX
local real FirstY = rmFirstLocY
local real StartX = rmStartLocX
local real StartY = rmStartLocY
local real EndX = rmEndLocX
local real EndY = rmEndLocY
local integer i = 0
set rmNextLocX = StartX
set rmNextLocY = StartY
set rmNextX = rmX2Loc(rmNextLocX)
set rmNextY = rmY2Loc(rmNextLocY)
set rmCleanRect = Rect( 0.0, 0.0, 0.0, 0.0 )
call rmCleanGoto()
set rmOldGoto = -1
call rmInitMap( Xs, Ys )
call TimerStart( GetExpiredTimer(), 0.0, false, function rmCreateRandomRoad )
endfunction
function rmMakeRandomMap_WaitAction takes nothing returns nothing
call rmMakeRandomMap( rmPointNumber )
endfunction
function rmMakeRandomMap_Wait takes integer number returns nothing
set rmPointNumber = number
call TimerStart( CreateTimer(), 0.0, false, function rmMakeRandomMap_WaitAction )
endfunction
[/jass] |
|