| Невозможно пройти тесты, в окне с вопросами пусто |
Искусственный интеллект в играх
В данном классе производится инициализация матрицы игрового мира и расстановка объектов. Здесь мы, помимо объекта-игрока и объекта-преследователя, разместили на игровом поле стену (рис.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
