2013-02-23 51 views
0

所以我一直在測試了在Silverlight創建一個垂直滾動遊戲的一些新的算法,一個流暢的遊戲幀計時器。我想出了一個非常簡單的解決方案。但是,當你在手機上運行它時,幀速率會有很多不一致。我不知道這是否是由於算法不好,一次吸引很多東西(目前只有png背景和股票圖片)或其他東西。創建爲WP7 Silverlight的遊戲

基本上我想要的是執行,我可以執行從所有更新方法,有一個一致的外觀和感覺,無論遊戲的你在哪一部分的方法的遊戲循環計時器。這是後端代碼。

public partial class MainPage : PhoneApplicationPage 
    { 
     // Constructor 
     int counter = 0; 
     DispatcherTimer playerTimer; 

     string _START = "START"; 
     string _FALLING = "FALLING"; 
     string _LEFT = "LEFT"; 
     string _RIGHT = "RIGHT"; 
     string _CENTER = "CENTER"; 

     string playerState = ""; 
     int playerMoveTimeout = 20; 
     public MainPage() 
     { 
      InitializeComponent(); 
      playerState = _START; 

      playerTimer = new DispatcherTimer(); 
      playerTimer.Interval = TimeSpan.FromSeconds(.00999); 
      playerTimer.Tick += playerTimer_Tick; 
      playerTimer.Start(); 
     } 

     void playerTimer_Tick(object sender, EventArgs e) 
     { 
      updatePlayer(); 

      if (counter > 0) 
      { 
       counter = updateBG(counter); 
      } 
     } 
     public void updatePlayer() 
     { 
      if (Canvas.GetLeft(Player) + Player.Width >= 480) 
      { 
       playerState = _LEFT; 

      } 
      else if (Canvas.GetLeft(Player) <= 0) 
      { 
       playerState = _RIGHT; 
      } 
      if(playerMoveTimeout <= 0) 
      { 
       playerState = _FALLING; 
      } 
      if (playerState.Equals(_START)) 
      { } 
      else if (playerState.Equals(_FALLING)) 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) + 30); 
      } 
      else if (playerState.Equals(_LEFT)) 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) - 60); 
       Canvas.SetLeft(Player, Canvas.GetLeft(Player) - 20); 
       playerMoveTimeout--; 
      } 
      else if (playerState.Equals(_RIGHT)) 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) - 60); 
       Canvas.SetLeft(Player, Canvas.GetLeft(Player) + 20); 
       playerMoveTimeout--; 
      } 
      else //CENTER 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) - 60); 
       playerMoveTimeout--; 
      } 
     } 

     public int updateBG(int time) 
     { 
      if (Canvas.GetTop(background) > 800) 
       Canvas.SetTop(background, -2400); 
      int x = time; 
      Canvas.SetTop(background, Canvas.GetTop(background) + 60); 
      x -= 40; 
      return x; 
     } 


     private void Player_Tap(object sender, GestureEventArgs e) 
     { 

      Point point = e.GetPosition(Player); 
      double Y = point.Y; 
      double X = point.X; 
      if (X < 80) 
      { 
       counter = 400; 
       playerMoveTimeout = 20; 
       playerState = _RIGHT; 

      } 
      else if (X > 120) 
      { 
       counter = 400; 
       playerMoveTimeout = 20; 
       playerState = _LEFT; 

      } 
      else 
      { 
       counter = 400; 
       playerMoveTimeout = 20; 
       playerState = _CENTER; 

      } 
     } 
    } 

回答

0

所以答案是更多的工作,而不是一個新的計時器。我的具體問題的答案不是算法。這一款實際上是我所製作的家用遊戲引擎的最平滑和最小的。問題是我試圖移動一個480X2400的背景圖像,並且它陷入了困境。所以我最終做的是在主體中嵌入一個新的畫布並將其命名爲背景。然後,所有我想在我放置背景繼續前行有

像這樣

<Canvas Name="background"> 
    <Image Name="cloud" Source="cloud.png" Width="247" Height="158"/> 
    <Image x:Name="cloud_Copy" Source="/cloud.png" Width="247" Height="158" Canvas.Left="192" Canvas.Top="268"/> 
    <Image x:Name="cloud_Copy1" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-11" Canvas.Top="592"/> 
    <Image x:Name="cloud_Copy2" Source="/cloud.png" Width="247" Height="158" Canvas.Left="192" Canvas.Top="-474"/> 
    <Image x:Name="cloud_Copy3" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-900"/> 
    <Image x:Name="cloud_Copy4" Source="/cloud.png" Width="247" Height="158" Canvas.Left="192" Canvas.Top="-1566"/> 
    <Image x:Name="cloud_Copy5" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-78" Canvas.Top="-2280"/> 
    <Image x:Name="cloud_Copy6" Source="/cloud.png" Width="247" Height="158" Canvas.Left="192" Canvas.Top="-2766"/> 
    <Image x:Name="cloud_Copy7" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-102" Canvas.Top="-3390"/> 
    <Image x:Name="cloud_Copy8" Source="/cloud.png" Width="247" Height="158" Canvas.Left="90" Canvas.Top="-3122"/> 
    <Image x:Name="cloud_Copy9" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-113" Canvas.Top="-2798"/> 
    <Image x:Name="cloud_Copy10" Source="/cloud.png" Width="247" Height="158" Canvas.Left="90" Canvas.Top="-3864"/> 
    <Image x:Name="cloud_Copy11" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-4290" Canvas.Left="-102"/> 
    <Image x:Name="cloud_Copy12" Source="/cloud.png" Width="247" Height="158" Canvas.Left="90" Canvas.Top="-4956"/> 
    <Image x:Name="cloud_Copy13" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-180" Canvas.Top="-5670"/> 
    <Image x:Name="cloud_Copy14" Source="/cloud.png" Width="247" Height="158" Canvas.Left="90" Canvas.Top="-6156"/> 
    <Image x:Name="cloud_Copy15" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-192" Canvas.Top="-7278"/> 
    <Image x:Name="cloud_Copy16" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-7010"/> 
    <Image x:Name="cloud_Copy17" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-203" Canvas.Top="-6686"/> 
    <Image x:Name="cloud_Copy18" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-7752"/> 
    <Image x:Name="cloud_Copy19" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-8178" Canvas.Left="-192"/> 
    <Image x:Name="cloud_Copy20" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-8844"/> 
    <Image x:Name="cloud_Copy21" Source="/cloud.png" Width="247" Height="158" Canvas.Left="-270" Canvas.Top="-9558"/> 
    <Image x:Name="cloud_Copy22" Source="/cloud.png" Width="247" Height="158" Canvas.Top="-10044"/> 
</Canvas> 


<Image Name="Star" Visibility="Collapsed" Source="star.png" Height="50" Width="50" /> 
<Image x:Name="Player" Source="star.png" Width="200" Height="200" Canvas.Left="117" Canvas.Top="403"/> 
<Rectangle Name="TapBox" Fill="#FFF4F4F5" Height="248" Stroke="Black" Width="301" Canvas.Left="68" Canvas.Top="403" Opacity="0" Tap="Rectangle_Tap_1"/> 
    <TextBlock x:Name="alt"/> 
</Canvas> 

您可以從我所看到的這個畫布上加載成噸的東西,而不降低性能的元素。

然後更新它這裏是我的新遊戲循環

public partial class MainPage : PhoneApplicationPage 
    { 
     DispatcherTimer gameTimer; 

     string _START   = "START"; 
     string _FALLING   = "FALLING"; 
     string _LEFT   = "LEFT"; 
     string _RIGHT   = "RIGHT"; 
     string _CENTER   = "CENTER"; 
     string playerState  = ""; 

     int counter    = 0; 
     int playerMoveTimeout = 40; 
     public int altitude { get; set; } 

     // Constructor 
     public MainPage() 
     { 
      InitializeComponent(); 
      buildGameArea(); 
      alt.Text = altitude.ToString(); 
      playerState = _START; 
      gameTimer = new DispatcherTimer(); 
      gameTimer.Interval = new TimeSpan(3333); 
      gameTimer.Start(); 
      gameTimer.Tick+=gameTimer_Tick; 

     } 

     void gameTimer_Tick(object sender, EventArgs e) 
     { 

      updatePlayer(); 
      updateGameElements(); 
     } 

     public void buildGameArea() 
     { 
      Canvas.SetTop(cloud, -300); 
     } 
     public void reloadPlayer() 
     { 
      playerState = _START; 
      playerMoveTimeout = 40; 
      Canvas.SetTop(Player, 300); 
      Canvas.SetLeft(Player, 200); 
     } 
     public void updatePlayer() 
     { 
      if (Canvas.GetTop(Player) > 800) 
      { 
       reloadPlayer(); 
      } 


      if (Canvas.GetLeft(Player) + Player.Width >= 480) 
      { 
       playerState = _LEFT; 

      } 
      else if (Canvas.GetLeft(Player) <= 0) 
      { 
       playerState = _RIGHT; 
      } 

      if (playerMoveTimeout <= 0) 
      { 
       playerState = _FALLING; 
      } 


      if (playerState.Equals(_START)) 
      { } 
      else if (playerState.Equals(_FALLING)) 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) + 30); 

      } 
      else if (playerState.Equals(_LEFT)) 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) - 40); 
       Canvas.SetLeft(Player, Canvas.GetLeft(Player) - 20); 
       playerMoveTimeout--; 
      } 
      else if (playerState.Equals(_RIGHT)) 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) - 40); 
       Canvas.SetLeft(Player, Canvas.GetLeft(Player) + 20); 
       playerMoveTimeout--; 

      } 
      else //CENTER 
      { 
       Canvas.SetTop(Player, Canvas.GetTop(Player) - 40); 
       playerMoveTimeout--; 
      } 
      TapBox.Margin = Player.Margin; 
     } 
     public void updateGameElements() 
     { 
      alt.Text = altitude.ToString(); 


      //This single conditional moves every single thing on the background canvas 
      if (counter > 0) 
      { 
       Canvas.SetTop(background, Canvas.GetTop(background) + 20); 
       counter -= 20; 
      } 
     } 

     private void Rectangle_Tap_1(object sender, GestureEventArgs e) 
     { 
      System.Windows.Point point = e.GetPosition(Player); 
      double Y = point.Y; 
      double X = point.X; 
      altitude += 100; 
      if (X < 80) 
      { 
       counter = 400; 
       playerMoveTimeout = 40; 
       playerState = _RIGHT; 

      } 
      else if (X > 120) 
      { 
       counter = 400; 
       playerMoveTimeout = 40; 
       playerState = _LEFT; 

      } 
      else 
      { 
       counter = 400; 
       playerMoveTimeout = 40; 
       playerState = _CENTER; 

      } 
     } 
    } 

如果你把這個設備上,你會看到有從開始一致的幀速率結束,無論你有多少會上。

希望我浪費了一天搞清楚了這一點可以幫助別人的未來。

再次,這是爲Silverlight遊戲編程。這裏沒有XNA