Движение мыши: нажмите спрайт «ходит», чтобы точка щелкнула

Я довольно новичок в C # и XNA и хорошо программирую (как будто я могу следовать учебному пособию, но большая часть его создания все еще очень трудна). Прямо сейчас я собираюсь изо всех сил, пытаясь выяснить, как сделать эту одну "простую" вещь.

Вот идея, это будет игра в защиту башни; сейчас я работаю над основами голой кости. У меня есть мой маленький спрайт, который будет перемещаться с помощью ввода с клавиатуры, теперь я хочу щелкнуть где-нибудь на экране и заставить его «пройтись» до этой точки. Только я заблудился от логики. Я могу нажать, и он прыгнет туда с

if (aMouse.LeftButton == ButtonState.Pressed)
{
  Position.X = aMouse.X;
  Position.Y = aMouse.Y;
} 

Из того, что я прочитал для других вводов мышью, я думаю, что мне понадобится какой-то цикл (может быть, bool?), который будет перемещать спрайт в направлении и должен будет выполнить проверку, чтобы увидеть, если он добрался до этого момента еще. Но, получая эту точку после щелчка мышью и создавая этот цикл, выполняя проверку ... Я не знаю.

4 голоса | спросил Steph 17 FebruaryEurope/MoscowbThu, 17 Feb 2011 08:14:46 +0300000000amThu, 17 Feb 2011 08:14:46 +030011 2011, 08:14:46

4 ответа


0

Вам нужно добавить несколько переменных экземпляра:

Point2D targetPos;

И некоторые константы:

const Point2D speed;

Когда вы выполняете цикл Update (), обновляйте текущую позицию, добавляя к ней вектор скорости (в правильном направлении курса), пока вы не окажетесь в пределах предварительно определенного порога от целевой позиции (обычно пороги рассчитываются из вектор скорости - если расстояние от текущей позиции до целевой позиции меньше длины вектора скорости, значит, вы находитесь на своей позиции). Использование bool в этом случае будет хорошо работать. Когда вы щелкаете мышью, установите для другой переменной экземпляра (перемещение) значение true, а после достижения целевого положения установите для перемещения значение false.

ответил João Lourenço 17 FebruaryEurope/MoscowbThu, 17 Feb 2011 08:26:53 +0300000000amThu, 17 Feb 2011 08:26:53 +030011 2011, 08:26:53
0

Люди отвечают на ваш вопрос на очень низком уровне. Иногда это помогает думать о проблеме на более высоком уровне.

Вам нужен тип государственного управления. Причудливый термин Computer Science для этого - конечный автомат. Но не надо сейчас искать это. Сначала это довольно сухо и запутанно:)

Ваш персонаж в настоящее время имеет одно состояние - «стоять вокруг». Вам необходимо добавить и обработать состояние «пешком до места назначения».

  

Из того, что я прочитал для другого ввода мышью, я думаю, что мне понадобится какой-то цикл

Вам нужен один цикл, называемый игровым циклом. Если вы используете XNA, у вас уже есть один. Но вы на правильном пути.

Каждый раз в игровом цикле вы должны обрабатывать текущее состояние и проверять то, что называется переходами между состояниями. Это когда вы меняете что-то в своем мире из одного состояния в другое. Например, когда вы щелкаете мышью, вы хотите, чтобы парень начал двигаться.

В вашем игровом цикле вы проверяете, не произошло ли щелчка мышью. Если это так, то настройте некоторые данные (куда двигаться) и скажите ему, чтобы он начал ходить, установив его состояние «ходьба к месту назначения». В следующем обновлении вы будете обрабатывать это состояние.

Когда ваш персонаж находится в состоянии «ходьбы до дезинтации», вам необходимо обновить его положение в зависимости от времени, прошедшего с момента последнего обновления игры. В XNA это рассчитывается для вас. Если вы не используете XNA, вам придется проверить себя. Вы можете использовать что-то вроде класса Stopwatch и проверить Elapsed поле.

Если персонаж находится в пункте назначения, вам необходимо переключить его обратно в состояние «стояния».

