вторник, 6 марта 2012 г.

Практическое применение XNA. Часть 4.

Пришло время понять как же управлять приложениями. На примере нашего телевизора, разберем как с помощью мыши можно останавливать воспроизведение видео и запускать его вновь. На самом деле этот способ прекрасно подходит для создания игровых меню и аналогичных задач.

Определение нажатых клавиш на клавиатуре производится с помощью класса KeyboardState, а мыши MouseState. Это общеизвестный способ в C#. Но нам предстоит понять, как привязываются конкретные фрагменты изображения, к каким – либо событиям. Ну например нажатие на одну из кнопок меню. В XNA для этого предусмотрены классы BoundingBox и BoundingSphere.С их помощью можно определить области прямоугольной или круглой формы, при пересечении которых будет происходить какое - либо событие. Следующий пример демонстрирует использование BoundingBox для определения области экрана нашего телевизора. При нажатии левой кнопки мыши на нем, видеоплеер переходит в режим паузы. Повторное нажатие запускает воспроизведение далее. Использование BoundingSphere аналогично BoundingBox, с учетом особенностей передачи параметров при создании. Это не ширина и высота прямоугольника, а позиция центра и радиус окружности, которая будет использоваться.
 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;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace myTV
{
  public class Game1 : Microsoft.Xna.Framework.Game
  {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Video myVideo;
    VideoPlayer myPlayer;
    Texture2D myTexture;
    Texture2D myCursor;
    KeyboardState myKeyboardState;
    MouseState myMouseState;
    MouseState myPerviousMouseState;
    BoundingBox bbox = new BoundingBox(new Vector3(125, 125, 0), new Vector3(625, 395, 0));
    BoundingBox mbox = new BoundingBox();
    bool isPaused = false;
    public Game1()
    {
      graphics = new GraphicsDeviceManager(this);    
      Content.RootDirectory = "Content";
     
    }
    protected override void Initialize()
    {
      myPlayer = new VideoPlayer();
      base.Initialize();
    }
    protected override void LoadContent()
    {
      spriteBatch = new SpriteBatch(GraphicsDevice);
      myVideo = Content.Load<Video>(@"video/xblcg");
      myTexture = Content.Load<Texture2D>(@"textures/telek");
      myCursor = Content.Load<Texture2D>(@"textures/cursor");
      myPlayer.IsLooped = true;
      myPlayer.IsMuted = false;
      myPlayer.Volume = 1f;
      myPlayer.Play(myVideo);
    }
    protected override void UnloadContent()
    {
    }
    protected override void Update(GameTime gameTime)
    {
      myKeyboardState = Keyboard.GetState();
      myMouseState = Mouse.GetState();
     
      if (myKeyboardState.IsKeyDown(Keys.Escape))
      {
        this.Exit();
      }
      mbox = new BoundingBox(new Vector3(myMouseState.X, myMouseState.Y,0), new Vector3(myMouseState.X + 100, myMouseState.Y + 100,0));
      if (bbox.Intersects(mbox))
      {
        if (myMouseState.LeftButton == ButtonState.Pressed && myPerviousMouseState.LeftButton == ButtonState.Released)
        {
          if (!isPaused)
          {
            myPlayer.Pause();
            isPaused = true;
          }
          else
          {
            myPlayer.Play(myVideo);
            isPaused = false;
          }
        }
      }
      myPerviousMouseState = myMouseState;
      base.Update(gameTime);
    }
    protected override void Draw(GameTime gameTime)
    {
      GraphicsDevice.Clear(Color.CornflowerBlue);
      spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
      spriteBatch.Draw(myPlayer.GetTexture(), new Rectangle(125, 125, 500, 270), Color.White);
      spriteBatch.Draw(myTexture, new Rectangle(0, 0, 800, 600), Color.White);
      spriteBatch.Draw(myCursor, new Rectangle(myMouseState.X, myMouseState.Y, 100, 100), Color.White);
      spriteBatch.End();
      base.Draw(gameTime);
    }
  }
}
Как видите, этот пример не на много сложнее предыдущих. Отличие заключается в проверках пересекается Box мыши с Box-ом экрана, и если да, то выполняем определенные действия.



Основываясь на этом примере и немного пофантазировав, вы уже в можете написать собственную несложную 2D игру или меню. Но она пока будет безмолвная. Как работать со звуком поговорим в следующих главах. Лично мне этих данных хватило, для повторения меню из моей любимой игры S.T.A.L.K.E.R. , чего и вам желаю.

1 комментарий:

Physically Based Rendering