.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
Figure 1-17:
Dividing a screen into 64 zones
If all we want to know is whether a certain zone contains an object (disregarding which one), we can use
bytes (instead of arrays) to store the zone information, where each bit will represent a zone on screen; this
is called
zoning
with bits
. We can divide our screen in zones according to the number of bits on each
variable used: 64 (8 × 8) zones with a
byte
, 256 (16 × 16) zones in an
int16
, 1024 (32 × 32) zones in an
int32
, and so on.
Using the zoning with bits method, at each game loop we reset the variables and, for each object, we
process any movement. We then calculate the zone of each object (multiply the current position of the
object by the number of zones on each axis and divide by the width or height of the screen), and set the bit
corresponding to the result at the x-axis variable and at the y-axis variable, accordingly. We have to set a
second bit if the sum of the position and the size of the object (width for x axis, height for y axis) lies in
another zone.
If when checking the variables we see that the bit in both variables is already set, then there's an object in
our zone, so we check all the objects to find out which one it is. Using this method, if we have 15 objects
on the screen, and only one collision, we'll have to do only one check against a given number of objects
(14 in the worst case of this scenario), instead of 15 tests with 14 objects. This method has some
drawbacks:
We don't know which object set the bit, so we have to test all the objects looking for the collision.
Some "ghost objects" are created when crossing the bit set for the x zone by one object with the bit set
for the y zones by another object, as depicted by
Figure 1-18
.
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
Figure 1-18:
Using zone bits, if we have big objects (like the bricks), there'll be lots of "ghost
objects."
This method is most useful when we want to test a group of objects against other objects (for example,
bullets against enemies on screen); if we need to test all the objects against each of the others, we'd
better use zoning with arrays of bits, as described in the
next section
.
Zoning with Arrays of Bits
If we have a limited number of objects on screen, we can use two arrays, instead of variables, to define
our zones. Each object will correspond to a specific bit in the array elements, so we'll use
byte
arrays to
control 8 objects,
int16
arrays to control 16 objects, and so on, and create a mapping table linking each
bit with a specific object. The size of each array will define the number of pixels in a zone for each
dimension. For example, creating two arrays each with 10 positions in a 640×480 resolution, we'll have
zones measuring 64 pixels wide by 48 pixels high.
We use the same idea as the previous method to define the zone (or zones) in which each object may be,
and then check to see if both x and y array elements aren't empty. If they aren't zero, and the bits set in
both arrays are the same, then we know for sure that there's another object near us (not a ghost object),
and only check for collision with the one that corresponds to the bit set. An example of this is shown in
Figure 1-19
.
Figure 1-19:
Using zone arrays, we can keep track of which objects are in each zone. The legend
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
shows the bit set in each array element, for each object.
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
Extending the Algorithms to Add a Third Dimension
There are many advanced algorithms for 3-D collisions described on game-related sites all over the
Internet. We'll not stress the many implications on including a z axis in the collision detection algorithms;
instead we'll just add some simple extensions to the preceding algorithms.
Extending the bounding box algorithm is very straightforward, as shown here:
If object1.x <= object2.x + object2.width and _
object1.y <= object2.y + object2.height and _
object1.z <= object2.z + object2.depth) or
(object2.x <= object1.x + object1.width and _
object2.y <= object1.y + object1.height and_
object2.z <= object1.z + object1.depth) then
' => The 3-D boxes are overlapping
Else
' => The 3-D boxes don't collide!!!
end if
As for the proximity algorithms, the extension is just as easy. This code sample depicts a proximity test with
cube-like objects:
Distance = math.max(math.abs(Object1.CenterX - Object2.CenterX), _
math.abs(Object1.CenterY - Object2.CenterY))
Distance = math.max(Distance,
math.abs(Object1.CenterX - Object2.CenterX))
If Distance < Object1.width + Object2.width then
' => The cube objects are overlapping
Else
' => The cubes don't collide!!!
end if
The next proximity algorithm extends the circle proximity test to use spheres in a 3-D space:
Cathetus1 = math.abs(Object1.CenterX - Object2.CenterX)
Cathetus2 = math.abs(Object1.CenterY - Object2.CenterY)
Cathetus3 = math.abs(Object1.CenterZ - Object2.CenterZ)
Distance = math.sqrt(Cathetus1^2 + Cathetus2^2 + Cathetus3^2)
If Distance < Object1.width + Object2.width then
' => The sphere objects are overlapping
Else
' => The spheres don't collide!!!
end if
The last proximity test is used for 3-D diamond-shaped objects:
Distance = math.abs(Object1.CenterX - Object2.CenterX) + _
math.abs(Object1.CenterY - Object2.CenterY) + _
math.abs(Object1.CenterZ - Object2.CenterZ)
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
If Distance < Object1.width + Object2.width then
=> The 3-D diamond objects are overlapping
Else
=> The 3-D diamonds don't collide!!!
end if
In the next sections we'll see how to apply these theoretical ideas in a real game project.
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
The Game Proposal
The first step in developing any project is to establish the project's scope and features.
Note
The main purpose for creating a game proposal is to have clear objectives stated; and everyone
involved in the game creation must agree on every point.
For our project we can summarize the scope in a list of desired features, as shown here:
Our game will be a puzzle game, and it'll be called .Nettrix.
The main objective of the game is to control falling blocks and try to create full horizontal lines, while
not allowing the block pile to reach the top of the game field.
The blocks will be made out of four squares (in every possible arrangement) that fall down in the
game field, until they reach the bottom of the field or a previously fallen block.
When the blocks are falling, the player can move the blocks horizontally and rotate them.
When a block stops falling, we'll check to see if there are continuous horizontal lines of squares in the
game field. Every continuous line must be removed.
The player gets 100 points per removed line, multiplied by the current level. After every couple of
minutes, the blocks must start falling faster, and the level number should be increased.
If the stack of blocks grows until it's touching the top of the game field, the game ends.
This list contains many definitions that are important for any game proposal:
The game genre (puzzle)
The main objective of the game
The actions the player can perform (e.g., to shoot and to get objects)
Details about how the player interacts with the game and vice-versa: keyboard, intuitive interface,
force-feedback joystick, etc.
How the player is rewarded for his or her efforts (points, extra lives, etc.)
How the player gets promoted from one level to the next (in this case, just a time frame)
The criteria for ending the game
Note
In more sophisticated games, there may be other considerations, such as the storyline, the
game flow, details about the level design or level of detail for the maps or textured surfaces, the
difficulty levels for the game, or even details on how the artificial intelligence (AI) of the game
should work.
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
The Game Project
In a commercial game project, the game project starts with a complete game proposal (not just some
simple phrases like ours) and continues with a project or functional specification. Although the proposal is
written in natural language-so anyone can understand and approve it (including the Big Boss, who will
approve or reject the budget for the project)-the project includes programming details that will guide the
development team through the coding phase.
It's not our objective here to explain what must appear in the project documents (it depends largely on the
development methodology used by the team), and we won't create any complete projects since this isn't
the focus of the book. But since it's not advisable to start any coding without a project, we'll take a quick
look at projects just to make some implementation details clearer.
Tip
Of course you can start coding without a project, but even when working alone, a project is the
best place to start, since it lets you organize your ideas and discover details that were not clear
before you put pen to paper. Even if the project is just some draft annotations, you'll see that the
average quality of your code will improve with its use. The more detailed the project is, the better
your code will be, since they'll help you see the traps and pitfalls along the way before you fall into
them.
Object-oriented (OO) techniques are the best to use in game projects, because usually games deal with
some representation (sometimes a very twisted one) of the real world, as OO techniques do. For example,
in Street Fighter, we don't have real fighters on the screen, we have some moving drawings, controlled by
the player or the computer, that create the illusion of a fight. Using an OO approach to project creation is
roughly the same thing: We decide the important characteristics from the real-world objects that we want
to represent in our program, and write them down. We aren't going to go any deeper into this topic at this
stage, but you can find some very good books on this topic.
Since this is our first program, we'll go through the process of making it step by step, in order to
demonstrate how we evolve from the game proposal to the final code; in later chapters we'll take a more
direct approach. In the next sections we'll see a first version of a class diagram, then pseudo-code for the
game main program, and after that we'll go back to the class diagram and add some refinements.
The Class Diagram: First Draft
Let's start with a simple class diagram (shown in
Figure 1-20
) illustrating the basic structures of the objects
for our game, and then we can add the details and go on refining until we have a complete version. Almost
all of the object-oriented analysis methodologies suggest this cyclic approach, and it's ideal to show how
the game idea evolves from draft to a fully featured project.
Figure 1-20:
The class diagram-first draft
From our game proposal we can see the first two classes:
Block
, which will represent each game piece,
and
Square
, the basic component of the blocks.
Reviewing our game proposal, we can think about some methods (functions) and properties (variables) for
the
Block
class, as described in
Table 1-1
.
Table 1-1:
The Block Class Members
.NET Game Programming with DirectX 9.0
by Alexandre Santos Lobão and Ellen
Hatton
ISBN:1590590511
Apress
© 2003
(696 pages)
The authors of this text show how easy it can be to produce
interesting multimedia games using Managed DirectX 9.0 and
programming with Visual Basic .NET on Everett, the latest
version of Microsoft's Visual Studio.
Table of Contents
.NET Game Programming with DirectX 9.0
Foreword
Preface
Introduction
Chapter 1
-
.Nettrix: GDI+ and Collision Detection
Chapter 2
-
.Netterpillars: Artificial Intelligence and Sprites
Chapter 3
-
Managed DirectX First Steps: Direct3D Basics and DirectX vs. GDI+
Chapter 4
-
River Pla.Net: Tiled Game Fields, Scrolling, and DirectAudio
Chapter 5
-
River Pla.Net II: DirectInput and Writing Text to Screen
Chapter 6
-
Magic KindergarteN.: Adventure Games, ADO.NET, and DirectShow
Chapter 7
-
Magic KindergarteN. II: Animation Techniques and Speech API
Chapter 8
-
.Netterpillars II: Multiplayer Games and Directplay
Chapter 9
-
D-iNfEcT: Multithreading, Nonrectangular Windows, and Access to
Nonmanaged Code
Bonus Chapter Porting .Nettrix to Pocket PC
Appendix A
-
The State of PC Gaming
Appendix B
-
Motivations in Games
Appendix C
-
How Do I Make Games?
Appendix D
-
Guidelines for Developing Successful Games
Index
List of Figures
List of Tables
TYPE NAME
DESCRIPTION
Method
Down
Makes the block go down on the screen
Method
Right
Moves the block right
Method
Left
Moves the block left
Method
Rotate
Rotates the block clockwise
Property
Square 1
One of the squares that compose the block
Property
Square 2
One of the squares that compose the block
Property
Square 3
One of the squares that compose the block
Property
Square 4
One of the squares that compose the block
Each block is composed of fours objects from the
Square
class, described in
Table 1-2
.
Table 1-2:
The Square Class Members
TYPE NAME
DESCRIPTION
Method
Show
Draws the square on the screen at its coordinates (
Location
property) and with its size (
Size
property), colored with a specific
color (
ForeColor
property) and filled with
BackColor
Method
Hide
Erases the square from the screen
Property
ForeColor
The square border color
Property
BackColor
The square inside color (fill color)
Property
Location
The x,y position of the square on the screen
Property
Size
The height and width of the square
Comparing the two tables, we can see that there are methods to show and hide the square. Because the
squares will be drawn from the
Block
object, we must have corresponding methods in the
Block
class,
and the corresponding properties too. We can adjust the first diagram accordingly to produce
Figure 1-21
.
Figure 1-21:
The class diagram-second draft
We use
SquareSize
as the size property for the block, since it's not important to know the block size, but
the block must know the size of the squares so that it can create them.