Control and collision detection by genie
In the previous section, we learned how to plot, move, and implement animations. Finally, we implemented simple animations for the three rings. Today we learned how to control the genie through devices, the content in this section is relatively simple and easy to understand. Here I first paste all the code of the control genie to facilitate the next learning!
Using system; using system. collections. generic; using system. LINQ; using Microsoft. xNa. framework; using Microsoft. xNa. framework. audio; using Microsoft. xNa. framework. content; using Microsoft. xNa. framework. gamerservices; using Microsoft. xNa. framework. graphics; using Microsoft. xNa. framework. input; using Microsoft. xNa. framework. media; namespace windowsgame6 {public class game1: Microsoft. xNa. framework. game {gr Aphicsdevicemanager graphics; spritebatch; texture2d ringtexture; // The related variable point ringframesize = new point (75, 75); point ringcurrentframe = new point (0, 0 ); point ringsheetsize = new point (6, 8); vector2 ringpos1 = vector2.zero; const float ringspeed = 5; texture2d skulltexture; // vertex header animation variable point skullframesize = new point (75, 75); point skullcurrentframe = new point (0, 0); point S Kullsheetsize = new point (6, 8); mousestate prevmousestate; Public game1 () {graphics = new graphicsdevicemanager (this); content. rootdirectory = "content";} protected override void initialize () {// todo: add the initialization logic base here. initialize ();} protected override void loadcontent () {// create a new spritebatch that can be used to draw a texture. Spritebatch = new spritebatch (graphicsdevice); ringtexture = content. load <texture2d> ("Images // threerings"); // Load two bitmap skulltexture = content. load <texture2d> ("Images // skullball"); // todo: use this. content loading game content} protected override void unloadcontent () {// todo: unload any non-contentmanager content here} protected override void Update (gametime) {// allow the game to exit if (gamepad. getstate (playerindex. one ). but Tons. back = buttonstate. pressed) This. exit (); ++ ringcurrentframe. x; // If (ringcurrentframe. x> = ringsheetsize. x) {ringcurrentframe. X = 0; ++ ringcurrentframe. y; If (ringcurrentframe. y> = ringsheetsize. y) ringcurrentframe. y = 0;} ++ skullcurrentframe. x; // If (skullcurrentframe. x> = skullsheetsize. x) {skullcurrentframe. X = 0; ++ skullcurrentframe. y; If (skullcurrentframe. y> = skul Lsheetsize. y) skullcurrentframe. y = 0;} // todo: add the update logic keyboardstate = keyboard here. getstate (); // The if (keyboardstate) statement that controls the three-ring animation on the keyboard. iskeydown (keys. left) ringpos1.x-= ringspeed; If (keyboardstate. iskeydown (keys. right) ringpos1.x + = ringspeed; If (keyboardstate. iskeydown (keys. up) ringpos1.y-= ringspeed; If (keyboardstate. iskeydown (keys. down) ringpos1.y + = ringspeed; mousestate mouses Tate = mouse. getstate (); // The mouse controls the three-ring animation statement if (mousestate. X! = Prevmousestate. x | mousestate. y! = Prevmousestate. y) ringpos1 = new vector2 (mousestate. x, mousestate. y); prevmousestate = mousestate; If (ringpos1.y <0) // keep the third-Ring Genie in the window ringpos1.y = 0; If (ringpos1.y> window. clientbounds. height-ringframesize. y) ringpos1.y = Window. clientbounds. height-ringframesize. y; If (ringpos1.x <0) ringpos1.x = 0; If (ringpos1.x> window. clientbounds. width-ringframesize. x) ringpos1.x = Window. clientbounds. width-ringframesize. x; base. update (gametime);} protected override void draw (gametime) {graphicsdevice. clear (color. cornflowerblue); spritebatch. begin (spritesortmode. fronttoback, blendstate. alphablend); spritebatch. draw (// draw the third-ring sprite ringtexture, ringpos1, new rectangle (ringcurrentframe. x * ringframesize. x, ringcurrentframe. y * ringframesize. y, ringframesize. x, ringframesize. y), color. white, 0, vector2.zero, 1, spriteeffects. none, 0); spritebatch. draw (// draw the skeleton genie skulltexture, new vector2 (100,100), new rectangle (skullcurrentframe. x * skullframesize. x, skullcurrentframe. y * skullframesize. y, skullframesize. x, skullframesize. y), color. white, 0, vector2.zero, 1, spriteeffects. none, 0); spritebatch. end (); // todo: add the drawing code base here. draw (gametime );}}}
1: Draw More genie
On the basis of the Three-Ring Genie program code yesterday, we need to add another sprite bitmap. The old method is as follows:
This is a skeleton sprite bitmap. Like a third-ring animation, you can add the code at the beginning of the class, load the bitmap in the loadcontent function, and draw a bitmap in the draw function, in order not to repeat the first one, we set the coordinates to (100,100), and then run it. We can see that there are two animations rotating on the screen!
2: Use the keyboard to control the movement of the genie!
A new knowledge is required here. The keyboard input is handled through the keyboard class in the Microsoft. xNa. Framework. Input namespace. The keyboard class has a static method called getstate, which returns the current state of the keyboard in the form of a keyboardstate structure.
The keyboardstate structure contains three key methods that can meet most of your functional requirements:
Keys [] getpressedkeys () returns an array of keys that are pressed when the method is called.
The return value of bool iskeydown (Keys key) is true or false, depending on whether the key represented by the parameter is pressed during method call.
The return value of bool iskeyup (Keys key) is true or false, depending on whether the keys represented by parameters are released during method calling.
For example, to check whether the key of the keyboard is pressed, write the code as follows:
If (keyboard. getstate (). iskeydown (Keys. ));
Now we can start to move the three-ring animation from top to bottom on the keyboard. Here, like yesterday, we need to add the variable ringpos1 of vector2, in addition, in the draw method, the position of the Third-ring animation is changed to ringpos1,
Next we should update the moving distance in the update method. The Code is as follows:
Keyboardstate = keyboard. getstate (); // The if (keyboardstate) statement that controls the three-ring animation on the keyboard. iskeydown (keys. left) ringpos1.x-= ringspeed; If (keyboardstate. iskeydown (keys. right) ringpos1.x + = ringspeed; If (keyboardstate. iskeydown (keys. up) ringpos1.y-= ringspeed; If (keyboardstate. iskeydown (keys. down) ringpos1.y + = ringspeed;
As shown above, if else is not used. Instead, four if statements can be moved from both directions, such as upper left and lower right, if you change it to If else, you can only move it in one direction. Now you can compile and run it. You can use the upper, lower, and lower layers of the keyboard to move our three-ring animation !!
3: Use the mouse to control the three-ring animation!
XNa provides a mouse class with similar keyboard behavior to interact with the mouse. The mouse class also has a getstate method that can return data from the mouse in the form of a mousestate structure.
Mousestate has some properties that will help you understand what happens when you call getstate. The details are as follows:
Leftbutton buttonstate returns the left mouse button status
Middlebutton buttonstate
Rightbutton buttonstate: Return to the right-click status
Scrollwheelvalue int returns the accumulated amount of the scroll wheel scale after the game starts. To know the scroll wheel size, compare the scrollwheelvalue of the current frame with that of the previous frame.
X int returns the horizontal position of the cursor relative to the upper left corner of the game window (sitting ). if the mouse cursor is on the left side of the game window, this value is a negative value. If it is on the right side of the game window, this value is greater than the width of the game window.
. Xbutton1 buttonstate returns the status of some additional buttons on the mouse
Xbutton2 buttonstate returns the status of some additional buttons on the mouse
Y int returns the vertical position of the cursor relative to the upper left corner of the game window (sitting ). if the cursor is over the game window, this value is a negative value. If the cursor is below the game window, this value is greater than the height of the game window.
To determine whether the mouse is moved, add a class member variable at the top of the game1 class:
Mousestate premousestate; (as shown in)
Add the following code to the update method before calling the base. Update method:
Mousestate = mouse. getstate (); // control the third-ring animation statement if (mousestate. X! = Prevmousestate. x | mousestate. y! = Prevmousestate. Y) ringpos1 = new vector2 (mousestate. X, mousestate. Y); prevmousestate = mousestate;
Now compile and run, the third-ring animation will follow the mouse, and our mouse control will be completed!
4: Keep the animation between windows
You may have noticed that the third-Ring Genie disappears at the edge of the screen when you move it far enough. It is never a good idea to let a player-controlled object exit the screen and disappear. To correct this problem, you must update the sprite position at the end of the update function. If the genie has moved too far to the left, right, up, or down, it is positioned to keep it in the game window. Add the following code to the end of the update method, before calling the base. Update method:
If (ringpos1.y <0) // keep the third ring genie in the window ringpos1.y = 0; If (ringpos1.y> window. clientbounds. height-ringframesize. y) ringpos1.y = Window. clientbounds. height-ringframesize. y; If (ringpos1.x <0) ringpos1.x = 0; If (ringpos1.x> window. clientbounds. width-ringframesize. x) ringpos1.x = Window. clientbounds. width-ringframesize. x;
Compile and run again. Now the mouse and keyboard can control the movement of the Three-Ring animation. At this time, the animation remains within the window!
5: General Collision Detection
We all know that collision detection is a very important part of the game and involves a lot of mathematical problems. However, in our xNa, collision problems are simplified to your imagination, which of the above programs should we first run:
These two genie, the ghost header is currently fixed. We can use the keyboard to control the third-Ring Genie. We can use the rectangular packaging method to achieve the meeting detection, that is, we can use two rectangles to pack the genie, then, check whether the two rectangles are intersecting to determine whether the two rectangles are colliding. The effect is as follows:
What we need to do next is to check whether two rectangles are intersecting on the screen. it happens that the rectangle class provided by xNa has such a member function that can detect the intersection of Rectangles and add a new member function, the Code is as follows:
Protected bool colline () // code for collision detection {rectangle ringrect = new rectangle (INT) ringpos1.x, (INT) ringpos1.y, ringframesize. x, ringframesize. y); rectangle skullerct = new rectangle (INT) skullpos2.x, (INT) skullpos2.y, skullframesize. x, skullframesize. y); Return ringrect. intersects (skullerct );}
Two New Rectangular areas are created in the program. The construction method gives the positions of the two genie respectively. The return value is Boolean, And the intersects method of the rectangle class is used, next, we can check the collision in the update method.
If (colline ())..... execute related tasks. Here we call the exit function. If a collision occurs, terminate the program immediately (although this is not logical, it is only for demonstration ).
Collision detection requires a balance between the size of the rectangle and the efficiency of the game to ensure the best performance when the user's eyes cannot be distinguished. Therefore, you cannot blindly pursue collision accuracy and perform too many operations, it is not worthwhile to sacrifice game efficiency,
This section is very simple, so far
Next Issue: User-Defined genie class!