У меня больше логический / математический вопрос, нежели технический. Я надеюсь, что это нормально с сообществом StackOverflow. У меня есть простая игра для Android с использованием акселерометра, который рисует шар в SurfaceView. Работает почти нормально. За исключением поведения шаров иногда.
Мне удалось установить логику, которая всегда держит мяч в границах экрана. Всякий раз, когда телефон наклоняется в одну сторону, шар движется и в конце концов ударяется о край экрана, и он остается там. Все хорошо, пока здесь.
Однако, когда я решаю вернуть мяч и наклонить телефон в противоположном направлении, происходит огромная задержка, прежде чем мяч начинает двигаться назад. Мяч, кажется, застрял на некоторое время край, даже если телефон наклонен в противоположном направлении, и я ожидаю, что шар начнет двигаться сразу же в противоположном направлении.
Это вызвано тем, что даже если мяч нарисован на краю экрана во время начального наклона, фактическое положение шара (xPos или yPos) продолжает изменяться, поскольку акселерометр продолжает излучать значения, увеличивая и увеличивая разницу ,
В конце концов, когда я переворачиваю телефон обратно в противоположное положение, мне приходится ждать, пока эти значения положения акселерометра вернутся к краю экрана, и только тогда мяч начнет двигаться в противоположном направлении.
Это вызывает огромную задержку. Например, если телефон был наклонен вправо по оси X в течение 10 секунд, то, когда я наклоню телефон в противоположном направлении (влево) по оси X, произойдет задержка еще на 10 секунд, прежде чем мяч начнет двигаться назад.
Вот то, что я до сих пор использую в качестве логики обновления позиции шара:
public void onSensorChanged(SensorEvent sensorEvent){
if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
yAcc = sensorEvent.values[1];
xAcc = sensorEvent.values[2];
float frameTime = 0.666f;
xVel += (xAcc * frameTime); // V[fin] = V[ini] + a*t
yVel += (yAcc * frameTime);
//travelled distance
float xS = (xVel /2)* frameTime; // d = V[fin]*t * 0.5
float yS = (yVel /2)* frameTime;
//switch values
xPos = -xS;
yPos = -yS;
//balls stays in borders
if (xPos > xScreenSize) { //ball hits right screen edge
xPos = xScreenSize;
} else if (xPos < 0) { //ball hits left edge
xPos = 0;
}
if (yPos > yScreenSize) { //ball hits top edge
yPos = yScreenSize;
} else if (yPos < 0) { //ball hits bottom edge
yPos = 0;
}
}
}
Также, если понадобится больше разъяснений по проблеме, я могу попытаться предоставить gif, показывающий вам поведение мяча.
Сейчас я думаю о двух возможных решениях, однако я не смог их реализовать.
Один должен был создать переменную смещения для положения x и y на экране и отследить смещение, другой должен был как-то перезапустить испускаемые значения акселерометра до 0, когда это было необходимо, что в основном будет перекалибровать его каждый раз, когда мяч ударяется о край. Однако я не знаю, как это сделать, и я не уверен, возможно ли это вообще. Вся помощь приветствуется.