2012-03-04 3 views
1

私はちょっとしたゲームに取り組んでいますが、ほとんどの場合は楽しいですが、ちょっとしたものに遭遇しました。このアルゴリズムを使うたびにランダムな地形を生成しようとしています。ノッチのミニクリップソース私は信じている。誰も私を助けることができる場合XNAランダムタイル地形

、病気

私の問題は、私は画面にこれを描くか、画面

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework.Graphics; 
using System.Runtime.InteropServices; 
using Microsoft.Xna.Framework.Media; 

namespace Tile_Engine.Game 
{ 
    public class LevelGen 
    { 
    private static Random random = new Random(); 
    public double[] values; 
    private int w, h; 
    public static MediaLibrary mlb; 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern uint MessageBox(IntPtr hWnd, String text, String caption, uint type); 

    public LevelGen(int w, int h, int featureSize) 
    { 
     this.w = w; 
     this.h = h; 
     mlb = new MediaLibrary(); 

     values = new double[w * h]; 

     for (int y = 0; y < w; y += featureSize) 
     { 
      for (int x = 0; x < w; x += featureSize) 
      { 
       setSample(x, y, random.NextDouble() * 2 - 1); 
      } 
     } 

     int stepSize = featureSize; 
     double scale = 1.0/w; 
     double scaleMod = 1; 
     do 
     { 
      int halfStep = stepSize/2; 
      for (int y = 0; y < w; y += stepSize) 
      { 
       for (int x = 0; x < w; x += stepSize) 
       { 
        double a = sample(x, y); 
        double b = sample(x + stepSize, y); 
        double c = sample(x, y + stepSize); 
        double d = sample(x + stepSize, y + stepSize); 

        double e = (a + b + c + d)/4.0 + (random.NextDouble() * 2 - 1) * stepSize * scale; 
        setSample(x + halfStep, y + halfStep, e); 
       } 
      } 
      for (int y = 0; y < w; y += stepSize) 
      { 
       for (int x = 0; x < w; x += stepSize) 
       { 
        double a = sample(x, y); 
        double b = sample(x + stepSize, y); 
        double c = sample(x, y + stepSize); 
        double d = sample(x + halfStep, y + halfStep); 
        double e = sample(x + halfStep, y - halfStep); 
        double f = sample(x - halfStep, y + halfStep); 

        double H = (a + b + d + e)/4.0 + (random.NextDouble() * 2 - 1) * stepSize * scale * 0.5; 
        double g = (a + c + d + f)/4.0 + (random.NextDouble() * 2 - 1) * stepSize * scale * 0.5; 
        setSample(x + halfStep, y, H); 
        setSample(x, y + halfStep, g); 
       } 
      } 
      stepSize /= 2; 
      scale *= (scaleMod + 0.8); 
      scaleMod *= 0.3; 
     } while (stepSize > 1); 
    } 

    private double sample(int x, int y) 
    { 
     return values[(x & (w - 1)) + (y & (h - 1)) * w]; 
    } 

    private void setSample(int x, int y, double value) 
    { 
     values[(x & (w - 1)) + (y & (h - 1)) * w] = value; 
    } 

    public static byte[][] createAndValidateTopMap(int w, int h) 
    { 
     int attempt = 0; 
     do 
     { 
      byte[][] result = createTopMap(w, h); 

      int[] count = new int[256]; 

      for (int i = 0; i < w * h; i++) 
      { 
       count[result[0][i] & 0xff]++; 
      } 
      if (count[Tile.Dirt.id & 0xff] < 100) continue; 
      if (count[Tile.Sand.id & 0xff] < 100) continue; 
      // if (count[Tile.grass.id & 0xff] < 100) continue; 
      // if (count[Tile.tree.id & 0xff] < 100) continue; 
      //if (count[Tile.stairsDown.id & 0xff] < 2) continue; 

      return result; 

     } while (true); 


    } 

