|
Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить..... |
Опубликован: 10.04.2009 | Уровень: специалист | Доступ: платный
Самостоятельная работа 8:
Методы искусственного интеллекта (ИИ) в компьютерных играх
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P8_1.GameObj
{
public class Me : gBaseClass
{
public Me(Game game, ref Texture2D _sprTexture,
Vector2 _sprPosition, Rectangle _sprRectangle)
: base(game, ref _sprTexture, _sprPosition, _sprRectangle)
{
sprSpeed = 2;
// TODO: Construct any child components here
}
public override void Initialize()
{
base.Initialize();
}
public void IsCollideWithAny()
{
//Заводим переменную для временного хранения
//ссылки на объект, с которым столкнулся игровой объект
gBaseClass FindObj = null;
//Проверка на столкновение с объектами Enemy
foreach (gBaseClass spr in Game.Components)
{
if (spr.GetType() == (typeof(Enemy)))
{
if (IsCollideWithObject(spr))
{
FindObj = spr;
}
}
}
if (FindObj != null)
{
this.Dispose();
}
}
//Процедура, отвечающая за перемещение игрового объекта
void Move()
{
KeyboardState kbState = Keyboard.GetState();
//При нажатии кнопки "Вверх"
if (kbState.IsKeyDown(Keys.Up))
{
MoveUp(sprSpeed);
while (IsCollideWithWall())
{
MoveDown((sprSpeed / 10));
}
}
//При нажатии кнопки "Вниз"
//Происходит обычная процедура перемещения
//объекта с проверкой
if (kbState.IsKeyDown(Keys.Down))
{
MoveDown(sprSpeed);
while (IsCollideWithWall())
{
MoveUp((sprSpeed / 10));
}
}
//Точно так же обрабатывается
//нажатие кнопки "Влево"
if (kbState.IsKeyDown(Keys.Left))
{
MoveLeft(sprSpeed);
while (IsCollideWithWall())
{
MoveRight((sprSpeed / 10));
}
}
//Аналогично - перемещение вправо
if (kbState.IsKeyDown(Keys.Right))
{
MoveRight(sprSpeed);
while (IsCollideWithWall())
{
MoveLeft((sprSpeed / 10));
}
}
}
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
//Вызовем процедуру перемещения объекта по клавиатурным командам
Move();
//Проверим, не вышел ли он за границы экрана, если надо
//исправим его позицию
Check();
IsCollideWithAny();
base.Update(gameTime);
}
}
}
Листинг
12.4.
содержит код класса Me.
Объект класса Me умеет перемещаться по клавиатурным командам, не выходя за границы экрана, останавливаться, "натыкаясь" на стену, а при столкновении с объектом-преследователем объект класса Me уничтожается. Алгоритм преследования реализован в коде класса Enemy (листинг 12.5.).
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;
namespace P8_1.GameObj
{
public class Enemy : gBaseClass
{
Vector2 Direction;
public Enemy(Game game, ref Texture2D _sprTexture,
Vector2 _sprPosition, Rectangle _sprRectangle)
: base(game, ref _sprTexture, _sprPosition, _sprRectangle)
{
sprSpeed = 1;
Direction = new Vector2(0, 0);
// TODO: Construct any child components here
}
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
//Вычисление направления на объект-игрока и передвижение в
//этом направлении
void SeekAndDestroy()
{
foreach (gBaseClass spr in Game.Components)
{
if (spr.GetType() == (typeof(Me)))
{
//найдем разницу между координатами преследователя и
//игрока
Direction = (this.sprPosition - spr.sprPosition);
//Если разность по X положительная
//переместим преследователя влево
//с учетом того, что стены для него
//непроницаемы.
if (Direction.X > 0)
{
MoveLeft(sprSpeed);
while (IsCollideWithWall())
{
MoveRight((sprSpeed / 10));
}
}
//При отрицательной разности по X
//переместим объект вправо
if (Direction.X < 0)
{
MoveRight(sprSpeed);
while (IsCollideWithWall())
{
MoveLeft((sprSpeed / 10));
}
}
//При положительной разности по Y
//переместим объект вверх
if (Direction.Y > 0)
{
MoveUp(sprSpeed);
while (IsCollideWithWall())
{
MoveDown((sprSpeed / 10));
}
}
//При отрицательной разности по Y переместим
//объект вниз
if (Direction.Y < 0)
{
MoveDown(sprSpeed);
while (IsCollideWithWall())
{
MoveUp((sprSpeed / 10));
}
}
}
}
}
public override void Update(GameTime gameTime)
{
// Перемещение к объекту игрока
SeekAndDestroy();
//Проверка на столкновение с границами экрана
Check();
base.Update(gameTime);
}
}
}
Листинг
12.5.
Код класса Enemy
На каждом шаге игрового цикла объект-преследователь сравнивает свои координаты и координаты объекта игрока и проводит необходимую коррекцию своей позиции.
Как мы уже отмечали, наш объект-преследователь не умеет обходить препятствия. Рассмотрим реализацию алгоритма преследования с обходом препятствий.