Avangs

  • 게임 정보
    • 게임 소개
    • 게임 리뷰
    • 게임 실황
    • 게임 공략
    • 모바일 테스트
  • 게임 작품new
    • 완성작 게임
    • 체험판 게임
    • 한글판 게임new
    • 온라인 게임
    • 추천작 제작자 저장소
  • 투표선정 작품
    • 아방스 추천작
    • 완성 기대작
    • 투표 신청
    • 투표소
    • 투표 결과
  • 강좌
    • 아방스 칼럼
    • 비주얼노벨 강좌
    • 알만툴 강좌
      • MZ 강좌
      • MV 강좌
      • VX Ace 강좌
      • VX 강좌
      • XP 강좌
      • 2003 강좌
      • 2000 강좌
    • 게임메이커 강좌
    • 울프툴 강좌
    • 3D 게임제작 강좌
    • 2D 게임제작 강좌
    • 그래픽 제작 강좌
    • 기타 강좌
  • 질문과 답변
    • 자주 묻는 질문
    • 질문과 답변
    • 제작의뢰
  • 커뮤니티
    • 구인·구직·외주
    • 테스트 요청
    • 자유게시판
    • 게임계 소식
    • 유머&정보
    • 사이트링크
    • 이벤트&대회
  • 창작
    • 게임 기획
    • 맵배치
    • 글쓰기
    • 그리기
    • 음악
  • 자료실
    • 게임제작툴
    • 예제 및 샘플
    • 그래픽 소재
      • 오리지널 소재
      • 이차창작 소재
      • 수정·개조 소재
      • 외부 소재
    • 사운드 소재
    • 확장·플러그인·스크립트
      • MZ 플러그인
      • MV 플러그인
      • Ace 스크립트
      • VX 스크립트
      • XP 스크립트
      • 2k3 플러그인
      • VN 플러그인·확장
    • 외부 소재사이트
    • 기타 자료
      • 한글화툴
      • 무료 폰트
      • 유틸리티
    • 디자인 참고자료
  • 고객센터
    • 공지사항
    • 건의 및 신고
    • 핫 이슈
로그인 회원가입
Avangs
  • 게임 정보
    • 게임 소개
    • 게임 리뷰
    • 게임 실황
    • 게임 공략
    • 모바일 테스트
  • 게임 작품new
    • 완성작 게임
    • 체험판 게임
    • 한글판 게임new
    • 온라인 게임
    • 추천작 제작자 저장소
  • 투표선정 작품
    • 아방스 추천작
    • 완성 기대작
    • 투표 신청
    • 투표소
    • 투표 결과
  • 강좌
    • 아방스 칼럼
    • 비주얼노벨 강좌
    • 알만툴 강좌
      • MZ 강좌
      • MV 강좌
      • VX Ace 강좌
      • VX 강좌
      • XP 강좌
      • 2003 강좌
      • 2000 강좌
    • 게임메이커 강좌
    • 울프툴 강좌
    • 3D 게임제작 강좌
    • 2D 게임제작 강좌
    • 그래픽 제작 강좌
    • 기타 강좌
  • 질문과 답변
    • 자주 묻는 질문
    • 질문과 답변
    • 제작의뢰
  • 커뮤니티
    • 구인·구직·외주
    • 테스트 요청
    • 자유게시판
    • 게임계 소식
    • 유머&정보
    • 사이트링크
    • 이벤트&대회
  • 창작
    • 게임 기획
    • 맵배치
    • 글쓰기
    • 그리기
    • 음악
  • 자료실
    • 게임제작툴
    • 예제 및 샘플
    • 그래픽 소재
      • 오리지널 소재
      • 이차창작 소재
      • 수정·개조 소재
      • 외부 소재
    • 사운드 소재
    • 확장·플러그인·스크립트
      • MZ 플러그인
      • MV 플러그인
      • Ace 스크립트
      • VX 스크립트
      • XP 스크립트
      • 2k3 플러그인
      • VN 플러그인·확장
    • 외부 소재사이트
    • 기타 자료
      • 한글화툴
      • 무료 폰트
      • 유틸리티
    • 디자인 참고자료
  • 고객센터
    • 공지사항
    • 건의 및 신고
    • 핫 이슈
로그인 회원가입

NOTICE

공지사항
더보기
  • 서버 안정성 및 보안 강화 조치 04.20

Recently Added Games

최근 등록 게임
  • 어드벤쳐 고철에 파묻힌 데모나 (屑鉄まとうデモナ) newfile 08.19
  • 어드벤쳐 비올레 저택의 시온 : 꽃눈의 저택|RPG Maker MZ 단편 심리공포 어드벤처 file 08.17
  • 기타 (똥 주의)그저 똥을 누러 가는 게임 Re:Boot updatefile 08.16
  • 롤플레잉 SACCHARINE SYNC (DEMO) 배포 file 08.12
  • 기타 (완성작) 야구장에 가자4 file 2 07.07
맵/타일
2009.02.22 12:24

Random Map Generator by Wachunga@rmxp.net

백호
조회 수 1181 추천 수 0 댓글 0
크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
이전에 올라온 모 일본쪽 스크립트처럼 임의의 던전맵을 생성할 수 있도록 하는 스크립트입니다.

http://s88387243.onlinehome.us/rmxp/rand_maze1.jpg
http://s88387243.onlinehome.us/rmxp/rand_maze2.jpg
http://s88387243.onlinehome.us/rmxp/rand_maze3.jpg

=begin

======================
Random Map Generator - version 0.51
======================
by Wachunga, based on Jamis Buck's D&D dungeon generator

==============
Instructions
==============

To indicate a map is to be randomly generated, include <rand> in its
name. You may also optionally specify custom randomness, sparsity and
deadend removal parameters to guide how the map is generated
(see comments within for more details). These may also be included
in the map name, as in this example: "XYZ <rand><0.8><5><0.8>"
(from left to right, randomness, sparsity and deadend removal in that order).
Finally, the optional parameter <save> may immediately follow <rand> to
indicate that the map should be generated randomly the first time but then
saved and remain the same thereafter instead of randomizing again.

Events are not erased on the map which will be randomly generated, but
there is no way to guarantee they'll be positioned correctly. (The only
exceptions to this are two events which determine the start and end of the
maze.)

Place an event named <start> to specify a location you'd like the player to
begin the maze (else a default is chosen). To avoid appearing inside a wall,
the start location should not be at any of the four corners of the map nor
any tile where x is even or y is odd (exceptions occur along an edge of the
map, i.e. when x=0, x=width-1, y=0 or y=height-1). The diagram below may
clarify, where discouraged starting points are marked with an X:

yx 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 X X X X X X X X X X X
1 X X X X X X X X X X X X X X X X X X X X
2 X X X X X X X X X
3 X X X X X X X X X X X X X X X X X X X X
4 X X X X X X X X X
5 X X X X X X X X X X X X X X X X X X X X
6 X X X X X X X X X
7 X X X X X X X X X X X X X X X X X X X X
8 X X X X X X X X X
9 X X X X X X X X X X X X X X X X X X X X
10 X X X X X X X X X
11 X X X X X X X X X X X X X X X X X X X X
12 X X X X X X X X X
13 X X X X X X X X X X X X X X X X X X X X
14 X X X X X X X X X X X

