Невозможно пройти тесты, в окне с вопросами пусто |
Опубликован: 14.08.2012 | Уровень: специалист | Доступ: платный
Самостоятельная работа 10:
Игровая физика
В табл. 16.1 приведено соответствие чисел, используемых в таблице-конструкторе уровня и объектов.
Номер | Название объекта |
0 | Объект отсутствует |
1 | Стена |
2 | Лестница |
3 | Бонус №1 |
4 | Бонус №2 |
5 | Враг |
6 | Игрок |
На рис. 16.3 приведено изображение игрового экрана, сконструированного в соответствии с таблицей и содержимым массива.
Кроме того, на экране можно видеть экранные элементы управления объектом и сообщение для пользователя.
На рис. 16.4 вы можете видеть окно Обозреватель решений нашего проекта.
Втабл. 16.2 приведено описание классов, которые мы используем в данном проекте.
Имя файла | Описание |
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
Здесь мы, во-первых, загружаем ресурсы, во-вторых, создаем игровые объекты, и, в-третьих, выводим на экран фоновое изображение (оно находится под всеми остальными изображениями