Невозможно пройти тесты, в окне с вопросами пусто |
Опубликован: 14.08.2012 | Уровень: специалист | Доступ: платный
Самостоятельная работа 15:
Многоуровневые игры
В листинге 21.2 приведен код класса gBaseClass.
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace P15_1 { public class gBaseClass : Microsoft.Xna.Framework.DrawableGameComponent { Texture2D sprTexture; public Vector2 sprPosition; public Rectangle sprRectangle; public gBaseClass(Game game, ref Texture2D _sprTexture, Vector2 _sprPosition, Rectangle _sprRectangle, int X_Coord, int Y_Coord) : base(game) { sprTexture = _sprTexture; //Здесь производится перевод индекса элемента массива //в координаты на игровом экране //Так как спрайты имеют различные размеры, для их размещения на экране //используются коэффициенты X_Coord и Y_Coord sprPosition.X = _sprPosition.X * X_Coord+16; sprPosition.Y = _sprPosition.Y * Y_Coord; sprRectangle = _sprRectangle; } public override void Draw(GameTime gameTime) { SpriteBatch sprBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); sprBatch.Draw(sprTexture, sprPosition, Color.White); base.Draw(gameTime); } } }Листинг 21.2. Код класса gBaseClass
В листинге 21.3 приведен код класса Bat. Он занимается обработкой перемещений биты по горизонтали и контролем за пересечением битой левой и правой границ экрана.
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input.Touch; namespace P15_1 { public class Bat : gBaseClass { Rectangle scrBounds; //True для движения биты влево и False - вправо public bool direction; public Bat(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) { scrBounds = new Rectangle(16, 0, game.Window.ClientBounds.Width-16, game.Window.ClientBounds.Height); direction = true; } public override void Update(GameTime gameTime) { TouchCollection touchLocations = TouchPanel.GetState(); foreach (TouchLocation touchLocation in touchLocations) { //При касании экрана или при перемещении if (touchLocation.State == TouchLocationState.Pressed||touchLocation.State == TouchLocationState.Moved) { //Узнаем направление движения объекта if (sprPosition.X+48 < touchLocation.Position.X) { direction = false; } else { direction = true; } //Установим объект, по оси Х, таким образом, чтобы //точка касания приходилась на середину объекта sprPosition.X = touchLocation.Position.X-48; } } //проверка на столкновение с границами экрана Check(); base.Update(gameTime); } //Процедура проверки столкновения с левой //и правой границами экрана void Check() { if (sprPosition.X < scrBounds.Left) { sprPosition.X = scrBounds.Left; } if (sprPosition.X > scrBounds.Width - sprRectangle.Width) { sprPosition.X = scrBounds.Width - sprRectangle.Width; } } } }Листинг 21.3. Код класса Bat
В листинге 21.4 вы можете видеть код класса Ball. Этот класс отвечает за перемещение мяча и за обработку столкновений мяча и других объектов.
using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace P15_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(5, -5); scrBounds = new Rectangle(16, 0, game.Window.ClientBounds.Width - 16, 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.4); speed.X += (float)((rand.NextDouble() - rand.NextDouble()) * 0.4); } //Для объектов типа Brick1 скорость лишь растет void RandomiseSpeedB1() { speed.Y += (float)(0.5 * Math.Sign(speed.Y) * Math.Abs(((rand.NextDouble() - rand.NextDouble())))); speed.X += (float)(0.5 * 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) { //Переместить мяч в соответствии со скоростью this.sprPosition += this.speed; //Ограничить скорость мяча 10 пикселями if (speed.Y > 10) speed.Y = (float)10; if (speed.Y < -10) speed.Y = (float)-10; if (speed.X > 10) speed.X = (float)10; if (speed.X < -10) speed.X = (float)-10; //Проверить столкновение с границами Check(); //проверить столкновение с объектами IsCollide(); base.Update(gameTime); } } }Листинг 21.4. Код класса Ball