সমান্তরাল প্রজেক্টড ভক্সেল টেরেইন জেনারেটর


20

আপনার কাজটি হাইটম্যাপ তৈরি করা এবং এটি সমান্তরাল প্রস্তাবিত, ভক্সেল ল্যান্ডস্কেপ হিসাবে দেখানো। নিয়মগুলি নিম্নলিখিত:

  • (উচ্চতার মানচিত্রের) ল্যান্ডস্কেপ এলোমেলোভাবে উত্পন্ন করতে হবে
  • এছাড়াও আপনি আছে বর্ণনা কীভাবে অ্যালগরিদম ব্যবহার করছেন করতে হবে, তাই প্রত্যেকে এখানে নতুন কিছু শিখতে পারে
  • আপনাকে হয় কোনও চিত্র তৈরি করতে হবে বা স্ক্রিনে উত্পন্ন আড়াআড়ি প্রদর্শন করতে হবে
  • ফলস্বরূপ চিত্রটি প্যারালেল প্রজেক্ট করতে হবে (সুতরাং দৃষ্টিভঙ্গি নয়), এবং এটিতে কেবল ভক্সেল থাকতে পারে (সুতরাং এটি ছোট বাক্সগুলি থেকে তৈরি করতে হবে)
  • এটি একটি জনপ্রিয়তা প্রতিযোগিতা, সুতরাং আপনি আরও বেশি কিছু পেতে আপনার প্রোগ্রামে কিছু অতিরিক্ত বৈশিষ্ট্য যুক্ত করতে চাইতে পারেন।
  • বিজয়ী সর্বশেষ বৈধ জমা দেওয়ার 7 দিন পরে সর্বাধিক উন্নত বৈধ উত্তর is সমস্ত বৈধ জমা দেওয়ার ক্ষেত্রে ব্যবহৃত অ্যালগরিদমের বিবরণ সহ বিধিগুলি অনুসরণ করা দরকার। আপনি অতিরিক্ত বৈশিষ্ট্যগুলি যুক্ত করতে পারেন যা কিছু নিয়ম অনুসরণ করে না (যেমন একটি দৃষ্টিকোণ মোড যুক্ত করে) তবে এই ক্ষেত্রে সেগুলি alচ্ছিক বৈশিষ্ট্যগুলি হতে হবে (যেমন ফলাফলগুলি সরিয়ে দেওয়ার সময় সমস্ত নিয়ম অনুসরণ করা উচিত)
  • আমার জমাটি বৈধ হিসাবে গণনা করে না।

উদাহরণস্বরূপ ফলাফলের চিত্রটি নিম্নলিখিত:

voxel আড়াআড়ি

চিত্র এখান থেকে তোলা

আপনার যদি কিছু অ্যালগরিদম প্রয়োজন হয় তবে এখানে চেক করুন


মাইনক্রাফ্ট এসকি রেন্ডার করা কিউবগুলি ভক্সেলের সমান হয় না। সত্য সমমান অভিক্ষেপ প্রয়োজনীয় হয়, অথবা ঢিলেঢালাভাবে হিসাবে ব্যবহার শব্দ খেলায় সাধারণ হয় en.wikipedia.org/wiki/Video_games_with_isometric_graphics
shiona

@ শিওনা: প্যারালেল প্রজেক্টেড বলতে কিছু দিন আগে এই বিষয়ের বর্ণনাকে পরিবর্তন করা হয়েছিল, সুতরাং অ-দৃষ্টিকোণকে গণনা করা উচিত। ভক্সেল হিসাবে: আমি মিনেক্রাফেসকিউ কিউবগুলি ভক্সেল হওয়ার ক্ষেত্রে বৈধ বলে মনে করি: এগুলি একটি বৃহত থ্রিডি গ্রিডে বিশাল পিক্সেল হিসাবে বিবেচনা করা যেতে পারে।
SztupY

না, মিনেক্রাফেস্কিউ কিউবগুলি ভক্সেল নয়, কারণ ভক্সেলগুলি কিউব নয়, ঠিক যেমন পিক্সেলগুলি বর্গক্ষেত্র নয়। citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.79.9093
ছদ্মনাম

আমি @ ছদ্মনাম ধরণের সাথে একমত। আমি মনে করি এটি বৈধ যদিও আপনি যদি সেগুলি কিউব হন। এটি যদিও প্রতিটি অন্যান্য ভক্সেল রাস্টারাইজেশন কৌশলটি বেশ কিছুটা বাদ দেয়।
টিম সেগুইন

উত্তর:


12

পাইথন 2 3 ডি ফাংশন প্লোটার ভক্সেল সংস্করণ

এটি এই প্রতিযোগিতায় আমার প্রবেশ:

import math
import random
import Image

terrain=""
randA=(random.random()*4+5)
randB=(random.random()*4+10)
randC=(random.random()*4+1)
randD=(random.random()*4+1)
im = Image.new("RGBA", (1248, 1000), "black")
tile=[Image.open("voxel/1.png"),Image.open("voxel/2.png"),Image.open("voxel/3.png"),Image.open("voxel/4.png"),Image.open("voxel/5.png"),Image.open("voxel/6.png"),Image.open("voxel/7.png"),Image.open("voxel/8.png"),Image.open("voxel/9.png")]


for y in range (-40,40):
        for x in range (-10, 10):
                val=int(1+abs(4+2.5*(math.sin(1/randA*x+randC)+math.sin(1/randB*y+randD))))
                if (val<9):
                        terrain+=str(val)
                else:
                        terrain+="9"
print terrain

for i in range (0,80*20):
        if((i/20)%2==0):
                shift=0
        else:
                shift=-32
        im.paste(tile[int(terrain[i])-1],((i%20)*64+shift,((i/20)*16-(32*(int(terrain[i])-1)))-32),tile[int(terrain[i])-1])

im.show()

