所以我一直在测试一些用于在silverlight中创建垂直滚动游戏的新算法。我提出了一个非常简单的解决方案。但是,当您在手机上运行时,帧速率会出现大量不一致的情况。我不知道这是否是由于算法不佳,同时吸引了很多东西(目前只有png背景和股票播放器图像)或其他东西。
基本上我想要的是一个游戏循环计时器,它执行一种方法,我可以执行所有更新方法,并且无论你在游戏的哪个部分,都具有一致的外观和感觉。这是后端代码。
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 :(得分: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