View Single Post
  #20    
Old April 15th, 2013 (01:41 AM). Edited April 15th, 2013 by Rayquaza..
Rayquaza.'s Avatar
Rayquaza. Rayquaza. is offline
Lead Dev in Pokémon Chaos
 
Join Date: Sep 2011
Location: United Kingdom
Age: 18
Gender: Male
Nature: Adamant
Posts: 602
Precisely, using that graphic that you attached would be ideal. If I remember rightly CNG also made a dual screen script that put the map on the bottom and parralaxes at the top.

Just found something useful here. It's a random dungeon generator for VX (I think) with instructions that are to complicated for me to understand but I think others may be able to.

Spoiler:
Code:
#===============================================================================
# Roguelike Random Dungeon Generator
#-------------------------------------------------------------------------------
# Version: 2.0a
# Author: cozziekuns (rmrk)
# Last Date Updated: 4/11/2011
#===============================================================================
# Description:
#-------------------------------------------------------------------------------
# A random dungeon generator akin to that of games like Rogue or Pokemon Mystery
# Dungeon.
#===============================================================================
# Updates
# ------------------------------------------------------------------------------
# o 16/07/2011 - Started Script
# o 17/07/2011 - Updated Script to support black outlines and some autotile 
#                features
# o 15/09/2011 - Bugfix.
# o 17/09/2011 - Major overhaul of the entire script. Now has fully functional
#                autotile support, and a much faster algorithm that can create a 
#                500 * 500 tile map with 1000 features in less than 10 seconds.
#===============================================================================
# To-do List
#------------------------------------------------------------------------------- 
# o Nothing! Suggest some features.
#===============================================================================
# Instructions
#-------------------------------------------------------------------------------
# Copy and paste this script above ? Main Process but below ? Materials, and
# edit the modules to your liking. Some difficult modules have links to the 
# instructions.
#===============================================================================
# Maps
#-------------------------------------------------------------------------------
# Start editing at:
#   case id
#   when [id] - Replace [id] with your map id.
#     ROOM_MIN_WIDTH : Minimum width for a single "Room"
#     ROOM_MAX_WIDTH : Maximum width for a single "Room"
#     ROOM_MIN_HEIGHT : Minimum height for a single "Room"
#     ROOM_MAX_HEIGHT : Maximum height for a single "Room"
#     FEATURES : How many features you want to fit in the map
#     WALL_TILE : Tile of the wall
#     FLOOR_TILE : Tile of the floor
#     BLACK_OUTLINE : Do you want a black outline surrounding your random 
#                     dungeon (slow).
#   end
#===============================================================================

module COZZIEKUNS
  
  module RDG
    
    def self.map_settings(id)
      case id
      when 1
        room_min_width = 3
        room_max_width = 6
        room_min_height = 3
        room_max_height = 6
        features = 200
        wall_tile = 0
        floor_tile = 16
        black_outline = false
      when 2
        room_min_width = 4
        room_max_width = 8
        room_min_height = 4
        room_max_height = 8
        features = 75
        wall_tile = 6
        floor_tile = 52
        black_outline = false
      end
      return [room_min_width, room_max_width, room_min_height, room_max_height,
      features, wall_tile, floor_tile, black_outline].compact 
    end
  
  end
  
end

#==============================================================================
# ** Game_Map
#==============================================================================