যেমন শিরোনামে স্পষ্টভাবে বলা হয়েছে এটি একটি 3 ডি ফাংশন প্লটার হিসাবে কাজ করে, তবে যেহেতু এই প্রতিযোগিতার জন্য অঞ্চলটি এলোমেলোভাবে তৈরি করা দরকার এটি এ র্যান্ডম সাইন ফাংশন 1.5*(math.sin(1/randA*x+randC)+math.sin(1/randB*y+randD))যা 4 টি এলোমেলো ভেরিয়েবলের উপর নির্ভর করে। এটি এর মতো ভূখণ্ড তৈরি করে: এলোমেলো আউটপুট

আমরা অবশ্যই 2 টি ভেরিয়েবল ফাংশন দ্বারা এই র্যান্ডম ফাংশনটিকে প্রতিস্থাপন করতে পারি, উদাহরণস্বরূপ sin(sqrt((x/2)²+(y/2)²))*3এই অঞ্চলটি দেয়: 3Dfunction

এবং -x*y*e^(-x^2-y^2)এটি দেয়: 3Dfunction2
(ডানদিকে প্লটগুলি উলফ্রাম আলফা দ্বারা গণনা করা হয়)

এবং যখন আমরা এটিতে এসেছি তখন সমালোচনামূলক স্ট্রিপ বরাবর রিমান জিতা:

রিমন জেটা ফাংশন

আপনি জানেন না এমন লোকদের জন্য, যেমন আপনি দেখতে পান এই পুলগুলি (যা ফাংশনের শূন্যের প্রতিনিধিত্ব করে) সমস্ত সোজা লাইনে থাকে (আসল অংশ = 0.5)। আপনি যদি এটি প্রমাণ করতে পারেন তবে আপনি 00 1000000 পাবেন! এই লিঙ্কটি দেখুন।

আশা করি তুমি পছন্দ করেছ!


হাই জেনস, দুর্দান্ত প্লট! আমি ভাবছিলাম আপনি কোথা থেকে ভক্সেল চিত্রগুলি পেয়েছেন?
উইলেম

আমার ঠিক মনে নেই কোথায়, আমি কোনও গোগল চিত্র অনুসন্ধান করেছি এবং রঙ সহ সম্পাদনা করেছি
জেনস রেন্ডার্স

10

সি #, ডব্লিউপিএফ

আমি একটি এলোমেলো হাঁটা নিয়ে পরীক্ষা করেছি , যা আমার প্রত্যাশার চেয়েও ভাল কাজ করে। আমি মানচিত্রে কোথাও শুরু করছি, এলোমেলো সংলগ্ন টাইলের দিকে হাঁটা এবং তার উচ্চতার মান বাড়িয়ে , তারপরে পরবর্তী এবং আরও কিছুতে চলেছি । এটি কয়েক হাজার বার পুনরাবৃত্তি হয় এবং অবশেষে এটির মতো উচ্চতার মানচিত্রের দিকে নিয়ে যায় (100 x 100):

প্রশস্ত উচ্চতা মানচিত্র উচ্চতার মানচিত্র

তারপরে, আমি মানচিত্রটিকে "বিচক্ষণ" করব, প্রদত্ত উচ্চতার স্তরের মানগুলির সংখ্যা হ্রাস করব এবং সেই উচ্চতার ভিত্তিতে ভূখণ্ড / রঙ নির্ধারণ করুন:

চৌম্বকীয় ভূখণ্ডের মানচিত্র ভূখণ্ডের মানচিত্র

ভক্সেল ভূখণ্ড 1

আরও অনুরূপ দ্বীপপুঞ্জের মতো ভূখণ্ড:

ভক্সেল ভূখণ্ড 2

ভক্সেল ভূখণ্ড 3

voxel ভূখণ্ড 4

ভক্সেল ভূখণ্ড 5

আরও পাহাড়ী অঞ্চল পেতে এলোমেলো পদক্ষেপ এবং উচ্চতার স্তর বর্ধিত সংখ্যা:

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন


কোড

বৈশিষ্ট্য: একটি বোতাম দিয়ে ভূখণ্ড পুনরুদ্ধার করুন। 3D ভূখণ্ড এবং 2D মানচিত্র দেখান। জুমিং (মাউস হুইল) এবং 3 ডি স্ক্রোলিং (তীর কী)। তবে এটি খুব পারফরম্যান্ট নয় - সর্বোপরি, এটি ডাইরেক্টএক্স বা ওপেনজিএল নয়, খাঁটিভাবে ডাব্লুপিএফ-এ লেখা হয়েছে।

MainWindow.xaml:

<Window x:Class="VoxelTerrainGenerator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Voxel Terrain Generator" Width="550" Height="280" KeyUp="Window_KeyUp">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <Viewport3D x:Name="ViewPort" MouseWheel="ViewPort_MouseWheel">
            <Viewport3D.Camera>
                <OrthographicCamera x:Name="Camera" Position="-100,-100,150" LookDirection="1,1,-1" UpDirection="0,0,1" Width="150" />
                <!--<PerspectiveCamera x:Name="Camera" Position="-100,-100,150" LookDirection="1,1,-1" UpDirection="0,0,1" />-->
            </Viewport3D.Camera>
        </Viewport3D>

        <Grid Grid.Column="1" Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Image Grid.Row="0" x:Name="TopViewImage"/>
            <Button Grid.Row="1" Margin="0 10 0 0" Click="Button_Click" Content="Generate Terrain" />
        </Grid>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Media.Media3D;

namespace VoxelTerrainGenerator
{
    public partial class MainWindow : Window
    {
        const int RandomSteps = 20000;
        const int MapLengthX = 100;
        const int MapLengthY = 100;
        const int MaxX = MapLengthX - 1;
        const int MaxY = MapLengthY - 1;
        const bool ForceIntoBounds = true;
        readonly Random Random = new Random();

