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

code used in the Button_Press() method in the Spin Globe program:

private void timer1_Tick(object sender, System.EventArgs e) { counter++;

if (counter >= 10){ counter = 0;

} // end if

picGlobe.Image = myPics.Images[counter];

}

Adding Motion

Another critical type of animation involves moving objects around on the screen. This can be a simple matter when you understand how C# deals with locations on the screen. Figures 7.12 and 7.13 illustrate an object moving on the screen under user control.

Figure 7.12: When the program starts, the arrow is moving to the right.

182

Figure 7.13: When the user presses an arrow key, the arrow image changes and moves in the indicated direction.

The easiest way to move an image in C# is to put the image in a picture box and move the picture box. This is easy to accomplish. The Mover program features one picture box named picArrow, an image list named myPics, and a timer left at the default name of timer1.

I declared two integer variables at the form level. The dX variable is meant to hold the difference in X (or delta X, if you want to sound like a rocket scientist). In other words, the dX variable determines how much the picture box will move in the X (that is, side−to−side) dimension. In computer graphics, an X value of 0 means the left side of the screen, and larger values move to the right. In a moment, you will add code that moves the picArrow picture box according to the value of dx. If dx is 0, the image does not move horizontally at all. If dx is negative, the image moves to the left, and if dx has a positive value, the picture box moves to the right. The dy variable controls the amount of motion in the Y axis, which determines whether the box moves up or down. Be careful, though, because in computer graphics, a Y value of 0 is at the top of the screen. As Y values get larger, you move down the screen.

Trap Because of the way computer screens work, the coordinate system in most programming languages differs from what you might remember from geometry class. The upper−left corner of the screen is (0,0). X values increase as you move to the right, and Y values increase as you move towards the bottom of the screen. It’s very easy to become confused about this, especially with Y values. However, it’s a relatively simple problem to spot and solve because you’ll find your anvils (for example) floating up rather than dropping to the earth as proper anvils do. If your objects are moving up when they should be going down, or vice−versa, you’ve probably forgotten the upside−down way Y values work in the computer world. Fortunately, it’s easy to fix.

183

Checking for Keyboard Input

The Mover program uses keyboard input to determine which direction the arrow should point and move. Here is the code to handle key presses:

private void theForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {

switch (e.KeyCode){ case Keys.Right:

picArrow.Image = myPics.Images[0]; dx = 2;

dy = 0; break;

case Keys.Down:

picArrow.Image = myPics.Images[1]; dx = 0;

dy = 2; break;

case Keys.Left:

picArrow.Image = myPics.Images[2]; dx = −2;

dy = 0; break;

case Keys.Up:

picArrow.Image = myPics.Images[3]; dx = 0;

dy = −2; break;

} // end switch

}// end KeyDown

As you can see, the keyboard handler is essentially a switch statement based on which key was pressed (which is discovered by investigating e.KeyCode). This is a common pattern. Keyboard handlers very often follow this type of structure. The actual code for each key press is similar as well. The program replaces the Image property of picArrow (which is, as you recall, the visible picture box showing the arrow) with the appropriate image from the ImageList control (myPics). The program then changes the values of dx and dy to indicate how the image will move. Note that I have not actually moved the object yet. If I had put the movement code in this method, the arrow would move when the user presses a key, but only then. I want the arrow to keep moving in the direction of the last key press, so I need to put code somewhere else. (If you must know, that somewhere else is in a timer_tick event, which you’ll see in a moment.)

Working with the Location Property

You can set and retrieve the location of any component by accessing that component’s Location property. Location is (of course) an object. To be specific, it is an instance of the System.Drawing.Point class. The best way to move a component is to make a new Point object and then assign that point to the Location property of the component. The actual movement of the picArrow object happens in the Tick event of the Timer1 class. Here is the code:

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

//change X value

newX = picArrow.Location.X + dx;

//check right boundary if (newX > this.Width){

184

newX =

0;

} // end

if

//check left boundary

if (newX

< 0){

newX =

this.Width − picArrow.Width;

} // end

if

//change

Y value

newY = picArrow.Location.Y + dy;

//check top

if (newY

< 0){

newY =

this.Height − picArrow.Height;

} // end

if

//check bottom

if (newY

> this.Height){

newY =

0;

} // end

if

//create new point, assign to picArrow Point newLoc = new Point(newX, newY); picArrow.Location = newLoc;

} // end timer tick

Getting New Values for X and Y

I started the method by creating integers named newX and newY. These integers will be used to build the point that will eventually be the new location of picArrow. I used the variables to simplify checking for boundaries. I started by copying the X location of picArrow into the dx variable. picArrow’s Location property has an X property that provides this value. I then added dx to newX. The value of dx will be negative if the user wants to move to the left, positive if the user wants to go right, and 0 if the user does not want to move at all in the horizontal axis. If dx is negative, the value of newX will be smaller than it was the last time the timer ticked, and the box will move to the left when newX is applied to the picture box. Likewise, a positive value in dx will cause the box to move to the right, and a 0 value for dx will keep the box in the same position.

Checking for Boundaries

As I’ve said before, whenever you increment or decrement a variable, you should be sure to check for upper or lower limits. This is an especially important consideration in code attached to a timer, because that code is designed to run at frequent intervals. If something goes wrong in timer code, it will go wrong 10 times per second (at least, as the timer is set up in this program).

Wrapping the Arrow around the Screen

The next consideration is what should happen when the arrow moves off the screen. In this particular case, I decided to have the picture box wrap to the other side of the screen. If newX is less than 0, the picture box is moving off the left side of the screen, so I’ll move it to the right side. However, it isn’t always easy to tell how wide the screen is because your user can change the size of a window at any time. Fortunately, you have access to a special value named this. The this keyword refers to the class you are currently defining. In most Windows programming, this refers to the form on which your program is based. You can get the width of the form by looking at this.Width. Not surprisingly, the height is stored in this.Height. If the arrow goes past the right side of the form (this.Width), the program replaces it at the left side, which is always 0. Notice that the location of the picture box refers to the upper−left corner of the box. If you want to place the picture box so that its

185

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