📄 level.cs
字号:
dt = dsAnimations.Tables["Definition"];
Debug.Assert(dt != null && dt.Rows != null,
"Level.Level: Failed to load animation DataTable");
foreach (DataRow dr in dt.Rows)
{
int numberRows = int.Parse((string)dr["Rows"],
CultureInfo.InvariantCulture);
int numberColumns = int.Parse((string)dr["Columns"],
CultureInfo.InvariantCulture);
int cellWidth = int.Parse((string)dr["CellWidth"],
CultureInfo.InvariantCulture);
int cellHeight = int.Parse((string)dr["CellHeight"],
CultureInfo.InvariantCulture);
Animation animation = new Animation(GameMain.GetFullPath(
@"Data\Animations\" + (string)dr["FileName"]),
graphics, numberRows, numberColumns, 0, cellWidth,
cellHeight, 0);
Debug.Assert(animation != null && animation.Init,
"Level.Level: Failed to load animation");
animations.Add(animation);
}
dsAnimations = null;
// Player
DataSet dsPlayer = new DataSet();
Debug.Assert(dsPlayer != null,
"Level.Level: Failed to initialize player DataSet");
dsPlayer.Locale = CultureInfo.InvariantCulture;
dsPlayer.ReadXml(GameMain.GetFullPath(@"Data\Player\player.xml"));
Player p = new Player(dsPlayer, graphics, animations);
Debug.Assert(p != null,
"Level.Level: Failed to initialize player");
worldObjectsValue.Add(p);
dsPlayer = null;
// World Objects
DataSet dsWorldObjects = new DataSet();
Debug.Assert(dsWorldObjects != null && dsWorldObjects.Tables !=
null,
"Level.Level: Failed to initialize world object DataSet");
dsWorldObjects.Locale = CultureInfo.InvariantCulture;
dsWorldObjects.ReadXml(GameMain.GetFullPath(@"Data\WorldObjects\worldobjects.xml"));
dt = dsWorldObjects.Tables["Instance"];
if (dt != null)
{
foreach (DataRow dr in dt.Rows)
{
WorldObject wo = new WorldObject(dr, this);
Debug.Assert(wo != null,
"Level.Level: Failed to initialize world object");
worldObjectsValue.Add(wo);
}
}
}
/// <summary>
/// Update the level.
/// </summary>
/// <param name="gi">Input instance</param>
public void Update(Input gi)
{
// Assume that the level is not stopped
bool bStopAll = false;
foreach (Layer l in layers)
{
l.Update(graphics);
// If any layer gets to the end of the world then stop
if (l.ScrollRate == 0.0F)
bStopAll = true;
}
// Update world objects in the level
for (int i = 0; i < worldObjectsValue.Count; i++)
{
// If Update returns true then the object is dead
if (((WorldObject)worldObjectsValue[i]).Update(gi, this))
{
worldObjectsValue.RemoveAt(i);
i--;
}
}
// Check collisions between world objects
CheckCollisions();
// Check if any objects have been killed by collision
for (int i = 0; i < worldObjectsValue.Count; i++)
{
if (((WorldObject)worldObjectsValue[i]).RemoveMe)
{
worldObjectsValue.RemoveAt(i);
i--;
}
}
// If the level is done or the player is dead then stop
if (bStopAll || Player.Dead)
{
foreach (Layer l in layers)
{
l.ScrollRate = 0.0F;
// If the player is dead then make sure he did not
// fall out of the level
if (Player.Dead)
l.MoveForPlayer(Player);
}
}
}
/// <summary>
/// Check for collisions between world objects. Each world object
/// has a set of bounds that are defined by the animation that is
/// currently playing.
/// </summary>
protected void CheckCollisions()
{
// Cycle through each world object
for (int i = 0; i < worldObjectsValue.Count; i++)
{
// Cache the object
WorldObject wo1 = (WorldObject)worldObjectsValue[i];
// Make sure the object can be checked
if (!wo1.Active || !wo1.Collidable ||
wo1.DrawX(this) > DrawX + ViewWidth)
continue;
Debug.Assert(wo1.Bounds != null,
"Level.Update: Invalid bounds on world object 1");
// Check every subsequent object in the list for collisions.
// All previous objects will have been checked already.
for (int j = i + 1; j < worldObjectsValue.Count; j++)
{
// Cache the object
WorldObject wo2 = (WorldObject)worldObjectsValue[j];
Debug.Assert(wo2 != null &&
((wo2.Active && wo2.Collidable) ?
wo2.Bounds != null : true),
"Level.Update: Invalid bounds on world object 2");
if (wo2.DrawX(this) > DrawX + ViewWidth)
continue;
if (wo2.Active && wo2.Collidable &&
!(wo1.Dynamic && wo2.Dynamic) &&
wo1.Bounds.CheckCollision(wo1.WorldX, wo1.WorldY,
wo2.Bounds, wo2.WorldX, wo2.WorldY))
{
// If the collided and are neither one owns the
// other then they both die here
if ((wo1.Parent != wo2 && wo2.Parent != wo1) ||
(wo1.Parent == Player && wo1.VelocityY > 0.0F) ||
(wo2.Parent == Player && wo2.VelocityY > 0.0F))
{
wo1.Die();
wo2.Die();
}
}
}
}
}
/// <summary>
/// Reset the level for replaying.
/// </summary>
public void ResetAll()
{
// Reset each layer
foreach (Layer l in layers)
{
l.Reset();
}
// Remove any dynamic objects from the level
for (int i = 0; i < worldObjectsValue.Count; i++)
{
if (((WorldObject)worldObjectsValue[i]).Dynamic)
{
worldObjectsValue.RemoveAt(i);
i--;
}
}
// Reset all world objects
foreach (WorldObject wo in worldObjectsValue)
{
wo.Reset(this);
}
}
/// <summary>
/// Draw the level and all of its objects.
/// </summary>
public void Draw()
{
// Draw the layers
for (int i = 0; i < 2; i++)
{
((Layer)layers[i]).Draw(graphics, images);
}
// Draw the world objects
foreach (WorldObject wo in worldObjectsValue)
{
wo.Draw(graphics, this);
}
// Draw any further layers in the foreground of the player
for (int i = 2; i < layers.Count; i++)
{
((Layer)layers[i]).Draw(graphics, images);
}
}
/// <summary>
/// Free any resources allocated by the level
/// </summary>
public void Dispose()
{
foreach (IBitmap bmp in images)
{
bmp.Dispose();
}
foreach (Animation animation in animations)
{
animation.Dispose();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -