MonoGame中克隆对象后设置随机位置绘制报错如何解决
问题解决方法
报错原因
ICloneable接口定义的Clone()方法返回值为object类型,你没有对克隆结果做类型转换,直接用object类型变量访问只有Trash类才有的Position字段,自然会触发编译错误。
修复步骤
1. 补充Game1的字段定义
你需要一个集合存储所有克隆生成的Trash对象,同时把随机数对象提到全局,避免短时间多次调用AddTrash时生成重复的随机值:
private SeaJam.Objects.Trash _trashPrototype; // 改为原型字段,仅用于克隆,不直接参与绘制更新 private List<SeaJam.Objects.Trash> _allTrash = new List<SeaJam.Objects.Trash>(); private Random _rnd = new Random(); // 全局随机数实例
2. 修改LoadContent逻辑
加载完原型后,你可以选择直接调用AddTrash生成第一个对象:
protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); var texture = Content.Load<Texture2D>("Prototype"); // 初始化克隆原型 _trashPrototype = new Objects.Trash(texture) { Position = new Vector2(100, 100), Origin = new Vector2(texture.Width / 2, texture.Height - 25), }; // 生成第一个垃圾对象 AddTrash(); }
3. 修复AddTrash方法
对克隆结果做强制类型转换,设置随机位置后加入集合:
private void AddTrash() { var newTrash = (SeaJam.Objects.Trash)_trashPrototype.Clone(); // 可根据需求调整随机位置的范围,示例为窗口范围内随机 newTrash.Position = new Vector2( _rnd.Next(0, GraphicsDevice.Viewport.Width), _rnd.Next(0, GraphicsDevice.Viewport.Height) ); _allTrash.Add(newTrash); }
4. 修改Update和Draw逻辑,遍历所有对象更新绘制
protected override void Update(GameTime gameTime) { foreach(var trash in _allTrash) { trash.Update(); } base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); foreach(var trash in _allTrash) { trash.Draw(spriteBatch); } spriteBatch.End(); base.Draw(gameTime); }
可选优化:强类型克隆方法
如果你不想每次克隆都做强制类型转换,可以修改Trash类的Clone方法,直接返回Trash类型:
// 替换原来的Clone方法 public Trash Clone() { return (Trash)this.MemberwiseClone(); }
修改后AddTrash里就可以直接写var newTrash = _trashPrototype.Clone();,不需要额外强转。
内容的提问来源于stack exchange,提问作者gogy255
相关产品推荐
相关产品推荐