        readonly List<Color> ColorsByHeight = new List<Color> 
        { 
            Color.FromArgb(0, 0, 50),
            Color.FromArgb(170, 170, 20),
            Color.FromArgb(0, 150, 0),
            Color.FromArgb(0, 140, 0),
            Color.FromArgb(0, 130, 0),
            Color.FromArgb(0, 120, 0),
            Color.FromArgb(0, 110, 0),
            Color.FromArgb(100, 100, 100),
        };

        public MainWindow()
        {
            InitializeComponent();
            TopViewImage.Width = MapLengthX;
            TopViewImage.Height = MapLengthY;
        }

        public int[,] CreateRandomHeightMap()
        {
            var map = new int[MapLengthX, MapLengthY];

            int x = MapLengthX/2;
            int y = MapLengthY/2;

            for (int i = 0; i < RandomSteps; i++)
            {
                x += Random.Next(-1, 2);
                y += Random.Next(-1, 2);

                if (ForceIntoBounds)
                {
                    if (x < 0) x = 0;
                    if (x > MaxX) x = MaxX;
                    if (y < 0) y = 0;
                    if (y > MaxY) y = MaxY;
                }

                if (x >= 0 && x < MapLengthX && y >= 0 && y < MapLengthY)
                {
                    map[x, y]++;
                }
            }

            return map;
        }

        public int[,] Normalized(int[,] map, int newMax)
        {
            int max = map.Cast<int>().Max();
            float f = (float)newMax / (float)max;

            int[,] newMap = new int[MapLengthX, MapLengthY];
            for (int x = 0; x < MapLengthX; x++)
            {
                for (int y = 0; y < MapLengthY; y++)
                {
                    newMap[x, y] = (int)(map[x, y] * f);
                }
            }
            return newMap;
        }

        public Bitmap ToBitmap(int[,] map)
        {
            var bitmap = new Bitmap(MapLengthX, MapLengthY);
            for (int x = 0; x < MapLengthX; x++)
            {
                for (int y = 0; y < MapLengthY; y++)
                {
                    int height = map[x, y];
                    if (height > 255)
                    {
                        height = 255;
                    }
                    var color = Color.FromArgb(255, height, height, height);
                    bitmap.SetPixel(x, y, color);
                }
            }
            return bitmap;
        }

        public Bitmap ToColorcodedBitmap(int[,] map)
        {
            int maxHeight = ColorsByHeight.Count-1;
            var bitmap = new Bitmap(MapLengthX, MapLengthY);
            for (int x = 0; x < MapLengthX; x++)
            {
                for (int y = 0; y < MapLengthY; y++)
                {
                    int height = map[x, y];
                    if (height > maxHeight)
                    {
                        height = maxHeight;
                    }
                    bitmap.SetPixel(x, y, ColorsByHeight[height]);
                }
            }
            return bitmap;
        }

        private void ShowTopView(int[,] map)
        {
            using (var memory = new System.IO.MemoryStream())
            {
                ToColorcodedBitmap(map).Save(memory, ImageFormat.Png);
                memory.Position = 0;
                var bitmapImage = new System.Windows.Media.Imaging.BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                TopViewImage.Source = bitmapImage;
            }
        }

        private void Show3DView(int[,] map)
        {
            ViewPort.Children.Clear();

            var light1 = new AmbientLight(System.Windows.Media.Color.FromArgb(255, 75, 75, 75));
            var lightElement1 = new ModelUIElement3D();
            lightElement1.Model = light1;
            ViewPort.Children.Add(lightElement1);

            var light2 = new DirectionalLight(
                System.Windows.Media.Color.FromArgb(255, 200, 200, 200),
                new Vector3D(0, 1, -0.1));
            var lightElement2 = new ModelUIElement3D();
            lightElement2.Model = light2;
            ViewPort.Children.Add(lightElement2);

            for (int x = 0; x < MapLengthX; x++)
            {
                for (int y = 0; y < MapLengthY; y++)
                {
                    int height = map[x, MapLengthY-y-1];
                    for (int h = 0; h <= height; h++)
                    {
                        Color color = ColorsByHeight[h];
                        if (height > 0 && h == 0)
                        {
                            // No water under sand
                            color = ColorsByHeight[1];
                        }

                        ViewPort.Children.Add(CreateCube(x, y, h, 1,
                            System.Windows.Media.Color.FromArgb(255, color.R, color.G, color.B)));
                    }
                }
            }
        }

        private ModelVisual3D CreateCube(int x, int y, int z, int length,
            System.Windows.Media.Color color)
        {
            List<Point3D> positions = new List<Point3D>()
            {
                new Point3D(x, y, z),
                new Point3D(x + length, y, z),
                new Point3D(x + length, y + length, z),
                new Point3D(x, y + length, z),
                new Point3D(x, y, z + length),
                new Point3D(x + length, y, z + length),
                new Point3D(x + length, y + length, z + length),
                new Point3D(x, y + length, z + length),
            };

            List<List<int>> quads = new List<List<int>> 
            { 
                new List<int> {3,2,1,0},
                new List<int> {0,1,5,4},
                new List<int> {2,6,5,1},
                new List<int> {3,7,6,2},
                new List<int> {3,0,4,7},
                new List<int> {4,5,6,7},
            };

            double halfLength = (double)length / 2.0;
            Point3D cubeCenter = new Point3D(x + halfLength, y + halfLength, z + halfLength);
            var mesh = new MeshGeometry3D();
            foreach (List<int> quad in quads)
            {
                int indexOffset = mesh.Positions.Count;
                mesh.Positions.Add(positions[quad[0]]);
                mesh.Positions.Add(positions[quad[1]]);
                mesh.Positions.Add(positions[quad[2]]);
                mesh.Positions.Add(positions[quad[3]]);

                mesh.TriangleIndices.Add(indexOffset);
                mesh.TriangleIndices.Add(indexOffset+1);
                mesh.TriangleIndices.Add(indexOffset+2);
                mesh.TriangleIndices.Add(indexOffset+2);
                mesh.TriangleIndices.Add(indexOffset+3);
                mesh.TriangleIndices.Add(indexOffset);

                double centroidX = quad.Select(v => mesh.Positions[v].X).Sum() / 4.0;
                double centroidY = quad.Select(v => mesh.Positions[v].Y).Sum() / 4.0;
                double centroidZ = quad.Select(v => mesh.Positions[v].Z).Sum() / 4.0;
                Vector3D normal = new Vector3D(
                    centroidX - cubeCenter.X,
                    centroidY - cubeCenter.Y,
                    centroidZ - cubeCenter.Z);
                for (int i = 0; i < 4; i++)
                {
                    mesh.Normals.Add(normal);
                }
            }

            Material material = new DiffuseMaterial(new System.Windows.Media.SolidColorBrush(color));
            GeometryModel3D model = new GeometryModel3D(mesh, material);
            ModelVisual3D visual = new ModelVisual3D();
            visual.Content = model;
            return visual;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            int[,] map = CreateRandomHeightMap();
            int[,] normalizedMap = (Normalized(map, ColorsByHeight.Count-1));

            ShowTopView(normalizedMap);
            Show3DView(normalizedMap);

            ToBitmap(Normalized(map, 255)).Save("heightmap-original.png");
            ToBitmap(Normalized(normalizedMap, 255)).Save("heightmap.png");
            ToColorcodedBitmap(normalizedMap).Save("terrainmap.png");
        }

