游戏不重新启动/冲突问题 [英] Game Not Restarting/Collision Problem

查看:92
本文介绍了游戏不重新启动/冲突问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我在小行星游戏中遇到碰撞问题.我成功地使小行星与飞船相撞,使我的游戏像死了一样重新开始.

但是,由于使小行星从屏幕的一侧移出并在另一侧返回,所以我的飞船现在与小行星发生碰撞,但小行星只是旋转而无需重置我的飞船.

这是我为小行星运动所做的代码.

Hi everybody, I''m having a problem with collision in my asteroids-type game. I succesfully managed to collide my asteroid with my spaceship, making my game re-start as if they had died.

However, since making the asteroids going out one side of the screen and back in the other, my spaceship now collides with the asteroid but the asteroids just spin round without my spaceship reseting.

Heres the code I did for my asteroid movement.

Sprite[] asteroid = new Sprite[10];
Vector2[] AsteroidPosition = new Vector2[10];
for (int i = 0; i < 10; i++)
{
  if (Utils.CircToCircCollision(spaceship.GetPosition(), spaceship.GetRadius(),
    asteroid[i].GetPosition(), asteroid[i].GetRadius()))
  {
    LoadContent();
    Random r = new Random();
    Vector2 randPos = new Vector2(r.Next(800), r.Next(600));
    float randRot = MathHelper.ToRadians(r.Next(360));
   }
 }
 if (position.X < 0 - spaceship.GetWidth())
 {
   position.X = 800 + spaceship.GetWidth();
 }
 if (position.X > 800 + spaceship.GetWidth())
 {
   position.X = 0 - spaceship.GetWidth();
 }
 if (position.Y < 0 - spaceship.GetHeight())
 {
   position.Y = 600 + spaceship.GetHeight();
 }
 if (position.Y > 600 + spaceship.GetHeight())
 {
   position.Y = 0 - spaceship.GetHeight();
 }
 spaceship.SetPosition(position);
 for (int i = 0; i < 10; i++)
 {
   if (AsteroidPosition[i].X < 0 - asteroid[i].GetWidth())
   {
     AsteroidPosition[i].X = 800 + asteroid[i].GetWidth();
   }
   if (AsteroidPosition[i].X > 800 + asteroid[i].GetWidth())
   {
     AsteroidPosition[i].X = 0 - asteroid[i].GetWidth();
   }
   if (AsteroidPosition[i].Y < 0 - asteroid[i].GetHeight())
   {
     AsteroidPosition[i].Y = 600 + asteroid[i].GetHeight();
   }
   if (AsteroidPosition[i].Y > 600 + asteroid[i].GetHeight())
   {
     AsteroidPosition[i].Y = 0 - asteroid[i].GetHeight();
   }
   asteroid[i].SetPosition(AsteroidPosition[i]);
 }

推荐答案

您并没有真正显示问题的根源,但仍有可疑之处.

CircToCircCollision使用GetPosition;同时,边界翻转使用AsteroidPosition[i].我怎么知道它们相同并且AsteroidPosition已更新?没有AsteroidPosition更新的迹象.这是应该修复的不一致之处.您只需要一个单一的对象坐标数据源.然后,应始终使用局部变量进行计算.

在循环中:

You don''t really show the source of the problem, but there are suspect things.

CircToCircCollision uses GetPosition; at the same time, boundary roll-over use AsteroidPosition[i]. How do I know they are the same and AsteroidPosition is updated? There is no indication of AsteroidPosition update. This is inconsistency that should be fixed. You need only one single source of object coordinate data. Then, you should always use a local variable for calculation.

Inside your loop:

var coordinate = asteroid[index].GetPosition();
coordinate.X = //???
asteroid[index].SetPosition(coordinate);



您不应真正在循环内部一遍又一遍地构造Random的实例,而应使用相同的实例.

您需要以这种方式重构您的代码,并查看它是否有帮助.
另外,由于缺乏代码重用和可支持性,您的代码也被大大破坏了.

仅当您删除每个独立的常数(例如10、600、800(在这种情况下,甚至是0))时,我们才会开始认真讨论.如果您需要不同的场景大小会怎样?您需要的一切都是单个定义类,或者更好的是单个可编辑选项类.

坐标翻转本身应做成与使用该对象无关的单独功能:



You should not really construct instances of Random over and over inside loop, you should use the same instance.

You need to refactor your code in this way and see it it helps.
Also, your code is greatly spoiled by lack of code re-use and supportability.

We will start talking seriously only if you remove every single innediate constant like 10, 600, 800 (and -- in this context -- even 0). What''s going to happen if you need different scene size? You need to everything is a single definition class, or better yet, to a single editable options class.

Coordinate roll-over itself should be made a separate function agnostic to what object is using it:

static Coordinate RollOver(
            Coordinate coodinate,
            Coordinate min, Coordinate max,
            Coordinate size) {
    Coordinate newCoordinate = coodinate;
    //allowed as it works with a copy of parameters:
    min = min - size;
    max = max + size;
    if (coodinate < min)
        coodinate = max;
    else if (coodinate > max)
        coodinate = min;
    return newCoordinate;
} //RollOver



甚至是这样的形式:



or even in this form:

static void RollOver(
        ref Coordinate coodinate,
        Coordinate min, Coordinate max,
        Coordinate size) {
    min = min - size;
    max = max + size;
    if (coodinate < min)
        coodinate = max;
    else if (coodinate > max)
        coodinate = min;
} //RollOver



我希望使用ref的第二种形式,因为另外它会阻止使用Asteroid属性,并迫使您使用局部变量(希望您将使用局部变量).使用具有某些副作用的属性可能是造成您特定问题的根源.这种形式的方法将阻止滥用副作用.

所有物体(如小行星或太空飞船)都应妥善封装,而不暴露任何字段(即使通过内部").应该将GetPosition和SetPosition重做为单个读/写属性.可以在类内部修改属性写入的副作用,以实现所需的效果(例如,场景的一部分无效或您使用的任何技术).使用这些对象的代码应与这些细节无关.

我正在告诉您,即使您没有真正在代码中显示问题:这完全是数据不一致(如果我可以相信您的描述).如果您为了单点访问数据而删除混乱,您将看到许多类似的问题将自动避免.

很抱歉,如果您的问题仍未解决.您应该理解,您的代码示例显示不足以完全解决问题,并且您不应基于进度不足而否决答案.



I would prefer the second form with ref, because additionally it will prevent using Asteroid property and force you into using a local (hopefully you will use local) variable. Using a property with some side effect could be a source of your particular problem; this form of the method would block the misuse of side effect.

All objects like Asteroid or Spaceship should be well encapsulated without exposing any fields (even via "internal"). GetPosition and SetPosition should be reworked into a single read/write properties. The side effect of property write can be modified inside class to achieve desired effect (such as invalidation of a part of the scene or whatever technique you use). The code using these objects should be made agnostic to these detail.

I''m telling you, even though you do not really show your problem in code: it is solely in data inconsistency (if I can trust your description). If you remove your mess in favor of single-point access to data, you will see that many similar problems will be avoided automatically.

Sorry if your problem is not still resolved. You should understand that your code sample does not show enough to dig out the problem completely and you should not down-vote the answer based on lack of your progress.


这篇关于游戏不重新启动/冲突问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