Xna随机平铺地形

时间:2012-03-04 03:16:15

标签: c# random xna tile

所以我正在开发一个小游戏,主要是为了好玩,但是我遇到了一些障碍,我每次使用这个算法时都会尝试生成随机地形我从相信的缺口的minicraft来源。< / p>

如果有人可以帮助我,我会非常感激

我的问题是我不知道如何将其绘制到屏幕或将其保存为纹理2d以将其绘制到屏幕

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; } } } } }
     */
}
}

1 个答案:

答案 0 :(得分: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();

但是,我不明白为什么代码的某些部分被标记为注释。