0
\$\begingroup\$

I am not using Unity or XNA. Eventually, I will probably use OpenTK for graphics. But for the concept of a game I'm writing, I am using the console for keyboard input and visual logging of events, etc.

I am also using a WPF window to display world and player data.

Update: I am using 0 deg as North. I understand that this may not be 'standard'. I don't mind switching to the standard where 0 deg is East if necessary.

The standard keys are W, A, D, S and Left/Right arrows.
W: move forward
A: move left
D: move right
S: move backward

L Arrow: rotate left 2.5 (degrees)
R Arrow: rotate right 2.5 (degrees)

I am new to the physics of movement within a 2D space (as if I am looking down from overhead). What I have is a World and Player model; each Player encapsulates an IEntityVector object.

Edit: added the conversion to radians in the following method. Seems to work more correctly as long as the orientation is 0, 90, 180, or 270 degrees.

Move Model:

  public static void MoveEntity (Guid EntityId, Direction Direction) {
     var entityVector = default(IEntityVector);
     var gameWorld = default(World);

     if (entityRealms.TryGetValue(EntityId, out gameWorld)) {
        if (gameWorld.entityVectors.TryGetValue(EntityId, out entityVector)) {
           var heading = (Math.PI/180) * entityVector.Heading;

           switch (Direction) {
              case Direction.Forward:
                 entityVector.AddMovementX((float)Math.Sin(heading));
                 entityVector.AddMovementY((float)Math.Cos(heading));

                 break;
              case Direction.Left:
                 entityVector.AddMovementX(-(float)Math.Cos(heading));
                 entityVector.AddMovementY((float)Math.Sin(heading));

                 break;
              case Direction.Right:
                 entityVector.AddMovementX((float)Math.Cos(heading));
                 entityVector.AddMovementY((float)Math.Sin(heading));

                 break;
              case Direction.Backward:
                 entityVector.AddMovementX((float)Math.Sin(heading));
                 entityVector.AddMovementY(-(float)Math.Cos(heading));

                 break;
              default:
                 break;
           }
        }
     }
  }

Rotate Model:

  public static void RotateEntity (Guid EntityId, float Heading) {
     var entityVector = default(IEntityVector);
     var gameWorld = default(World);

     if (entityRealms.TryGetValue(EntityId, out gameWorld)) {
        if (gameWorld.entityVectors.TryGetValue(EntityId, out entityVector)) {
           entityVector.Heading += Heading;
        }
     }
  }

#1 I am trying to understand the rotation first of all. If Heading is increased or decreased by 2.5 per rt/lf arrow key press, how do I keep the resulting value as a true degree value?

#2 How can I use the Heading degrees as the facing to properly move the entity?

Btw, here are the AddMovement methods:

  public static void AddMovementX (this IEntityVector Vector, float X) {
     var newPosition = Vector.Location.X + (X * Vector.Thrust);
     Vector.Location = new Vector(newPosition, Vector.Location.Y);
  }

  public static void AddMovementY (this IEntityVector Vector, float Y) {
     var newPosition = Vector.Location.Y + (Y * Vector.Thrust);
     Vector.Location = new Vector(Vector.Location.X, newPosition);
  }
\$\endgroup\$
1
\$\begingroup\$

After quite a headache and a lot of fumbling about, I have finally solved this using the WPF libraries - WindowsBase.dll, PresentationCore.dll - for vectors, rotation, translation, etc. Also some correction to handling facing:

  public static void MoveEntity (Guid EntityId, Direction Direction) {
     var entityVector = default(IEntityVector);
     var gameWorld = default(World);

     if (entityRealms.TryGetValue(EntityId, out gameWorld)) {
        if (gameWorld.entityVectors.TryGetValue(EntityId, out entityVector)) {
           var heading = default(double);

           switch (Direction) {
              case Direction.Forward:
                 heading = entityVector.Heading;

                 break;
              case Direction.Backward:
                 heading = entityVector.Heading - 180;

                 break;
              case Direction.Right:
                 heading = entityVector.Heading - 90;

                 break;
              case Direction.Left:
                 heading = entityVector.Heading + 90;

                 break;
              default:
                 break;
           }

           heading *= Math.PI / 180;
           var direction = new Vector(Math.Cos(heading), Math.Sin(heading));
           var translate = new TranslateTransform(direction.X * entityVector.Thrust, direction.Y * entityVector.Thrust);
           entityVector.Location = Vector.Add(entityVector.Location, new Vector(Math.Round(translate.X, 3), Math.Round(translate.Y, 3)));
        }
     }
  }

Also, removed the methods AddMovementX and AddMovementY.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.