Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Microsoft CSharp Programming For The Absolute Beginner (2002) [eng]-1.pdf
Скачиваний:
46
Добавлен:
16.08.2013
Размер:
15.71 Mб
Скачать

right border is touching the right edge of the form (that is, it starts entirely visible along the right edge of the form), you place it at this.Width—picArrow.Width.

In the Real World

You can do essentially three things to an object when it moves off the screen. You can have it wrap around to the opposite side of the screen, as I did in the Mover program. This is a useful effect when you want to emulate limitless space. It’s often used in space games. Sometimes you see map games that allow wrapping along the sides but not the top of the map, to simulate the effects of playing a game on a globe.

The second thing you can do is to have the object stop when it hits the edge of the screen. Do this by setting both dx and dy to 0 when the object encounters the edge of the screen. You can use this effect in a racing game, for example.

The third effect is to have the object appear to bounce off the screen. This is easily done by inverting the dx or dy value, as appropriate. For example, if an object hits the right border of the form, its dx must be positive, so subtract dx from 0 to get a negative value. If you like, you could also take into consideration the energy lost when an object bounces off something. If it hits the wall at dx of 4, set dx to –3 so that it moves back to the left but with less energy. You will see a version of this technique in the Crasher program later in this chapter.

Regardless of the technique you choose when hitting a boundary, using dx and dy variables greatly simplifies your coding of graphic objects.

Assigning the New Location to the Picture Box

Of course, the whole point of figuring out newX and newY is to determine where the picture box should go. Start by creating a new instance of the Point object, based on newX and newY:

Point newLoc = new Point(newX, newY);

Then assign that value to the Location property of picArrow:

picArrow.Location = newLoc;

Detecting Collisions between Objects

If you are moving objects around on the screen, sooner or later they are going to bump into each other. In arcade programming, the most important parts of the game are often related to these events. If you have a racing game, you need to know when the car passes the start line or hits a pedestrian (I mean, safety barrier—I don’t write that kind of game). In a shooting game, you want to keep track of whether the missile hits the target. Game programmers have used collision detection algorithms for years to determine whether two objects overlap on the screen. There are several approaches to collision detection, but C# makes one form exceptionally easy to implement. I’ll illustrate with the simple program featured in Figures 7.14 and 7.15.

186

Figure 7.14: The ball is moving towards the target, and the background is white.

187

Figure 7.15: When the ball moves over the target, the form’s background color changes to black. The Crasher program is essentially two picture boxes, named picBall and picTarget. I set up picBall under the timer control so that it constantly moves back and forth on the screen. Whenever picBall collides with picTarget, the form’s background changes color. This program is simple but illustrates how to test for intersections between objects.

Coding the Crasher Program

I created the Crasher form in the typical way. The only variable I added at the class level is dx, which is an integer value, initialized to positive 4. I didn’t use dy at all in this program because the ball will not move vertically, only horizontally.

All the remaining code for the program goes in the timer’s tick method:

private void timer1_Tick(object sender, System.EventArgs e) { int newX, newY;

newX = picBall.Location.X + dx; newY = picBall.Location.Y;

//check for borders

if (newX > this.Width − picBall.Width){ dx = − dx;

} // end if

if (newX < 0){ dx = − dx;

} // end if

188

// look for collision

if (picBall.Bounds.IntersectsWith(picTarget.Bounds)){ this.BackColor = Color.Black;

}else {

this.BackColor = Color.White;

}//end if

picBall.Location = new Point(newX, newY); } // end timer

Getting Values for newX and newY

I created the newX and newY variables just as in the Mover program. The newX variable is the X location of picBall + dx. This will effectively move the picture box dx pixels each time the timer ticks. The newY variable gets the Y location of picBall. Because I never add anything to newY, the ball will never move in the vertical axis. Still, I find it handy to have a newY value because this makes setting the location of the ball at the end of the tick method easier.

Bouncing the Ball off the Sides

As usual, when you move something, you should check for boundaries. In this case, I decided to bounce the ball whenever it hits a side. To reverse an object’s direction, all you have to do is invert the value of dx. In other words, if dx is 4 and the ball hits the right side of the screen, set dx to –4. If dx is –4 and the ball hits the left side of the screen, set dx to 4. In either case, you can set dx to its inverse value by assigning its negative value. I did this in the code by setting dx = −dx.

Checking for Collisions

The actual collision is relatively simple to check for if you let the .NET objects do all the work. You yourself can come up with a formula to determine whether two objects collide. If you search around, though, you’re likely to find that you have access to objects that will do this work for you.

Extracting a Rectangle from a Component

Each component is automatically given a special property named a Bound. The Bound is an instance of the Rectangle class describing where that object is on the screen. The Rectangle class has an IntersectsWith() method that is used to determine whether one rectangle intersects with another rectangle. When you know all that, you can easily write the code that determines whether the rectangles collided:

if (picBall.Bounds.IntersectsWith(picTarget.Bounds)){

picBall has a Bounds property, which is a Rectangle. All Rectangles have the IntersectsWith() method, which can accept another Rectangle. I sent the Bounds property of picTarget as a parameter to the IntersectsWith() method. The result of all this is a Boolean value just perfect for an if statement. If the rectangles intersect, I change the form’s background to black. If not, I change the background to white.

189

Соседние файлы в предмете Программирование на C++