2011-05-13 8 views
7

Sto lavorando a un gioco in C# con XNA e ho imparato un programma in C# grazie alle esercitazioni di Nick Gravelyn, ma ho avuto un problema. Mentre sto usando il sistema di collisione di Nick, non sto usando il suo codice giocatore. Ne sto usando uno basato su un tutorial di Fatso784 che ho modificato. Quindi, di conseguenza, sto avendo problemi a far funzionare correttamente la mia versione modificata del sistema di collisione. Sono arrivato al punto che spinge il giocatore fuori da certe tessere, ma ho bisogno che sia più solido perché il giocatore è ancora in grado di camminare attraverso i muri occasionalmente. Sono abbastanza sicuro che sto gestendo la collisione sbagliata, ma potrebbe essere che la collisione sia un po 'molle. Quindi, ecco il codice corrispondente della mia classe giocatore, il codice mossa:Come posso ottenere che la mia collisione sia più solida?

public void Move() 
    { 
     pos.X = bounds.X; 
     pos.Y = bounds.Y; 

     offsetPos.X = bounds.Width; 
     offsetPos.Y = bounds.Height; 

     if (frameCount % delay == 0) 
     { 
      switch (direction) 
      { 
       case "stand": 
        if (sideCollide == "none") 
        { 
         Equalize(2); 
        } 
        else if (sideCollide == "left") 
        { 
         speed += 1f; 
        } 
        else if (sideCollide == "right") 
        { 
         speed -= 1f; 
        } 
        bounds.X += (int)speed; 
        if (frameCount/delay >= 8) 
         frameCount = 0; 
        srcBounds = new Rectangle(frameCount/delay * 64, 0, 64, 64); 
        break; 
       case "left": 
        if (sideCollide != "left") 
        { 
         if (speed > -maxspeed) 
         { 
          speed -= acceleration; 
         } 
         else if (speed < -maxspeed) 
         { 
          speed -= acceleration; 
          speed += drag; 
          Equalize(2); 
         } 
         speed += friction; 
        } 
        bounds.X += (int)speed; 
        if (frameCount/delay >= 4) 
         frameCount = 0; 
        srcBounds = new Rectangle(frameCount/delay * 64, 64, 64, 64); 
        break; 
       case "right": 
        if (sideCollide != "right") 
        { 
         if (speed < maxspeed) 
         { 
          speed += acceleration; 
         } 
         else if (speed > maxspeed) 
         { 
          speed += acceleration; 
          speed -= drag; 
          Equalize(2); 
         } 
         speed -= friction; 
        } 
        bounds.X += (int)speed; 
        if (frameCount/delay >= 4) 
         frameCount = 0; 
        srcBounds = new Rectangle(frameCount/delay * 64, 64, 64, 64); 
        break; 
       case "up": 
        if (speed > -4 && speed < 4) 
         srcBounds.Y = 128; 
        else 
         srcBounds.Y = 64; 
        if (srcBounds.Y == 0 || srcBounds.Y == 128) 
        { 
         if (jumpCount < 2) 
         { 
          if (frameCount/delay >= 9) 
           frameCount = 0; 
         } 
         else if (jumpCount > 2 && jumpCount <= 10) 
         { 
          if (frameCount/delay > 3) 
           frameCount = 2 * delay; 
         } 
         else if (jumpCount > 10 && jumpCount <= 18) 
         { 
          if (frameCount/delay > 5) 
           frameCount = 4 * delay; 
         } 
         else if (jumpCount > 18) 
         { 
          if (frameCount/delay >= 9) 
           frameCount = 0; 
         } 

         srcBounds = new Rectangle(frameCount/delay * 64, 128, 64, 64); 
        } 
        else if (srcBounds.Y == 64) 
        { 
         if (frameCount/delay >= 4) 
          frameCount = 0; 
         if (jumpCount <= 10) 
          srcBounds = new Rectangle((frameCount/delay)/2 * 64, 64, 64, 64); 
         else 
          srcBounds = new Rectangle(frameCount/delay * 64, 64, 64, 64); 
        } 
        if (jumpCount == 0) 
         startY = bounds.Y; 
        bounds = new Rectangle(bounds.X + (int)speed, 
         (jumpCount - 10) * (jumpCount - 10) - 100 + startY, 64, 64); 
        jumpCount++; 
        if (bounds.Y > startY) 
        { 
         bounds.Y = startY; 
         direction = "stand"; 
         jumpCount = 0; 
        } 
        break; 
      } 
     } 

     frameCount++; 
    } 

E il codice di collisione:

public void CollideOutside(TileMap tilemap) 
    { 
     Point cell = Engine.PointCell(PlayerCenter); 

     Point? upLeft = null, Up = null, upRight = null, Right = null, downRight = null, Down = null, downLeft = null, Left = null; 

     if (cell.Y > 0) 
     { 
      Up = new Point(cell.X, cell.Y - 1); 
     } 
     if (cell.Y < tilemap.collisionMap.HeightinPixels) 
     { 
      Down = new Point(cell.X, cell.Y + 1); 
     } 
     if (cell.X > 0) 
     { 
      Left = new Point(cell.X - 1, cell.Y); 
     } 
     if (cell.X < tilemap.collisionMap.WidthinPixels) 
     { 
      Right = new Point(cell.X + 1, cell.Y); 
     } 

     if (cell.X > 0 && cell.Y > 0) 
     { 
      upLeft = new Point(cell.X - 1, cell.Y - 1); 
     } 
     if (cell.X < tilemap.collisionMap.WidthinPixels - 1 && cell.Y > 0) 
     { 
      upRight = new Point(cell.X + 1, cell.Y - 1); 
     } 
     if (cell.X > 0 && cell.Y < tilemap.collisionMap.HeightinPixels - 1) 
     { 
      downLeft = new Point(cell.X - 1, cell.Y + 1); 
     } 
     if (cell.X < tilemap.collisionMap.WidthinPixels - 1 && cell.Y < tilemap.collisionMap.Height - 1) 
     { 
      downRight = new Point(cell.X + 1, cell.Y + 1); 
     } 

     if (Up != null && tilemap.collisionMap.GetCellIndex(Up.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(Up.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 

      } 
     } 
     if (Down != null && tilemap.collisionMap.GetCellIndex(Down.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(Down.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 

      } 
     } 
     if (Right != null && tilemap.collisionMap.GetCellIndex(Right.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(Right.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 
       speed = -1f; 
       sideCollide = "right"; 
      } 
      else 
      { 
       sideCollide = "none"; 
      } 
     } 
     if (Left != null && tilemap.collisionMap.GetCellIndex(Left.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(Left.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 
       speed = 1f; 
       sideCollide = "left"; 
      } 
      else 
      { 
       sideCollide = "none"; 
      } 
     } 
     if (upLeft != null && tilemap.collisionMap.GetCellIndex(upLeft.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(upLeft.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 

      } 
     } 
     if (upRight != null && tilemap.collisionMap.GetCellIndex(upRight.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(upRight.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 

      } 
     } 
     if (downLeft != null && Left != null && tilemap.collisionMap.GetCellIndex(downLeft.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(downLeft.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 
       speed = 1f; 
       sideCollide = "left"; 
      } 
     } 
     if (downRight != null && Right != null && tilemap.collisionMap.GetCellIndex(downRight.Value) == 1) 
     { 
      Rectangle rect = Engine.CreateCell(downRight.Value); 
      Rectangle playerCell = Boundary; 

      if (rect.Intersects(playerCell)) 
      { 
       speed = -1f; 
       sideCollide = "right"; 
      } 
     } 

     if (Right == null && Left == null) 
     { 
      sideCollide = "none"; 
     } 
    } 

    public Rectangle Boundary 
    { 
     get 
     { 
      Rectangle rect = bounds; 
      rect.X = (int)pos.X; 
      rect.Y = (int)pos.Y; 
      return rect; 
     } 
    } 

Così come posso migliorare la collisione?

risposta

1

Questa risposta è in gran parte in risposta alla risposta di Tim - perché ha dato molto l'approccio sbagliato. (La tua domanda è un dump di codice molto grande, non riesco a giocare spot-the-error con così tanto codice.)

Il trucco con il rilevamento delle collisioni - il modo in cui i motori fisici "reali" lo fanno - è sempre considera i tuoi oggetti come solidi. Si sempre - ogni frame - controllare gli oggetti per la compenetrazione, e quindi separati se si compenetrano.

Se si prova solo per lo spostamento attraverso il confine di un oggetto che si sono andare perdere collisioni. Questo include qualsiasi approccio in cui si tenta di prevedere ed evitare una collisione scattando sulla superficie. Se lo fai, stai solo chiedendo errori di precisione a virgola mobile per farti scivolare dentro gli oggetti.

EDIT: naturalmente, tutto il codice sembra essere numero intero a base (Point e Rectangle). Quindi, almeno la precisione a virgola mobile non dovrebbe essere un problema. Ma forse hai un < dove dovresti avere uno <= o qualcosa del genere?

(Inoltre, stai utilizzando stringhe in molti luoghi in cui dovresti utilizzare le enumerazioni.)

Problemi correlati