Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить..... |
Организация многоуровневых игр, конструктор уровней
В листинге 15.4. вы можете видеть код класса Ball. Этот класс отвечает за перемещение мяча и за обработку столкновений мяча и других объектов.
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 P11_1 { public class Ball : gBaseClass { //для хранения границ экрана Rectangle scrBounds; //скорость мяча public Vector2 speed; Random rand = new Random(); public Ball(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, int x_c, int y_c) : base(game, ref _sprTexture, _sprPosition, _sprRectangle, x_c, y_c) { speed = new Vector2(1, -1); scrBounds = new Rectangle(0, 0, game.Window.ClientBounds.Width, game.Window.ClientBounds.Height); } //Проверка на столкновение с границами экрана void Check() { if (sprPosition.X < scrBounds.Left) { sprPosition.X = scrBounds.Left; RandomiseSpeed(); speed.X *= -1; } if (sprPosition.X > scrBounds.Width - sprRectangle.Width) { sprPosition.X = scrBounds.Width - sprRectangle.Width; RandomiseSpeed(); speed.X *= -1; } if (sprPosition.Y < scrBounds.Top) { sprPosition.Y = scrBounds.Top; RandomiseSpeed(); speed.Y *= -1; } if (sprPosition.Y > scrBounds.Height - sprRectangle.Height) { this.Dispose(); } } //Проверка на столкновение с объектом bool IsCollideWithObject(gBaseClass spr) { return (this.sprPosition.X + this.sprRectangle.Width > spr.sprPosition.X && this.sprPosition.X < spr.sprPosition.X + spr.sprRectangle.Width && this.sprPosition.Y + this.sprRectangle.Height > spr.sprPosition.Y && this.sprPosition.Y < spr.sprPosition.Y + spr.sprRectangle.Height); } //Процедуры случайного изменения скорости при контакте с объектами //Для всех объектов - скорость может либо возрасти, либо упасть void RandomiseSpeed() { speed.Y += (float)((rand.NextDouble() - rand.NextDouble())*0.2 ); speed.X += (float)((rand.NextDouble() - rand.NextDouble())*0.2 ); } //Для объектов типа Brick1 скорость лишь растет void RandomiseSpeedB1() { speed.Y += (float)(0.3*Math.Sign(speed.Y) * Math.Abs(((rand.NextDouble() - rand.NextDouble())))); speed.X += (float)(0.3*Math.Sign(speed.X) * Math.Abs(((rand.NextDouble() - rand.NextDouble())))); } //Проверка на столкновения public void IsCollide() { gBaseClass FindObj=null; Bat FindedBat; foreach (gBaseClass spr in Game.Components) { if (IsCollideWithObject(spr)) { //Если столкнулись с блоком Brick1 if (spr.GetType() == (typeof(Brick1))) { //сохраним найденный объект FindObj = spr; //Изменим скорость RandomiseSpeedB1(); //Обратим скорость speed *= -1; } //Если столкнулись с блоком 2 //обращаем скорость if (spr.GetType() == (typeof(Brick2))) { speed *= -1; } //если столкнулись с битой if (spr.GetType() == (typeof(Bat))) { FindedBat =(Bat) spr; RandomiseSpeed(); //Если бита двигалась влево //Мяч отразится от нее влево if (FindedBat.direction) { speed.Y = Math.Abs(speed.Y); speed.X = Math.Abs(speed.X); speed *= -1; } //Если двигалась вправо //отразится вправо else { speed.Y = Math.Abs(speed.Y); speed.X = Math.Abs(speed.X); speed.Y *= -1; } } } } //Если был найден блок Block1 if (FindObj != null) { //Уничтожить его FindObj.Dispose(); FindObj = null; } } public override void Update(GameTime gameTime) { // TODO: Add your update code here //Переместить мяч в соответствии со скоростью this.sprPosition += this.speed; //Ограничить скорость мяча 1.5 пикселями if (speed.Y > 2) speed.Y = (float)2; if (speed.Y < -2) speed.Y = (float)-2; if (speed.X > 2) speed.X = (float)2; if (speed.X < -2) speed.X = (float)-2; //Проверить столкновение с границами Check(); //проверить столкновение с объектами IsCollide(); base.Update(gameTime); } } }Листинг 15.4. Код класса Ball
Листинг 15.5. содержит коды классов Brick1, Brick2 и BrickBuilder. Эти классы наследованы от gBaseClass и не вносят в его функциональность никаких дополнений.
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 P11_1 { public class Brick1 : gBaseClass { public Brick1(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, int x_c, int y_c) : base(game, ref _sprTexture, _sprPosition, _sprRectangle, x_c, y_c) { // TODO: Construct any child components here } } } 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 P11_1 { public class Brick2 : gBaseClass { public Brick2(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, int x_c, int y_c) : base(game, ref _sprTexture, _sprPosition, _sprRectangle, x_c, y_c) { // TODO: Construct any child components here } } } 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 P11_1 { public class BrickBuilder : gBaseClass { public BrickBuilder(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, int x_c, int y_c) : base(game, ref _sprTexture, _sprPosition, _sprRectangle, x_c, y_c) { // TODO: Construct any child components here } } }Листинг 15.5. Коды классов Brick1, Brick2 и BrickBuilder
Выводы
В этой лабораторной работе мы создали игру, предусматривающую несколько игровых уровней и конструктор уровней для пользователя. Как правило, разработка реальных игр включает в себя создание конструктора уровней, с помощью которого разработчик создает игровые уровни. Этот конструктор можно включить в поставку игры, предоставив пользователю возможность самостоятельно создавать новые уровни к игре. Конструкторы уровней так же разнообразны, как сами игры.
Задание
В этой лабораторной работе мы создали макет игры, допускающей использование нескольких уровней и содержащей конструктор уровней. Доработайте этот макет. А именно, выполните следующие улучшения исходного проекта:
- Переработайте процедуры обработки столкновений мяча с блоками. Мяч должен отскакивать от блоков точно так же, как он отскакивает от границ экрана.
- Создайте интерфейс игры – меню, систему справки.
- Предусмотрите сохранение пользовательского уровня в файл (с помощью сериализации специально созданного объекта) и загрузку его из файла
- Создайте систему подсчета очков, предусмотрите сохранение данных о набранных очках в файле.
- Улучшите процесс прохождения игры – разработайте дополнительные уровни, сделайте игровой процесс разнообразнее, разработав бонусные объекты, которые появляются при уничтожении некоторых из блоков. Игрок должен "поймать" бонусный объект битой для того, чтобы активировать соответствующий бонус.