Не работает обнаружение столкновений в платформерной игреC#

Место общения программистов C#
Ответить
Anonymous
 Не работает обнаружение столкновений в платформерной игре

Сообщение Anonymous »

Я пытаюсь реализовать обнаружение столкновений в игре в стиле платформера на XNA/MonoGame.
Я следую двум отдельным руководствам: одному по менеджеру анимации, а другому по добавлению столкновений. Я пытаюсь объединить их вместе, но они конфликтуют.
Я думаю, проблема в том, что прямоугольник игрока (и, возможно, скорость тоже) не рисуется игрой из класса спрайта1. файл, поскольку класс спрайта использует метод Draw менеджера анимации. Но я новичок в программировании и понятия не имею, как с этим обойти (возможно, я тоже ошибаюсь, это также может быть проблема с «Обновлением»).
Вот код основного файла игры:

Код: Выделить всё

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;

namespace Test.Platformer
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;

private Dictionary tilemap;
private Dictionary collisions;
private List textureStore;
private Texture2D textureMap;
private Texture2D collisionMap;

int tilesize = 16;

private Sprite player;
private List intersections;

private Texture2D rectangleTexture;

private KeyboardState prevKBState;

public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
tilemap = LoadMap("../../../Data/map1_main.csv");
collisions = LoadMap("../../../Data/map1_collisions.csv");
intersections = new();

}

private Dictionary LoadMap(string filepath)
{
Dictionary result = new();

StreamReader reader = new(filepath);

int y = 0;
string line;
while ((line = reader.ReadLine()) != null)
{
string[] items = line.Split(',');

for (int x = 0; x < items.Length; x++)
{
if (int.TryParse(items[x], out int value))
{
if (value >  -1)
{
result[new Vector2(x, y)] = value;
}
}

}
y++;
}
return result;
}
protected override void Initialize()
{
base.Initialize();
}

protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);

var animations = new Dictionary()
{
{"RunDown", new Animation(Content.Load("PlayerRunDown"), 4) },
{"RunUp", new Animation(Content.Load("PlayerRunUp"), 4) },
{"RunLeft", new Animation(Content.Load("PlayerRunLeft"), 6) },
{"RunRight", new Animation(Content.Load("PlayerRunRight"), 6) },
};

textureMap = Content.Load("TexturePack");
collisionMap = Content.Load("TextureCollisionPack");

player = new Sprite(animations, new Rectangle(0,0,16,32));
}

protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();

player.Update(Keyboard.GetState(), prevKBState, gameTime);
player.isClinging = false;

prevKBState = Keyboard.GetState();

// add player's Velocity and grab the intersecting tiles
player.rect.X += (int)player.velocity.X;
intersections = getIntersectingTilesHorizontal(player.rect);

foreach (var rect in intersections)
{

// handle collisions if the tile position exists in the tile map layer.
if (collisions.TryGetValue(new Vector2(rect.X, rect.Y), out int _val))
{

// create temp rect to handle collisions (not necessary, you can optimize!)
Rectangle collision = new(
rect.X * tilesize,
rect.Y * tilesize,
tilesize,
tilesize
);

if (!player.rect.Intersects(collision))
{
continue;
}

// handle collisions based on the direction the player is moving
if (player.velocity.X > 0.0f)
{
player.rect.X = collision.Left - player.rect.Width;
player.isClinging = true;
}
else if (player.velocity.X < 0.0f)
{
player.rect.X = collision.Right;
player.isClinging = true;
}

}

}

// same as horizontal collisions

player.rect.Y += (int)player.velocity.Y;
intersections = getIntersectingTilesVertical(player.rect);

foreach (var rect in intersections)
{
if (collisions.TryGetValue(new Vector2(rect.X, rect.Y), out int _val))
{

// create temp rect to handle collisions (not necessary, you can optimize!)
Rectangle collision = new(
rect.X * tilesize,
rect.Y * tilesize,
tilesize,
tilesize
);

if (!player.rect.Intersects(collision))
{
continue;
}

// handle collisions based on the direction the player is moving
if (player.velocity.Y > 0.0f)
{
player.rect.Y = collision.Top - player.rect.Height;
player.velocity.Y = 2f;
}
else if (player.velocity.Y <  0.0f)
{
player.rect.Y = collision.Bottom;
}

}
}

base.Update(gameTime);
}
// wabs the intersecting tiles for a Rect.  This grabs all tile positions where
// an intersection is __possible__, not if a tile actually exists there.
public List getIntersectingTilesHorizontal(Rectangle target)
{

List intersections = new();

int widthInTiles = (target.Width - (target.Width % tilesize)) / tilesize;
int heightInTiles = (target.Height - (target.Height % tilesize)) / tilesize;

for (int x = 0; x = _animation.FrameCount)
_animation.CurrentFrame = 0;
}
}
}
}
Класс анимации получает FrameWidth и FrameHeight в зависимости от размера текстуры.
Полный проект и ресурсы здесь
Любая помощь приветствуется

Подробнее здесь: https://stackoverflow.com/questions/790 ... ot-working
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»