Michael Yuwono
Michael Yuwono

Reputation: 2617

Moving RPG Character in C# WinForms

I am pretty new at C# and I wanted to make a simple 2D RPG (Role-Playing-Game) character which can move around with its walking animation by simply using 'W' 'A' 'S' 'D' keywords. To do that, I used Picture Box to hold character image and 2 Timers Tool, one for managing the 'walking' animation by changing the picture every 100 ms, and the another timer is for moving that Picture Box location every 1 ms.

In the 'Form_KeyDown' event, I set those 2 timers Enabled = True whenever user presses one of the moving keywords and I set those 2 timers Enabled = False in the 'Form_KeyUp' event to indicate that the character is no longer moving.

Here is the first timer code that control the animation by changing the picture on each tick:

private void timerchangepic_Tick(object sender, EventArgs e)
{
    //movementPhase will determine the picture to be displayed, added by 1
    //every tick means character image change every tick
    movementPhase++;
    if (movementPhase > 4) movementPhase = 1;

    //determining which image is currently displayed
    if (charDirection == Direction.Front)
    {
        if (movementPhase == 1)
            pbcharacter.BackgroundImage = Image.FromFile("Icon\\front.png");
        else if (movementPhase == 2)
            pbcharacter.BackgroundImage = Image.FromFile("Icon\\front2.png");
        else if (movementPhase == 3)
            pbcharacter.BackgroundImage = Image.FromFile("Icon\\front3.png");
        else if (movementPhase == 4)
            pbcharacter.BackgroundImage = Image.FromFile("Icon\\front4.png");
    }

    //and goes the same for another 3 directions (left, right, and back)
}

Here is the second timer code that move the location of the character on each tick:

private void timermovement_Tick(object sender, EventArgs e)
{
    if (charDirection == Direction.Front)
    {
        pbcharacter.Location = new Point(pbcharacter.Location.X, pbcharacter.Location.Y + 5);
    }

    //and goes the same for another 3 directions (left, right, and back)
}

My problem is: the character can't move well when I hold one of the moving keystroke. In a first second it works fine, but after a few second (2-3 seconds) pressing and holding 'S' stroke made the character stopped, moved a little, stopped again, moved a little and over and over. Besides, the animation only worked for 1 lap, the picture changed from 'front' to 'front2' until 'front4' well, but not from 'front4' back to 'front'. In conclusion, the character's animation only ran for 1 shift, then it became a static image which moved a little, stopped, moved again, and stopped again whenever i hold 'S' button.

What is wrong with my codes? Are there any better approaches to implement a moving 2D character task with its animation?

Upvotes: 1

Views: 2287

Answers (3)

koss
koss

Reputation: 3

I think if you must make your game using windows form then you need to at least handle your update with a gameloop instead of form timers and if your moving things around your going to need some kind of clock to help your game run at the same speed on any cpu

Upvotes: 0

Needham
Needham

Reputation: 467

Building a game using windows forms can be incredible hard, and also extremely inefficient. If you were to use XNA, which isn't that difficult to learn, you could create a much better and much stronger game.

If your using WinForms i will presume your a beginner so I wouldn't bother with unity or mono as they are much more complicated. If you still reject this I would advise you to:

  1. Cache images
  2. more accurately calculate ElapsedTime and use dependencies
  3. use a while loop to repeat for each tick, this point should fix your problem

Hope to have been of help.

Upvotes: 0

al_amanat
al_amanat

Reputation: 615

I suggest you to use somethimg more specific to build your application: XNA, MonoGame or Unity3D. But if you are using winforms I have several suggestion for you:

1) Cache images instead load them from file every time.
2) Cause Timer Events interval is not very accurate calculate ElapsedTime from last event. And make change +5 to something dependent of ElapsedTime.
3) Instead using several timers organize game loop to handle your events.
4) Use Double Buffer on your form.

Upvotes: 1

Related Questions