Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Ilhan · Jul 20, 2012 at 01:43 PM · readbinary

Problems with calculating binary file to 2D array

Hello and thanks for reading my question. I am working on a 2D game which has randomly generated terrain. My terrain generation is optimized and works perfectly, I have tried it many times with different property configurations. You can imagine my terrain as being a 2D grid with either empty or solid cells, each cell has its own ID (a byte value from 0 to 255) for example ID 0 means empty cell, ID 1 is dirt, ID 2 is sand.. etc. Now my terrain is very huge and I can't just load it up into the memory. The plan was to generate the terrain directly into a binary file. The terrain gets split up into chunks of terrain each chunk gets its own file name like chunk0 chunk1 chunk2 etc.. Each file is made as follows: The first two numbers are of type long and they hold the Width and Height of the "grid" of the particular chunk. The numbers after represent the IDs of the tiles (bytes from range 0-255 as I said already). Now I am sure that the binary writing is correct because I tested it by making it simultaneously drawing and writing the file (output was correct). When I read the file I am getting into a trouble.. because I get only diagonal lines and I have no idea why. Here is my code snippet for reading the file:

  long width = 0;
         long height = 0;

         for (int i = 0; i < ChunkCount; i++)
         {
             using (BinaryReader Reader = new BinaryReader(File.Open(path + i.ToString(), FileMode.Open)))
             {
                 int pos = 0;
                 width = Reader.ReadInt64();
                 height = Reader.ReadInt64();
                 
                 while (pos < Reader.BaseStream.Length - 2 * sizeof(long))
                 {
                     long y = pos / width;
                     long x = pos - (y * height);
                     byte ID = Reader.ReadByte();

                     if (ID != 0)
                         Instantiate(Dirt, new Vector2(x * Unit, y * Unit), Quaternion.Euler(270, 0, 0));

                     pos++;
                 }
             }
         }

Well I said diagonal lines, they are more like flat lines with a slight tilt (minor angle). In my code at the instantiate part you should see Unit now Unit is a value holding the width and height of a tile. I multiply with Unit to get the world position inside Unity. (For example tile number 1, 1 is on location 1x16, 1x16.. etc) The width and height are the width and height of the chunks old 2D grid before it got dumped into a 1D byte array. I store the chunk ID within the file name so like chunk_0 chunk_1 etc I will need this probably later to figure out non relative positions but, this concept above SHOULD work for only one chunk which it does not. I'm not quite sure what I'm doing wrong probably something in recalculating the coordinates from 1D to 2D but however I'm stuck. Also note that I'm currently having only 2 IDs , 0 (empty) and 1 (dirt) so don't get confused why I instantiate dirt for every value that is not 0. Hope I explained everything clearly and if you got questions just ask.

PS: here is a little picture representing my 2D and 1D array and how it should look like: alt text

Thanks in Regards~ Ilhan

EDIT:

Thanks for replies but I found some other info out which might help to solve:

I did this to fix the x,y

long x = pos % width; long y = pos / width;

