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