        private void ViewPort_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            // Zoom in or out
            Camera.Width -= (double)e.Delta / 100;
        }

        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            // Scrolling by moving the 3D camera
            double x = 0;
            double y = 0;
            if (e.Key == Key.Left)
            {
                x = +10;
                y = -10;
            }
            else if (e.Key == Key.Up)
            {
                x = -10;
                y = -10;
            }
            else if (e.Key == Key.Right)
            {
                x = -10;
                y = +10;
            }
            else if (e.Key == Key.Down)
            {
                x = +10;
                y = +10;
            }

            Point3D cameraPosition = new Point3D(
                Camera.Position.X + x,
                Camera.Position.Y + y,
                Camera.Position.Z);
            Camera.Position = cameraPosition;
        }
    }
}

ঝরঝরে, তবে আপনি আরও বালতি অন্তর্ভুক্ত করতে 'বিবেচনা' করার সময় এটি আরও ভাল লাগবে। আরও একটি বা দুটি গ্রুপিং হতে পারে? (কোনওভাবেই প্রয়োজনীয় নয়! তবুও আমার কাছ থেকে +1।)
গাফি

1
@ গাফি আমি আরও পর্বতমালা সহ আরও ফলাফল যুক্ত করেছি
সেবাস্তিয়ান নেগ্রাসজাস

4

জাভাস্ক্রিপ্ট এবং ক্রাফটি.জেএস, অনেক উন্নত হতে হবে

এখানে একটি নমুনা আউটপুট:

স্ক্রিনশট

এবং এখানে কোড (সম্পূর্ণ ওয়েবপেজ):

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
    <script type="text/javascript" src="http://craftyjs.com/release/0.4.2/crafty-min.js"></script>
    <script type="text/javascript">

    $(document).ready(function() {
        Crafty.init();

        var tilesize = 20
        Crafty.sprite(20, "sprite.png#UPDATE", {
            grass1: [0,0,1,3],
            grass2: [1,0,1,3],
            grass3: [2,0,1,3],
            stone1: [3,0,1,3],
            stone2: [4,0,1,3]
        });

        genTerrainInit()
        while(1) {
            try { stepTerrainGen() }
            catch(e) { break }
        }


        iso = Crafty.isometric.init(20);
        var z = 0;
        for(var i = tdata.length - 1; i >= 0; i--) {
            for(var y = 0; y < tdata[i].length; y++) {
                var which = Math.max(0, Math.round(tdata[i][y]))
                var tile = Crafty.e("2D, DOM, "+["grass1", "grass2", "grass3", "stone1", "stone2"][which])
                .attr('z',i+1 * y+1)

                iso.place(i,y,0, tile);
            }
        }

        Crafty.addEvent(this, Crafty.stage.elem, "mousedown", function(e) {
            if(e.button > 1) return;
            var base = {x: e.clientX, y: e.clientY};

            function scroll(e) {
                var dx = base.x - e.clientX,
                    dy = base.y - e.clientY;
                    base = {x: e.clientX, y: e.clientY};
                Crafty.viewport.x -= dx;
                Crafty.viewport.y -= dy;
            };

            Crafty.addEvent(this, Crafty.stage.elem, "mousemove", scroll);
            Crafty.addEvent(this, Crafty.stage.elem, "mouseup", function() {
                Crafty.removeEvent(this, Crafty.stage.elem, "mousemove", scroll);
            });
        });
    });

    function genTerrainInit() {
        //Variables
        size = Math.pow(2, 6) + 1; //MUST be a power of 2 plus 1!
        initHeight = 2;
        rndRange = 4;
        smoothSpeed = 0.5; // lower is faster

        tdata = new Array(size);
        toAverage = new Array(size);
        for (var i = 0; i < size; i ++) {
            tdata[i] = new Array(size);
            toAverage[i] = new Array(size);
            for (var i2 = 0; i2 < size; i2 ++) {
                tdata[i][i2] = null;
                toAverage[i][i2] = false;
            }
        }

        //Generate corners
        tdata[0][0] = initHeight;
        tdata[size-1][0] = initHeight;
        tdata[0][size-1] = initHeight;
        tdata[size-1][size-1] = initHeight;
    }

    function stepTerrainGen() {
        //The square step - for each square, take the center point and set it to the average of its corners plus a random amount
        oldi = 0;
        for (var i = 1; i < size; i ++) {
            if (tdata[0][i] != null) {
                oldi2 = 0;
                for (var i2 = 1; i2 < size; i2 ++) {
                    if (tdata[i2][i] != null) {
                        pointDistance = (i - oldi)/2;
                        tdata[(oldi2 + i2)/2][(oldi + i)/2] =
                            ((tdata[oldi2][oldi] + tdata[i2][oldi] + tdata[oldi2][i] + tdata[i2][i])/4) // average of 4 corners
                            + Math.random() * rndRange - (rndRange/2.0);                                // plus a random amount

                        // Now mark the squares for the diamond step
                        toAverage[(oldi2 + i2)/2][oldi] = true;
                        toAverage[oldi2][(oldi + i)/2] = true;
                        toAverage[(oldi2 + i2)/2][i] = true;
                        toAverage[i2][(oldi + i)/2] = true;
                        oldi2 = i2;
                    }
                }
                oldi = i;
            }
        }

        //The diamond step - same as the square step but with newly formed diamonds
        for (var i = 0; i < size; i ++) {
            for (var i2 = 0; i2 < size; i2 ++) {
                if (toAverage[i][i2]) {
                    diamondArray = [];
                    if (i-pointDistance >= 0) diamondArray = diamondArray.concat(tdata[i-pointDistance][i2]);
                    if (i+pointDistance < size) diamondArray = diamondArray.concat(tdata[i+pointDistance][i2]);
                    if (i2-pointDistance >= 0) diamondArray = diamondArray.concat(tdata[i][i2-pointDistance]);
                    if (i2+pointDistance < size) diamondArray = diamondArray.concat(tdata[i][i2+pointDistance]);
                    addedPoints = 0;
                    for (var i3 = 0; i3 < diamondArray.length; i3 ++) addedPoints += diamondArray[i3];
                    tdata[i][i2] = addedPoints/diamondArray.length + Math.floor(Math.random() * rndRange - (rndRange/2.0));
                }
            }
        }
        rndRange *= smoothSpeed;
        resetToAverage();
    }

    function resetToAverage() {
        for (var i = 0; i < size; i ++) {
            for (var i2 = 0; i2 < size; i2 ++) {
                toAverage[i][i2] = false;
            }
        }
    }

    </script>
    <title>Iso</title>
    <style>
    body, html { margin:0; padding: 0; overflow:hidden }
    </style>
