Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить..... |
Устройства ввода, перемещение объектов
Задачи работы
- Научиться получать данные о состоянии мыши и клавиатуры
- Научиться перемещать игровые объекты в соответствии с параметрами, полученными от устройства ввода
- Научиться перемещать игровые объекты в автоматическом режиме, используя средства игрового цикла
- Научиться организовывать управление несколькими объектами для применения в играх, в которые могут играть два игрока, пользующиеся одним компьютером
- Научиться узнавать и изменять размеры игрового окна
- Научиться переводить программу в полноэкранный режим, настраивать разрешение экрана при работе в таком режиме
- Научиться предотвращать пересечение объектом границ экрана при перемещении объекта
Обработка состояния клавиатуры
Создадим новый стандартный проект, назовем его P3_1. Добавим в проект изображение, переменные для хранения текстуры и позиции изображения в игровом окне, загрузим его в методе LoadContent. Вот, как выглядит текст программы после модификации (листинг 7.1.).
using System; using System.Collections.Generic; 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.Net; using Microsoft.Xna.Framework.Storage; namespace P3_1 { /// <summary> /// This is the main type for your game /// </summary> public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; private Texture2D MySprite; private Vector2 position = new Vector2(150, 200); public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); MySprite = Content.Load<Texture2D>("ball"); } protected override void UnloadContent() { // TODO: Unload any non ContentManager content here } protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // TODO: Add your update logic here base.Update(gameTime); } protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin(); spriteBatch.Draw(MySprite, position, Color.White); spriteBatch.End(); // TODO: Add your drawing code here base.Draw(gameTime); } } }Листинг 7.1. Код класса Game1
Теперь добавим в метод Update код, который будет изменять позицию выведенного спрайта в соответствии с изменением состояния клавиатуры. В частности, будет реагировать на клавиши-стрелки, перемещая объект в соответствующем направлении. На рис. 7.1. вы можете видеть внешний вид игрового окна
Для того, чтобы настроить перемещение спрайта по клавиатурным командам, нам понадобится такой код (листинг 7.2.).
KeyboardState kbState = Keyboard.GetState(); if (kbState.IsKeyDown(Keys.Up)) position.Y -= 1; if (kbState.IsKeyDown(Keys.Down)) position.Y += 1; if (kbState.IsKeyDown(Keys.Left)) position.X -= 1; if (kbState.IsKeyDown(Keys.Right)) position.X += 1;Листинг 7.2. Код, реализующий чтение состояния клавиатуры и перемещение спрайта
Здесь мы сначала создали переменную kbState типа KeyboardState, в которую записали текущее состояние клавиатуры, вызвав метод GetState() объекта KeyBoard. Этот метод возвращает состояние клавиатуры.
После этого мы проверили, с помощью метода IsKeyDown, была ли нажата клавиша-стрелка "Вверх". Наименования клавиш хранятся в перечислении Keys. В нашем случае клавиша-стрелка "вверх" символизируется именем Keys.Up. Если клавиша нажата – изменим координату Y позиции объекта, вычтя из нее 1. Позиция изменится и при следующем выводе спрайта он переместится на 1 пиксель вверх. Точно так же обрабатываются другие клавиши-стрелки. Keys.Down – это клавиша "вниз", если она нажата, к координате Y прибавляется единица и объект перемещается вниз. Keys.Left – это клавиша "влево" - объект перемещается влево – от его координаты X отнимается единица. Keys.Right – это клавиша "вправо" - объект перемещается вправо, к его координате X прибавляется 1.
Если нажать и удерживать одну из клавиш – объект будет непрерывно перемещаться в указанном направлении. Если, не отпуская нажатую клавишу, нажать другую, объект изменит направление или остановится. Например, нажав одновременно клавиши "вверх" и"влево", мы заставим объект двигаться по диагонали влево и вверх. А если в то время, как нажата клавиша "вверх" мы нажмем и клавишу "вниз" - объект остановится – нажатие "вверх" вычитает единицу из его позиции, нажатие "вниз" - прибавляет единицу, в результате объект оказывается неподвижным.
С помощью метода IsKeyUp объекта kbState мы проводим проверку, обратную методу IsKeyDown – то есть этот метод возвращает True, если клавиша не нажата, и False – если нажата.
Для перемещения объекта мы модифицируем его координаты на игровом поле. Можно заметить, что модификация ведется с шагом в 1. Это значение можно назвать скоростью перемещения объекта. Увеличив шаг изменения координаты по нажатию клавиши, можно увеличить скорость перемещения.
Можно заметить, что описанный подход к перемещению объекта по клавиатурным командам работает, однако если сложность игровой программы увеличится – он оказывается неудобным. Поэтому ниже мы рассмотрим пример использование управляемого с клавиатуры игрового компонента, унаследованного от DrawableGameComponent. Такой подход делает удобным не только клавиатурное управление, но и автоматическое управление объектом, делает возможным удобное применение ограничений на управление объектом, обработку столкновений объектов (этот вопрос будет рассмотрен на следующем занятии) и другие задачи. Однако, стоит отметить, что принципы управления объектами с клавиатуры даже при управлении игровым компонентом, сохраняются.
Теперь рассмотрим управление игровым объектом с помощью мыши.