Los monstruos aleatorios se mueven sincronizados en lugar de individualmente

Estoy haciendo un juego en el que los monstruos aparecen aleatoriamente y comienzan a moverse aleatoriamente. Soy bastante nuevo en progtwigción, pero no en el desarrollo de juegos. Mediante el uso de unos pocos tutoriales, pude hacer que 1 criatura se engendrara aleatoriamente y se moviera random (¡con animaciones!) De una manera que parecía orgánica en lugar de robótica.

Entonces, pasé al siguiente paso de hacer esto con varias criaturas. Sin embargo, cuando ejecuté esto, encontré que en lugar de ejecutar sus propias instrucciones, el rest de los monstruos simplemente imitan los movimientos relativos de 1 hombre central. ¡Todos se mueven sincronizados como un desfile militar de Corea del Norte!

Estoy usando loops foreach y numbers aleatorios para elegir sus direcciones. Como mi juego es isométrico de 2d de arriba hacia abajo, estoy usando un dictionary para almacenar 4 direcciones. He hecho algunos cambios basados ​​en las sugerencias aquí, ¡y ahora todas las criaturas se animan! Pero todavía no cambian las direcciones ni hacen las cosas por sí mismos.

¿Cómo hago para que cada uno tenga su propio set de instrucciones en lugar de que todos sigan al querido líder?

Debajo hay un recorrido de mi código:

Inicialización de monstruo:

public void AddCreatures() { NewMonster = new Monster(Texture); NewMonster.AddAnimation("northeast", 0, 96, 48, 48, 8, 0.2f); NewMonster.AddAnimation("northwest", 0, 144, 48, 48, 8, 0.2f); NewMonster.AddAnimation("southeast", 0, 240, 48, 48, 8, 0.2f); NewMonster.AddAnimation("southwest", 0, 288, 48, 48, 8, 0.2f); NewMonster.AddAnimation("hoon", 144, 336, 48, 48, 1, 1.0f); NewMonster.Position = RandomPos(); NewMonster.DrawOffset = new Vector2(49, 80); NewMonster.CurrentAnimation = "southwest"; NewMonster.IsAnimating = false; creatures.Add(NewMonster); } 

Desovar:

 for (int v = 0; v < 12; v++) { AddCreatures(); } 

Randomize spawn Posición:

  private Vector2 RandomPos() { Vector2 location = Vector2.Zero; location.X = rng.Next(300,900); location.Y = rng.Next(200, 700); return location; } 

Movimientos:

  public void Update(GameTime gameTime) { timenow += (float)gameTime.ElapsedGameTime.TotalSeconds; foreach (Monster mon in creatures) { if (mon.IsAnimating) { if (timenow - (float)gameTime.ElapsedGameTime.TotalSeconds > 0.5f) { mon.Velocity = directions[rng.Next(1, 5)]; ChooseAnim(mon); mon.Velocity.Normalize(); speed = (float)(rng.Next(0, 3)); diff = new Vector2(mon.Position.X - mon.GetLastPosition.X, mon.Position.Y - mon.GetLastPosition.Y); if (Math.Abs(diff.X) >= 4 && Math.Abs(diff.Y) >= 4) { mon.Velocity = directions[rng.Next(1, 5)]; ChooseAnim(mon); mon.Velocity.Normalize(); } mon.Velocity.X *= speed; mon.Velocity.Y *= speed; timenow = 0f; } mon.MoveBy(mon.Velocity); } DoNotExit(); mon.Update(gameTime); } } 

Método de elección de la animation:

  private void ChooseAnim(Monster mon) { if (mon.Velocity == directions[1]) mon.CurrentAnimation = "northeast"; if (mon.Velocity == directions[2]) mon.CurrentAnimation = "northwest"; if (mon.Velocity == directions[3]) mon.CurrentAnimation = "southeast"; if (mon.Velocity == directions[4]) mon.CurrentAnimation = "southwest"; } 

Hay una manera muy rápida de arreglar tu código. Cada monstruo debe tener su propio timenow . El rest del código se puede mejorar, pero no es responsable del error que estás experimentando.

Una vez hecho, en lugar de esto:

  timenow += (float)gameTime.ElapsedGameTime.TotalSeconds; foreach (Monster mon in creatures) { ... 

Tu hiciste esto:

  foreach (Monster mon in creatures) { mon.timenow += (float)gameTime.ElapsedGameTime.TotalSeconds; ... 

De lo contrario, cuando reinicie timenow = 0f la operación sincronizará todos los monstruos.

No sé si eso es todo, pero aquí hay algunas cosas que también me parecen mal:

  • Parece que tu variable oldLoc es común a todos tus monstruos. Probablemente debería ser una variable miembro de tu class Monster . De lo contrario, no puede mantener un logging separado de cada location de monstruo.
  • También tienes un thisMonster global y otro NewMonster global, me parecen inútiles, si no están trayendo este error ahora, seguramente traerán uno más tarde.
  • En ChooseDirection , establece otra variable global chosen y luego la usa. Probablemente no esté rompiendo nada por el momento, pero simplemente devolver la dirección elegida sería un poco más limpio. De lo contrario, podría sentirse tentado de usar esto antes de llamar a ChooseDirection y terminaría con algunos problemas más extraños.
  • Menos problemático, pero aún así: está reinicializando su matriz de directions en cada actualización, esto podría hacerse en una function init, esto debería ser una variable estática.

Moraleja de la historia: las variables globales son malas. A less que seas un fanático de desfiles militares inesperados.

Bueno, ¿dónde estás decidiendo el movimiento aleatorio? Este es un síntoma de crear múltiples instancias Random (la class) al mismo time. Todos tendrán el mismo time de siembra (probablemente algunos difieran solo en un poco).
Por lo general, puedes arreglar esto en lugar de crear un new Random() para cada class que necesita movimientos aleatorios, puedes simplemente crear un object Random en tu "class de gestión (o algo así) y pasar por reference a las classs que usarán Y creo que tu falla está en el método RandomPos() o en el constructor de Monster.

Algo como esto:

En lugar de esto:

 Vector2 RandomPos() { Random rand = new Random(); return new Vector2(rand.nextInt(x1, x2), rand.nextInt(y1, y2) ); } 

o esto:

 Monster(Texture2D texture) { this.rand = new Random(); ///blablabla define movement with rand object. } 

Deberías usar:

 Vector2 RandomPos(Random rand) { return new Vector2(rand.nextInt(x1, x2), rand.nextInt(y1, y2) ); } 

o esto:

 Monster(Texture2D texture, Random rand) { this.rand = rand; ///blablabla define movement with rand object. } 

Con este ejemplo, rand debería crearse en AddCreatures() y ser compartido por todas las llamadas de la function RandomPos o el constructor de Monster.