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.
12 replies to this topic
#1
Posted 24 February 2011 - 11:46 AM
|
|
|
#2
Posted 24 February 2011 - 12:51 PM
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.
Post up the code, we'd be happy to help.
#3
Posted 24 February 2011 - 01:12 PM
OK, not sure if I am posting too much or too little, but i'm including everything I think is relevant to the issue.
If anybody wants to help, I wouldn't mind sending the whole project for you too look at.
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
Posted 25 February 2011 - 05:35 AM
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
Posted 25 February 2011 - 06:28 AM
I wouldn't mind seeing the whole project.
I wonder if you have a circular (almost recursive) call somehow.
Anyways, post that sucker
I wonder if you have a circular (almost recursive) call somehow.
Anyways, post that sucker
#6
Posted 25 February 2011 - 10:38 AM
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.
,
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
#7
Posted 25 February 2011 - 11:25 AM
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...
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
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
Posted 25 February 2011 - 01:15 PM
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!
So I gotta fix that and hopefully that will work better.
Thanks!
#9
Posted 25 February 2011 - 01:27 PM
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
Posted 25 February 2011 - 01:41 PM
I can in fact!
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
then you can always access your main from using Program.MainForm
eg
There may be more problems with your code, causing this, this just seemed like the first thing to address...
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
Posted 26 February 2011 - 09:46 AM
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!
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
Posted 26 February 2011 - 01:38 PM
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
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


Sign In
Create Account


Back to top











