|
DirectInput Walking the Bear
One cannot imagine game programming without devices such as
keyboard, mouse and joystick. The user input comes in the form of events like
KeyDown and MouseMouve. We would have to write handlers for processing these
events. However, this message based input processing is slow.
But game programming is all about speed. For example, in a game you are flying
an aircraft and you want to perform two actions at the same timehit an
enemy aircraft and take a steep turn. To perform these actions simultaneously
we need to press two keys, one for hitting the aircraft and other for turning
the aircraft. This would result in two messages being sent to the message queue.
Depending upon which key was pressed first, that message would be sent first.
The messages would be pressed one after the other. Because of this sequential
message processing the speed would get seriously hampered.
This is where DirectInput comes in. As the name suggests, direct input communicates
directly with the device drivers of the input devices. This means that it responds
immediately to hardware interrupts rather than waiting for Windows to send an
event. Giving a faster response by directly communicating with the device drivers
makes DirectInput a favorite with game developers.
In this article, we intend to create a game-like application in which we want
that a bear should move on pressing arrow keys.
At the same time the background as well as the foreground view of trees should
also change. There would be three layersfront, back and clouds.
The following figure shows the three pictures we are going to use as background
and
foreground.
The following
figure shows how scrolling will occur. 
Variables c and c1 are used for cloud2 and cloud1 and both are initialised to
0 and 800 respectively. So initially, the cloud2 with coordinate 0 would
be visible. The cloud1 will be blitted from 800 and cloud2 from 0. Then,
x will vary from 0 to 800, as a result both clouds would shift and slowly cloud1
would become fully visible. Similar procedure occurs for trees.
In this game, we will first see tree1.bmp. As variable x varies
from 0 to 800, the images keep on shifting and finally when the second image
i.e. tree2.bmp is made visible, the tree1.bmp is drawn
before tree2.bmp and this continues.
Let us now do the actual coding. Firstly, add the following members to the GraphicsClass
class in the ddraw.cs file.
private Rectangle bearRect ;
private Surface[ ] treeback = new Surface[ 2 ] ;
private Surface[ ] treefront = new Surface[ 2 ] ;
private Surface[ ] bear = new Surface[ 12 ] ;
private Surface[ ] cloud = new Surface[ 2 ] ;
public ImagePosition imgPos ;
The ImagePosition is a user defined structure. Declare this
structure in ddraw.cs outside the Graphics Class declaration as
given below.
public struct ImagePosition
{
public int x, y, z ;
public int c, c1 ;
public int b, b1 ;
public int f, f1 ;
public int bearImgNo ;
}
Initialise these elements in the constructor of the GraphicsClass
class as shown below.
public GraphicsClass ( Control owner
)
{
imgPos.x = imgPos.y = imgPos.z = 0 ;
imgPos.c = 0 ;
imgPos.c1 = -800 ;
imgPos.b = 0 ;
imgPos.b1 = -1200 ;
imgPos.f = 0 ;
imgPos.f1 = -1200 ;
imgPos.bearImgNo = 4 ;
this.owner = owner ;
localDevice = new Device( ) ;
localDevice.SetCooperativeLevel ( owner,
CooperativeLevelFlags.FullscreenExclusive |
CooperativeLevelFlags.AllowReboot |
CooperativeLevelFlags.NoWindowChanges ) ;
localDevice.SetDisplayMode (
800, 600, 24, 0, false ) ;
desc = new SurfaceDescription( ) ;
SurfaceCaps caps = new SurfaceCaps( ) ;
localClipper = new Clipper ( localDevice ) ;
localClipper.Window = owner ;
//primary surface creation
desc.SurfaceCaps.PrimarySurface = true ;
desc.SurfaceCaps.Complex = true ;
desc.SurfaceCaps.Flip = true ;
desc.BackBufferCount = 1 ;
//desc.SurfaceCaps.BackBuffer = true ;
surfacePrimary = new Surface ( desc, localDevice ) ;
//attach clipper object to the primary surface
//surfacePrimary.Clipper = localClipper
caps.BackBuffer = true ;
surfaceSecondary = surfacePrimary.GetAttachedSurface ( caps ) ;
surfaceSecondary.Clipper = localClipper ;
CreateSurfaces( ) ;
}
In the constructor in addition to initializing the ImagePosition structure elements
we have also acquired the exclusive full screen display, set the display mode,
created the primary surface and obtained the secondary surface.
To be continued
|