Пишу мини-игру, опыта мало - жду критику :)
использую сетку grid, суть игры: с неба падают блоки(блок - Rectangle в клетке сетки), наш персонаж находиться внизу, мы должны передвигать блоки, чтобы составить на земле ряд блоков(как в тетрисе).
Мой изначальный вариант - таймер, через определенное тиков спамит блоки, с каждым тиком блоки снижаются на сегмент(сектор, клетку) грида, персонаж работает вне таймера(падение запускается только после передвижения). Этот вариант явно не лучший, надо делать "падение" общим для блоков и персонажа.
Собственно, сама проблема: надо реализовать "падение" для блоков и персонажа, сами блоки падают вниз(сдвигаются вниз на одну клетку) через 180мс, сравнятся они через 8 тиков (timer.interval=180мс), персонаж двигается вне таймера, это значит, что его "падение" нужно запускать вне таймера(как я и сделал, и это являлось плохой идеей).
Была идея сделать уменьшить timer.interval до, например, 10мс, запускать падение для всех элементов грида - перебирать их всех в timer_tick, но блоки должны снижаться вниз на клетку через 180мс, а, так как, timer.interval = 10мс, то каждые 10мс будет запускаться "падение". Наверное надо как-то отмечать, что блок эмм... падает? или метод падения переписать?
тик таймера:
private void Timer_Tick(object sender, EventArgs e)
{
tick_num++;
foreach (UIElement element in Sharp.Children)
{
if (element is Rectangle)
{
Falling(element);
}
}
// time_for_block - кол-во тиков для спавна блока
if (tick_num == time_for_block)
{
int block_Horizontal = random.Next(13);
Draw_Block(block_Horizontal);// спавн блока
tick_num = 0;
}
}
движение героя:
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (game_active)
{
switch (e.Key.ToString())
{
case "Up":
if (hero.vertical > 0)
{
step = (0, -1);
Move();
}
break;
case "Left":
if (hero.horizontal > 0)
{
step = (-1, 0);
Move();
}
break;
case "Right":
if (hero.horizontal < 12)
{
step = (1, 0);
Move();
}
break;
case "Space":
break;
}
}
}
private async void Move()
{
//step - передвижение героя, horizontal - по горизонтали, vertical - ...
//moving_Block - блок в направлении движения героя
Rectangle moving_Block = Get_Rectangle(hero.horizontal + step.horizontal, hero.vertical + step.vertical);
//Block_Is_Free - проверка блока на возможность его переместить
if (moving_Block == null || Block_Is_Free(moving_Block))
{
if (moving_Block != null && Block_Is_Free(moving_Block))
if (step.vertical == 0)
{
Grid.SetColumn(moving_Block, hero.horizontal + (2 * step.horizontal));
}
Rectangle hero_View = Get_Rectangle(hero.horizontal, hero.vertical);
hero.horizontal += step.horizontal;
hero.vertical += step.vertical;
Grid.SetRow(hero_View, hero.vertical);
Grid.SetColumn(hero_View, hero.horizontal);
//"падение" героя
if (Down_Is_Clear(hero.horizontal, hero.vertical))
{
await Task.Delay(250);
Hero_Falling(hero_View);
}
}
}