</head>
<body>
</body>
</html>

এখানে sprite.png:

sprite.png

এখন, আমি কিছু বলার আছে।

  1. সেই ভয়ানক কোডের জন্য আমাকে বিচার করবেন না! : পিআই অনেক বছর আগে এটি লিখেছিল যখন আমি একটি ভয়ানক প্রোগ্রামিং ছিলাম। আসলে, এটি আমার ওয়েবসাইটের পুরানো দিনগুলি থেকে আমার মনে ছিল না যে আমার ছিল! http://oddllama.cu.cc/terrain/

  2. আমি ক্র্যাটি.জেএস আইসোমেট্রিক ডেমো থেকে অনেক ধরণের কোড অনুলিপি করেছি : P: P

  3. ব্যাখ্যা শিগগিরই আসবে! এখানে আসতে দেরি হওয়ায় আমাকে এখনই ঘুমাতে হবে। (এ কারণেই স্প্রাইট এত ভয়ঙ্কর!)

মূলত, এটি সত্যিই অপরিবর্তিত এবং পরে এটির ব্যাপক উন্নতি হবে!

এটি ওপি-র উত্তরে উল্লিখিত একই হীরা-বর্গাকার অ্যালগোরিদম ব্যবহার করে।


আমরা কি অন্যান্য ভাষায় ব্যবহারের জন্য এই স্প্রিটগুলি ধার নিতে পারি?
পাইরুলেজ

@ পাইরুলেজ ওয়েল, আমি, উহ, ক্র্যাটি.জেএস সাইট থেকে এক ধরণের তাদের চুরি করেছি (এবং তাদের সম্পাদনা করেছি), সুতরাং আমার কোনও ধারণা নেই: পি সম্ভবত আমার উল্লেখ করা উচিত ছিল
ডোরকনব

3

রুবি + আরম্যাগিক

হাইটম্যাপ তৈরি করতে আমি ডায়মন্ড-স্কোয়ার অ্যালগরিদম ব্যবহার করছি ।

সংক্ষেপে অ্যালগরিদম:

  • 2 a n এর আকারের সাথে একটি মোড়কের অ্যারে ম্যাট্রিক্স ব্যবহার করুন
  • মোড়কের অর্থ সীমানার বাইরে যে কোনও সূচি চারপাশে মোড়ানো, যেমন অ্যারের আকার 4 হয় [0,0] == [4,0] == [0,4] == [4,4]। এছাড়াও[-2,0] == [2,0] , ইত্যাদি
  • [0,0]একটি এলোমেলো রঙ সেট করুন
  • ছবিতে প্রদর্শিত পদক্ষেপগুলি অনুসরণ করুন।

ব্যাখ্যা চিত্র

  • দ্রষ্টব্য, যেহেতু অ্যারেটি প্রায় আবৃত হয়, যখন আপনাকে সীমানার বাইরে কিছু সূচি করতে হয়, আপনি অ্যারের অন্য দিক থেকে ডেটা ব্যবহার করতে পারেন।
  • আরও মনে রাখবেন, খুব প্রথম ধাপে চারটি কোণার অর্থ হ'ল একই মান (হিসাবে [0,0] == [4,0] == [0,4] == [4,4])
  • কালো বিন্দুর মান গণনা করতে, আপনাকে চারপাশে চারটি পয়েন্ট গড় করতে হবে
  • এটি বোরিং, ধূসর চিত্রের ফলস্বরূপ, প্রতিটি পদক্ষেপে আপনাকে এই মানটিতে একটি এলোমেলো সংখ্যা যুক্ত করতে হবে। এটি অগ্রাধিকারযুক্ত যে এই এলোমেলো মানটি প্রথম পুনরাবৃত্তিতে পুরো ব্যাপ্তিকে বিস্তৃত করে, তবে আপনি যখন অ্যারের ছোট এবং ছোট সাবসেটগুলিকে সম্বোধন করছেন তখন সময়ের সাথে সাথে হ্রাস পায়। সময়ের সাথে সাথে এই এলোমেলোতা যত কমবে, ততই গোলমাল হবে চিত্রটি।

  • আমার কাজ শেষ হওয়ার পরে আমি প্রতিটি উচ্চতার মানের জন্য কেবল একটি রঙ নির্ধারণ করছি।

