В настоящее время я работаю над платформой 2d с помощью Monogame. Я могу нарисовать спрайт, я могу нарисовать характер и уровень, я могу перемещать персонажа и прыгать, но когда я прыгаю, мой персонаж «плавает» над блоком уровня вместо посадки на него. Левое и правое столкновение работает нормально, персонаж останавливается, когда он должен быть остановлен, но при прыжке он не приземляется должным образом. У меня есть следующий код:C# Monogame: «плавающий» спрайт после прыжка
Чтобы проверить, хочет ли игрок прыгать, выполняется проверка, чтобы увидеть, нажата ли стрелка вверх.
if(state.IsKeyDown(Keys.Up) && hasJumped == false)
{
jumping = true;
}
После проверки на нажатие клавиши будет сделано, есть проверка, чтобы увидеть, если переменная jumping
верно
if (jumping == true)
{
jump();
} else if (falling == true && topOfBlock == false)
{
fall();
}
else
{
hasJumped = false;
verticalMovement = 14;
}
В основном jumping
проверяет, хотите ли вы, чтобы прыгать, falling
проверяет, является ли символ падения , topOfBlock
проверяет, находится ли символ над блоком, hasJumped
проверяет, идет ли прыжок (так что двойной прыжок невозможен), а verticalMovement
- количество пикселей, которое персонаж прыгает/падает на отметку.
jump()
и fall()
метод выглядеть следующим образом:
private void jump()
{
if (verticalMovement >= 0)
{
position.Y -= verticalMovement;
verticalMovement--;
} else
{
jumping = false;
hasJumped = true;
falling = true;
}
}
public void fall()
{
position.Y += verticalMovement;
verticalMovement++;
}
код говорит сам за себя, я думаю. В основном, если символ больше не перемещается вверх, falling
устанавливается в true
, что вызывает метод fall()
, если символ не находится над блоком.
И наконец, прямоугольник столкновения персонажа обновляется до новой позиции символа.
colRect = new Rectangle((int)position.X, (int)position.Y, 64, 48);
Где position.X
и position.Y
являются Х персонажа и У позиции, и 64
и 48
являются ширина и высота спрайта.
Чтобы проверить, пересекает ли столкновение прямоугольник с таранной прямоугольником блока У меня есть следующий код
private void checkCollision()
{
bool topCol = false;
for (int x = 0; x < blockTileArray.GetLength(0); x++)
{
for (int y = 0; y < blockTileArray.GetLength(1); y++)
{
if (blockTileArray[x, y] != null)
{
if (hero.colRect.Intersects(blockTileArray[x, y].topWall))
{
topCol = true;
}
}
}
}
if(topCol == true)
{
hero.topOfBlock = true;
} else
{
hero.topOfBlock = false;
}
}
topCol
является BOOL, который проверяет, есть ли столкновение с верхней части блока или нет. Петли проверяют каждый блок в массиве, пересекается ли символ с его topWall
или нет. Если да, то устанавливает значение topCol
в true. После цикла он проверяет, действительно ли topCol
или нет. Если да, то он говорит hero.topOfBlock
- true
, что означает, что персонаж не должен падать. Если это false
, он устанавливает hero.topOfBlock
в false
, что вызовет метод fall()
в классе Hero, если jumping
также является ложным.
Наконец, topWall
столкновения прямоугольник создается следующим образом:
topWall = new Rectangle((int)position.X, (int)position.Y - size, size, 1);
position.X
и position.Y
являются Х и Y позиции, size
ширина и высота блока (оба 30, как это квадрат) , 1 - сделать его высотой всего 1 пиксель.
Теперь, как я уже сказал, проблема в том, что персонаж плавает после прыжка. Начальная позиция y составляет 402 пикселя (при этом первый блок topWall.Y
равен 420, то есть символ стоит на вершине блока, когда игра загружается), после прыжка он должен вернуться к 402. Однако; после прыжка один раз он переходит на 374, затем 373, затем 387, 386, ..., 374, 373, обратно на 387 и так далее. Я понятия не имею, что вызывает проблему. Я пробовал несколько вещей, например, рисовать прямоугольники столкновений как с блоком, так и с персонажем, но ничего не работает. Когда я удаляю - size
от (int)position.Y - size
в topWall = new Rectangle()
(который, как я думал, будет проблемой), символ попадает через блок, так что он не исправляет его.
Просто, чтобы сделать немного понятнее, что я имею в виду, вот две фотографии:
У вас есть 'position.Y - = verticalMovement;' для прыжков? Не следует ли добавлять его при прыжках и вычитании при падении? Кроме того, при каком значении инициализируется ваш 'verticalMovement'? – AsheraH
Нет, чем выше значение Y, тем ниже будет размещен спрайт. Поэтому, если вы хотите прыгать, вам нужно уменьшить значение Y, таким образом, '- =' вместо '+ ='. – lolwut147258369
@AsheraH Позиция 0,0 находится в левом верхнем углу в большинстве случаев при программировании, для XNA, а также winforms, html ect. – Steven