|
Быть может кто-то из Вас знает игру 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, который хранит параметры экрана. В методе производятся проверки допустимости новых значений, при нарушении объектом границ, координаты модифицируются.
Теперь рассмотрим еще один способ организации управления и работы с объектами.