#c# #xna #monogame
Вопрос:
Мне нужна помощь, у меня есть игра в лабиринт, в которой мне нужно нажать на блок. Если я пересечусь с блоком, первый должен переместиться вправо, а второй-влево. Проблема в том, что я не могу заставить ни одного из них двигаться, когда я пересекаюсь. Помощь была бы признательна.
Игра1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;
namespace Labyrintspel
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
Texture2D pixelTexture;
Texture2D playerTexture;
List<Block> blocks = new List<Block>();
Player player;
Color backgroundColor = Color.CornflowerBlue;
Block door;
Block door2;
int i = 0;
int i2 = 0;
int speed1 = 1;
int speed2 = -1;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
_graphics.PreferredBackBufferWidth = 800;
_graphics.PreferredBackBufferHeight = 500;
_graphics.ApplyChanges();
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
base.Initialize();
blocks.Add(BlockFactory.CreateEatableBlock(70, 300));
blocks.Add(BlockFactory.CreateEatableBlock(190, 300));
blocks.Add(BlockFactory.CreateEatableBlock(490, 300));
blocks.Add(BlockFactory.CreateWall(0, 460, 800, 40));
blocks.Add(BlockFactory.CreateWall(0, 0, 800, 30));
blocks.Add(BlockFactory.CreateWall(0, 0, 40, 460));
blocks.Add(BlockFactory.CreateWall(760, 0, 40, 460));
blocks.Add(BlockFactory.CreateWall(640, 200, 40, 260));
blocks.Add(BlockFactory.CreateWall(140, 100, 700, 40));
blocks.Add(BlockFactory.CreateWall(540, 130, 40, 250));
blocks.Add(BlockFactory.CreateWall(440, 200, 40, 260));
blocks.Add(BlockFactory.CreateWall(340, 130, 40, 250));
blocks.Add(BlockFactory.CreateWall(240, 200, 40, 260));
blocks.Add(BlockFactory.CreateWall(140, 130, 40, 250));
blocks.Add(BlockFactory.RemovableWall(600, 0, 40, 100));
blocks.Add(BlockFactory.CreateWall(650, 375, 150, 200));
door = new Block(720, 40, 30, 50, Color.SaddleBrown);
blocks.Add(door);
door2 = new Block(700, 400, 30, 50, Color.SaddleBrown);
player = new Player(700, 300, playerTexture.Width, playerTexture.Height);
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
pixelTexture = Content.Load<Texture2D>("pixel");
playerTexture = Content.Load<Texture2D>("player");
}
protected override void Update(GameTime gameTime)
{
var keyState = Keyboard.GetState();
base.Update(gameTime);
player.StorePosition();
if (keyState.IsKeyDown(Keys.Left)) player.MoveLeft();
if (keyState.IsKeyDown(Keys.Right)) player.MoveRight();
if (keyState.IsKeyDown(Keys.Up)) player.MoveUp();
if (keyState.IsKeyDown(Keys.Down)) player.MoveDown();
if (player.GetRectangle().Intersects(door.Rectangle))
{
i = 0;
blocks.RemoveAll(block => block.IsVisible);
blocks.Add(BlockFactory.CreateWall(0, 460, 800, 40));
blocks.Add(BlockFactory.CreateWall(0, 0, 800, 30));
blocks.Add(BlockFactory.CreateWall(0, 0, 40, 460));
blocks.Add(BlockFactory.CreateWall(760, 0, 40, 460));
blocks.Add(BlockFactory.CreateWall(100, 100, 800, 40));
blocks.Add(BlockFactory.CreateWall(0, 200, 400, 40));
blocks.Add(BlockFactory.CreateWall(500, 200, 400, 40));
blocks.Add(BlockFactory.CreateWall(0, 300, 200, 40));
blocks.Add(BlockFactory.CreateWall(300, 300, 500, 40));
blocks.Add(BlockFactory.RemovableWall(600, 300, 40, 300));
blocks.Add(BlockFactory.CreateEatableBlock(700, 250));
blocks.Add(BlockFactory.CreateEatableBlock(190, 150));
blocks.Add(BlockFactory.CreateEatableBlock(500, 400));
blocks.Add(BlockFactory.CreatePushableBlock(50, 150));
blocks.Add(BlockFactory.CreatePushableBlock(50, 400));
blocks.Add(door2);
}
if (player.GetRectangle().Intersects(door2.Rectangle))
{
this.Exit();
}
backgroundColor = Color.CornflowerBlue;
foreach (var block in blocks)
{
if (player.GetRectangle().Intersects(block.Rectangle))
{
if (block.IsPushable amp;amp; keyState.IsKeyDown(Keys.Space) amp;amp; i2 == 0)
{
block.MoveRight();
i2 ;
}
if (block.IsSolid) player.RestorePosition();
if (block.IsEatable)
{
block.IsVisible = false;
i ;
}
}
if (i == 3)
{
if (block.IsRemovable)
{
block.IsSolid = false;
block.IsVisible = false;
}
}
}
blocks.RemoveAll(block => !block.IsVisible);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(backgroundColor);
_spriteBatch.Begin();
blocks.ForEach(block => block.Draw(_spriteBatch, pixelTexture));
player.Draw(_spriteBatch, playerTexture);
_spriteBatch.End();
Window.Title = "Antal block: " blocks.Count;
base.Draw(gameTime);
}
}
Блок.cs
public class Block
{
public Rectangle Rectangle { get; set; }
public Color Color { get; set; }
public bool IsSolid { get; set; } = true;
public bool IsEatable { get; set; } = false;
public bool IsVisible { get; set; } = true;
public bool IsRemovable { get; set; } = false;
public bool IsPushable { get; set; } = false;
private Vector2 position;
private Rectangle rectangle;
public Block(int x, int y, int w, int h, Color color)
{
Color = color;
position.X = x;
position.Y = y;
Rectangle = new Rectangle(x, y, w, h);
}
public void Move(float dx, float dy)
{
position.X = dx;
position.Y = dy;
}
public Rectangle PushabelRectangle()
{
rectangle.X = (int)position.X;
rectangle.Y = (int)position.Y;
return rectangle;
}
internal void MoveLeft() => Move(-10, 0);
internal void MoveRight() => Move(100, 0);
public void Draw(SpriteBatch spriteBatch, Texture2D texture)
{
if (IsVisible)
{
spriteBatch.Draw(texture, Rectangle, Color);
}
}
}
blockfactory.cs
internal class BlockFactory
{
internal static Block CreateEatableBlock(int x, int y)
{
var block = new Block(x, y, 40, 40, Color.Yellow);
block.IsSolid = false;
block.IsEatable = true;
return block;
}
internal static Block CreatePushableBlock(int x, int y)
{
var block = new Block(x, y, 40, 40, Color.Orange);
block.IsPushable = true;
return block;
}
internal static Block CreateWall(int x, int y, int w, int h)
{
return new Block(x, y, w, h, Color.Black);
}
internal static Block RemovableWall(int x, int y, int w, int h)
{
var block = new Block(x, y, w, h, Color.Black);
block.IsSolid = true;
block.IsEatable = false;
block.IsVisible = true;
block.IsRemovable = true;
return block;
}
internal static Block CreatePushBlock(int x, int y, int w, int h)
{
return new Block(x, y, w, h, Color.Orange);
}
}
Этот код не показывает ошибок, но ничего не происходит, когда я пересекаюсь и нажимаю пробел.
Комментарии:
1. Вы установили точку останова и отладили ее, чтобы проверить и посмотреть, достигнет ли она
block.MoveRight()
?2. Мне нужно подчеркнуть минимальный воспроизводимый код, необходимый для отображения проблемы. Никаких толкаемых блоков до тех пор, пока вы не пройдете через дверь? Многократное сокращение кода показывает вам ответ.
Ответ №1:
Move()
меняется position
переменная, но блок рисуется из Rectangle
поля, которое не изменяется для отражения движения.
Я бы предложил следующую корреляцию: public Rectangle Rectangle { get{return rectangle; } set {rectangle = value;} }
)
public void Move(float dx, float dy)
{
position.X = dx;
position.Y = dy;
Rectangle = new Rectangle((int)position.X, (int)position.Y, Rectangle.Width, Rectangle.Height);
// you cannot set the X and Y of field structures directly.
}