2017-09-04 55 views
0

https://www.gamasutra.com/blogs/AAdonaac/20150903/252889/Procedural_Dungeon_Generation_Algorithm.php地牢發電機jQuery中

我試着做一些像jQuery的鏈接,但我有一些麻煩促成這件事情。

1)創建10(X)不同的矩形,並放置在畫布在彼此都混了中間 - 沒問題

2)單獨的房間,讓每一個房間發現畫布上空白的地方 - 大問題

計劃1:我比較兩個房間,如果他們相互接觸,然後將其中一個移動到另一個的最短路徑。但是如果在那裏已經有一個房間了呢?然後,我剛剛有兩個新的房間相互接觸...

計劃2:製作一個空/被佔據的地方陣列,並將每個房間移動到一個空的地方。但是,我怎麼知道哪個方向移動,所以所有的房間都放在中心?

Plz help!

試用代碼:

<canvas id="cnvs" width="500" height="500" style="background-color: #333;"></canvas> 

var rooms = [], 
    gw = 25, //grid width 
    gh = 25; //grid height 

//Room 
function Room(x,y,w,h){ 
    this.x = x; this.y = y; 
    this.w = w; this.h = h; 
    }; 

//Setup 
for(var i=0; i<10; i++){ 
    var w = Math.floor(2+Math.random()*3), 
    h = Math.floor(2+Math.random()*3), 
    x = Math.floor(gw/2)-Math.floor(w/2), 
    y = Math.floor(gh/2)-Math.floor(h/2), 
    room = new Room(x,y,w,h); 
    rooms.push(room); 
    }; 

//Draw in canvas 
var ctx = $("#cnvs")[0].getContext("2d"), 
    sz = 20; 
ctx.lineWidth = "2"; 
ctx.strokeStyle = 'white'; 

for(var i=0; i<rooms.length; i++){ 
    ctx.rect(rooms[i].x*sz,rooms[i].y*sz,rooms[i].w*sz,rooms[i].h*sz); 
    ctx.stroke(); 
    }; 
+0

你能解釋什麼不工作嗎?哪裏有問題? – ventiseis

+0

第1步工作,但我很困惑如何做第2步(單獨的房間)。如何將房間分隔成鏈接,所以沒有空間覆蓋另一個房間? –

回答

0

現在我做第2步的工作。我認爲它可以更優雅,所以請隨時讓它變得更加明智。

var rooms = [], 
 
    grid = [], 
 
    gw = 25, //grid width 
 
    gh = 25; //grid height 
 

 
//Room 
 
Room = function(x,y,w,h){ 
 
    this.x = x; this.y = y; 
 
    this.w = w; this.h = h; 
 
    }; 
 

 
//functions 
 
refreshGrid = function(){ 
 
    for(var i=0; i<grid.length; i++){ 
 
    for(var j=0; j<grid[i].length; j++) grid[i][j] = -1; 
 
    }; 
 
    return; 
 
    }; 
 

 
roomDistance = function(x,y,c){ 
 
    if(grid[y][x]==-1 || grid[y][x]>c){ 
 
    grid[y][x] = c; 
 
    if(x>0) roomDistance(x-1, y, c+1); 
 
    if(x<gw-1) roomDistance(x+1, y, c+1); 
 
    if(y>0) roomDistance(x, y-1, c+1); 
 
    if(y<gh-1) roomDistance(x, y+1, c+1); 
 
    }; 
 
    return; 
 
    }; 
 

 