    private static byte[][] createTopMap(int w, int h) { 
    LevelGen mnoise1 = new LevelGen(w, h, 16); 
    LevelGen mnoise2 = new LevelGen(w, h, 16); 
    LevelGen mnoise3 = new LevelGen(w, h, 16); 

    LevelGen noise1 = new LevelGen(w, h, 32); 
    LevelGen noise2 = new LevelGen(w, h, 32); 

    byte[] map = new byte[w * h]; 
    byte[] data = new byte[w * h]; 
    for (int y = 0; y < h; y++) { 
     for (int x = 0; x < w; x++) { 
      int i = x + y * w; 

      double val = Math.Abs(noise1.values[i] - noise2.values[i]) * 3 - 2; 
      double mval = Math.Abs(mnoise1.values[i] - mnoise2.values[i]); 
      mval = Math.Abs(mval - mnoise3.values[i]) * 3 - 2; 

      double xd = x/(w - 1.0) * 2 - 1; 
      double yd = y/(h - 1.0) * 2 - 1; 
      if (xd < 0) xd = -xd; 
      if (yd < 0) yd = -yd; 
      double dist = xd >= yd ? xd : yd; 
      dist = dist * dist * dist * dist; 
      dist = dist * dist * dist * dist; 
      val = val + 1 - dist * 20; 

      if (val < -0.5) { 
       map[i] = Tile.Sand.id; 
      } else if (val > 0.5 && mval < -1.5) { 
       //map[i] = Tile.rock.id; 
      } else { 
       map[i] = Tile.Dirt.id; 
      } 
     } 
    } 

    for (int i = 0; i < w * h/2800; i++) { 
     int xs = random.Next(w); 
     int ys = random.Next(h); 
     for (int k = 0; k < 10; k++) { 
      int x = xs + random.Next(21) - 10; 
      int y = ys + random.Next(21) - 10; 
      for (int j = 0; j < 100; j++) { 
       int xo = x + random.Next(5) - random.Next(5); 
       int yo = y + random.Next(5) - random.Next(5); 
       for (int yy = yo - 1; yy <= yo + 1; yy++) 
        for (int xx = xo - 1; xx <= xo + 1; xx++) 
         if (xx >= 0 && yy >= 0 && xx < w && yy < h) { 
          if (map[xx + yy * w] == Tile.Dirt.id) { 
           map[xx + yy * w] = Tile.Sand.id; 
          } 
         } 
      } 
     } 
    } 

    /* 
    * for (int i = 0; i < w * h/2800; i++) { int xs = random.Next(w); int ys = random.Next(h); for (int k = 0; k < 10; k++) { int x = xs + random.Next(21) - 10; int y = ys + random.Next(21) - 10; for (int j = 0; j < 100; j++) { int xo = x + random.Next(5) - random.Next(5); int yo = y + random.Next(5) - random.Next(5); for (int yy = yo - 1; yy <= yo + 1; yy++) for (int xx = xo - 1; xx <= xo + 1; xx++) if (xx >= 0 && yy >= 0 && xx < w && yy < h) { if (map[xx + yy * w] == Tile.grass.id) { map[xx + yy * w] = Tile.dirt.id; } } } } } 
    */ 

    for (int i = 0; i < w * h/400; i++) { 
     int x = random.Next(w); 
     int y = random.Next(h); 
     for (int j = 0; j < 200; j++) { 
      int xx = x + random.Next(15) - random.Next(15); 
      int yy = y + random.Next(15) - random.Next(15); 
      if (xx >= 0 && yy >= 0 && xx < w && yy < h) { 
       if (map[xx + yy * w] == Tile.Dirt.id) { 
        //map[xx + yy * w] = Tile.tree.id; 
       } 
      } 
     } 
    } 

    for (int i = 0; i < w * h/400; i++) { 
     int x = random.Next(w); 
     int y = random.Next(h); 
     int col = random.Next(4); 
     for (int j = 0; j < 30; j++) { 
      int xx = x + random.Next(5) - random.Next(5); 
      int yy = y + random.Next(5) - random.Next(5); 
      if (xx >= 0 && yy >= 0 && xx < w && yy < h) { 
       if (map[xx + yy * w] == Tile.Dirt.id) { 
        //map[xx + yy * w] = Tile.flower.id; 
       // data[xx + yy * w] = (byte) (col + random.Next(4) * 16); 
       } 
      } 
     } 
    } 

    for (int i = 0; i < w * h/100; i++) { 
     int xx = random.Next(w); 
     int yy = random.Next(h); 
     if (xx >= 0 && yy >= 0 && xx < w && yy < h) { 
      if (map[xx + yy * w] == Tile.Sand.id) { 
      // map[xx + yy * w] = Tile.cactus.id; 
      } 
     } 
    } 

    int count = 0; 
    stairsLoop: for (int i = 0; i < w * h/100; i++) { 
     int x = random.Next(w - 2) + 1; 
     int y = random.Next(h - 2) + 1; 

     for (int yy = y - 1; yy <= y + 1; yy++) 
      for (int xx = x - 1; xx <= x + 1; xx++) { 
       //if (map[xx + yy * w] != Tile.rock.id) continue stairsLoop; 
      } 

     //map[x + y * w] = Tile.stairsDown.id; 
     count++; 
     if (count == 4) break; 
    } 

    return new byte[][] { map, data }; 
} 

