A game loop is the technique of choice for most real-time games. It is a chunk of code that is continuosly run over and over, as fast as the computer can possibly handle. The general format of the loop is:
You will have to have data structures set up to hold all the relevant game state data, this includes the position of every player and monster/npc, the position of anything else that moves (for example bullets, balls in a pong game, the pieces in a tetris game, etc), it will also include any other data that will change in your game, such as how much HP you have left, how fast your car is going and what direction for a racing game, which "nuggets" have been eaten in a pacman game, etc. What is actually contained in the Game State will depend entirely on your game, and it will be different for every game. How you choose to store this is entirely up to you. You can use a whole bunch of variables, you can use arrays, collections, user-defined types, custom classes, etc. The possibilities are endless.
In the UpdateGameState code you will have to calculate how much time has elapsed since the last call to this method (this also means you will have to store the exact time that method is called in order to calculate elapsed time). The code for this could use the GetTickCount() API and may look something like this:
ElapsedTime = GetTickCount() - LastCallTime
LastCallTime = LastCallTime + ElapsedTime
Where LastCallTime and ElapsedTime are both public variables (meaning they maintain their values between successive calls to this method) of type Long. You will probably also have some code in there to get input from the user, stuff like checking the current keyboard state to see what buttons are pressed, or checking to see if any mouse buttons are pressed. Then you will have to update everything that encompasses your game state appropriately. How you actually update it will be dependent on the rules of your game, and what is contained in your Game State. But some examples could be updating the position of a car in a racing game, by multiplying its velocity by the elapsed time, then updating its position appropriately. Updating the position of a bullet, and checking if it hit somebody, if it did hit a player then subtract the correct amount from their HP. For animations you could have a variable representing the current frame in the animation, and another representing the number of milliseconds until the next frame should be displayed, in the UpdateGameState you would have to decrease the time remaining, and when it goes below 0 you would change the variable representing the current frame and reset the time remaining variable. For things that have to occur every x number of seconds you will have to maintain separate variables that contain the amount of time remaining until the event happens again. An example could be in a tetris game, you want the piece to drop 1 square every 2 seconds. So you would have a variable (that is considered part of the game state) that contains the number of milliseconds until the next "drop". In your UpdateGameState code you would do something like so:
TimeTillNextDrop = TimeTillNextDrop - ElapsedTime
If TimeTillNextDrop <= 0 Then
CurrentPiece.y = CurrentPiece.y - 1
TimeTillNextDrop = 2000
This will decrease the TimeTillNextDrop variable (which contains the number of milliseconds until the piece drops again), and then check if it has become less than 0. If so it indicates the piece has to be dropped by one square. It does this by decreasing the .y member of the object that contains position data of the current piece (this could be stored in many many different ways, and the way you decide to store it may be different, just make sure you write the code to update it appropriatly taking into account the method you chose to store this data). It then resets the TimeTillNextDrop variable to 2000 (2 seconds).
As you can see, if your game state is made up of alot of different variables, then the code in the UpdateGameState method can get very large, and this is expected, and this contains a relatively large chunk of the code for your game.
Once you have that code taken care of you can focus your attention on the RenderGraphics code. This code will take all the data from the current game state (which was just updated) and it will use that data to draw the current frame. For example, in an RPG you will get the players current position (which is stored somewhere in your game state) and from that you can determine which part of the map to display. You then draw that part of the map to the screen, then you draw the player to the screen, then you may loop through all the monsters/npc's and determine which ones are currently visible (based on their positions which were just updated in the UpdateGameState code) and draw them if necessary. In a tetris game, you may have an array representing all the pieces that are sitting at the bottom, each array element would have to contain the pieces position and orientation. You would then loop through that array and draw (render) each piece to the screen, then you would access the position data of the "current" piece (the one that is currently falling) and draw that to the screen also. The RenderGraphics code can use many methods of drawing to the screen (pictureboxes, BitBlt()/GDI, DirectX, OpenGL, etc), but the functionality this code performs will be the same in all cases, it redraws the screen based on the newly updated GameState.
Once the RenderGraphics code is done executing, this whole process is repeated, and then repeated again, and again, and again, and again... This continues until the game is exited.