after running the code my terrain looks like this: Well I'm sure that the X, Y calcing is correct now yet the terrain still looks dodgy. As u see the diagonal lines are still there but you can clearly see a frame. I calculated in scene view the frame size and its exactly as it should be. This means that even though I tested it, my saving method bugs? Here is the code how I save it:

 public void GenerateChunk(string path)
 {
     Initialize();

     List<Tile> Tiles = new List<Tile>();
     List<Tile> Lines = new List<Tile>();

     Tiles = Midpoint_Generate();

     for (int i = 1; i < Tiles.Count; i++)
     {
         Tile Previous = Tiles[i - 1];
         Tile Current = Tiles[i];

         Lines.AddRange(Bresenham_Drawline(Previous.X, Previous.Y, Current.X, Current.Y));
     }

     long blockCount = 0;

     using (FileStream stream = new FileStream(path, FileMode.Create))
     {
         using (BinaryWriter writer = new BinaryWriter(stream))
         {
             writer.Write(Width);
             writer.Write(Height);

             long Bottom = -Depth;

             for (int i = 0; i < Lines.Count; i++)
             {
                 long Top = Lines[i].Y;
                 int Column = 0;

                 for (long j = Bottom; j <= Height; j++)
                 {
                     if (j <= Top)
                         writer.Write(TileTypes["Dirt"]);
                     else 
                         writer.Write(TileTypes["Empty"]);
                     
                     Column++;
                     blockCount++;
                 }
             }
         }
     }

     Tiles.Clear();
     Lines.Clear();

     Debug.Log("Generated: [" + blockCount + "] blocks");

alt text

     private void Initialize()
 {
     if (MaxHeight > Height)
         MaxHeight = Height;

     if (MaxHeight > Depth)
         MaxHeight = Depth;

     TileTypes = new Dictionary<string, byte>();
     TileTypes.Add("Empty", 0);
     TileTypes.Add("Dirt", 1);
 }

Well, I'm trying to think out what went wrong here yet I cant! The Midpoint_Generate() creates a heightmap of tiles. Brensenham then goes from height 1 to height 2 , from height 2 to height 3 etc and makes an array of tiles in between two heights so I get a connected terrain conture made out of tiles. Now I fill up from Bottom (-depth) to top which is the tile conture. From conture until map height I fill up with empty space (this will be important later for adding squares).

Before I forgot, here is my Tile struct (just so the code makes sense to you):

 public struct Tile

{ public long X, Y; public byte ID;

 public Tile(byte id, long x, long y)
 {
     X = x;
     Y = y;
     ID = id;
 }

}

The other functions (midpoint, brenseham) work 100%, I didn't change them in a while because they always worked and they work even now if I directly plot it to the game world, its the save/load that makes the mess. Here is a picture of how those two functions work together seperated from the binary writer/loader:

alt text

A lot of work has went into this as you see :). Anyways this means that those two functions are working correctly. Its either the save method or the load method that doesen't. Thanks for the replies also!

matrix.png (10.9 kB)
unity.png (261.4 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by whydoidoit · Jul 20, 2012 at 01:54 PM

Your code would be much faster if it just incremented X and did a test to increment Y. Those divides are probably the cause of your problem and are in any case expensive.

   x++;
   if(x >= width) 
   {
       x = 0;
       y++;
   }
Comment
Add comment · Show 13 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Owen-Reynolds · Jul 20, 2012 at 02:11 PM 2
Share

The OPs error is in that section, incorrectly dividing by height ins$$anonymous$$d of width: y=pos/width; x=pos-(y*height); (check: assume W=10, H=15, pos=13; results are y=1, x=13-y*15=-2.)

Should be using width twice. The textbook method is: y=pos/W; x=pos%W;. But the above fix does the same thing.

avatar image whydoidoit · Jul 20, 2012 at 02:19 PM 0
Share

Yep I was going to go down that path but 2 divides rather than a inc/test just felt more gamey to me ;)

avatar image whydoidoit · Jul 20, 2012 at 04:35 PM 0
Share

So it appears to me that your -Depth/Bottom thing is screwing with your Height seeing as how you write (vertically) Height + 1 - Bottom or in other words Height + 1 + Depth items in the writing loop.

avatar image Ilhan · Jul 20, 2012 at 04:46 PM 0
Share

Hmm could you specify maybe what you think causes the problem? I took a look at bottom, height they seem to make sense to me. Well at least I know that my terrain starts and ends at Y = 0 world height so -depth would work (I think). $$anonymous$$ight be overlooking something obvious here.

avatar image whydoidoit · Jul 20, 2012 at 04:48 PM 0
Share

So - you write something called Height and Width. Then your for j loop doesn't write Height number of things.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Missing (sprite) errors appear after checking read/write box on a spritesheet........ 0 Answers

Epic slow android build time, lots of Read/Write enabled sprites! 1 Answer

Write and Read to a iOS device! Help 1 Answer

(Solved)StreamWriter Write line 0 Answers

Reading - Writing data to - from file? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges