Я предлагаю вам разместить level.bricks [] массива в ArrayList списка, так что вы можете дешево удалить() и/или уничтожить() их из списков на лета, избегая проверки завершает каждую итерацию в массиве level.bricks (если ваша установка не имеет значения null в вашем массиве). Кроме того, он избавит вас от необходимости проверять размер массива, каждую итерация, для всех кирпичей, во время каждого цикла рендеринга ...
List<Brick> brickList = new ArrayList<Brick>();
for (brick: level.bricks) {
brickList.add(new Brick(brick));
}
//-------or-------
//if the brick object is a Sprite
for (brick: level.bricks) {
brickList.add(brick);
}
Я считаю, что вопрос о неправильных кирпичах быть обнаружен как «хит «имеет какое-то отношение к попытке компенсировать текстуру и границы мяча как прямоугольник Rectangle. Я бы рекомендовал использовать класс com.badlogic.gdx.math.Circle для определения границ шара. Ниже приведена грязная пользовательская оболочка столкновений для com.badlogic.gdx.math.Intersector, которая должна работать с тем, что вы пытались сделать выше. Это предполагает, что визуальные пиксели шара простираться до края текстуры и мяч текстура площади:
public class Collider {
private String bounceType = "";
private boolean vertical = false;
private boolean horizontal = false;
// Segment Vertices of the Rectangle
private Vector2 leftStart = new Vector2();
private Vector2 leftEnd = new Vector2();
private Vector2 topStart = new Vector2();
private Vector2 topEnd = new Vector2();
private Vector2 rightStart = new Vector2();
private Vector2 rightEnd = new Vector2();
private Vector2 bottomStart = new Vector2();
private Vector2 bottomEnd = new Vector2();
private Vector2 center = new Vector2();
private Circle ballBounds = new Circle();
// Pointers passed once during construction
private Ball ball;
private List<Brick> brickList;
private List<Score> scoreList;
/**
* Constructor requires that ball and brickList pointers are given.
* <p>
* Runs the updateBallBounds() method after assigning the parameters
*
*@param ball points to the ball to be used for the collision calculations
*@param brickList points to a list of brick objects to check against
*@param scoreList points to a list of score objects to track the score
*/
public Collider(Ball ball, List<Brick> brickList, List<Score> scoreList) {
this.ball = ball;
this.brickList = brickList;
updateBallBounds(this.ball, this.ballBounds);
}
/**
* Sets the position and radius of the bounding circle
* for the given ball with a rectangular shape in order
* to prepare it for bounds checking.
*
* @param ball The ball object to
* @param bounds The circle object that will store the bounds information
*/
private void updateBallBounds(Ball ball, Circle bounds) {
bounds.set((ball.ballRect.x + (ball.ballRect.width/2)), //Center x pos
(ball.ballRect.y + (ball.ballRect.height/2)), //Center y pos
(ball.ballRect.width/2)); //Radius of ball
}
/**
* Builds the start and end Vectors for each of the segments
* of the provided rectangle. Also builds the center Vector for
* the ball.
* <p>
* Used to prepare for finding which segments of the rectangle the
* ball is intersecting
*
* @param brickRect The rectangle to process the line segments from
*/
private setVectors(Rectangle brickRect) {
leftStart.set(brickRect.x, brickRect.y);
leftEnd.set(brickRect.x, brickRect.height);
topStart.set(brickRect.x, brickRect.height);
topEnd.set(brickRect.width, brickRect.height);
rightStart.set(Poyline(brickRect.width, brickRect.y);
rightEnd .set(brickRect.width, brickRect.height);
bottomStart.set(brickRect.x, brickRect.y);
bottomEnd.set(brickRect.width, brickRect.y);
center.set(ballBounds.x, ballBounds.y);
}
/**
* Finds bricks in the list that the ball is currently
* colliding with.
* <p>
* For every rectangle that the ball is currently colliding with,
* the method calls the setVectors() method to prepare the start-end
* vertices for the processCollision() method.
* <p>
* WARNING: this may not handle multiple collision very well. It
* should work, but you most likely will not give very good results
* on multiple brick hit detected. You should think about including
* a break statement after the first collision is detected and let
* the Collider find an additional collision during the next render()
* call.
*/
public void detectCollisions() {
updateBallBounds(ball, ballBounds);
for (brick: brickList) {
if(Intersector.overlaps(ballBounds, brick.brickRect)) {
setVectors(brick.brickRect);
processCollision(brick, brick.brickRect);
//break;
}
}
}
/**
* Detects how to handle the collision based on the segments being hit.
*
*@param brick the brick found by detectCollision() method. will be
* destroyed after collision is processed
*/
public void processCollision(Brick brick) {
if (Intersector.intersectSegmentCircle(topStart, topEnd,
center * center,
ballBounds.radius) ||
Intersector.intersectSegmentCircle(bottomStart, bottomEnd,
center * center,
ballBounds.radius)) {
vertical = true;
}
if (Intersector.intersectSegmentCircle(leftStart, leftEnd,
center * center,
ballBounds.radius) ||
Intersector.intersectSegmentCircle(rightStart, rightEnd,
center * center,
ballBounds.radius)) {
horizontal = true;
}
// The following could return the value to a calling entity.
// Then the game logic of what to do here would be decoupled.
if (vertical && horizontal) {
bounceType = "CORNER"
} else if (vertical && !horizontal) {
bounceType = "VERTICAL"
} else if() {
bounceType = "HORIZONTAL"
} else {
// The game blows up...
}
switch (bounceType) {
case "VERTICAL":
ball.ballSpeedY = -ball.ballSpeedY;
break;
case "HORIZONTAL":
ball.ballSpeedX = -ball.ballSpeedX;
break;
case "CORNER":
ball.ballSpeedY = -ball.ballSpeedY;
ball.ballSpeedX = -ball.ballSpeedX;
break;
default: // Try not to blow up the game...
break;
}
Score score = new Score(brick.getScore(), brick.x, brick.y)
scoreList.add(score);
brickList.remove(brick);
brick.destroy();
}
}
Я уверен, что есть ошибки здесь, она не тестировалась. В дополнение к предыдущим предположениям, это не останавливает выделение кирпича в вашем массиве (если только destroy() не позаботится об этом и, надеюсь, не ищет нулевые значения, поскольку он отображает ...).
Базовая структура может быть лучше ...
- С некоторым исключением, попробуйте поймать вещи.
- Вы можете добавить больше типизированных конструкторов и методов для покрытия большего количества фигур.
- Пространственное разделение может быть добавлено методом сопоставления статических границ на . Затем ваши динамические объекты могут регистрировать разделы, которые они занимают в настоящее время, и выполняют только результаты коллизии запросов для других объектов , зарегистрированных в этих списках разделов.
- Я утверждаю, что реализация этого класса должна быть развязана и обработана где-то в другом месте.
- Это также позволит создать класс столкновения или событие, которое будет возвращено/вызвано.
Надеюсь, что это помогло.
Я также рекомендую вам изучить Box2D. Ваши требования кажутся достаточно простыми для удобного обучения при его использовании. This page может показать вам, как он настроен и используется с LibGDX.Это позволит вам быстро реализовать свойства материала на объектах, вращаться на шаре, изменения скорости, угловые подборов ..., все виды доброты с автоматикой, которые сэкономит ваш мозг на несколько циклов. Физический движок делает для вас всю математику. Вы просто инициализируете и выполняете его, слушая события (например, столкновения).
Удачи вам в игре.
Я бы проверял один за другим, если углы шара сталкиваются с кирпичом. Тогда, основываясь на этом, я бы уточнил, куда должен идти мяч. Я также проверил бы столкновение ВСЕХ кирпичей, которые пересекаются, прежде чем заставить мяч спрыгнуть. Это предотвратит переход мяча в более странное направление при ударе более 1 кирпича. Проблема с этими методами заключается в том, что она не будет работать, если мяч будет быстрым (но тот, который у вас есть, тоже не будет). – Zelenova
Это проблема, которая у меня есть. Выяснение того, как проверить. Я пробовал кучу разных методов, которые не работают правильно. Я понимаю принцип этого. Это просто код. – Bassex
Я не уверен, как работают прямоугольники в java, но в принципе, чтобы проверить, находится ли точка внутри прямоугольника, вы должны: 'boolean colliding = ((point.x> rect.x && point.x rect.y && point.y
Zelenova