roomFit = function(x,y,w,h){ 
 
    var tmp = true; 
 
    if(x+w>=gw) tmp = false; 
 
    else if(y+h>=gh) tmp = false; 
 
     else { 
 
     for(var i=y; i<y+h; i++){ 
 
      for(var j=x;j<x+w; j++){ 
 
      if(grid[i][j]<0) tmp = false; 
 
      }; 
 
      }; 
 
    return tmp; 
 
    }; 
 

 
blockSpaces = function(w,h){ 
 
    for(var i=0; i<rooms.length; i++){ 
 
    var rx = rooms[i].x, 
 
     ry = rooms[i].y, 
 
     rw = rooms[i].w, 
 
     rh = rooms[i].h; 
 
    if(rx+rw<gw) rw = rw+1; 
 
    if(rx>0){ rx = rx-1; rw = rw+1; }; 
 
    if(ry+rh<gh) rh = rh+1; 
 
    if(ry>0){ ry = ry-1; rh = rh+1; }; 
 
    for(var j=0;j<rh; j++){ 
 
     for(var k=0;k<rw; k++){ 
 
     grid[ry+j][rx+k] = -1; 
 
     }; 
 
     }; 
 
    }; 
 
    for(var i=0; i<grid.length; i++){ 
 
    for(var j=0;j<grid[i].length; j++){ 
 
     if(roomFit(j,i,w,h)==false) grid[i][j] = -1; 
 
     }; 
 
    }; 
 
    }; 
 

 
findPlace = function(room){ 
 
    var x=0, y=0, c=-1; 
 
    for(var i=0; i<grid.length; i++){ 
 
    for(var j=0;j<grid[i].length; j++){ 
 
     if(grid[i][j]>=0 && (c==-1 || grid[i][j]<c)){ 
 
     c = grid[i][j]; 
 
     x= j; 
 
     y = i; 
 
     }; 
 
     }; 
 
    }; 
 
    room.x = x; 
 
    room.y = y; 
 
    }; 
 

 
//Setup 
 
for(var i=0; i<gh; i++){ 
 
    var arr = []; 
 
    for(var j=0; j<gw; j++) arr.push(0); 
 
    grid.push(arr); 
 
    }; 
 

 
for(var i=0; i<15; i++){ 
 
    var w = Math.floor(2+Math.random()*3), 
 
    h = Math.floor(2+Math.random()*3), 
 
    x = Math.floor(gw/2)-Math.floor(w/2), 
 
    y = Math.floor(gh/2)-Math.floor(h/2); 
 
    refreshGrid(); 
 
    roomDistance(x,y,0); 
 
    blockSpaces(w,h); 
 
    var room = new Room(x,y,w,h); 
 
    findPlace(room); 
 
    rooms.push(room); 
 
    }; 
 

 
//Draw in canvas 
 
var ctx = $("#cnvs")[0].getContext("2d"), 
 
    sz = 20; 
 
ctx.beginPath(); 
 
ctx.lineWidth = '1'; 
 
ctx.strokeStyle = '#666'; 
 
for(var i=0; i<gh; i++){ ctx.moveTo(0,i*sz); ctx.lineTo(gw*sz,i*sz); }; 
 
for(var i=0; i<gw; i++){ ctx.moveTo(i*sz,0); ctx.lineTo(i*sz,gh*sz); }; 
 
ctx.stroke(); 
 

 
ctx.beginPath(); 
 
ctx.lineWidth = "2"; 
 
ctx.strokeStyle = '#fff'; 
 
for(var i=0; i<rooms.length; i++){ ctx.rect(rooms[i].x*sz,rooms[i].y*sz,rooms[i].w*sz,rooms[i].h*sz); ctx.stroke(); };
<canvas id="cnvs" width="500" height="500" style="background-color: #333;"></canvas>

0

我覺得這是更好的:

//global variables 
 
var rooms = [], 
 
\t gw = 35, //grid width 
 
\t gh = 35; //grid height 
 

 
//Room 
 
Room = function(){ 
 
\t var w = Math.floor(2+Math.random()*4), 
 
\t \t h = Math.floor(2+Math.random()*4), 
 
\t \t x = Math.floor(gw/3+Math.random()*gw/3)-Math.floor(w/2), 
 
\t \t y = Math.floor(gh/3+Math.random()*gw/3)-Math.floor(h/2), 
 
\t \t grid = []; 
 

 
\t //create grid with -1 
 
\t grid = []; 
 
\t for(var i=0; i<gh; i++){ 
 
\t \t grid.push([]); 
 
\t \t for(var j=0; j<gw; j++) grid[grid.length-1].push(-1); 
 
\t \t }; 
 

 
\t //Fill grid with distances 
 
\t this.gridDistance = function(x1,y1,c){ 
 
\t \t if(grid[y1][x1]==-1 || grid[y1][x1]>c){ 
 
\t \t \t grid[y1][x1] = c; 
 
\t \t \t if(x1>0) this.gridDistance(x1-1, y1, c+1); 
 
\t \t \t if(x1<gw-1) this.gridDistance(x1+1, y1, c+1); 
 
\t \t \t if(y1>0) this.gridDistance(x1, y1-1, c+1); 
 
\t \t \t if(y1<gh-1) this.gridDistance(x1, y1+1, c+1); 
 
\t \t \t }; 
 
\t \t return; 
 
\t \t }; 
 
\t this.gridDistance(x,y,0); 
 

 
\t //block rooms and rooms border 
 
\t for(var i=0; i<rooms.length; i++){ 
 
\t \t var x1 = rooms[i].x, y1 = rooms[i].y, w1 = rooms[i].w, h1 = rooms[i].h; 
 
\t \t if(x1+w1<gw) w1 = w1+1; 
 
\t \t if(x1>0){ x1 = x1-1; w1 = w1+1; }; 
 
\t \t if(y1+h1<gh) h1 = h1+1; 
 
\t \t if(y1>0){ y1 = y1-1; h1 = h1+1; }; 
 
\t \t for(var j=0;j<h1; j++){ 
 
\t \t \t for(var k=0;k<w1; k++){ 
 
\t \t \t \t grid[y1+j][x1+k] = -1; 
 
\t \t \t \t }; 
 
\t \t \t }; 
 
\t \t }; 
 

 
\t //block spaces where room cant fit 
 
\t for(var i=0; i<grid.length; i++){ 
 
\t \t for(var j=0;j<grid[i].length; j++){ 
 
\t \t \t var tmp = false; 
 
\t \t \t if(i+h>=gh) tmp = true; 
 
\t \t \t else if(j+w>=gw) tmp = true; 
 
\t \t \t else { 
 
\t \t \t \t for(var k=i; k<i+h; k++){ 
 
\t \t \t \t \t for(var l=j;l<j+w; l++){ 
 
\t \t \t \t \t \t if(grid[k][l]<0) tmp = true; 
 
\t \t \t \t \t \t }; 
 
\t \t \t \t \t }; 
 
\t \t \t \t }; 
 
\t \t \t if(tmp) grid[i][j] = -1; 
 
\t \t \t }; 
 
\t \t }; 
 

 
\t //find shortest distance to fitable space 
 
\t var x1=0, y1=0, c=-1; 
 
\t for(var i=0; i<grid.length; i++){ 
 
\t \t for(var j=0;j<grid[i].length; j++){ 
 
\t \t \t if(grid[i][j]>=0 && (c==-1 || grid[i][j]<c)){ 
 
\t \t \t \t c = grid[i][j]; 
 
\t \t \t \t x1= j; 
 
\t \t \t \t y1 = i; 
 
\t \t \t \t }; 
 
\t \t \t }; 
 
\t \t }; 
 
\t 
 
\t this.gridDistance = undefined; 
 

 
\t this.x = x1; this.y = y1; 
 
\t this.w = w; this.h = h; 
 
\t }; 
 

 
//Setup 
 
for(var i=0; i<25; i++){ 
 
\t var room = new Room(); 
 
\t rooms.push(room); 
 
\t }; 
 

 
$('body').append('ok'); 
 

 
//Draw in canvas 
 
var ctx = $("#cnvs")[0].getContext("2d"), 
 
\t sz = 20; 
 
ctx.beginPath(); 
 
ctx.lineWidth = '1'; 
 
ctx.strokeStyle = '#666'; 
 
for(var i=0; i<gh; i++){ ctx.moveTo(0,i*sz); ctx.lineTo(gw*sz,i*sz); }; 
 
for(var i=0; i<gw; i++){ ctx.moveTo(i*sz,0); ctx.lineTo(i*sz,gh*sz); }; 
 
ctx.stroke(); 
 

 
ctx.beginPath(); 
 
ctx.lineWidth = "2"; 
 
ctx.strokeStyle = '#fff'; 
 
for(var i=0; i<rooms.length; i++){ ctx.rect(rooms[i].x*sz,rooms[i].y*sz,rooms[i].w*sz,rooms[i].h*sz); ctx.stroke(); };