Если вы получили еще один щелчок мыши, вам решать, хотите ли вы, чтобы состояние «ходьба к месту назначения» обращало на это внимание или нет. Если вы обращаете на это внимание, вы настраиваете те же данные, что и при переходе из состояния «стояния».

Итак, вам понадобятся эти переменные:

  • Таймер, чтобы узнать, сколько времени прошло с момента последнего игрового цикла (XNA дает его вам)
  • Текущее состояние игрока (возможно, enum)
  • Текущая позиция игрока (вектор)
  • Скорость ходьбы игрока (вероятно, с плавающей точкой), измеряемая в единицах в секунду (или миллисекундах)
  • Данные для состояния "ходьба к месту назначения" - целевая позиция (другой вектор)
  • Данные, связанные с пользовательским вводом (события мыши, произошедшие с момента последнего обновления, положение этих кликов и т. д.)

Данные, характерные для персонажа, будут разными для каждого персонажа в вашей игре, поэтому вы хотите получить новую копию для каждого из них. Вы, вероятно, захотите поместить это в класс. Все остальное носит более глобальный характер, поэтому вы можете хранить его отдельно или сделать его частью своей игры, игрового цикла, классов ввода и т. Д. (Как бы вы ни организовали это).

Я не буду описывать векторную математику для того, как на самом деле рассчитывать частичное движение, так как другие люди уже это обсуждали. Нет смысла дублировать эти ответы. В основном это сводится к созданию вектора между вашей текущей позицией и целевой позицией и умножению /делению его на вашу скорость ходьбы (чтобы разделить его на расстояние, пройденное в одном обновлении).

ответил Merlyn Morgan-Graham 17 FebruaryEurope/MoscowbThu, 17 Feb 2011 09:03:49 +0300000000amThu, 17 Feb 2011 09:03:49 +030011 2011, 09:03:49
0

Я предполагаю, что у вас есть три вещи:

  1. Текущая позиция
  2. Желаемая позиция
  3. Скорость перемещения каждого «игрового тика» //не знаете, что такое игровой тик? узнай!

Ты смотришь на это

введите описание изображения здесь

// dx, dy are delta x and delta y. It's how far in each direction
// the player must travel
// note, I fixed a typo where they were desired - desired... should be
// desired - current, as they are now
float dx = desiredX - currentX;
float dy = desiredY - currentY;

// d uses the pythagorean theorum to find the distance between current and desired
float d = sqrt(dx*dx + dy*dy);
// fac is how far along that line between desired and current will you move
float fac = d / speed;

// mx is the component of the dx line proportional to the size of fac : d
// which means it's how far in the x direction you'll move
float mx = dx * fac;
float my = dy * fac;

// the new postition is the old position plus the move value
float newPositionX = dx + mx;
float newPositionY = dy + my;
ответил corsiKa 17 FebruaryEurope/MoscowbThu, 17 Feb 2011 08:28:53 +0300000000amThu, 17 Feb 2011 08:28:53 +030011 2011, 08:28:53
0

Я нашел этот код наиболее полезным ... кроме того, я добавил дополнительную пару строк, чтобы предотвратить возникновение определенных ситуаций. Например, будут моменты, когда направление равно 0,83, а скорость может быть изменена такими игровыми факторами, как местность /погода /и т.д. ... если скорость ниже 1, спрайт может вообще не двигаться или даже двигаться в неправильном направлении!

 if (Vector2.Distance(Position, TargetPosition) > 2.0f)
 {
    velocity = Vector2.Subtract(TargetPosition, Position);
    velocity.Normalize();
    /// Now no matter which direction we are going we are always moving @ sprite.Speed
    /// at velocity or speed below 1 - problems occur where the unit may not move at all!!
    if(current_Speed < 1)
    {
       Vector2 temp = (velocity * 10) * (current_Speed * 10);
       Position += temp / 10;
    }
    else
    { 
       Vector2 temp = velocity * current_Speed;
       Position += temp;
    }
    //convert to int to render sprite to pixel perfect..
    Position = new Vector2((int)Position.X, (int)Position.Y);
 }
ответил Bixel 18 WedEurope/Moscow2013-12-18T03:45:46+04:00Europe/Moscow12bEurope/MoscowWed, 18 Dec 2013 03:45:46 +0400 2013, 03:45:46

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132