我目前正在编写C#WPF中的经典街机游戏Asteroids来进行练习。 我遇到了一个我似乎无法解决的问题。
我在生成小行星时遇到问题,并添加到包含我所有游戏对象的canvas元素。
我有一个generateAsteroids方法,每20毫秒调用一次更新玩家船位的方法等等。 generateAsteroids方法执行各种计算(函数中的注释)以确定要添加到asteroidCollection列表的小行星数量。一切正常。
当我尝试将小行星Polygon对象添加到游戏画布时出现问题。
我收到以下错误:“ArugementException未被用户代码处理:指定的Visual已经是另一个Visual的子项或CompositionTarget的根”
现在我明白这意味着什么(我认为),所有的Asteroid对象都被称为“小行星”,这显然是不理想的,我研究过并发现你不能动态地为对象动态创建变量名。
我尝试在每次将一个动态名称添加到画布时为其赋予动态名称。
知道这个问题的任何人都可以帮帮我吗?
我添加了我认为相关的所有代码,如果您需要了解更多信息,请与我们联系。
由于
C#:
public void drawAsteroid(Asteroid theAsteroid)
{
// entityShape is a Polygon object
theAsteroid.entityShape.Name = "asteroid" + this.asteroidsAdded.ToString();
theAsteroid.entityShape.Stroke = Brushes.White;
theAsteroid.entityShape.StrokeThickness = 2;
theAsteroid.entityShape.Points = theAsteroid.getEntityDimensions();
gameCanvas.Children.Add(theAsteroid.entityShape);
}
// Called every 20 milliseconds by method that updates the game canvas. Possibly quite inefficient
public void generateAsteroids()
{
// Number of asteroids to add to the collection = the length of the game so far / 3, then subtract the amount of asteroids that have already been added
int asteroidNum = Convert.ToInt32(Math.Ceiling((DateTime.Now - gameStartTime).TotalSeconds / 3));
asteroidNum -= asteroidsAdded;
for (int i = 0; i <= asteroidNum; i ++)
{
asteroidCollection.Add(new Asteroid());
this.asteroidsAdded += 1;
}
foreach (Asteroid asteroid in asteroidCollection)
{
drawAsteroid(asteroid);
}
}
XAML:
<Window x:Name="GameWindow" x:Class="AsteroidsAttempt2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="1000" Height="1000" HorizontalAlignment="Left" VerticalAlignment="Top" Loaded="GameWindow_Loaded">
<Canvas x:Name="GameCanvas" Focusable="True" IsEnabled="True" HorizontalAlignment="Left" Height="1000" VerticalAlignment="Top" Width="1000" KeyDown="GameCanvas_KeyDown" KeyUp="GameCanvas_KeyUp">
<Canvas.Background>
<ImageBrush ImageSource="D:\CPIT\BCPR283\Asteroids\Asteroids\AsteroidsAttempt2\Resources\SpaceBackground.jpg" Stretch="Fill"/>
</Canvas.Background>
</Canvas>
答案 0 :(得分:0)
在drawAsteroid
方法的每次调用中,您都会将asteroidCollection
中的所有多边形添加到“画布”中,无论它们是否已添加。但是,您无法将同一对象两次添加到WPF面板的Children
集合中。这就是你得到例外的原因(它与Name
没有任何关系。)
更改您的代码:
if (!gameCanvas.Children.Contains(theAsteroid.entityShape))
{
gameCanvas.Children.Add(theAsteroid.entityShape);
}
当然,代码仍缺乏从Canvas中删除不再包含在asteroidCollection
中的多边形的逻辑。你还必须添加它。
您根本不需要设置Polygon对象的Name
,除非您希望稍后通过其名称访问它们。