class Game_Map 
  
  alias coz_rdg_gm_setup setup
  def setup(*args)
    coz_rdg_gm_setup(*args)
    create_dungeon if not COZZIEKUNS::RDG.map_settings(@map_id).empty?
  end
  
  def create_dungeon
    set_variables
    fill_wall_tiles
    dig_random_room
    for i in 0...@features
      count = 0
      loop do
        count += 1
        choose_next_wall
        make_new_feature
        break if @can_make or count == 5
      end
    end
    refine_tilemap
    set_player_and_events
  end
  
  def set_variables
    settings = COZZIEKUNS::RDG.map_settings(@map_id)
    @rmiw = settings[0]
    @rmaw = settings[1]
    @rmih = settings[2]
    @rmah = settings[3]
    @features = settings[4]
    @walls = []
    @floor = []
    @next_wall = []
    @wall_tile = (settings[5] + 80) * 48 + 2048
    @wall2_tile = (settings[5] + 88) * 48 + 2048
    @floor_tile = (settings[6] + 128) + 1408
    @black_outline = settings[7]
    @next_feature = 0
    @can_make = false
    @player_transfered = false
  end
  
  def set_player_and_events
    for event in $game_map.events.values + [$game_player]
      loop do
        ax = @floor[rand(@floor.size)][0]
        ay = @floor[rand(@floor.size)][1]
        if passable_in_area?(ax - 1, ay - 1, event)
          event.moveto(ax, ay)
          break
        end
      end
    end
  end
  
  alias coz_rdg_gm_update update
  def update
    coz_rdg_gm_update
    unless @player_transfered or COZZIEKUNS::RDG.map_settings(@map_id).empty?
      @player_transfered = true
      set_player_and_events
    end
  end
  
  def passable_in_area?(x, y, char, width = 3, height = 3)
    for i in x...x + width; for j in y...y + height
      return false if not char.passable?(i, j)
    end; end
    return true
  end
  
  def fill_wall_tiles
    for i in 0...width; for j in 0...height
      @map.data[i, j, 0] = @wall_tile
    end; end
  end
  
  def dig_random_room
    x = [rand(width) + 1, width - @rmaw - 1].min
    y = [rand(height) + 1, height - @rmah - 1].min
    dig_room(x, y)
  end
  
  def dig_room(x, y, direction = 2)
    width = rand(@rmiw) + @rmaw - @rmiw + 1
    height = rand(@rmih) + @rmah - @rmih + 1
    for i in 0...width
      for j in 0...height
        case direction
        when 0; new_x = x + j; new_y = y + i
        when 1; new_x = x - i; new_y = y + j
        when 2; new_x = x + i; new_y = y + j
        when 3; new_x = x + j; new_y = y - i
        end
        @map.data[new_x, new_y, 0] = @floor_tile
        @floor.push([new_x, new_y]) 
        @walls.push([new_x - 1, new_y, 1]) if new_x == x
        @walls.push([new_x + 1, new_y, 2]) if new_x == x + width - 1
        @walls.push([new_x, new_y - 1, 3]) if new_y == y
        @walls.push([new_x, new_y + 1, 0]) if new_y == y + height - 1
      end
    end
    @next_feature = 1
  end
  
  def dig_corridor(x, y, direction)
    j = 0
    width = rand(@rmiw) + @rmaw - @rmiw + 1
    height = 0
    for i in 0...width
      case direction
      when 0; new_x = x + j; new_y = y + i
      when 1; new_x = x - i; new_y = y + j
      when 2; new_x = x + i; new_y = y + j  
      when 3; new_x = x + j; new_y = y - i 
      end
      @map.data[new_x, new_y, 0] = @floor_tile
      @floor.push([new_x, new_y]) 
      @walls.push([new_x - 1, new_y, 1]) if new_x == x
      @walls.push([new_x + 1, new_y, 2]) if new_x == x + width - 1
      @walls.push([new_x, new_y - 1, 3]) if new_y == y
      @walls.push([new_x, new_y + 1, 0]) if new_y == y + height - 1
    end
    case direction
    when 0; @next_wall = [x + height, y + width, 0]
    when 1; @next_wall = [x - width, y + height, 1]
    when 2; @next_wall = [x + width, y + height, 2]
    when 3; @next_wall = [x + height, y - width, 3]
    end
    @next_feature = 0
  end
  
  def choose_next_wall; @next_wall = @walls[rand(@walls.size)]; end
  
  def make_new_feature
    direction = rand(4)
    @can_make = scan_area(@next_wall[0], @next_wall[1], @next_wall[2])
    return if not @can_make
    @walls.delete(@next_wall)
    dig_corridor(@next_wall[0], @next_wall[1], @next_wall[2])
    @can_make = scan_area(@next_wall[0], @next_wall[1], @next_wall[2])
    dig_room(@next_wall[0], @next_wall[1], @next_wall[2]) if @can_make
    @next_feature = 1
  end
  
  def scan_area(x, y, direction)
    case @next_feature
    when 0
      for i in 0..@rmaw + 1; for j in 0..@rmah + 1
        case direction
        when 0; return false if passable?(x + j, y + i) or !valid?(x + j, y + i)
        when 1; return false if passable?(x - i, y + j) or !valid?(x - i, y + j)
        when 2; return false if passable?(x + i, y + j) or !valid?(x + i, y + j)
        when 3; return false if passable?(x + j, y - i) or !valid?(x + j, y - i)
        end
      end; end
    when 1
      for i in 0..@rmaw + 1; for j in -2..2
        case direction
        when 0; return false if passable?(x + j, y + i) or !valid?(x + j, y + i)
        when 1; return false if passable?(x - i, y + j) or !valid?(x - i, y + j)
        when 2; return false if passable?(x + i, y + j) or !valid?(x + i, y + j)
        when 3; return false if passable?(x + j, y - i) or !valid?(x + j, y - i)
        end
      end; end
    end
    return true
  end
  
  def refine_tilemap
    for point in @floor
      next if passable?(point[0], point[1] - 1)
      if passable?(point[0], point[1] - 2)
        @map.data[point[0], point[1] - 1, 0] = @floor_tile
      else
        @map.data[point[0], point[1] - 1, 0] = @wall2_tile
      end
    end
    for i in 0...width; for j in 0...height
      next if @map.data[i, j, 0] == @floor_tile 
      type = @map.data[i, j, 0] == @wall2_tile ? 1 : 0
      @map.data[i, j, 0] = rdg_tilemap_id(i, j, type) 
    end; end
    return if not @black_outline
    for i in 0...width; for j in 0...height
      next if @floor.include?([i, j])
      if (@map.data[i, j, 0] - 2048) % 48 == 0 
        @map.data[i, j, 0] = 0
      end
    end; end
  end
  
  def rdg_tilemap_id(x, y, type)
    data = @map.data
    base = @map.data[x, y, 0]
    return base if x == 0 or x == width - 1 or y == 0 or y == width - 1
    case type
    when 0
      count = 0
      count += 1 if (data[x - 1, y, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
      count += 2 if (data[x, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
      count += 4 if (data[x + 1, y, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
      count += 8 if (data[x, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
      id = case count 
      when 0 then check_corners(x, y, base)
      when 1 then 16 + ((check_corners(x, y, base, [2, 4])) / 2)
      when 2 then 20 + ((check_corners(x, y, base, [4, 8])) / 4)
      when 3 then 34 + ((check_corners(x, y, base, [4])) / 4)
      when 4 then 24 + ([0,8,1,9].index(check_corners(x, y, base, [1, 8])))
      when 5 then 32
      when 6 then 36 + ((check_corners(x, y, base, [8])) / 8)
      when 7 then 42
      when 8 then 28 + check_corners(x, y, base, [1, 2])
      when 9 then 40 + ((check_corners(x, y, base, [2])) / 2)
      when 10 then 33
      when 11 then 43
      when 12 then 38 + check_corners(x, y, base, [1])
      else
        31 + count
      end
    when 1
      count = 0
      count += 1 if passable?(x - 1, y)
      count += 4 if passable?(x + 1, y)
      id = count + 10
    end
    return base + id
  end

  def check_corners(x, y, base, corners = [1, 2, 4, 8])
    count = 0
    data = @map.data
    count += 1 if corners.include?(1) and (data[x - 1, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
    count += 2 if corners.include?(2) and (data[x + 1, y - 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
    count += 4 if corners.include?(4) and (data[x + 1, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
    count += 8 if corners.include?(8) and (data[x - 1, y + 1, 0] - 2048) / 48 != (base - 2048) / 48 rescue false
    return count
  end
  
end
__________________