2012-10-11 4 views
0

타일 엔진을 가지고 있고 그 모든 것이 부풀어 오르고 있으며, 플레이어가 모두 돌아 다니며 아이템을 추가하고 있습니다. 플레이어는 항상 스크린 중앙에 있습니다. 그가 세계의 가장자리에 다다를 때까지 그는 가장자리에 가까이 가기 시작합니다.지도의 가장자리 근처에있을 때의 아이템 그리기

세계에서 항목을 그릴 때 플레이어가 가운데를 벗어나는 경우 (세계 가장자리)를 제외하고는 잘 자릅니다. 이 문제를 해결하는 방법에 대해 머리를 감쌀 수 없습니다.

public static void Draw(SpriteBatch spriteBatch, World w, Item i, Player p, Point screenDimensions) 
    { 
     bool IsOnScreen = true; 

     float leftX = p.X - ((screenDimensions.X/32)/2); 
     float rightX = leftX + (screenDimensions.X/32); 

     float topY = p.Y - ((screenDimensions.Y/32)/2); 
     float bottomY = topY + (screenDimensions.Y/32); 

     if (i.x < leftX || i.x > rightX || i.y < topY || i.y > bottomY) 
      IsOnScreen = false; 

     if (IsOnScreen) 
      i.animation.Draw(spriteBatch, (int)Math.Floor((i.x - leftX) * 32), (int)Math.Floor((i.y - topY) * 32)); 
    } 

그것의 꽤 자기 explainatory이, 세상이 치수 (폭 w.worldDimensions.x 및 높이 .y)을 얻기 위해 전달되는 항목은 게임 세계에서 i.xi.y (위치하지에 가져 오는 데 사용됩니다 화면), 상대적으로 그림을 그리는 플레이어 (위치는 .x.y)와 screenDimensions.

+0

Menno가 제안했듯이 카메라에서이를 처리해야합니다. 여기에 쓴 답변을 살펴보십시오. http://stackoverflow.com/questions/12152662/having-the-background-or-camera-scroll-based-on-charcter-position/12167478#comment16291765_12167478 – Cyral

답변

0

글쎄 그것은 나에게 분명하지 않습니다. 카메라 수업을 사용하고 있습니까? 카메라 클래스를 사용하여 카메라 클래스를 사용하여 세상을 탐색하면이 일은 결코 일어나지 않아야합니다.

내 프로젝트에 현재 사용하고있는 기본 기능은 다음과 같습니다.

class Camera 
{ 
    float zoom; 
    public float Rotation { get; private set; } 
    public Vector2 Position { get; private set; } 
    Matrix transform; 

    int velocity = 60; 

    UserInput input; 

    public float Zoom 
    { 
     get { return zoom; } 
     set { zoom = value; if (zoom < 0.1f) zoom = 0.1f; } // Negative zoom will flip image 
    } 

    public Camera(UserInput input) 
    { 
     zoom = 1.0f; 
     Rotation = 0f; 
     Position = new Vector2(0, 0); 
     this.input = input; 
    } 

    public void MoveCam() 
    { 
     if (input.IsKeyHold(Keys.Up)) 
     { 
      Position += new Vector2(0, -velocity); 
     } 
     if (input.IsKeyHold(Keys.Left)) 
     { 
      Position += new Vector2(-velocity, 0); 
     } 
     if (input.IsKeyHold(Keys.Down)) 
     { 
      Position += new Vector2(0, velocity); 
     } 
     if (input.IsKeyHold(Keys.Right)) 
     { 
      Position += new Vector2(velocity, 0); 
     } 

     if (input.IsKeyHold(Keys.OemMinus)) 
     { 
      Zoom -= .01f * Zoom; 
     } 
     else if (input.IsKeyHold(Keys.OemPlus)) 
     { 
      Zoom += .01f * Zoom; 
     } 
    } 

    public void FollowCam(int xPos, int yPos) 
    { 
     Position = new Vector2(xPos * TileData.Width, yPos * TileData.Height); 
    } 


    public Matrix TransformMatrix(GraphicsDevice device) 
    { 
     transform = Matrix.CreateTranslation(new Vector3(-Position.X, -Position.Y, 0)) * 
      Matrix.CreateRotationX(MathHelper.ToRadians(Rotation)) * 
      Matrix.CreateRotationY(MathHelper.ToRadians(Rotation)) * 
      Matrix.CreateRotationZ(MathHelper.ToRadians(Rotation)) * 
      Matrix.CreateScale(new Vector3(zoom, zoom, 0)) * 
      Matrix.CreateTranslation(new Vector3(device.Viewport.Width * 0.5f, device.Viewport.Height * 0.5f, 0)); 
     return transform; 
    } 
} 

메인에서와 같이 클래스를 인스턴스화하고 이것을 그리기 메소드에 사용하십시오.

batch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, camera.TransformMatrix(graphicsDevice)); 
batch.End() 

이의 SpriteBatch 이내에 세계 모든 그리기와 GUI/HUD 같은 화면 cooridinates에 그리는 새로운 기본을 사용합니다. 카메라 이동 방법을 사용하여 수동으로 이동하고 잠금을 사용하여 모든 위치에서 잠글 수 있습니다 (업데이트 된 경우 따라야 함).

큰지도가있는 경우 필요한 타일 만 렌더링 할 수 있습니다. 나는지도 클래스에서 이것을 좋아한다 :

public void Draw(SpriteBatch batch, Vector2 camPosition, float camZoom, GraphicsDevice device) 
    { 
     float top = (camPosition.Y/TileData.Height) - ((device.Viewport.Height/2)/TileData.Height + 1)/camZoom; 
     float bottom = (camPosition.Y/TileData.Height) + ((device.Viewport.Height/2)/TileData.Height + 2)/camZoom; 
     float left = (camPosition.X/TileData.Width) - ((device.Viewport.Width/2)/TileData.Width + 1)/camZoom; 
     float right = (camPosition.X/TileData.Width) + ((device.Viewport.Width/2)/TileData.Width + 2)/camZoom; 

     for (int y = (int)top; y < (int)bottom; y++) 
     { 
      for (int x = (int)left; x < (int)right; x++) 
      { 
       if (y >= 0 && y < map.GetLength(1) && x >= 0 && x < map.GetLength(0)) 
       { 
        batch.Draw(map[x, y].texture, new Rectangle(x * TileData.Width, y * TileData.Height, TileData.Width, TileData.Height), Color.White); 

       } 
      } 
     } 
    } 

먼저, 각 방향에서 어떤 타일을 그려야하는지 알아 낸다. camZoom을 참고하면 축소 할 때 더 많은 타일을 그릴 수 있습니다. 그런 다음이 "경계"를 for 루프에 사용하면 if 문은 존재하지 않는 타일에 액세스하지 못하게합니다 (범위를 벗어남).

+0

이렇게 보입니다. 제가 현재하고있는 것보다 더 나은 시스템이 될 수 있습니다. –

+0

그것의 통합을 시도했지만 그 그림은 화면의 중앙에지도. –

+0

항상 카메라 위치를 오프셋 할 수 있습니다. – Madmenyo