কোড:

generate.rb

#!/usr/bin/env ruby
require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)

class Numeric
  def clamp min, max
    [[self, max].min, min].max
  end
end

class WrappedArray
  def initialize(size)
    @size = size
    @points = Array.new(size){Array.new(SIZE)}
  end
  def [](y,x)
    @points[(@size+y) % @size][(@size+x) % @size]
  end
  def []=(y,x,value)
    @points[(@size+y) % @size][(@size+x) % @size] = value.clamp(0,@size*@size-1)
  end
end

SIZE = 256
MAXHEIGHT = 256*256

points = WrappedArray.new(SIZE)

points[0,0] = 0

s = SIZE
d = []
sq = []
r = MAXHEIGHT
while s>1
  (0...SIZE).step(s) do |x|
    (0...SIZE).step(s) do |y|
      d << [y,x]
    end
  end
  while !d.empty?
    y,x = *d.shift
    mx = x+s/2
    my = y+s/2

    points[my,mx]  = (points[y,x]   + points[y,x+s]      + points[y+s,x] + points[y+s,x+s])/4 + rand(r)-r/2
    sq << [my,x]
    sq << [my,x+s]
    sq << [y,mx]
    sq << [y+s,mx]
  end
  while !sq.empty?
    y,x = *sq.shift
    points[y,x]    = (points[y-s/2,x] + points[y+s/2,x] + points[y,x-s/2] + points[y,x+s/2])/4 + rand(r)-r/2
  end
  s = s / 2
  r = r * 2 / 3
end

def get_color(height)
  val = height.to_f/MAXHEIGHT*3-1
  r = 0
  g = 0
  b = 0
  if val<=-0.25
    Magick::Pixel.new(0,0,128*256)
  elsif val<=0
    Magick::Pixel.new(0,0,255*256)
  elsif val<=0.0625
    Magick::Pixel.new(0,128*256,255*256)
  elsif val<=0.1250
    Magick::Pixel.new(240*256,240*256,64*256)
  elsif val<=0.3750
    Magick::Pixel.new(32*256,160*256,0)
  elsif val<=0.7500
    Magick::Pixel.new(224*256,224*256,0)
  else
    Magick::Pixel.new(128*256,128*256,128*256)
  end
end

canvas = Magick::ImageList.new
canvas.new_image(SIZE+1, SIZE+1)
0.upto(SIZE) do |y|
  0.upto(SIZE) do |x|
    canvas.pixel_color(x,y,get_color(points[y,x]))
  end
end
canvas.write('result.png')

Gemfile

source "https://rubygems.org"
gem 'rmagick'

দ্রষ্টব্য: আমি যে চিত্রমাফিকটি ব্যবহার করছি তা 16 বিট

ফলাফল চিত্র:

ফলাফল চিত্র

দ্রষ্টব্য: এই চিত্রটি একটি শীর্ষ-নীচে, আইসোমেট্রিক উপস্থাপনা, যেখানে একটি ভক্সেলের আকার হুবহু এক পিক্সেল, সুতরাং এটি নিয়ম অনুসারে বৈধ (এটি ব্যতীত: আমার উত্তরটি বৈধ বলে বিবেচিত হবে না)


আপনার ওয়ান-পিক্সেলের শীর্ষ-ডাউন আইসোমেট্রিক দ্রবণটির গুণমানটি কী সেই গুরত্বের সূচক হিসাবে বোঝানো হচ্ছে যার সাথে আপনি লোকেরা আপনার প্রশ্নের কাছে যেতে চান?
জোনাথন ভ্যান মাত্রে

আইসোমেট্রিক হিসাবে শীর্ষের গণনাগুলি আমি মনে করি না? en.wikipedia.org/wiki/Isometric_projection
mattnewport

@ জোনাথনভান মাত্রে: প্রশ্নে আমি পছন্দসই ফলাফলটি দেখিয়েছি। উত্তরে আমি বৈধ হওয়ার জন্য সর্বনিম্ন আপনার করা উচিত তা দেখিয়েছি। এটি একটি জনপ্রিয়তা-প্রতিযোগিতা হিসাবে আপনি যা করতে চান তা চয়ন করতে পারেন তবে অবশ্যই আপনার পছন্দসই ফলাফলটি করার জন্য সাফল্য অর্জন করা উচিত।
SztupY

@ ম্যাটনিউপোর্ট: ভাল কথা, আমি ভুল করে এটিকে সব ধরণের প্যারালেল অনুমানের জন্য ব্যবহার করেছিলাম। সংশোধন করা হয়েছে।
SztupY

3

জাভা (@ ফেজেসোকোর রঙ-চিত্রটি বেস অ্যালগরিদম হিসাবে ব্যবহার করে)

