Я прочитал все предложенные темы.Я хочу создать коллизии для платформерной игры с C #, .NET Gatgeteer, .NETMF 4.3 на VS 2013. Я начал с одной платформы, и через некоторое время коллизии на ней работали хорошо.Я думал, что для коллизий со многими платформами мне просто нужно было поставить массив платформ через проверку коллизий вместо одной платформы, но я ошибся.Я получаю массив моей платформы из карты уровней, которая является строковым массивом.До сих пор я сталкивался с этими проблемами:
1) Если ширина или высота платформы изменяется, это также меняет положение платформы, и, как бы я ни старался, я не мог найти причину.
2) Если я добавлю только одну платформу на карту (если в массиве только одна платформа), игрок падает через платформу и даже сквозь землю.
3) Если существует более одной платформы, столкновениелучше всего работает с последними созданными:
* Верхнее столкновение работает только в том случае, если в начале уровня, когда игрок падает, он падает только на платформе, созданной последней, и работает отлично.Вы можете прыгать столько раз, сколько захотите, пока не приземлитесь на землю.После этого верхнее столкновение исчезает.
* Столкновение сторон работает все время.Платформа, созданная последней, работает отлично.Пока игрок немного перемещается по другим платформам, пока я держу джойстик, сразу после того, как я выпустил джойстик, он возвращается к тому месту, где он должен находиться при столкновении.
Я читал в статье Stackoverflow "Столкновения платформы C #, не работающие с несколькими платформами », что в случае обнаружения конфликта цикл должен быть разорван.Я попробовал несколько его вариантов: for, foreach, хотя и с bool, но все они сильно отставали от игры (foreach зависает даже без перерыва).Использование тормоза должно привести к полной противоположности замедлению игры.
4) Столкновения работают только на уровне карты groud (карта [11]).
Спасибо, четыре раза, я хотел бывысоко ценю ответ на любой из моих вопросов.
------------------------------------------------------------КОД------------------------------------------------------------- Эта часть отвечает за карту и массив платформ.Столкновения работают только на уровне земли (карта [11]).
//Map generation
// -88 this offset makes the platform align with botom of the screen
int basePositionTop = -88;
int basePositionLeft = 0;
int platformId = 0;
int playerHeight = 30;
int playerWidth = 30;
Platform[] platformMap = new Platform[200];
void SetupUI()
{
// initialize window
mainWindow = displayT43.WPFWindow;
// setup the layout
layout = new Canvas();
Border background = new Border();
background.Background = new SolidColorBrush(Colors.Black);
background.Height = 272;
background.Width = 480;
layout.Children.Add(background);
Canvas.SetLeft(background, 0);
Canvas.SetTop(background, 0);
//add the player
player = new Rectangle(playerWidth, playerHeight);
player.Fill = new SolidColorBrush(Colors.Red);
layout.Children.Add(player);
// Platformer map
string[] map = new string[12];
map[0] = ".....................................";
map[1] = ".....................................";
map[2] = ".....................................";
map[3] = ".....................................";
map[4] = ".....................................";
map[5] = ".....................................";
map[6] = ".....................................";
map[7] = ".....................................";
map[8] = ".....................................";
map[9] = ".....................................";
map[10] = ".....................................";
map[11] = ".....#..#............................";
for (int i = 0; i < map.Length; i++)
{
for (int j = 0; j < map[i].Length; j++)
{
if (map[i][j] == '#')
{
platformMap[platformId] = new Platform(platWidth, platHeight);
platformMap[platformId].set(basePositionLeft + j * platWidth , basePositionTop + i * platHeight);
platformId++;
}
}
}
// Adding platforms to screen
for (int i = 0; i < platformId; i++)
{
layout.Children.Add(platformMap[i].get());
}
mainWindow.Child = layout;
}
Эта часть отвечает за обнаружение столкновений, а также за действия при обнаружении верхнего или нижнего столкновения.
int power;
int jumpPower = 36;
bool jumped = true;
int playerTopPosition;
int playerLeftPosition = 250;
void jumpTimer_Tick(GT.Timer timer)
{
double y = joystick.GetPosition().Y;
//Jump part
if (!jumped) // if didn't jump
{
if (y >= 0.7) // and jumps
{
jumped = true;
power = jumpPower;
}
}
//Jump
if (jumped)
{
playerTopPosition -= power;
power -= 8;
}
// update player top position
Canvas.SetTop(player, playerTopPosition);
// Platform check loop
for (int i = 0; i < platformId; i++)
{
//TOP AND BOTTOM COLLISION
//Check if player is in platform bounds x axis
if ((playerLeftPosition + playerWidth) >= platformMap[i].posLeft()
&& playerLeftPosition <= platformMap[i].posLeft() + platWidth)
{
//TOP collision. (platHeight/2 -1) - even if player is in platform
// (from top) and doesn't touch the middle he is set on top
if (playerTopPosition + playerHeight >= platformMap[i].posTop()
&& playerTopPosition + playerHeight <= platformMap[i].posTop() + (platHeight / 2 - 1))
{
playerTopPosition = platformMap[i].posTop() - playerHeight;
jumped = false;
}
//BOTTOM collision. (platHeight/2 + 1) - even if player is in platform
//(from bottom) and don't touch the middle he collides with bottom
if (playerTopPosition <= platformMap[i].posTop() + platHeight
&& playerTopPosition >= platformMap[i].posTop() + (platHeight / 2 + 1))
{
playerTopPosition = platformMap[i].posTop() + platHeight;
power = -1;// without this player gets stuck on platform bottom
}
}
else jumped = true; // if player steps off platform - he falls
// the very bottom collision
if (playerTopPosition + playerHeight >= displayT43.Height)
{
playerTopPosition = displayT43.Height - playerHeight;
jumped = false;
}
//SIDES COLLISION
//Check if player is in platform bounds y axis
if (playerTopPosition + playerHeight <= platformMap[i].posTop() + platHeight
&& playerTopPosition >= platformMap[i].posTop())
{
//RIGHT collision. (platWidth / 2 - 1) - even if player is in platform
// (from left) and don't touch the middle he collides with left
if ((playerLeftPosition + playerWidth) + 1 >= platformMap[i].posLeft()
&& (playerLeftPosition + playerWidth) <= platformMap[i].posLeft() + (platWidth/2-1))
{
playerLeftPosition = platformMap[i].posLeft() - playerWidth;
stopRight = true;// stops moving right
}
else stopRight = false;
//LEFT collision. (platWidth / 2 - 1) - even if player is in platform
// (from right) and don't touch the middle he collides with right
if (playerLeftPosition - 1 <= platformMap[i].posLeft() + platWidth
&& playerLeftPosition >= platformMap[i].posLeft() + (platWidth / 2 + 1))
{
playerLeftPosition = platformMap[i].posLeft() + platWidth;
stopLeft = true;// stops moving left
}
else stopLeft = false;
}
else
{
stopRight = false;
stopLeft = false;
}
// update player top position
Canvas.SetTop(player, playerTopPosition);
}
}
Это ответственно за левое / правое движение и действия при обнаружении левого или правого столкновения.
bool stopLeft = false;// makes stop move left
bool stopRight = false;// makes stop move right
void JoystickTimer_Tick(GT.Timer timer)
{
double x = joystick.GetPosition().X; // joystic x scale [-1;1]
// move left
if (x < -0.3 && playerLeftPosition > 0 && !stopLeft)
{
playerLeftPosition -= 5;
}
// move right
else if (x > 0.7 && playerLeftPosition < displayT43.Width - playerWidth
&& !stopRight)
{
playerLeftPosition += 5;
}
Canvas.SetLeft(player, playerLeftPosition);// update player left postion
}
Класс Platform.cs
class Platform
{
private Rectangle platformRectangle { get; set; }
int left = 0;
int top = 0;
public Platform()
{
}
public Platform(int Width, int Height)
{
this.platformRectangle = new Rectangle();
this.platformRectangle.Height = Height;
this.platformRectangle.Width = Width;
platformRectangle.Fill = new SolidColorBrush(Colors.Orange);
}
public void set(int leftPosition, int topPosition)
{
Canvas.SetLeft(platformRectangle, leftPosition);
Canvas.SetTop(platformRectangle, topPosition);
this.left = leftPosition;
this.top = topPosition;
}
public Rectangle get()
{
return platformRectangle;
}
public int posLeft()
{
return left;
}
public int posTop()
{
return top;
}
}