(These restrictions are unfortunate, but necessary. Note as well that if
you're not using a wall face then y SHOULD BE even. Either way,
you should get a warning message if you've placed a start/end incorrectly.)

If you want there to be a passage leading off the map, the start location
must be placed on an edge (i.e. x=0, y=0, x=width-1 or y=height-1).
Alternatively, the start and/or exit locations can be somewhere in the
interior of the map... in this case the player arrives/exits by magic,
falling, climbing, etc.

All the above also applies for the exit location, except the event is named
<end>. Again, a default end is chosen if one is not supplied.

Of course, if the player is to be able to exit the map from either of
these two points, you must make the event teleport appropriately.

Also, the teleport into the maze should point at same square as the <start>
event, or else you may get stuck in a wall.

You can specify which tiles to use for the floor, walls, etc in the Maze
class (just add an appropriate 'elsif').

Questions and feedback should be directed to the thread in the
"User-Submitted RGSS Scripts" forum at [url=http://www.rmxp.net/forums]http://www.rmxp.net/forums[/url]

=end

$save_map_list = []

class Game_Map

alias old_setup_map setup_map
def setup_map(map_id)
old_setup_map(map_id)
tags = map_name.delete(' ').scan(/<[A-Za-z0-9_.]+>/) # get all the tags
if not tags.empty? and tags[0].upcase == '<RAND>'
tags.shift # remove the first element
if not tags.empty? and tags[0].upcase == '<SAVE>'
$save_map_list.push(@map_id)
tags.shift
end
if not tags.empty?
for i in 0...tags.length
tags[i] = tags[i].delete("<>").to_f
end
end
startX = 0; startY = 2 # default starting position
endX = @map.width-1; endY = @map.height-1 # default ending position
# note that these defaults haven't yet been tested much
for i in @map.events.keys
if @map.events[i].name.upcase == '<START>'
startX = @map.events[i].x
startY = @map.events[i].y
elsif @map.events[i].name.upcase == '<END>'
endX = @map.events[i].x
endY = @map.events[i].y
end
end
# note that *tags will expand the array, passing individual elements
# (if any) as arguments (randomness, sparsity and chance to remove deadends)
# e.g. if map name includes "<rand><0.5><10><0.6>", then the call is:
# maze = Maze.new( @map.width, @map.height, startX, startY, endX, endY, 0.5, 10, 0.6)
maze = Maze.new( @map.tileset_id, @map.width, @map.height, startX, startY, endX, endY, *tags)
# set these up for teleports into the maze
maze.draw
end
end

def data=(newdata)
@map.data = newdata
end

def map_name
return load_data("Data/MapInfos.rxdata")[@map_id].name
end

end



class Maze

WALL = 0
PASSAGE = 1

attr_reader :width
attr_reader :height
attr_reader :startX
attr_reader :startY
attr_reader :endX
attr_reader :endY

def initialize(pTileset, pWidth, pHeight, pStartX, pStartY, pEndX, pEndY,
pRandomness=0.5, pSparsity=3, pRemovalChance=0.5)
@tileset = pTileset
@width = pWidth
@height = pHeight
@startX = pStartX
@startY = pStartY
@endX = pEndX
@endY = pEndY

# prepare the base matrix
@base = Direction_Matrix.new(@width, @height, @startX, @startY, @endX, @endY, pRandomness, pSparsity, pRemovalChance)

# reset everything in the Tile module to 0
Tile.floor = 0
Tile.wall = 0
Tile.wallFace = 0

# prepare the tiles depending on the tileset
if @tileset == 27
Tile.setFloor(2,1) # 384
Tile.setWall(1,2) # 48-95
Tile.setWallFace(4,2) # 401
elsif @tileset == 51
Tile.setFloor(2,2) # 384
Tile.setWall(2,1) # 385
#elsif @tileset == 'y'
# others go here
else
# nothing specified so just use default
Tile.setFloor(2,1) # 384
Tile.setWall(1,2) # 48-95
end

# if no wall face is being used, then Y locations should be ODD (opposite of
# when using a wall face)
if (@startX % 2) == 0 and @startX != 0 and @startX != @width-1
print 'Warning: player may start in a wall (starting X location is even).'
end
if Tile.wallFace != 0
if (@startY % 2) != 0 and @startY != 0 and @startY != @height-1
print 'Warning: player may start in a wall (starting Y location is odd).'
end
else
if (@startY % 2) == 0 and @startY != 0 and @startY != @height-1
print 'Warning: player may start in a wall (starting Y location is even).'
end
end

if (@endX % 2) == 0 and @endX != 0 and @endX != @width-1
print 'Warning: maze end may be unreachable (X location is even).'
end
if Tile.wallFace != 0
if (@endY % 2) != 0 and @endY != 0 and @endY != @height-1
print 'Warning: maze end may be unreachable (Y location is odd).'
end
else
if (@endY % 2) == 0 and @endY != 0 and @endY != @height-1
print 'Warning: maze end may be unreachable (Y location is even).'
end
end


# initialized with all walls
@matrix = Array.new(@width, WALL)
for i in 0...@width
@matrix[i] = Array.new(@height, WALL)
end

setup
end


=begin
Sets up the actual maze from a base matrix of only directions.
(Basic algorithm from Jamis Buck's D&D dungeon generator.)
=end
def setup

for x in 0...@base.width
for y in 0...@base.height
dir = @base.matrix[x][y]
if (dir != 0) # not sparsified
@matrix[x*2+1][y*2+1] = PASSAGE
end
if ((dir & Direction_Matrix::NORTH) != 0)
@matrix[x*2+1][y*2] = PASSAGE
end
if ((dir & Direction_Matrix::WEST) != 0)
@matrix[x*2][y*2+1] = PASSAGE
end
# only necessary for right edge start/exit
if ((dir & Direction_Matrix::EAST) != 0)
@matrix[x*2+2][y*2+1] = PASSAGE
# if extra wall is there, need to "dig deeper"
if (@width % 2) == 0 and x*2+3 == @width-1
@matrix[x*2+3][y*2+1] = PASSAGE
end
end
# only necessary for bottom edge start/exit
if ((dir & Direction_Matrix::SOUTH) != 0)
@matrix[x*2+1][y*2+2] = PASSAGE
# if extra wall is there, need to "dig deeper"
if (@height % 2) == 0 and y*2+3 == @height-1
@matrix[x*2+1][y*2+3] = PASSAGE
end
end
end
end
end

=begin
Display the matrix in an ASCII table (useful for debugging).
(Much more readable if you're using a monospaced font for dialog boxes.)
=end
def display
char_array = Array.new(@width, 0)
for i in 0...@width
char_array[i] = Array.new(@height, 0)
end

for x in 0...@width
for y in 0...@height
tile = @matrix[x][y]
char = ' '
if ((tile == WALL)) then char << '#' end
if ((tile == PASSAGE)) then char << ' ' end
char_array[y][x] = char
end
end

display = ''
for i in 0...@height
display << char_array[i].flatten.to_s << "n"
end
print display
end


=begin
Draw the maze using the map's tileset.
=end
def draw
newdata = Table.new(@width, @height, 3)
# put down the floor on the first layer (z=0)
z = 0
for x in 0...@width
for y in 0...@height
newdata[x,y,z] = Tile.floor
end
end

# now for the walls on the second layer (z=1)
z = 1

if Tile.wall.type.to_s.upcase != "HASH" # not autotiles
for x in 0...@width
for y in 0...@height
newdata[x,y,z] = Tile.wall if (@matrix[x][y] == WALL)
end
end
else # autotiles...
for x in 0...@width
for y in 0...@height
# skip passages
if (@matrix[x][y] == PASSAGE) then next end

# calculate adjacent walls
adj = ''

if (x == 0)
adj << '147'
else
if (y == 0) then adj << '1'
else
if (@matrix[x-1][y-1] == WALL) then adj << '1' end
end
if (@matrix[x-1][y] == WALL) then adj << '4' end
if (y == @height-1) then adj << '7'
else
if (@matrix[x-1][y+1] == WALL) then adj << '7' end
end
end

if (x == @width-1)
adj << '369'
else
if (y == 0) then adj << '3'
else
if (@matrix[x+1][y-1] == WALL) then adj << '3' end
end
if (@matrix[x+1][y] == WALL) then adj << '6' end
if (y == @height-1) then adj << '9'
else
if (@matrix[x+1][y+1] == WALL) then adj << '9' end
end
end

if (y == 0)
adj << '2'
else
if (@matrix[x][y-1] == WALL) then adj << '2' end
end
if (y == @height-1)
adj << '8'
else
if (@matrix[x][y+1] == WALL) then adj << '8' end
end

# if no adjacent walls, set it as 0
if (adj == '') then adj = '0' end

# convert to an array, sort, and then back to a string
adj = adj.split(//).sort.join

newdata[x,y,z] = eval 'Tile.wall[adj.to_i]'

# show single wall tile beneath bottom-facing walls
if Tile.wallFace > 0
if not adj.include?('8')
newdata[x,y+1,z] = Tile.wallFace
end
end
end # for
end # for
end # if-else
$game_map.data = newdata
end # draw method

end



=begin
A matrix whose elements each contains 1-4 directions (north, east, south,
west) forming the basis for a maze or dungeon.

(Basic algorithms from Jamis Buck's D&D dungeon generator.)
=end
class Direction_Matrix
NORTH = 0b00001
EAST = 0b00010
SOUTH = 0b00100
WEST = 0b01000
ALL_DIRS = NORTH | EAST | SOUTH | WEST
FLAG = 0b10000

attr_reader :width
attr_reader :height
attr_reader :matrix

def initialize(pWidth, pHeight, pStartX, pStartY, pEndX, pEndY,
pRandomness, pSparsity, pRemovalChance)
@width = pWidth/2
@height = pHeight/2
# convert to Direction_Matrix's dimensions
@startX = pStartX/2
@startY = pStartY/2
@endX = pEndX/2
@endY = pEndY/2

# if even, decrement by 1
@width -= 1 if (pWidth % 2 == 0)
@height -= 1 if (pHeight % 2 == 0)
if @startX != 0
@startX -= 1 if (pStartX % 2 == 0)
end
if @startY != 0
@startY -= 1 if (pStartY % 2 == 0)
end
if @endX != 0
@endX -= 1 if (pEndX % 2 == 0)
end
if @endY != 0
@endY -= 1 if (pEndY % 2 == 0)
end

# handle a weird situation
if @startX >= @width then @startX = @width-1 end
if @endX >= @width then @endX = @width-1 end

@randomness = pRandomness
@sparsity = pSparsity
@removalChance = pRemovalChance

@matrix = Array.new(@width, 0)
for i in 0...@width
@matrix[i] = Array.new(@height, 0)
end

generate

# we need the original start/end locations and width/height in these cases
if pStartY == 0
@matrix[@startX][@startY] |= NORTH
elsif pStartX == 0
@matrix[@startX][@startY] |= WEST
elsif (pStartX == @width*2+1 and (pWidth % 2) == 0) or
(pStartX == @width*2 and (pWidth % 2) != 0)
@matrix[@startX][@startY] |= EAST
elsif (pStartY == @height*2+1 and (pHeight % 2) == 0) or
(pStartY == @height*2 and (pHeight % 2) != 0)
@matrix[@startX][@startY] |= SOUTH
end

if pEndY == 0
@matrix[@endX][@endY] |= NORTH
elsif pEndX == 0
@matrix[@endX][@endY] |= WEST
elsif (pEndX == @width*2+1 and (pWidth % 2) == 0) or
(pEndX == @width*2 and (pWidth % 2) != 0)
@matrix[@endX][@endY] |= EAST
elsif (pEndY == @height*2+1 and (pHeight % 2) == 0) or
(pEndY == @height*2 and (pHeight % 2) != 0)
@matrix[@endX][@endY] |= SOUTH
end

sparsify
removeDeadends

end


=begin
The algorithm for generating random mazes is as follows:
(1) randomly pick a starting tile from the map
(2) pick a random direction and move that way as long as there
is a new tile in that direction and hasn't been visited yet
(3) perform (2) until there is no valid direction to move in, then
pick a new tile that HAS been visited before and perform (2)
and (3) until all the tiles have been visited
=end
def generate
testedDirs = lastDir = straightStretch = 0

x = @startX
y = @startY

remaining = @width * @height - 1

# loop for all remaining tiles
while (remaining > 0)

if (testedDirs == ALL_DIRS)
# we're stuck so choose an already-visited tile
while true
x = rand(@width)
y = rand(@height)
break if @matrix[x][y] != 0
end
testedDirs = @matrix[x][y]
end

# eliminate impossible directions
if (x < 1) then testedDirs |= WEST
elsif (x+1 > @width) then testedDirs |= EAST
end

if (y < 1) then testedDirs |= NORTH
elsif (y+1 > @height) then testedDirs |= SOUTH
end

randomSelection = false

# depending on randomness parameter of map,
# either select direction randomly or continue straight
# (but no stretch can be longer than half the width/height)
if ( rand < @randomness)
randomSelection = true
else
case lastDir
when NORTH
if ( y>0 and straightStretch < @height/2 and @matrix[x][y-1]==0 )
direction = lastDir
else randomSelection = true
end
when EAST
if ( x+1<@width and straightStretch < @width/2 and @matrix[x+1][y]==0 )
direction = lastDir
else randomSelection = true
end
when SOUTH
if ( y+1<@height and straightStretch < @height/2 and @matrix[x][y+1]==0 )
direction = lastDir
else randomSelection = true
end
when WEST
if ( x>0 and straightStretch < @width/2 and @matrix[x-1][y]==0 )
direction = lastDir
else randomSelection = true
end
else randomSelection = true
end
end

if (randomSelection)

# reset
direction = 0
straightStretch = 0

# pick random direction
# keep trying until a valid one is found
while ( (direction == 0) or ((testedDirs & direction) != 0) )
temp_x = x
temp_y = y
case rand(4)
when 0 # north
if (y > 0) then direction = NORTH; temp_y-=1
else testedDirs |= NORTH
end
when 1 # east
if (x+1 < @width) then direction = EAST; temp_x+=1
else testedDirs |= EAST
end
when 2 # south
if (y+1 < @height) then direction = SOUTH; temp_y+=1
else testedDirs |= SOUTH
end
when 3 # west
if (x > 0) then direction = WEST; temp_x-=1
else testedDirs |= WEST
end
end

# check next square to ensure it's valid
if ( @matrix[temp_x][temp_y] != 0 )
# record direction as tested
testedDirs |= direction
# if all directions are invalid, impossible to
# select random direction so break out
if (testedDirs == ALL_DIRS) then break end
direction = 0
end
end
else
straightStretch+=1
end

# if all directions are tested, move on to next
# iteration where an already-visited tile will be picked
if (testedDirs == ALL_DIRS) then next end

lastDir = direction

# set selected direction in maze at both current tile
# and destination tile
@matrix[x][y] |= direction

case direction
when NORTH then y-=1; direction = SOUTH
when EAST then x+=1; direction = WEST
when SOUTH then y+=1; direction = NORTH
when WEST then x-=1; direction = EAST
end
@matrix[x][y] |= direction
testedDirs = @matrix[x][y]
remaining-=1
end
end


=begin
Sparsify the maze by the given amount ("sparsity") representing the
number of times to sparsify (i.e. shorten deadends, creating empty areas so the
maze isn't perfectly dense).

A smaller maze will sparsify faster than a larger maze, so the smaller the maze,
the smaller the number should be to accomplish the same relative amount of "sparsification".
=end
def sparsify
for i in 0...@sparsity
for x in 0...@width
for y in 0...@height
# don't sparsify from the beginning or end points --
# this guarantees a solution to the maze
if (x == @startX) and (y == @startY) then next end

if (x == @endX) and (y == @endY) then next end

dir = @matrix[x][y]

# if only one direction, found a deadend
# so otherwise, go to next tile
if not [NORTH, EAST, SOUTH, WEST].include?(dir)
next
end

# remove deadend
@matrix[x][y] = 0

# for previous tile, remove direction to removed deadend
# also temporarily flag it as visited so any new deadends
# created aren't sparsified in the same pass
case dir
when NORTH
@matrix[x][y-1] &= ~SOUTH
@matrix[x][y-1] |= FLAG
when EAST
@matrix[x+1][y] &= ~WEST
@matrix[x+1][y] |= FLAG
when SOUTH
@matrix[x][y+1] &= ~NORTH
@matrix[x][y+1] |= FLAG
when WEST
@matrix[x-1][y] &= ~EAST
@matrix[x-1][y] |= FLAG
end

end
end

# clear the flags for the next sparsifying pass
for x in 0...@width
for y in 0...@height
@matrix[x][y] &= ~FLAG
end
end
end

end

=begin
Display the matrix in an ASCII table (useful for debugging)
(Much more readable if you're using a monospaced font for dialog boxes.)
=end
def display
char_array = Array.new(@width, 0)
for i in 0...@width
char_array[i] = Array.new(@height, 0)
end

for x in 0...@width
for y in 0...@height
dir = @matrix[x][y]
char = '['
if ((dir & NORTH) != 0) then char << 'N' else char << ' ' end
if ((dir & EAST) != 0) then char << 'E' else char << ' ' end
if ((dir & WEST) != 0) then char << 'W' else char << ' ' end
if ((dir & SOUTH) != 0) then char << 'S' else char << ' ' end
char << ']'
char_array[y][x] = char
end
end

display = ''
for i in 0...@height
display << char_array[i].flatten.to_s << "n"
end
print display
end



=begin
Clears the given percentage ("removalChance") of deadends from the maze by
causing the deadends to extend until they hit another passage. As this
causes cycles in the maze, it can result in multiple possible solutions
to the maze (but makes it seem more natural).
=end
def removeDeadends

for x in 0...@width
for y in 0...@height

dir = @matrix[x][y]

# if only one direction, found a deadend
# so otherwise, go to next tile
if not [NORTH, EAST, SOUTH, WEST].include?(dir)
next
end

# random roll to see if this deadend is skipped
if (rand > @removalChance) then next end

cur_x = x; cur_y = y
back_dir = dir

# continue as long as new corridor not reached
while (@matrix[cur_x][cur_y] == back_dir)
direction = 0
testedDirs = 0

# pick random direction
# keep trying until a valid one is found
while (direction == 0)
temp_x = cur_x
temp_y = cur_y

case rand(4)

when 0 # north
if (cur_y > 0) then direction = NORTH; back_dir = SOUTH; temp_y-=1
else testedDirs |= NORTH
end
when 1 # east
if (cur_x+1 < @width) then direction = EAST; back_dir = WEST; temp_x+=1
else testedDirs |= EAST
end
when 2 # south
if (cur_y+1 < @height) then direction = SOUTH; back_dir = NORTH; temp_y+=1
else testedDirs |= SOUTH
end
when 3 # west
if (cur_x > 0) then direction = WEST; back_dir = EAST; temp_x-=1
else testedDirs |= WEST
end
end

# check if deadend tile already goes this way
if ( @matrix[cur_x][cur_y] == direction )
# record direction as tested
testedDirs |= direction
direction = 0
end

# if all directions are invalid, impossible to
# select random direction so break out
if (testedDirs == ALL_DIRS) then break end
end

if (testedDirs == ALL_DIRS) then break end

# add new direction to deadend
@matrix[cur_x][cur_y] |= direction

# add new direction to tile adjacent to deadend
@matrix[temp_x][temp_y] |= back_dir

# move on to next tile
cur_x = temp_x; cur_y = temp_y

end
end
end
end

end



module Tile

@floor = 0
@wallFace = 0
@wall = 0
# to be extended with others to make maps "pretty", e.g. random ground features

=begin
The following array lists systematic keys which are based on adjacent
walls (where 'W' is the wall itself):
1 2 3
4 W 6
7 8 9
e.g. 268 is the key that will be used to refer to the autotile
which has adjacent walls north, east, and south. For the Castle Prison
tileset (autotile #1), this is 67.

(It's a bit unwieldy, but it works.)
=end

Autotile_Keys = [
12346789,
2346789,
1246789,
246789,
1234678,
234678,
124678,
24678,

1234689,
234689,
124689,
24689,
123468,
23468,
12468,
2468,

23689,
2689,
2368,
268,
46789,
4678,
4689,
468,

12478,
1248,
2478,
248,
12346,
2346,
1246,
246,

28,
46,
689,
68,
478,
48,
124,
24,

236,
26,
8,
6,
2,
4,
0 ]

# many autotiles handle multiple situations
# this hash keeps track of which keys are identical
# to ones already defined above
Duplicate_Keys = {
123689 => 23689,
236789 => 23689,
1236789 => 23689,
34689 => 4689,
14689 => 4689,
134689 => 4689,
14678 => 4678,
34678 => 4678,
134678 => 4678,
146789 => 46789,
346789 => 46789,
1346789 => 46789,
23467 => 2346,
23469 => 2346,
234679 => 2346,
123467 => 12346,
123469 => 12346,
1234679 => 12346,
12467 => 1246,
12469 => 1246,
124679 => 1246,
124789 => 12478,
123478 => 12478,
1234789 => 12478,
146 => 46,
346 => 46,
467 => 46,
469 => 46,
1346 => 46,
1467 => 46,
1469 => 46,
3467 => 46,
3469 => 46,
4679 => 46,
13467 => 46,
13469 => 46,
14679 => 46,
34679 => 46,
134679 => 46,
128 => 28,
238 => 28,
278 => 28,
289 => 28,
1238 => 28,
1278 => 28,
1289 => 28,
2378 => 28,
2389 => 28,
2789 => 28,
12378 => 28,
12389 => 28,
12789 => 28,
23789 => 28,
123789 => 28,

1247 => 124,
2369 => 236,
147 => 4,
247 => 24,
14 => 4,
47 => 4,
1478 => 478,
3478 => 478,
4789 => 478,
134789 => 478,
14789 => 478,
13478 => 478,
34789 => 478,
1234 => 124,
1247 => 124,
1249 => 124,
12347 => 124,
12349 => 124,
12479 => 124,
123479 => 124,
1236 => 236,
2367 => 236,
2369 => 236,
12367 => 236,
12369 => 236,
23679 => 236,
123679 => 236,
12368 => 2368,
23678 => 2368,
123678 => 2368,
12348 => 1248,
12489 => 1248,
123489 => 1248,
1689 => 689,
3689 => 689,
6789 => 689,
13689 => 689,
16789 => 689,
36789 => 689,
136789 => 689,
12689 => 2689,
26789 => 2689,
126789 => 2689,
23478 => 2478,
24789 => 2478,
234789 => 2478
}

def Tile.setFloor(row, col)
if row > 1
@floor = Tile.index(row, col)
else # autotiles
@floor = Hash.new(0)
j = Tile.index(row, col)
for i in Autotile_Keys
@floor[i] = j
j += 1
end
# add duplicates
for i in Duplicate_Keys.keys
@floor[i] = @floor[Duplicate_Keys[i]]
end
end
end

def Tile.floor
@floor
end

def Tile.setWallFace(row, col)
if row > 1
@wallFace = Tile.index(row, col)
else # autotiles
@wallFace = Hash.new(0)
j = Tile.index(row, col)
for i in Autotile_Keys
@wallFace[i] = j
j += 1
end
# add duplicates
for i in Duplicate_Keys.keys
@wallFace[i] = @wallFace[Duplicate_Keys[i]]
end
end
end

def Tile.wallFace
@wallFace
end

def Tile.setWall(row, col)
if row > 1
@wall = Tile.index(row, col)
else # autotiles
@wall = Hash.new(0)
j = Tile.index(row, col)
for i in Autotile_Keys
@wall[i] = j
j += 1
end
# add duplicates
for i in Duplicate_Keys.keys
@wall[i] = @wall[Duplicate_Keys[i]]
end
end
end

def Tile.wall
@wall
end

=begin
This method returns the index of a specific tile in the tileset,
or the base index for one of the 7 autotiles.
Parameters:
row - row where the tile is found within the tileset ( 1+ )
col - column where the tile is found within the tileset ( 1-8 )
Note: this method is NOT zero-indexed, i.e. rows and columns start at 1

e.g.
index(1,2) returns 48
index(2,1) returns 384
index(4,8) returns 407

By the way, here's an example of how autotile indexes work...

Autotile in column 2:

rowcol| 1 2 3 4 5 6 7 8
---------------------------
1 | 48 49 50 51 52 53 54 55
2 | 56 57 58 59 60 61 62 63
3 | 64 65 66 67 68 69 70 71
4 | 72 73 74 75 76 77 78 79
5 | 80 81 82 83 84 85 86 87
6 | 88 89 90 91 92 93 94 95

The function to return the index of a single tile within an autotile
(given by at_index) is (at_index-1)*48 + col-1 + (row-1)*8
(where row, col, and at_index are again NOT zero-indexed)
=end
def Tile.index(row, col)
if row > 1 # if not autotiles
return 383 + col + 8*(row-2)
else
return (col-1)*48
end
end

end


**사용법등은 rmxp.net에 있는 해당글을 참조해야 하지만, 로그인하지 않으면 볼 수 없으니.....
FAQ

QUOTE
I can't figure out how to use the parameters (randomness, sparsity and deadend removal)

If you want to specify them (they're optional), you include them in the map name, as in this example: "your-map-name <rand><0.8><5><0.8>" (from left to right, randomness, sparsity and deadend removal in that order).

Randomness is the chance that a corridor will twist instead of continuing straight (decimal value between 0 and 1.0, default is 0.5).

Sparsity represents the number of deadends to be shortened, creating empty spaces (integer value of 0 or more, default is 3). Note that a smaller maze will sparsify faster than a larger one, so for small mazes you'll want a small number.

Deadend removal (or removalChance) is the chance for a deadend to be removed by connecting it (creating a loop) to a nearby one (decimal value between 0 and 1.0, default is 0.5). Note that this can create multiple solutions to the maze, but it may also make the maze seem more natural.

So if you wanted very twisty mazes with no empty spaces or deadends, you'd name the map something like: "your-map-name <rand><1.0><0><1.0>". Spaces etc. between the tags shouldn't matter.



**생성된 맵을 저장하려면 Near Fantastica의 Dynamic Map 스크립트가 필요합니다.  더불어:
class Game_Map
#--------------------------------------------------------------
# modified slightly: only certain maps are actually saved
def setup(map_id)
if $save_map_list.include? @map_id
save_map(@map_id)
end
if Map.data(map_id) == nil
setup_map(map_id)
else
load_map(map_id)
end
end
end

Game_Map.setup을 위처럼 수정해야 한다는군요..

Who's 백호

?

이상혁입니다.

http://elab.kr

0 추천 0 비추천
Atachment
첨부 '1'
  • Random_Map_Generator.zip,
Facebook Twitter Google Pinterest KakaoStory Band
위로 아래로 댓글로 가기 인쇄 첨부
에디터 선택하기
✔ 텍스트 모드 ✔ 에디터 모드
?
댓글 쓰기 권한이 없습니다. 로그인 하시겠습니까?
Comment '0'

Category
  • 그래픽(16)
  • 맵/타일(15)
  • 메뉴(88)
  • 메시지(26)
  • 미니맵(9)
  • 버그픽스(0)
  • 변수/스위치(10)
  • 상점(14)
  • 상태/속성(8)
  • 스킬(49)
  • 아이템(34)
  • 액터(4)
  • 원경(0)
  • 영상(7)
  • 오디오(8)
  • 온라인(23)
  • 이동 및 탈것(62)
  • 이름입력(10)
  • 장비(34)
  • 저장(34)
  • 전투(174)
  • 제작도구(1)
  • 직업(2)
  • 퀘스트(3)
  • 키입력(18)
  • 타이틀/게임오버(24)
  • 파티(11)
  • HUD(34)
  • 기타(254)
List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 스크립트 자료 게시물 작성시 주의사항 습작 2012.12.24 10171
1021 제작도구 [XP/VX/VXA] Doodad's Editor by newold Alkaid 2020.07.12 600
1020 메시지 Taylor's Simple Message System 2000 Alkaid 2020.07.05 436
1019 이름입력 한글조합입력기(영어가능) file 조규진1 2019.11.10 743
1018 맵/타일 맵연결 스크립트 (데모첨부) file 게임애호가 2018.06.15 909
1017 전투 전투중에 장비들 교체하기 file 레이스89 2017.08.19 940
1016 온라인 인터넷 웹 상에서의 시간을 취득하는 스크립트 1 이우 2016.05.24 1099
1015 장비 착용한 장비에 따라 모습이 달라지는 스크립트 예제 5 file 게임애호가 2015.02.14 2258
1014 기타 [All RGSS] File-Ex file Cheapmunk 2014.12.29 1108
1013 기타 [All RGSS] FileTest (Unicode) file Cheapmunk 2014.12.29 749
1012 기타 [RGSS XP] 게임 해상도 조절 스크립트 (*2) 11 file Cheapmunk 2014.10.03 2867
1011 그래픽 Drago - Custom Resolution II 1 Alkaid 2014.09.10 1267
1010 기타 레벨업스크립트(xp) 2 게임을만들자! 2014.08.05 1950
1009 메뉴 MOG - Scroll Bar for XP file 습작 2014.07.06 1731
1008 기타 [All RGSS] 윈도우 메세지박스 스크립트 (Completed ver) 5 file Cheapmunk 2014.06.22 2396
1007 기타 [All RGSS] 게임 다중 실행 방지 스크립트 1 file Cheapmunk 2014.05.24 1567
1006 기타 RM2kXP file 습작 2014.03.17 1712
1005 기타 [All RGSS] 윈도우 커서 숨기기/보이기 1 file Cheapmunk 2014.03.02 2161
1004 기타 Drago - Custom Resolution by LiTTleDRAgo Alkaid 2014.02.13 1316
1003 그래픽 [XP/VX/VXA] Drago - Transition Pack Alkaid 2014.02.13 1386
1002 기타 [XP/VX/VXA] Map Screenshot by LiTTleDRAgo 1 Alkaid 2014.02.13 1045
쓰기
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 52 Next
/ 52
AVANGS

게임 제작, 창작, 자료, 강좌를 연결하는 커뮤니티

  • 개인정보 취급방침

Copyright © 2026 Avangs