    public static void main(String[] args) 
    { 
     int d = 0; 
     int w = 128; 
     int h = 128; 
     byte[] map = LevelGen.createAndValidateTopMap(w, h)[0]; 



     MessageBox(new IntPtr(0), "Completed!", "File Save Done", 0); 
     while (true) 
     { 
      //int w = 128; 
      // int h = 128; 

      //byte[] map = LevelGen.createAndValidateTopMap(w, h)[0]; 

      // byte[] map = LevelGen.createAndValidateUndergroundMap(w, h, (d++ % 3) + 1)[0]; 
      // byte[] map = LevelGen.createAndValidateSkyMap(w, h)[0]; 


      int[] pixels = new int[w * h]; 
      for (int y = 0; y < h; y++) 
      { 
       for (int x = 0; x < w; x++) 
       { 
        int i = x + y * w; 

       // if (map[i] == Tile.water.id) pixels[i] = 0x000080; 
        if (map[i] == Tile.Dirt.id) pixels[i] = 0x604040; 
        if (map[i] == Tile.Sand.id) pixels[i] = 0xa0a040; 
       } 
      } 
      // System.IO.File.WriteAllBytes("C:\\TESTPNG.png", map); 
     } 



    } 

    /* 
    * for (int i = 0; i < w * h/2800; i++) { int xs = random.Next(w); int ys = random.Next(h); for (int k = 0; k < 10; k++) { int x = xs + random.Next(21) - 10; int y = ys + random.Next(21) - 10; for (int j = 0; j < 100; j++) { int xo = x + random.Next(5) - random.Next(5); int yo = y + random.Next(5) - random.Next(5); for (int yy = yo - 1; yy <= yo + 1; yy++) for (int xx = xo - 1; xx <= xo + 1; xx++) if (xx >= 0 && yy >= 0 && xx < w && yy < h) { if (map[xx + yy * w] == Tile.Dirt.id) { map[xx + yy * w] = Tile.dirt.id; } } } } } 
    */ 
} 
} 
にそれを描画するテクスチャ2Dとして保存する方法を本当のアイデアを持っていないということです非常に感謝します

答えて

1

なぜコードの一部についてコメントしましたか?

あなただけの画像でそれを置くことができるようにしたい場合は、あなたが行うことができます:

System.Drawing.Image yourNewMap; 

using (MemoryStream ms = new MemoryStream(myByteArray,0,myByteArray.Length)) 
{  
    ms.Write(myByteArray,0,myByteArray.Length);  
    yourNewMap = Image.FromStream(ms,true);  
} 

それとも、クラスにすべてこのコードを追加することで、クラスには、このコンソールアプリケーションを変換し、追加することができますイメージを返す静的メソッド:

public static Image getRandomMap() 
{ 
    int d = 0; 
    int w = 128; 
    int h = 128; 
    byte[] map = LevelGen.createAndValidateTopMap(w, h)[0]; 



    int w = 128; 
    int h = 128; 

    byte[] map = LevelGen.createAndValidateTopMap(w, h)[0]; 
    byte[] map = LevelGen.createAndValidateUndergroundMap(w, h, (d++ % 3) + 1)[0]; 
    byte[] map = LevelGen.createAndValidateSkyMap(w, h)[0]; 

    int[] pixels = new int[w * h]; 
    for (int y = 0; y < h; y++) 
    { 
     for (int x = 0; x < w; x++) 
     { 
      int i = x + y * w; 

     // if (map[i] == Tile.water.id) pixels[i] = 0x000080; 
      if (map[i] == Tile.Dirt.id) pixels[i] = 0x604040; 
      if (map[i] == Tile.Sand.id) pixels[i] = 0xa0a040; 
     } 
    } 

    System.Drawing.Image yourNewMap; 

    using (MemoryStream ms = new MemoryStream(myByteArray,0,myByteArray.Length)) 
    {  
     ms.Write(myByteArray,0,myByteArray.Length);  
     yourNewMap = Image.FromStream(ms,true);  
    } 

    return yourNewMap; 

} 

あなたのゲームからあなたのイメージを取得することができます。

Image myMap = Tile_Engine.Game.getRandomMap(); 

まだ、コードの一部がコメントとしてマークされている理由はわかりません。

+0

System.Drawing.Image dosentが私の仕事ですが、私の問題は今修正されました – Gravity