Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить..... |
Устройства ввода, перемещение объектов
Централизованное управление несколькими объектами
Создадим новый проект (P3_6), аналогичный проекту P2_3 (лишь отключим вывод фона). Игровой компонент spriteComp будет использован для построения двух объектов. Изменим его код так, как показано в листинге 7.12.
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 P3_6 { public class spriteComp : Microsoft.Xna.Framework.DrawableGameComponent { protected Texture2D sprTexture; public Rectangle sprRectangle; public Vector2 sprPosition; public spriteComp(Game game, ref Texture2D newTexture, Rectangle newRectangle, Vector2 newPosition) : base(game) { sprTexture = newTexture; sprRectangle = newRectangle; sprPosition = newPosition; // TODO: Construct any child components here } public override void Initialize() { // TODO: Add your initialization code here base.Initialize(); } public override void Update(GameTime gameTime) { // TODO: Add your update code here base.Update(gameTime); } public override void Draw(GameTime gameTime) { SpriteBatch sprBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); sprBatch.Draw(sprTexture, sprPosition, sprRectangle, Color.White); base.Draw(gameTime); } } }Листинг 7.12. Код класса spriteComp
Обратите внимание на то, что класс содержит лишь несколько свойств, собственный конструктор и команды для вывода изображения на экран в методе Draw(). Свойства sprRectangle и sprPosition объявлены с модификатором доступности Public – они пригодятся нам для управления поведением объекта из объекта класса Game1.
Вот как выглядит код класса Game1. Вся логика по перемещению объектов и по проверке допустимости перемещения реализована в нем.
using System; using System.Collections.Generic; 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.Net; using Microsoft.Xna.Framework.Storage; namespace P3_6 { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; spriteComp gameObject1, gameObject2; Texture2D texture; Rectangle scrBounds; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { // TODO: Add your initialization logic here base.Initialize(); } protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); Services.AddService(typeof(SpriteBatch), spriteBatch); texture = Content.Load<Texture2D>("BallandBats"); scrBounds = new Rectangle(0, 0, this.Window.ClientBounds.Width, this.Window.ClientBounds.Height); CreateNewObject(); // TODO: use this.Content to load your game content here } protected void CreateNewObject() { gameObject1 = new spriteComp (this, ref texture, new Rectangle(18, 9, 17, 88), new Vector2(100, 150)); Components.Add(gameObject1); gameObject2 = new spriteComp (this, ref texture, new Rectangle(17, 106, 17, 88), new Vector2(200, 150)); Components.Add(gameObject2); } void Test (spriteComp spr, Rectangle scr) { if (spr.sprPosition.X < scr.Left) { spr.sprPosition.X = scr.Left; } if (spr.sprPosition.X > scr.Width - spr.sprRectangle.Width) { spr.sprPosition.X = scr.Width - spr.sprRectangle.Width; } if (spr.sprPosition.Y < scr.Top) { spr.sprPosition.Y = scr.Top; } if (spr.sprPosition.Y > scr.Height - spr.sprRectangle.Height) { spr.sprPosition.Y = scr.Height - spr.sprRectangle.Height; } } void MoveUp(spriteComp spr) { spr.sprPosition.Y -= 5; } void MoveDown(spriteComp spr) { spr.sprPosition.Y += 5; } void MoveLeft(spriteComp spr) { spr.sprPosition.X -= 5; } void MoveRight(spriteComp spr) { spr.sprPosition.X += 5; } protected override void UnloadContent() { // TODO: Unload any non ContentManager content here } protected override void Update(GameTime gameTime) { // TODO: Add your update logic here KeyboardState kbState = Keyboard.GetState(); if (kbState.IsKeyDown(Keys.Up)) { MoveUp(gameObject1); } if (kbState.IsKeyDown(Keys.Down)) { MoveDown(gameObject1); } if (kbState.IsKeyDown(Keys.Left)) { MoveLeft(gameObject1); } if (kbState.IsKeyDown(Keys.Right)) { MoveRight(gameObject1); } Test(gameObject1, scrBounds); if (kbState.IsKeyDown(Keys.W)) { MoveUp(gameObject2); } if (kbState.IsKeyDown(Keys.S)) { MoveDown(gameObject2); } if (kbState.IsKeyDown(Keys.A)) { MoveLeft(gameObject2); } if (kbState.IsKeyDown(Keys.D)) { MoveRight(gameObject2); } Test(gameObject2, scrBounds); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); base.Draw(gameTime); spriteBatch.End(); } } }Листинг 7.13. Код класса Game1
Для перемещения объектов класса spriteComp мы модифицируем их свойства sprPosition из кода объекта Game1. Для удобства мы создали четыре процедуры – Up, Down, Left, Right – каждая из них принимает на входе объект типа spriteComp и модифицирует соответствующую координату, хранящуюся в свойстве sprPosition этого объекта. Эти процедуры вызываются после анализа состояния клавиатуры в методе Update(). После этого вызывается метод Test(), который принимает на входе объект типа spriteComp и объект типа Rectangle, который хранит параметры экрана. В методе производятся проверки допустимости новых значений, при нарушении объектом границ, координаты модифицируются.
Теперь рассмотрим еще один способ организации управления и работы с объектами.