我试图制作一款使用状态机的游戏。 " GameState"通过从" World"中调用getInstance()来创建世界(进入时)这是一个单身人士。
世界单身人士有一个2D列表" Tile"物体(世界由瓷砖制成)。在World类的构造函数中,列表由嵌套的for循环填充,该循环使用SimpleTileFactory类创建切片并将它们放在列表中。
问题是我得到了StackOverflow。我调试了代码,发现World单例的构造函数被多次调用,这可能导致堆栈溢出。我不知道为什么它不止一次被召唤,并且感觉我忽略了一些简单的东西。我的单身人士是否正确?
守则如下。
提前致谢。
GameState Class
public partial class GameState : UserControl, IState<MainView>
{
private bool ready = false;
public GameState()
{
InitializeComponent();
}
public void enter(MainView owner)
{
this.Width = owner.Width;
this.Height = owner.Height;
this.Location = new Point(0, 0);
owner.Controls.Add(this);
World.getInstance();
this.ready = true;
}
public void update(MainView owner)
{
this.Refresh();
}
public void exit(MainView owner)
{
owner.Controls.Remove(this);
}
public bool isReady()
{
return this.ready;
}
private void GameState_Paint(object sender, PaintEventArgs e)
{
//for (int i = 0; i < World.getInstance().tiles.Count; i++)
//{
// for (int j = 0; j < World.getInstance().tiles[0].Count; j++)
// {
// //e.Graphics.DrawImage(new Image(), new Rectangle());
// }
//}
}
}
世界级
class World
{
private static World instance;
public GameResources gameResources;
public SimpleTileFactory tileFactory;
public List<List<Tile>> tiles = new List<List<Tile>>();
public Size worldSize = new Size(100, 100);
private World()
{
this.gameResources = new GameResources();
this.tileFactory = new SimpleTileFactory();
for (int i = 0; i < worldSize.Height; i++)
{
List<Tile> row = new List<Tile>();
for (int j = 0; j < worldSize.Width; j++)
{
row.Add(tileFactory.createTile(new Point(j, i)));
}
}
}
public static World getInstance()
{
if (instance == null)
{
instance = new World();
}
return instance;
}
}
SimpleTileFactory类
class SimpleTileFactory
{
public SimpleResourceFactory resourceFactory = new SimpleResourceFactory();
private Random random = new Random();
private int maxNumOfResourcesPerTile = 5;
public SimpleTileFactory()
{
}
public Tile createTile(Point location)
{
//create tile
Tile tile = new Tile();
tile.location = location;
//give tile terrain type
Terrain terrain = new Terrain();
terrain.type = random.Next(0, World.getInstance().gameResources.terrainNames.Count);
terrain.name = World.getInstance().gameResources.terrainNames[terrain.type];
terrain.accessability = 1000;
//add resources to terrain
int numberOfResources = random.Next(0, maxNumOfResourcesPerTile + 1);
for (int i = 0; i < numberOfResources; i++)
{
terrain.resources.Add(resourceFactory.createTerrainResource(terrain.type));
}
tile.terrain = terrain;
return tile;
}
}
SimpleResourceFactory Class
class SimpleResourceFactory
{
public List<string> resourceNames = new List<string>();
public List<Image> resourceImages = new List<Image>();
private Random random = new Random();
public SimpleResourceFactory()
{
resourceNames.Add("asdfasfd");
resourceNames.Add("asdfasfd");
resourceNames.Add("asdfasfd");
}
public TerrainResource createTerrainResource(int terrainType)
{
TerrainResource resource = new TerrainResource();
resource.type = random.Next(0, resourceNames.Count);
resource.name = this.resourceNames[resource.type];
resource.amount = 100;
return resource;
}
}
瓷砖类
class Tile
{
public Point location;
public Terrain terrain;
public Tile()
{
}
}
地形等级
class Terrain
{
public int type;
public string name;
public int accessability;
public List<TerrainResource> resources = new List<TerrainResource>();
public Terrain()
{
}
}
TerrainResource Class
class TerrainResource
{
public int type;
public string name;
public int amount;
public TerrainResource()
{
}
}
答案 0 :(得分:0)
createTile正在调用getInstance,并导致溢出:
WpfApplication2.exe!WpfApplication2.SimpleResourceFactory.SimpleResourceFactory()第116行C# WpfApplication2.exe!WpfApplication2.SimpleTileFactory.SimpleTileFactory()第76行C# WpfApplication2.exe!WpfApplication2.World.World()第49行C# WpfApplication2.exe!WpfApplication2.World.getInstance()第66行C# WpfApplication2.exe!WpfApplication2.SimpleTileFactory.createTile(System.Windows.Point位置)第95行C# WpfApplication2.exe!WpfApplication2.World.World()第56行C# WpfApplication2.exe!WpfApplication2.World.getInstance()第66行C# WpfApplication2.exe!WpfApplication2.SimpleTileFactory.createTile(System.Windows.Point位置)第95行C# WpfApplication2.exe!WpfApplication2.World.World()第56行C# WpfApplication2.exe!WpfApplication2.World.getInstance()第66行C# WpfApplication2.exe!WpfApplication2.SimpleTileFactory.createTile(System.Windows.Point位置)第95行C#
答案 1 :(得分:0)
问题是在World构造函数中调用了createTile()。这样,当执行createTile()时,还没有完全创建World对象,然后调用getInstance(),然后再生成一个新的World(因为它尚未完全创建),它再次调用createTile()。这是一个无限循环。
我通过更改World构造函数和createTile()代码快速修复了它,如下所示。这不是解决它的最美妙的方法,所以我可能只是从世界中分离GameResources。
private World()
{
this.gameResources = new GameResources();
this.tileFactory = new SimpleTileFactory();
for (int i = 0; i < this.worldSize.Height; i++)
{
List<Tile> row = new List<Tile>();
for (int j = 0; j < this.worldSize.Width; j++)
{
row.Add(tileFactory.createTile(new Point(j, i), this));
}
this.tiles.Add(row);
}
}
createTile方法:
public Tile createTile(Point location, World world)
{
//create tile
Tile tile = new Tile();
tile.location = location;
//give tile terrain type
Terrain terrain = new Terrain();
terrain.type = random.Next(0, world.gameResources.terrainNames.Count);
terrain.name = world.gameResources.terrainNames[terrain.type];
terrain.accessability = 1000;
//add resources to terrain
int numberOfResources = random.Next(0, maxNumOfResourcesPerTile + 1);
for (int i = 0; i < numberOfResources; i++)
{
terrain.resources.Add(resourceFactory.createTerrainResource(terrain.type));
}
tile.terrain = terrain;
return tile;
}