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 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .