如何将整数分配给列表中的对象
本文关键字:列表 对象 分配 整数 | 更新日期: 2023-09-27 18:29:37
所以我在一个列表中有对象,我试图为每个对象分配一个角度。目前我有两个列表:
List<double> BulletAngles = new List<double>();
List<OvalShape> Bullets = new List<OvalShape>();
我对列表工作方式的看法显然很不一致。现在子弹是基于以下代码传播的:
foreach (OvalShape b in Bullets)
{
int i = Bullets.IndexOf(b);
if (b.Location.X > -10 && b.Location.X < (this.Width - 6) + 10
&& b.Location.Y > -10 && b.Location.Y < (this.Height - 30) + 10)
{
b.Left += Convert.ToInt32(bulletSpeed * Math.Cos(BulletAngles[i]));
b.Top += Convert.ToInt32(bulletSpeed * Math.Sin(BulletAngles[i]));
}
}
角度完全基于鼠标单击时的位置,但在测试时,所有项目符号都指向第一次鼠标单击的方向。这也是用于设置角度和放置在项目符号中的代码:
Point target = new Point(mousePos.X - origin.X, mousePos.Y - origin.Y);
OvalShape g = Bullet;
double y = Math.Atan2(target.Y, target.X);
g.Left = origin.X - (g.Width / 2);
g.Top = origin.Y - (g.Height / 2);
g.Visible = true;
BulletAngles.Add(y);
Bullets.Add(g);
使用IndexOf方法可能不会返回您要查找的结果,因为此方法使用默认的相等比较器来确定相等。
虽然在两个单独的列表中包含与对象相关的属性是有问题的,并且可以通过将属性封装到一个对象中来更好地解决,如前所述。如果在遍历列表时尝试获取对象的索引,那么最好使用for语句而不是foreach语句。
for (int index = 0; index < Bullets.Count; index++)
{
var b = Bullets[index];
if (b.Location.X > -10 && b.Location.X < (this.Width - 6) + 10
&& b.Location.Y > -10 && b.Location.Y < (this.Height - 30) + 10)
{
b.Left += Convert.ToInt32(bulletSpeed*Math.Cos(BulletAngles[index]));
b.Top += Convert.ToInt32(bulletSpeed * Math.Sin(BulletAngles[index]));
}
}
下面是一个使用封装的示例:
public class OvalShapeBullet
{
private readonly OvalShape _ovalShape;
private Point _location;
private readonly double _angle;
private double _distance;
public OvalShapeBullet(Point orgin, Point target, OvalShape ovalShape)
{
_ovalShape = ovalShape;
_location = new Point(orgin.X - ((int)ovalShape.Width / 2), orgin.Y - ((int)ovalShape.Height / 2));
_distance = Math.Sqrt((orgin.X - target.X) ^ 2 + (orgin.Y - target.Y) ^ 2);
_angle = Math.Atan2(target.Y, target.X);
}
public Point Location { get { return _location; } }
public bool Visible
{
get { return _ovalShape.Visible; }
set { _ovalShape.Visible = value; }
}
/// <summary>
/// Attempts to move bullet to target
/// </summary>
/// <param name="distance">The distance the bullt will travel</param>
/// <returns>True if bullet connects with target</returns>
public bool TryMoveToTarget(float distance)
{
if (_distance <= 0)
return true; // check if bullet has travelled far enough
_location.X += (int)(distance * Math.Cos(_angle));
_location.Y += (int)(distance * Math.Sin(_angle));
_distance -= distance;
return _distance <= 0; // check if bullet has traveled far enough
}
}
当原始语句变成单个列表声明时,您的代码就会变得更干净
List<OvalShapeBullet> Bullets = new List<OvalShapeBullet>();
创建新对象的处理
Point target = new Point(mousePos.X - origin.X, mousePos.Y - origin.Y);
OvalShapeBullet g = new OvalShapeBullet(mousePos, target, Bullet);
g.Visible = true;
Bullets.Add(g);
管理子弹的移动并检查目标连接
foreach (OvalShapeBullet b in Bullets)
{
if (b.TryMoveToTarget(bulletSpeed))
{
// handle bullet has hit the target
Bullets.Remove(b);
}
}