Jump to content

Loading Times and Running out of memory

- - - - -

  • Please log in to reply
12 replies to this topic

#1
justanothernoob

justanothernoob

    Newbie

  • Members
  • PipPip
  • 22 posts
I am making a tile based game. When I load the world(which is 100x100 tiles), it takes very long to load, about 3 minutes. This wasn't really much of a problem until today when I coded in a new sector.

When you walk off sector 1 into sector 2, it has to load the new sector, and it runs out of memory. My game isn't really isnt that big, it just runs out of memory when trying to load the second sector.

I'm not sure what I should do. Any help would be appreciated.

#2
BlaineSch

BlaineSch

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,448 posts
Oh, I see, on line 25 there seems to be a huge memory leak.. oh wait, I can't see your code! :P

Post up the code, we'd be happy to help.

#3
justanothernoob

justanothernoob

    Newbie

  • Members
  • PipPip
  • 22 posts
OK, not sure if I am posting too much or too little, but i'm including everything I think is relevant to the issue.


 private void btnE_Click(object sender, EventArgs e)

//The move east button - when you're on square 96(the edge) and click move east, i want it to load the next sector.

        {

            m33.Image = global::WindowsFormsApplication1.Properties.Resources.guyright;

            if ((currentsectorx == 0) && (currentsectory == 0))

            {

                if (currentx == 96)

                {

                    EnterNewSectorE();



                }

                

            }

            if (sectors[currentsectorx, currentsectory].tiles[currentx + 1, currenty].getMovable() == true)

            {

                currentx = currentx + 1;

                

            }

            UpdateTileImages();

                UpdateMapLabels();

        }


 private void EnterNewSectorE()

        {

            currentx = 3;


            if (sectors[currentsectorx + 1, currentsectory].getDiscovered() == false)

            {

                sectors[currentsectorx + 1, currentsectory].LoadTiles();                //RIGHT HERE IS 

                sectors[currentsectorx + 1, currentsectory].RandomizeTiles();       //WHERE IT GIVES 

                sectors[currentsectorx + 1, currentsectory].setDiscovered(true);   //ME THE EXCEPTION

            }

            currentsectorx = currentsectorx + 1;

            SetSectorBoundaries();

        }


//Sector Class

class Sector

    {

        bool discovered = false;

        public Tile[,] tiles = new Tile[100,100];


        public bool getDiscovered()

        {

            return discovered;

        }

        public void setDiscovered(bool d)

        {

            discovered = d;

        }

        public void LoadTiles()

        {

            int x = 0;

            int y = 0;


            while (y <= 99)

            {

                tiles[x, y] = new Tile();

               


                if (x < 99)

                {

                    tiles[x, y] = new Tile();

                    

                    x = x + 1;

                }

                else if (x == 99)

                {

                    tiles[x, y] = new Tile();

                    y = y + 1;

                    x = 0;

                }

            }

           

        }

        public void RandomizeTiles()

        {

            int x = 0;

            int y = 0;


            while (y <= 99)

            {

                tiles[x, y].RandomizeTile();


                if (x < 99)

                {

                    tiles[x, y].RandomizeTile();

                    x = x + 1;

                }

                else if (x == 99)

                {

                    tiles[x, y].RandomizeTile();

                    y = y + 1;

                    x = 0;

                }

            }


        }

    }

}


 class Tile

    {

        Form1 form1 = new Form1();

        int type;

        bool movable = true;

        Image image;

        Random random = new Random();


        public void setMovable(bool m)

        {

            movable = m;

        }

        public bool getMovable()

        {

            return movable;

        }

        public void Grass()

        {

            type = 1;

            movable = true;

            image = global::WindowsFormsApplication1.Properties.Resources.grass;

        }

        public void Tree()

        {

            type = 2;

            movable = false;

            image = global::WindowsFormsApplication1.Properties.Resources.tree;

        }

        public void Water()

        {

            type = 3;

            movable = false;

            image = global::WindowsFormsApplication1.Properties.Resources.water;

        }

        public void BlackSpace()

        {

            type = 4;

            movable = false;

            image = global::WindowsFormsApplication1.Properties.Resources.black;

        }

        public Image getImage()

        {

            return image;

        }

        public void setImage(Image i)

        {

            image = i;

        }

        public void RandomizeTile()

        {

            

            

            int randomseed;

            int selection;

            randomseed = random.Next(0, 499);

            selection = form1.GetRandom(0, 99, randomseed);


            //tiles: 0-30 = tree    31-50 = water    51-99 = grass


            if (selection < 30)

            {

                Tree();

            }

            else if (selection < 50)

            {

                Water();

            }

            else if (selection < 100)

            {

                Grass();

            }

        }

    }

}


