Hi there!
I'm writing an online game, and I'm trying to come up with a good movement system.
One of the first things I thought about was packing bits into a byte to register when a movement key is pressed. Well... it doesn't seem to be so easy. :
[source="C#"] void m_MovementTimer_Elapsed(object sender, ElapsedEventArgs e)
{
byte MovementUpdate = new byte();
if (Keyboard.GetState().IsKeyDown(Keys.Left))
MovementUpdate = Utility.SetFlag(MovementUpdate, 0, 1);
else
MovementUpdate = Utility.SetFlag(MovementUpdate, 0, 0);
if (Keyboard.GetState().IsKeyDown(Keys.Right))
MovementUpdate = Utility.SetFlag(MovementUpdate, 1, 1);
else
MovementUpdate = Utility.SetFlag(MovementUpdate, 1, 0);
if (Keyboard.GetState().IsKeyDown(Keys.Up))
MovementUpdate = Utility.SetFlag(MovementUpdate, 2, 1);
else
MovementUpdate = Utility.SetFlag(MovementUpdate, 2, 0);
if (Keyboard.GetState().IsKeyDown(Keys.Down))
MovementUpdate = Utility.SetFlag(MovementUpdate, 3, 1);
else
MovementUpdate = Utility.SetFlag(MovementUpdate, 3, 0);
if (!Keyboard.GetState().IsKeyDown(Keys.Left) && !Keyboard.GetState().IsKeyDown(Keys.Right) &&
!Keyboard.GetState().IsKeyDown(Keys.Up) && !Keyboard.GetState().IsKeyDown(Keys.Down))
{
//No movement keys are hit, so start timing...
m_IdleTimer++;
if (m_IdleTimer == 10)
{
m_IdleTimer = 0;
//Set the fourth bit to indicate the player is idle.
MovementUpdate = Utility.SetFlag(MovementUpdate, 4, 1);
}
}
RealmPacketHandlers.SendMovementUpdate(m_Client, MovementUpdate);
}
]
The function up there is called every 100 msecs by the client. Also, here is my SetFlag function:
[source="C#"] public static byte SetFlag(byte Number, byte Flag, byte TrueOrFalse)
{
byte Val = (byte)(1 << (Flag - 1));
if ((Number & Val) == Val && TrueOrFalse == 0)
Number = (byte)(Number - Val);
if ((Number & Val) == 0 && TrueOrFalse == 1)
Number = (byte)(Number + Val);
return Number;
}
The server code looks like this:
[source="C#"] public static void OnMovementUpdate(NetMessage Msg, NetServer Server)
{
int ID = Msg.ReadInt();
byte MovementUpdate = Msg.ReadByte();
Account PlayerAccount = Globals.AccountMgr.GetAccount(ID);
if (Utility.ReadFlag(MovementUpdate, 0) == true)
{
//Left
Console.WriteLine("Left key was pressed!");
PlayerAccount.CurrentCharacter.X--;
}
if (Utility.ReadFlag(MovementUpdate, 1) == true)
{
//Right
Console.WriteLine("Right key was pressed!");
PlayerAccount.CurrentCharacter.X++;
}
if (Utility.ReadFlag(MovementUpdate, 2) == true)
{
//Up
Console.WriteLine("Up key was pressed!");
PlayerAccount.CurrentCharacter.X--;
}
if (Utility.ReadFlag(MovementUpdate, 3) == true)
{
//Down
Console.WriteLine("Down key was pressed!");
PlayerAccount.CurrentCharacter.X++;
}
List<Account> Accts = Globals.AccountMgr.GetAccounts(ID);
//TODO: Send server movement update...
}
What this results in is that the server constantly spits out "Left key was pressed!" even when it isn't pressed! None of the other keys seems to function... at all! I've been trying to come up with a solution for days now - any ideas?
Thanks in advance!
[Edited by - MatsVed on August 11, 2008 8:59:20 AM]