Опубликован: 14.08.2012 | Уровень: специалист | Доступ: платный
Самостоятельная работа 15:

Многоуровневые игры

< Самостоятельная работа 14 || Самостоятельная работа 15: 12345 || Лекция 6 >

Рассмотрим коды классов, которые используются в игре.

В листинге 21.1 приведен код класса Game1.

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Devices;

namespace P15_1
{
    /// <summary>
    /// Это главный тип игры
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        //Текстуры
        Texture2D txtBack, txtBrick1, txtBrick2, txtBat, txtBall;
        Texture2D txtBrBuild1, txtBrBuild2, txtBrBuild0;
        Texture2D txtArrows, txtToGame, txtToConstr;
        //Массивы для хранения данных об уровнях
        public byte[,] Layer1, Layer2, Layer3, UserLayer;
        //Прямоугольник для фона
        Rectangle recBack = new Rectangle(0, 0, 480, 800);
        //Прямоугольник для "блока"
        Rectangle recBrick = new Rectangle(0, 0, 64, 16);
        //Прямоугольник для "мяча"
        Rectangle recBall = new Rectangle(0, 0, 10, 10);
        //Прямоугольник для биты
        Rectangle recBat = new Rectangle(0, 0, 96, 16);
        //Номер текущего уровня
        //1 - первый
        //2 - второй
        //3 - третий
        //-1 - пользовательский
        int currentLayer;
        //Установлена в false, если программа находится в 
        //режиме игры, при установке в True включается
        //режим конструктора
        bool IsBuild;
        //Позиция указателя в режиме конструктора
        Vector2 PositionBuild;
        //Тип блока, который будет добавлен на игровое поле
        //при поступлении соответствующей команды в режиме 
        //конструктора
        byte typeOfBuildBlock;
        //Прямоугольники для элементов управления
        Rectangle keyGameOrBuild = new Rectangle(0, 0, 480, 100);
        Rectangle keyChange = new Rectangle(90, 600, 100, 100);
        Rectangle keyUp = new Rectangle(190, 600, 100, 100);
        Rectangle keyOK = new Rectangle(290, 600, 100, 100);
        Rectangle keyLeft = new Rectangle(90, 700, 100, 100);
        Rectangle keyDown = new Rectangle(190, 700, 100, 100);
        Rectangle keyRight = new Rectangle(290, 700, 100, 100);

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.IsFullScreen = true;
            graphics.SupportedOrientations = DisplayOrientation.Portrait;
            graphics.PreferredBackBufferHeight = 800;
            graphics.PreferredBackBufferWidth = 480;
            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        /// <summary>
        /// Позволяет игре выполнить инициализацию, необходимую перед запуском.
        /// Здесь можно запросить нужные службы и загрузить неграфический
        /// контент.  Вызов base.Initialize приведет к перебору всех компонентов и
        /// их инициализации.
        /// </summary>
        protected override void Initialize()
        {
            //Программа находится в игровом режиме
            IsBuild = false;
            //Позиция для указателя в режиме конструктора (0,0)
            PositionBuild = new Vector2(0, 0);
            //Тип блока по умолчанию в режиме конструктора - 1
            typeOfBuildBlock = 1;
            //пользовательский уровень по умолчанию пуст - ячейки
            //заполнены нулями
            UserLayer = new byte[50, 7];
            //Заполняем массивы для разных уровней
            //0 - пустая ячейка
            //1 - блок первого типа (уничтожимый)
            //2 - блок второго типа (неуничтожимый)
            Layer1 = new byte[50, 7]{
            {1,1,1,1,1,1,1},
            {0,1,0,1,0,1,0},
            {1,0,1,0,1,0,1},
            {0,1,0,1,0,1,0},
            {1,0,1,0,1,0,1},
            {0,1,0,1,0,1,0},
            {0,0,0,0,0,0,0},
            {2,0,0,2,0,0,2},
            {0,1,0,0,0,0,0},
            {0,0,1,0,0,0,1},
            {0,0,0,1,0,1,0},
            {0,0,0,0,1,0,0},
            {1,1,1,1,1,1,1},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            };

            Layer2 = new byte[50, 7]{
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,1,2,1,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            };

            Layer3 = new byte[50, 7]{
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,1,2,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,1,1,1,1,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,1,2,0,2,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,1,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,1,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,1,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,1,1,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0},
            };

            //Текущий уровень - 1
            currentLayer = 1;


            base.Initialize();
        }

        /// <summary>
        /// LoadContent будет вызываться в игре один раз; здесь загружается
        /// весь контент.
        /// </summary>
        protected override void LoadContent()
        {
            // Загружаем ресурсы
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);
            txtBack = Content.Load<Texture2D>("Back");
            txtBrick1 = Content.Load<Texture2D>("Brick1");
            txtBrick2 = Content.Load<Texture2D>("Brick2");
            txtBall = Content.Load<Texture2D>("Ball");
            txtBat = Content.Load<Texture2D>("Bat");
            txtBrBuild0 = Content.Load<Texture2D>("BrickBuild0");
            txtBrBuild1 = Content.Load<Texture2D>("BrickBuild1");
            txtBrBuild2 = Content.Load<Texture2D>("BrickBuild2");
            txtArrows = Content.Load<Texture2D>("Arrows");
            txtToGame = Content.Load<Texture2D>("ToGame");
            txtToConstr = Content.Load<Texture2D>("ToConstr");
            //Создаем уровень
            AddSprites(Layer1);
            //Добавляем биту и мяч
            addBallAndBAts();

        }

        //Процедура создания уровня
        //расставляет элементы в соответствии с
        //массивом
        void AddSprites(byte[,] RenderLayer)
        {
            //Просматриваем массив
            for (int i = 0; i < 50; i++)
            {
                for (int j = 0; j < 7; j++)
                {
                    if (RenderLayer[i, j] == 1)
                        Components.Add(new Brick1(this, ref txtBrick1, new Vector2(j, i), recBrick, 64, 16));
                    if (RenderLayer[i, j] == 2)
                        Components.Add(new Brick2(this, ref txtBrick2, new Vector2(j, i), recBrick, 64, 16));
                }
            }
        }
        //Процедура для установки биты и мяча
        void addBallAndBAts()
        {
            Components.Add(new Ball(this, ref txtBall, new Vector2(300, 750), recBall, 1, 1));
            Components.Add(new Bat(this, ref txtBat, new Vector2(300, (800 - 16)), recBat, 1, 1));
        }



        /// <summary>
        /// UnloadContent будет вызываться в игре один раз; здесь выгружается
        /// весь контент.
        /// </summary>
        protected override void UnloadContent()
        {
            // ЗАДАЧА: выгрузите здесь весь контент, не относящийся к ContentManager
        }
        //Проверка попадания касания в область, занимаемую одним из элементов управления
        private bool MenuSelect(Rectangle m, Vector2 p)
        {
            bool res = false;
            if (p.X > m.X && p.X < m.X + m.Width && p.Y > m.Y && p.Y < m.Y + m.Height)
            {
                res = true;
            }

            return res;
        }

        /// <summary>
        /// Позволяет игре запускать логику обновления мира,
        /// проверки столкновений, получения ввода и воспроизведения звуков.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Update(GameTime gameTime)
        {
            // Позволяет выйти из игры
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            TouchCollection touchLocations = TouchPanel.GetState();
            //Если находимся в игровом режиме
            if (!IsBuild)
            {
                foreach (TouchLocation touchLocation in touchLocations)
                {
                    if (touchLocation.State == TouchLocationState.Pressed)
                    {
                        //Если пользователь коснулся кнопки для перехода в режим конструктора
                        if (MenuSelect(keyGameOrBuild, touchLocation.Position))
                        {
                            //Включаем конструктор уровней
                            IsBuild = true;
                            builder();
                        }
                    }
                }

            }
            //Если мы уже в конструкторе
            else
            {
                foreach (TouchLocation touchLocation in touchLocations)
                {
                    if (touchLocation.State == TouchLocationState.Pressed)
                    {
                        //Ищем попадание точки касания в один из элементов управления
                        //Стрелка вверх
                        if (MenuSelect(keyUp, touchLocation.Position))
                        {
                            if (PositionBuild.Y > 0) PositionBuild.Y--;
                        }
                        //Стрелка вниз
                        if (MenuSelect(keyDown, touchLocation.Position))
                        {
                            if (PositionBuild.Y < 49) PositionBuild.Y++;
                        }
                        //Стрелка влево
                        if (MenuSelect(keyLeft, touchLocation.Position))
                        {
                            if (PositionBuild.X > 0) PositionBuild.X--;
                        }
                        //Стрелка вправо
                        if (MenuSelect(keyRight, touchLocation.Position))
                        {
                            if (PositionBuild.X < 6) PositionBuild.X++;
                        }
                        //Кнопка изменения блока
                        if (MenuSelect(keyChange, touchLocation.Position))
                        {
                            //Всего три вида блоков
                            //Циклически изменяем вид блока при нажатии
                            typeOfBuildBlock++;
                            if (typeOfBuildBlock == 3) typeOfBuildBlock = 0;
                        }
                        //Кнопка подтверждения
                        if (MenuSelect(keyOK, touchLocation.Position))
                        {
                            //Записываем данные о позиции блока в соответствующую ячейку массива
                            //хранящего пользовательский уровень
                            UserLayer[(int)PositionBuild.Y, (int)PositionBuild.X] = typeOfBuildBlock;
                        }
                        //очищаем массив компонентов
                        Components.Clear();
                        //выводим пользовательский уровень
                        AddSprites(UserLayer);
                        //уничтожаем указатель и изменяем его в соответствии с типом выбранного блока
                        BrickBuilder br = null;
                        if (typeOfBuildBlock == 1)
                            br = new BrickBuilder(this, ref txtBrBuild1, PositionBuild, recBrick, 64, 16);
                        if (typeOfBuildBlock == 2)
                            br = new BrickBuilder(this, ref txtBrBuild2, PositionBuild, recBrick, 64, 16);
                        if (typeOfBuildBlock == 0)
                            br = new BrickBuilder(this, ref txtBrBuild0, PositionBuild, recBrick, 64, 16);
                        Components.Add(br);
                        //Если нажата кнопка перехода в игровой режим
                        if (MenuSelect(keyGameOrBuild, touchLocation.Position))
                        {
                            //укажем, что режим конструирования не активен
                            IsBuild = false;
                            Components.Clear();
                            AddSprites(UserLayer);
                            addBallAndBAts();
                            //запустим игру с уровнем -1
                            currentLayer = -1;

                        }

                    }
                }
            }

            //Если находимся в режиме игры
            //проверим - завершен ли текущий уровень
            //признак завершения уровня

            if (!IsBuild)
            {
                IsLayerCompleted();
            }

            base.Update(gameTime);
        }
        //Процедура старта конструктора уровней
        //очищаем набор компонентов
        //Создаем и выводим указатель
        public void builder()
        {
            Components.Clear();
            BrickBuilder br = new BrickBuilder(this, ref txtBrBuild1, PositionBuild, recBrick, 64, 16);
            Components.Add(br);
        }

        //Процедура проверки на завершенность
        //текущего уровня
        //Если на поле отсутствует мяч - игра начинается сначала
        //если на поле нет ни одного блока типа Brick1 - 
        //переход на следующий уровень или переход на первый уровень
        //с выводом надписи "Вы выиграли"

        public void IsLayerCompleted()
        {
            //Предположим, что на поле нет ни одного блока
            //типа Brick1
            bool f = false;
            //Предположим, что на поле нет мяча
            bool Ball = false;
            foreach (gBaseClass spr in this.Components)
            {
                //Если найден хотя бы один блок типа 1
                //установим F в True
                if (spr.GetType() == (typeof(Brick1)))
                {
                    f = true;
                }
                //Если найден мяч - установим Ball в True
                if (spr.GetType() == (typeof(Ball)))
                {
                    Ball = true;
                }
            }
            //Если мяч не обнаружен
            //игра начинается сначала
            if (!Ball)
            {
                Components.Clear();
                currentLayer = 1;
                AddSprites(Layer1);
                addBallAndBAts();
            }
            //иначе
            else
            {
                //Если не было найдено ни одного блока
                //типа Brick1
                if (!f)
                {
                    //Очистим набор компонентов
                    Components.Clear();
                    //Увеличим номер уровня
                    currentLayer++;
                    //в зависимости от номера
                    //запустим соответствующий уровень
                    if (currentLayer == 2)
                    {
                        AddSprites(Layer2);
                        addBallAndBAts();
                    }
                    if (currentLayer == 3)
                    {
                        AddSprites(Layer3);
                        addBallAndBAts();
                    }
                    //4 - если был пройден 3-й уровень
                    //0 - при прохождении пользовательского уровня
                    if (currentLayer == 4 | currentLayer == 0)
                    {
                        currentLayer = 1;
                        AddSprites(Layer1);
                        addBallAndBAts();
                        //Включим вибраацию на 0,1 секунды
                        VibrateController.Default.Start(TimeSpan.FromMilliseconds(100));

                    }
                }
            }
        }

        /// <summary>
        /// Вызывается, когда игра отрисовывается.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin();
            //выведем фоновое изображение
            spriteBatch.Draw(txtBack, recBack, Color.White);
            //Выведем игровые объекты
            base.Draw(gameTime);
            //Если в режиме конструктора - выведем экранные элементы управления

            if (IsBuild)
            {
                //для управления конструированием
                spriteBatch.Draw(txtArrows, new Rectangle(90, 600, 300, 200), Color.White);
                //для перехода в игровой режим
                spriteBatch.Draw(txtToGame, new Rectangle(0, 0, 480, 100), Color.White);
            }
            else
            {
                //Если в игровом режиме - выведем элемент управления
                //для перехода в конструктор
                spriteBatch.Draw(txtToConstr, new Rectangle(0, 0, 480, 100), Color.White);
            }
            spriteBatch.End();


        }
    }
}
Листинг 21.1. Код класса Game1
< Самостоятельная работа 14 || Самостоятельная работа 15: 12345 || Лекция 6 >
Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто
Сашечка Огнев
Сашечка Огнев
Россия, Красноярский край
Андрей Корягин
Андрей Корягин
Россия, Пенза, Вазерская средняя школа, 2001