@Fejesjoco থেকে ফুলআরজিবি রঙিন চিত্রগুলি নিয়ে কিছুটা খেলার পরে আমি লক্ষ্য করেছি যে সেগুলি আকর্ষণীয় ক্লিফাই ভক্সেল ল্যান্ডস্কেপের জন্য বেস হিসাবে ব্যবহার করা যেতে পারে। অ্যালগরিদমটিকে পুনরায় প্রয়োগ করার পরিবর্তে আমি তার কোডটি বাহ্যিক এক্সিকিউটেবল হিসাবে ব্যবহার করেছি (এটি http://joco.name/2014/03/02/all-rgb-colors-in-one-image/ থেকে ডাউনলোড করুন এবং এটি আর্টজেন হিসাবে নামকরণ করুন। একই ডিরেক্টরিতে উদাহরণস্বরূপ)

পূর্বরূপ:
পূর্বরূপ

উচ্চতা ম্যাপ ব্যবহৃত (নীল চ্যানেলে সঞ্চিত)
Heightmap

ইনপুট চিত্র:
ইনপুট

আমি এটি থেকে যে সাবালগরিদম ব্যবহার করি তা সেভাবে কাজ করে:
1. বাছাই করা
2. কেন্দ্রে একটি কালো পিক্সেল দিয়ে শুরু করুন
all. যতক্ষণ না সমস্ত রঙ ব্যবহার করা হয়: বর্তমান রঙটি সবচেয়ে কাছের ফিটিং স্পটে রাখুন এবং অব্যবহৃত প্রতিবেশীদেরকে নতুন ব্যবহারযোগ্য স্পট হিসাবে যুক্ত করুন এটি শেষ হয়ে গেলে আমি 256 বিভিন্ন মান red&(green|blue) 4 এ কমানোর জন্য এটি ম্যাঙ্গাল করি then তারপরে আমি প্রিজেনারেটেড স্প্রাইট ব্যবহার করি এবং স্তর দ্বারা চিত্র স্তরটি উত্পন্ন করি

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author LH
 */
public class Voxelizer2
{
    static final String zipembeddedsprites =
            "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";
    public static void main(String[] args) throws Exception
    {
        //embedded zip idea borrowed from over here:
        //http://codegolf.stackexchange.com/a/22262/10801

        //algorithm and embedded executable borrowed from
        //http://joco.name/2014/03/02/all-rgb-colors-in-one-image/

        //256 8192 2048 4096 1024 1000 9263 11111111 hue-0 one
        /**/
        ProcessBuilder p = new ProcessBuilder("artgen","64","512","512","256","256","1",((int)(Math.random()*(2<<32)))+"","11111111","hue-0","one");
        Process po = p.start();
        BufferedReader x = new BufferedReader(new InputStreamReader(po.getInputStream()),1024);
        String xl = x.readLine();
        //String x2l = x2.readLine();
        while(!xl.startsWith("Press ENTER to exit"))
        {
            System.out.println(xl);
            xl=x.readLine();
        }
        System.out.println(xl);
        po.destroy();/**/
        BufferedImage source = ImageIO.read(new File("result00000.png"));
        BufferedImage heightmap = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_INT_RGB);
        for (int i = 0; i < source.getWidth(); i++)
        {
            for (int j = 0; j < source.getHeight(); j++)
            {
                int basecolor=source.getRGB(i, j)&0x00FFFFFF;
                int r = (basecolor&0x00FF0000)>>16;
                int g = (basecolor&0x0000FF00)>>8;
                int b = (basecolor&0x000000FF);
                int color = r&(g|b);//Math.max(r,Math.max(g,b));
                heightmap.setRGB(i, j, color);

            }
        }/**/
        ImageIO.write(heightmap, "png", new File("heightmap.png"));


        //generate sizedata for Sprites....

        ZipInputStream zippedSprites = new ZipInputStream(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(zipembeddedsprites)));
        ZipEntry z = zippedSprites.getNextEntry();
        BufferedImage water=null,grass=null,stone=null,air = new BufferedImage(24,24, BufferedImage.TYPE_INT_ARGB);
        while(z!=null)
        {
            String name = z.getName();
            switch(name)
            {
                case "water.png":
                    water=ImageIO.read(zippedSprites);
                    System.out.println("water");
                break;
                case "stone.png":
                    stone=ImageIO.read(zippedSprites);
                    System.out.println("stone");
                break;
                case "grass.png":
                    grass=ImageIO.read(zippedSprites);
                    System.out.println("grass");
                break;
            }
            z=zippedSprites.getNextEntry();
        }

        //int height = heightmap.getHeight()*12+12;
        int width16 = heightmap.getWidth()/16;
        int height16=heightmap.getHeight()/16;
        int widthtemp1 = 384+(height16-1)*(384/2);
        int width = (width16-1)*(384/2)+widthtemp1;
        //int heightt1=height16*(12*16)+12*16;
        int height = (width16-1)*(12*16)+(12*16);
        System.out.println(width*height);
        //if(true)return;

        int StartPos =heightmap.getHeight()*12;

        //BufferedImage[] layers = new BufferedImage[256];

        BufferedImage complete = new BufferedImage(width, height+(255*12), BufferedImage.TYPE_INT_ARGB);
        int mergeOffset=255*12;
        for (int i = 0; i < 256; i++)
        {
            System.out.println("Rendering layer"+i);
            BufferedImage layer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            int basePointerX = StartPos-12;
            int basePointerY=0;
            Graphics g = layer.getGraphics();
            for (int k = 0; k < heightmap.getHeight(); k++)
            {
                //System.out.println("Processing line"+k);
                int pointerX = basePointerX;
                int pointerY = basePointerY;
                for (int j = 0; j < heightmap.getWidth(); j++)
                {

                    Image tile = air;
                    int pxheight =heightmap.getRGB(j, k)&0x00FFFFFF;
                    if(pxheight>i)
                    {
                        tile=stone;
                    }
                    if(pxheight==i)
                    {
                        if(i<64)
                        {
                            tile=stone;
                        }
                        else
                        {
                            tile=grass;
                        }
                    }
                    if(pxheight<i)
                    {
                        if(i<64)
                        {
                            tile=water;
                        }
                        else
                        {
                            tile=air;
                        }
                    }
                    g.drawImage(tile, pointerX, pointerY, null);
                    pointerX+=12;
                    pointerY+=6;
                }

                basePointerX-=12;
                basePointerY+=6;


            }

            //

            complete.getGraphics().drawImage(layer, 0, mergeOffset, null);

            mergeOffset-=12;
        }
        ImageIO.write(complete, "png", new File("landscape.png"));
    }
}

1

