Невозможно пройти тесты, в окне с вопросами пусто |
Искусственный интеллект в играх
В данном классе производится инициализация матрицы игрового мира и расстановка объектов. Здесь мы, помимо объекта-игрока и объекта-преследователя, разместили на игровом поле стену (рис.12.2.).
С её помощью можно заметить, что объект-преследователь может выполнять свои функции лишь на открытом пространстве. Если между преследователем и игроком находится стена – преследователь упирается в нее, перемещаясь вдоль стены до тех пор, пока либо не окажется на свободном пространстве, либо – не окажется строго напротив объекта-игрока. Наш преследователь не способен обходить препятствия – преследованием с обходом препятствий мы займемся ниже, а пока продолжим рассмотрение классов игры.
В листинге 18.2 приведен код класса gBaseClass.
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 P12_1.GameObjects { /// <summary> /// Это игровой компонент, реализующий интерфейс IUpdateable. /// </summary> public class gBaseClass : Microsoft.Xna.Framework.DrawableGameComponent { Texture2D sprTexture; public Vector2 sprPosition; public Rectangle sprRectangle; public SpriteFont myFont; public string message=""; //Прямоугольник, представляющий игровое окно public Rectangle scrBounds; //Скорость объекта public float sprSpeed; public gBaseClass(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, SpriteFont _myFont) : base(game) { sprTexture = _sprTexture; //Именно здесь производится перевод индекса элемента массива //в координаты на игровом экране sprPosition = _sprPosition * 64; sprPosition.X += 16; sprRectangle = _sprRectangle; myFont = _myFont; scrBounds = new Rectangle(16, 0, 768, 448); } /// <summary> /// Позволяет игровому компоненту выполнить необходимую инициализацию перед\r\запуском. Здесь можно запросить нужные службы и загрузить контент. /// /// </summary> public override void Initialize() { // ЗАДАЧА: добавьте здесь код инициализации base.Initialize(); } /// <summary> /// Позволяет игровому компоненту обновиться. /// </summary> /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param> public override void Update(GameTime gameTime) { // ЗАДАЧА: добавьте здесь код обновления base.Update(gameTime); } public override void Draw(GameTime gameTime) { SpriteBatch sprBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); sprBatch.Draw(sprTexture, sprPosition, Color.White); //Если строка сообщения не пуста if (this.message != "") { sprBatch.DrawString(myFont, message, new Vector2(0, 455), Color.Red); } base.Draw(gameTime); } //Проверка на столкновение с каким-либо объектом public bool IsCollideWithObject(gBaseClass spr) { return (this.sprPosition.X + this.sprRectangle.Width > spr.sprPosition.X && this.sprPosition.X < spr.sprPosition.X + spr.sprRectangle.Width && this.sprPosition.Y + this.sprRectangle.Height > spr.sprPosition.Y && this.sprPosition.Y < spr.sprPosition.Y + spr.sprRectangle.Height); } //Процедуры для перемещения объекта public void MoveUp(float speed) { this.sprPosition.Y -= speed; } public void MoveDown(float speed) { this.sprPosition.Y += speed; } public void MoveLeft(float speed) { this.sprPosition.X -= speed; } public void MoveRight(float speed) { this.sprPosition.X += speed; } //Проверка на столкновение со стеной public bool IsCollideWithWall() { foreach (gBaseClass spr in Game.Components) { if (spr.GetType() == (typeof(Wall))) { if (IsCollideWithObject(spr)) return true; } } return false; } //Проверка на столкновение с границами экрана public void Check() { if (sprPosition.X <= scrBounds.Left) { sprPosition.X = scrBounds.Left; } if (sprPosition.X >= scrBounds.Width - sprRectangle.Width) { sprPosition.X = scrBounds.Width - sprRectangle.Width; } if (sprPosition.Y <= scrBounds.Top) { sprPosition.Y = scrBounds.Top; } if (sprPosition.Y >= scrBounds.Height - sprRectangle.Height) { sprPosition.Y = scrBounds.Height - sprRectangle.Height; } } } }Листинг 18.2. Код класса gBaseClass
Мы включили в этот класс методы и свойства, которые будем использовать и для объекта игрока и для объекта-преследователя. Они знакомы вам по проекту P10_1.
Теперь рассмотрим код класса Wall – (листинг 18.3.) мы приводим его здесь лишь для полноты изложения – он не претерпел изменений.
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 P12_1.GameObjects { /// <summary> /// Это игровой компонент, реализующий интерфейс IUpdateable. /// </summary> public class Wall : gBaseClass { public Wall(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, SpriteFont _myFont) : base(game, ref _sprTexture, _sprPosition, _sprRectangle, _myFont) { // ЗАДАЧА: здесь создаются дочерние компоненты } /// <summary> /// Позволяет игровому компоненту выполнить необходимую инициализацию перед\r\запуском. Здесь можно запросить нужные службы и загрузить контент. /// /// </summary> public override void Initialize() { // ЗАДАЧА: добавьте здесь код инициализации base.Initialize(); } /// <summary> /// Позволяет игровому компоненту обновиться. /// </summary> /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param> public override void Update(GameTime gameTime) { // ЗАДАЧА: добавьте здесь код обновления base.Update(gameTime); } } }Листинг 18.3. Код класса Wall