Опубликован: 14.08.2012 | Доступ: свободный | Студентов: 881 / 20 | Оценка: 5.00 / 5.00 | Длительность: 09:59:00
Специальности: Программист
Самостоятельная работа 15:

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

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

В листинге 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
< Самостоятельная работа 14 || Самостоятельная работа 15: 12345 || Лекция 6 >
Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто