Спонсор: Microsoft
Опубликован: 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

На каждом шаге игрового цикла объект-преследователь сравнивает свои координаты и координаты объекта игрока и проводит необходимую коррекцию своей позиции.

Как мы уже отмечали, наш объект-преследователь не умеет обходить препятствия. Рассмотрим реализацию алгоритма преследования с обходом препятствий.

Alina Lasskaja
Alina Lasskaja

Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить.....

Дмитрий Кацман
Дмитрий Кацман
Израиль
Андрей Веденин
Андрей Веденин
Россия, Белгород