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

Игровая физика

В табл. 16.1 приведено соответствие чисел, используемых в таблице-конструкторе уровня и объектов.

Таблица 16.1. Номера объектов для размещения в массиве Layer
Номер Название объекта
0 Объект отсутствует
1 Стена
2 Лестница
3 Бонус №1
4 Бонус №2
5 Враг
6 Игрок

На рис. 16.3 приведено изображение игрового экрана, сконструированного в соответствии с таблицей и содержимым массива.

Игровой экран проекта

Рис. 16.3. Игровой экран проекта

Кроме того, на экране можно видеть экранные элементы управления объектом и сообщение для пользователя.

На рис. 16.4 вы можете видеть окно Обозреватель решений нашего проекта.

Обозреватель решений, проект P10_1

Рис. 16.4. Обозреватель решений, проект P10_1

Втабл. 16.2 приведено описание классов, которые мы используем в данном проекте.

Таблица 16.2. Классы проекта P10_1
Имя файла Описание
Game1.cs Класс стандартного проекта
gBaseClass.cs Базовый класс – родитель классов игровых объектов. Он содержит процедуры визуализации объектов и их расстановки по игровому полю. Этот класс наследует класс DrawableGameComponent
Bonus1.cs Класс для создания объектов бонусов вида №1
Bonus2.cs Класс для создания объектов бонусов вида №2
Enemy.cs Класс для создания объектов-врагов
Ladder.cs Класс для создания лестниц
Me.cs Класс для создания объекта игрока. Именно он содержит основную часть игровой логики, в том числе – реализацию игровой физики для объекта-игрока
Wall.cs Класс для создания стен

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

>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.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace P10_1
{
    /// <summary>
    /// Это главный тип игры
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D txtBackground;
        Texture2D txtBonus1;
        Texture2D txtBonus2;
        Texture2D txtEnemy;
        Texture2D txtLadder;
        Texture2D txtMe;
        Texture2D txtWall;
        Texture2D txtArrows;
        SpriteFont myFont;
        //Массив для конструирования уровня
        public int[,] Layer;
        Rectangle recBackround = new Rectangle(16, 0, 768, 448);
        Rectangle recSprite = new Rectangle(0, 0, 64, 64);
        Rectangle recArrows = new Rectangle(500, 280, 300, 200);
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.IsFullScreen = true;
            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        /// <summary>
        /// Позволяет игре выполнить инициализацию, необходимую перед запуском.
        /// Здесь можно запросить нужные службы и загрузить неграфический
        /// контент.  Вызов base.Initialize приведет к перебору всех компонентов и
        /// их инициализации.
        /// </summary>
        protected override void Initialize()
        {
           Layer = new int[7, 12] { 
            { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
            { 1, 5, 1, 3, 5, 1, 1, 2, 1, 1, 1, 5 }, 
            { 0, 0, 0, 1, 2, 1, 1, 2, 0, 0, 0, 4 }, 
            { 0, 1, 3, 0, 2, 0, 0, 2, 0, 0, 0, 3 }, 
            { 0, 5, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1 }, 
            { 6, 0, 1, 3, 4, 0, 5, 2, 0, 0, 0, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
            };

            base.Initialize();
        }

        /// <summary>
        /// LoadContent будет вызываться в игре один раз; здесь загружается
        /// весь контент.
        /// </summary>
        protected override void LoadContent()
        {
            // Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);
            txtBackground = Content.Load<Texture2D>("background");
            txtBonus2 = Content.Load<Texture2D>("bonus2");
            txtBonus1 = Content.Load<Texture2D>("bonus1");
            txtEnemy = Content.Load<Texture2D>("enemy");
            txtLadder = Content.Load<Texture2D>("ladder");
            txtMe = Content.Load<Texture2D>("me");
            txtWall = Content.Load<Texture2D>("wall");
            txtArrows = Content.Load<Texture2D>("arrows");
            myFont = Content.Load<SpriteFont>("MyFont");
            //Вызываем процедуру расстановки объектов в игровом окне
            AddSprites ();
           
        }

 void AddSprites()
        {
            //Переменные для временного хранения адреса
            //объекта-игрока
            int a=0,b=0; 
            //Просматриваем массив Layer
            for (int i = 0; i < 7; i++)
            {
                for (int j = 0; j < 12; j++)
                {
                    //Если элемент с индексом (i,j) равен 1 - 
                    //устанавливаем в соответствующую позицию элемент с
                    //номером 1, то есть - стену
                    if (Layer[i,j]==1) 
                        Components.Add(new GameObjects.Wall(this, ref txtWall, new Vector2(j, i), recSprite, myFont));
                    if (Layer[i, j] == 2)
                        Components.Add(new GameObjects.Ladder(this, ref txtLadder, new Vector2(j, i), recSprite, myFont));
                    if (Layer[i, j] == 3)
                        Components.Add(new GameObjects.Bonus1(this, ref txtBonus1, new Vector2(j, i), recSprite, myFont));
                    if (Layer[i, j] == 4)
                        Components.Add(new GameObjects.Bonus2(this, ref txtBonus2, new Vector2(j, i), recSprite, myFont));
                    if (Layer[i, j] == 5)
                        Components.Add(new GameObjects.Enemy(this, ref txtEnemy, new Vector2(j, i), recSprite, myFont));
                    //Если обнаружен объект игрока - запишем его координаты
                    if (Layer[i, j] == 6)
                    {
                        a = i;
                        b = j;
                    }  
                }
            }
           //Последним установим объект игрока - так он гарантированно
           //расположен поверх всех остальных объектов
                Components.Add(new GameObjects.Me(this, ref txtMe, new Vector2(b, a), new Rectangle (0,0,32,32), myFont));
        }

        /// <summary>
        /// UnloadContent будет вызываться в игре один раз; здесь выгружается
        /// весь контент.
        /// </summary>
        protected override void UnloadContent()
        {
            txtBackground.Dispose();
            txtBonus1.Dispose();
            txtBonus2.Dispose();
            txtBonus1.Dispose();
            txtEnemy.Dispose();
            txtLadder.Dispose();
            txtMe.Dispose ();
            txtWall.Dispose();
            spriteBatch.Dispose();
        }

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

            // ЗАДАЧА: добавьте здесь логику обновления

            base.Update(gameTime);
        }

        /// <summary>
        /// Вызывается, когда игра отрисовывается.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // ЗАДАЧА: добавьте здесь код отрисовки
            spriteBatch.Begin();
            //выведем фоновое изображение
            spriteBatch.Draw(txtBackground, recBackround ,Color.White);
            //Выведем игровые объекты
            base.Draw(gameTime);
            //Стрелки
            spriteBatch.Draw(txtArrows, recArrows, Color.White);
            spriteBatch.End();
           
        }
    }
}
Листинг 16.2. Код класса Game1

Здесь мы, во-первых, загружаем ресурсы, во-вторых, создаем игровые объекты, и, в-третьих, выводим на экран фоновое изображение (оно находится под всеми остальными изображениями

Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто
Сашечка Огнев
Сашечка Огнев
Россия, Красноярский край
Андрей Корягин
Андрей Корягин
Россия, Пенза, Вазерская средняя школа, 2001