2011-02-06 27 views
6

Tôi đang cố gắng mô phỏng trọng lực trong trò chơi xna 2d đầu tiên của mình. Tôi có sauXna thêm lực hấp dẫn vào một sprite 2d

 //Used for Jumping 
    double elapsedAirTime = 0.0; 
    double maxAirTime = 8.35; 
    //End Jumping 

Vì vậy, tôi đang cố gắng để di chuyển sprite lên bởi một số tiền nhất định trong khi elapsedAirTime < maxAirTime Tuy nhiên, có một số vấn đề mà mã của tôi dường như chỉ để di chuyển sprite lên một lần và không nhiều lần trong phân đoạn thời gian này. đây là mã trong lớp "player.cs" của tôi hoặc phương thức cập nhật của lớp.

if (newState.IsKeyDown(Keys.Space)) 
     { 
      if(oldState.IsKeyUp(Keys.Space)) 
      { 
       //if we are standing or jumping then change the velocity 
       if (playerState == PlayerStates.Standing) 
       { 
        playerState = PlayerStates.Jumping; 
        this.position.Y -= (float)(30.0 + ((1.2)*elapsedAirTime)*elapsedAirTime); 
       } 
      } 
     } 
     //if we are jumping give it some time 
     if (playerState == PlayerStates.Jumping) 
     { 
      if ((elapsedAirTime < maxAirTime) && position.Y < 3) 
      { 
       this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime); 
       elapsedAirTime += gameTime.ElapsedGameTime.TotalSeconds; 
      } 
      //otherwise time to fall 
      else 
      { 
       playerState = PlayerStates.Falling; 
      } 

     } 

     //add gravity to falling objects 
     if (playerState == PlayerStates.Falling || playerState == PlayerStates.Standing) 
     { 
      //if we are above the ground 
      if (this.position.Y < windowBot - 110) 
      { 
       //chnage state to falling 
       playerState = PlayerStates.Falling; 
       this.position.Y += 3.0f + ((float)(gameTime.ElapsedGameTime.TotalSeconds)); 
      } 
      else 
      { 
       playerState = PlayerStates.Standing; 
       elapsedAirTime = 0.0f; 
      } 
     } 

Bất kỳ trợ giúp nào được đánh giá cao, xin cảm ơn!

Trả lời

11

Để cho phép bạn cảm nhận được trọng lực, bạn nên thêm vận tốc và gia tốc vào lớp Sprite của bạn. Sau đó, tạo phương thức Cập nhật cho Sprite và tăng tốc được thêm vào vận tốc của bạn mỗi lần cập nhật và vận tốc được thêm vào vị trí mỗi lần cập nhật. Vị trí không nên dựa trên lượng thời gian không khí trôi qua. Bạn có thể đặt gia tốc thành một giá trị hấp dẫn không đổi, và sau đó thêm vào vận tốc của Sprite bất cứ khi nào bạn nhảy. Điều này sẽ tạo ra một nhảy parabolic chảy trông đẹp. Nếu bạn muốn bao gồm thời gian, bạn có thể chuyển GameTime vào phương thức Cập nhật của Sprite và sử dụng nó làm công cụ sửa đổi trên vận tốc. Dưới đây là một ví dụ Cập nhật phương pháp:

 
void Update(GameTime gt) 
{ 
    int updateTime = gt.ElapsedGameTime.TotalMilliseconds - oldgt.ElapsedGameTime.TotalMilliseconds; 
    float timeScalar = updateTime/AVG_FRAME_TIME; 
    this.velocity += this.acceleration * timeScalar; 
    this.position += this.velocity; 
    oldgt = gt; 
} 

Nếu bạn sử dụng thời gian, phương pháp này là một chút phức tạp. Bạn phải theo dõi lượng thời gian cập nhật, sau đó chia thời gian trung bình cho bản cập nhật hoặc khung hình để có được số tiền bạn nên điều chỉnh vận tốc của mình. Nếu không có thời gian, phương pháp này rất đơn giản:

 
void Update() 
{ 
    this.velocity += this.acceleration; 
    this.position += this.velocity; 
} 

tôi sẽ đề nghị sử dụng phương pháp đơn giản hơn cho đến khi bạn hiểu chính xác như thế nào thời gian hoạt động và tại sao bạn cần phải thực hiện nó.

+0

Tại sao tính thời gianScalar và lưu trữ thời gian trò chơi cũ?Nếu chức năng cập nhật này được gọi là mỗi vòng lặp trò chơi (vì nó phải là), gt.ElapsedGameTime đã thực hiện tất cả việc nâng hạng nặng cho bạn. –

+1

Lý do sử dụng timeScalar là a) nếu bạn muốn thay đổi tốc độ khung hình mặc định hoặc b) nếu máy tính của bạn chậm đến mức không thể theo kịp với 60 UPS/FPS XNA mặc định. Trong cả hai trường hợp, nếu bạn rơi sau tốc độ cập nhật mục tiêu, trò chơi của bạn sẽ trông giống như đang bị chậm trễ mà không có mã timeScalar. – Darkhydro

2

Dường như dòng này là có lỗi:

this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime); 

Tôi nghĩ rằng bạn sẽ thấy rằng đây cập nhật vị trí sprites nhanh hơn bạn tưởng tượng, ma sẽ di chuyển 330 pixel lên màn hình trong 10 cập nhật (giả sử Game.IsFixedTimeStep == true) tức là 1/10 của thời gian thực thứ hai

Có thể đây chỉ là cập nhật nhanh đến nỗi bạn không thể thay đổi để tăng lên trước khi điều kiện && position.Y < 3 khởi động và thay đổi playerState.

Có vẻ như bạn đang cố gắng nói - nhảy với tốc độ x pixel mỗi giây trong tối đa 8,5 giây miễn là không gian được giữ.

Điều bạn cần làm là thay đổi phép tính thành this.position.y -= (float) (30 * gameTime.ElapsedGameTime.TotalSeconds), điều này sẽ tạo chuyển động rất lót cho hành động nhảy nhưng điều đó có nghĩa là sprite nhảy chính xác 30 pixel mỗi giây.

Nếu Game.IsFixedTimeStep == true - là mặc định - bản cập nhật được gọi là 60 lần mỗi giây, do đó, thời gian của gameTime.ElapsedGameTime.TotalSeconds sẽ là khoảng 0,1 lần cập nhật. Nếu một cái gì đó xảy ra gây ra một bản cập nhật để bỏ qua (các vấn đề kết xuất ví dụ) thì cập nhật sẽ bị trễ và gameTime.ElapsedGameTime.TotalSeconds có thể là 0,3 (2 cập nhật bị bỏ qua) nhưng formular vẫn hoạt động với tốc độ nhảy đúng.

Các vấn đề liên quan