এইচটিএমএল + জাভাস্ক্রিপ্ট

প্রতিযোগিতায় আমার প্রচেষ্টা এখানে:

<html>
    <head>
        <script type='text/javascript' language='JavaScript'>
            function create() {
                var con = document.getElementById("can").getContext("2d"),
                    map = new Array(),
                    p = new Array(15 + Math.floor(Math.random() * 10)),
                    tc = ["#000040", "#000070", "#0000a0", "#5050ff", "#f0f000", "#007000", "#00aa00", "#00c000", "#00e000", "#00ff00", "#90ff90", "#a0ffa0", "#c0ffc0", "#e0ffe0", "#f0fff0"],
                    sc = ["#000020", "#000050", "#000085", "#3030df", "#d0d000", "#005000", "#008000", "#008000", "#00b500", "#00d000", "#00ea00", "#80ff80", "#a0ffa0", "#c0ffc0", "#d0ffd0"];
                for (var n = 0; n < p.length; n++) {
                    p[n] = [15 + Math.floor(Math.random() * 70), 15 + Math.floor(Math.random() * 70)];
                }
                for (var x = 0; x < 100; x++) {
                    map[x] = new Array();
                    for (var y = 0; y < 100; y++) {
                        map[x][y] = 0;
                        for (var n = 0; n < p.length; n++) {
                            if (20 - Math.sqrt(Math.pow(x - p[n][0], 2) + Math.pow(y - p[n][1], 2)) > map[x][y]) {
                                map[x][y] = 20 - Math.sqrt(Math.pow(x - p[n][0], 2) + Math.pow(y - p[n][2], 2));
                            }
                        }
                    }
                }
                for (var x = 0; x < 100; x++) {
                    for (var y = 0; y < 100; y++) {
                        if (map[x][y] < 0) {
                            map[x][y] = 0;
                        }
                        map[x][y] = Math.floor(map[x][y] / 2);
                        con.fillStyle = tc[map[x][y]];
                        con.fillRect(x * 10, y * 10 - map[x][y] * 4, 10, 10);
                        con.fillStyle = sc[map[x][y]];
                        con.fillRect(x * 10, y * 10 - map[x][y] * 4 + 10, 10, map[x][y] * 4);
                    }
                }
            }
        </script>
    </head>
    <body>
        <canvas id='can' width='1000' height='1000' style='border: 1px solid #000000;'></canvas>
        <button onclick='create();'>Create</button>
    </body>
</html>

আমি উচ্চতা মানচিত্র উত্পন্ন করতে ইউক্যালিডিয়ান এফ 1 সেল নয়েজ অ্যালগরিদম ব্যবহার করি যা আমি তারপরে একটি অ্যারের থেকে উপযুক্ত রঙ নিয়ে এবং 10x, 10y-উচ্চতায় একটি বর্গক্ষেত্র অঙ্কন করে একটি চিত্রে রূপান্তর করি যাতে উচ্চতর পিক্সেল উত্থাপিত হয়। আমি তখন ভিন্ন অ্যারে থেকে একই রঙ ব্যবহার করে পাশ হিসাবে একটি আয়তক্ষেত্র আঁকবো।

সেল নয়েজ ঘ সেল নয়েজ 2

10,000-পদক্ষেপের এলোমেলো ওয়াক অ্যালগরিদম ব্যবহার করে এখানে একই কোডটি দেওয়া হচ্ছে:

<html>
    <head>
        <script type='text/javascript' language='JavaScript'>
            function create() {
                var con = document.getElementById("can").getContext("2d"),
                    map = new Array(),
                    l = 10000,
                    tc = ["#000040", "#000070", "#0000a0", "#5050ff", "#f0f000", "#007000", "#00aa00", "#00c000", "#00e000", "#00ff00", "#90ff90", "#a0ffa0", "#c0ffc0", "#e0ffe0", "#f0fff0"],
                    sc = ["#000020", "#000050", "#000085", "#3030df", "#d0d000", "#005000", "#008000", "#008000", "#00b500", "#00d000", "#00ea00", "#80ff80", "#a0ffa0", "#c0ffc0", "#d0ffd0"];
                for (var x = 0; x < 100; x++) {
                    map[x] = new Array();
                    for (var y = 0; y < 100; y++) {
                        map[x][y] = 0;
                    }
                }
                x = 49;
                y = 49;
                for (var n = 0; n < l; n++) {
                    var d = Math.floor(Math.random() * 4);
                    if (d == 0) {
                        x++
                    }
                    else if (d == 1) {
                        y++
                    }
                    else if (d == 2) {
                        x--
                    }
                    else if (d == 3) {
                        y--
                    }
                    map[(x % 100 + 100) % 100][(y % 100 + 100) % 100]++;
                }
                for (var x = 0; x < 100; x++) {
                    for (var y = 0; y < 100; y++) {
                        if (map[x][y] < 0) {
                            map[x][y] = 0;
                        }
                        map[x][y] = Math.floor(map[x][y] / 2);
                        con.fillStyle = tc[map[x][y]];
                        con.fillRect(x * 10, y * 10 - map[x][y] * 4, 10, 10);
                        con.fillStyle = sc[map[x][y]];
                        con.fillRect(x * 10, y * 10 - map[x][y] * 4 + 10, 10, map[x][y] * 4);
                    }
                }
            }
        </script>
    </head>
    <body>
        <canvas id='can' width='1000' height='1000' style='border: 1px solid #000000;'></canvas>
        <button onclick='create();'>Create</button>
    </body>
</html>

র্যান্ডম ওয়াক 1 ! [র্যান্ডম ওয়াক 2] [4]

এটি যখন একটি প্রান্ত থেকে 'হাঁটতে' যায় তখন এটি অন্য প্রান্তে আবৃত হয়, তাই এটি এখনও ভাল টাইল্ড দেখায়।

এটি এখনও প্রযুক্তিগতভাবে সমান্তরাল, ঠিক অন্য কোণ থেকে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.