If anybody wants to help, I wouldn't mind sending the whole project for you too look at.

#4
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
you can zip up the whole project, and attach it to the thread with the advanced button, in the meantime, I'll take a look here too at what you posted

#5
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
I wouldn't mind seeing the whole project.
I wonder if you have a circular (almost recursive) call somehow.

Anyways, post that sucker

#6
justanothernoob

justanothernoob

    Newbie

  • Members
  • PipPip
  • 22 posts
sam_coder, you're awesome lol.
,
When you open the form, click the menu and hit 'Load World'. It takes like 3 minutes lol (if you know how to fix that let me know). After the world has loaded, click 'Set Sector Boundaries'.

To see my problem, go to square 96 on the x axis and try to go east. The world is really hard to navigate, I put way too many trees, so if you want, go to the menu and I put some warp options there so you can warp too. You can move with W,S,A, and D.

Attached Files

  • Attached File  RPG.zip   144.9K   2 downloads


#7
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
I'll ask due to the lack of comments in the code.
Why are you creating a brand new form for every single title?

This might explain some of the weight, by the looks of it, when you load the map, your creating basically 10, 000 Form1's right? Well much more actually. Observe...

public void LoadTiles()

        {

            int x = 0;

            int y = 0;


            while (y <= 99)

            {

              [COLOR="red"]  tiles[x, y] = new Tile();[/COLOR]

               


                if (x < 99)

                {

                   [COLOR="red"] tiles[x, y] = new Tile();[/COLOR]

                    

                    x = x + 1;

                }

                else if (x == 99)

                {

                  [COLOR="red"]  tiles[x, y] = new Tile();[/COLOR]

                    y = y + 1;

                    x = 0;

                }

            }
see, the first two will get hit every iteration, for a while, and that's at least a 200% efficiency loss. That was my first take, then I followed to that Tile Class...

class Tile

    {

       [COLOR="red"] Form1 form1 = new Form1();[/COLOR]

        int type;

        bool movable = true;

        Image image;

        Random random = new Random();

that kind of bothered me. Is the intent to reference the original form? You could pass reference back into the tile through its constructor

well, I'll give you a chance to respond, before going down that road

#8
justanothernoob

justanothernoob

    Newbie

  • Members
  • PipPip
  • 22 posts
Oh wow that makes a lot of sense. I was only creating the form on the tile class, so that I could access the GetRandom() method on form 1. I guess I forgot that I'm creating like a thousand tiles, and with each of those creating a form, that explains it.

So I gotta fix that and hopefully that will work better.

Thanks!

#9
justanothernoob

justanothernoob

    Newbie

  • Members
  • PipPip
  • 22 posts

sam_coder said:

that kind of bothered me. Is the intent to reference the original form? You could pass reference back into the tile through its constructor


This sounds like what I need to do. Could you elaborate?

#10
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
I can in fact!

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Drawing;


namespace WindowsFormsApplication1

{

    class Tile

    {

       [COLOR="red"] Form1 form1;[/COLOR]

        int type;

        bool movable = true;

        Image image;

        Random random = new Random();


       [COLOR="red"] public Tile(Form1 form_reference) {

            form1 = form_reference;

        }

[/COLOR]

        public void setMovable(bool m)

        {

            movable = m;

        }

        public bool getMovable()

        {

            return movable;

        }

        public void Grass()

        {

            type = 1;

            movable = true;

            image = global::WindowsFormsApplication1.Properties.Resources.grass;

        }

        public void Tree()

        {

            type = 2;

            movable = false;

            image = global::WindowsFormsApplication1.Properties.Resources.tree;

        }

        public void Water()

        {

            type = 3;

            movable = false;

            image = global::WindowsFormsApplication1.Properties.Resources.water;

        }

        public void BlackSpace()

        {

            type = 4;

            movable = false;

            image = global::WindowsFormsApplication1.Properties.Resources.black;

        }

        public Image getImage()

        {

            return image;

        }

        public void setImage(Image i)

        {

            image = i;

        }

        public void RandomizeTile()

        {

            

            

            int randomseed;

            int selection;

            randomseed = random.Next(0, 499);

            selection = form1.GetRandom(0, 99, randomseed);


            //tiles: 0-30 = tree    31-50 = water    51-99 = grass


            if (selection < 30)

            {

                Tree();

            }

            else if (selection < 50)

            {

                Water();

            }

            else if (selection < 100)

            {

                Grass();

            }

        }

    }

}


then when you need to make a new tile, you pass reference to the form you initially created. There are lots of ways of obtaining that information. One way is to add the form parameter to as many calls as needed to ensure a clean path.

The other way is to just make a central point of reference. like, changing your Program.cs file
using System;

using System.Collections.Generic;

using System.Linq;

using System.Windows.Forms;


namespace WindowsFormsApplication1

{

    static class Program

    {

        public static Form1 MainForm { get; set; }


        /// <summary>

        /// The main entry point for the application.

        /// </summary>

        [STAThread]

        static void Main()

        {

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            using (MainForm = new Form1()) {

                Application.Run(MainForm);

            }

        }

    }

}


then you can always access your main from using Program.MainForm

eg

   class Tile

    {

[COLOR="red"]        Form1 form1 = Program.MainForm;[/COLOR]

        int type;

        bool movable = true;

        Image image;

        Random random = new Random();

There may be more problems with your code, causing this, this just seemed like the first thing to address...

#11
justanothernoob

justanothernoob

    Newbie

  • Members
  • PipPip
  • 22 posts
Thanks! I took the second option and changed the program.cs file. First thing I noticed was loading was about ten times faster. When I tried to go into the next sector, it worked! So these problems are solved.

The only thing is somehow the tiles aren't as random anymore, All the trees are together, all the water is together, and all the grass is together, making the only walkable space the strip of grass tiles.

I'm not even sure how what I changed would cause that, but hopefully I can figure it out. If not I will be back in a new thread!

#12
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
well, you have a very big spread of what you're using to determine the type right? Like several hundred or something

have you considered double randomizing it? Like generating a random number between 1 and 10, and then randomly determining the ranges for each type?

You could also try a more secure random number generator, but, in all honesty, you're trying to increase performance here.. =)
for example, say you have 4 types (I forget what types you had, and I don't have the code in front of me, im on my netbook), but say you have 4 types

so generate a number between 1 and 4,
and as an extra step, if you wanted to try, each time you generate a type, randomly determine which number will generate each type.

I just think that its easier to randomize that way, than to say, generate 1 - 40, and say a result of 1 - 10 gives this, 2 - 20 gives this etc.

I have also found over the years, that if generating 1 - 10, 1 and 10 get generated far less often than other numbers, and this is where the idea of randomly determining which numbers generate which type comes in, is you can make each type appear more evenly...


anyways, just a few thoughts, if you want me to elaborate with code, I will when I get back to my other computer




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users