Сталкивая формы и заставляя их отскакивать друг от друга - PullRequest
1 голос
/ 05 марта 2011

Я начинал учить себя, как работать с HTML5 Canvas, и решил научиться делать короткую игру / демонстрацию.

Я хотел, чтобы простые блоки отскакивали от экрана, отскакивали от стен,и отскакивать друг от друга.

Я застрял на том, чтобы заставить их отскакивать друг от друга.Кажется, что код, который заставляет его отскочить, заставляет его отскочить сразу после.Я вижу, где происходит сбой кода, но я не знаю, как это исправить :( Кто-нибудь может помочь?

(Дополнительный вопрос: я знаю, что я не работаю настолько чисто, эффективно / профессионально, насколько это возможно в этом примерено если бы я хотел улучшить с помощью обратной связи и мнений о «лучшем» методе для этого типа примера, такого как обзор кода или что-то, можно ли задать вопрос о stackoverflow?)

jsfiddle: http://jsfiddle.net/vdcSv/

HTML:

<canvas id="canvas" Width="400" Height="300"></canvas>

Javscript:

    function CheckBallCollision(BallsArray, index) {
        for (var i = 0; i < BallsArray.length; i++) {
            if (index != i) {
                if (BallsArray[index].Xdir == 1) {
                    if ((BallsArray[index].Xmax >= BallsArray[i].Xmin)) {
                        if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
                       ((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
                            BallsArray[index].Xdir = -BallsArray[index].Xdir;
                        }
                    }
                } else if (BallsArray[index].Xdir == -1) {
                    if ((BallsArray[index].Xmin <= BallsArray[i].Xmax)) {
                        if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
                       ((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
                            BallsArray[index].Xdir = -BallsArray[index].Xdir;
                        }
                    }
                }


            }
        }
    }

Объект Ball:

function Ball() {
    this.Xmin = 0;//top left X coord
    this.Ymin = 0;//top left y coord
    this.Height = 25; 
    this.Width = 25;
    this.Xmax = this.Xmin + this.Width;
    this.Ymax = this.Ymin + this.Height;
    this.Xdir = 0; // 0 not moving, 1 moving right, -1 moving left
    this.Ydir = 0;
    this.Red = 0;
    this.Green = 0;
    this.Blue = 200;
    this.Opacity = 1;
    this.Speed = 1;
}

Ответы [ 3 ]

1 голос
/ 05 марта 2011

Получилось, изменив <= на == </p>

Это грязно, и вещи часто пропускают необходимый отскок от блока :( Я уверен, что отчасти причина заключается в том, что вместо этого используется ==из <=. Если у кого-то есть лучшее решение - у меня все уши:) </p>

http://jsfiddle.net/vdcSv/1/

function CheckBallCollision(BallsArray, index) {
        for (var i = 0; i < BallsArray.length; i++) {
            if (index != i) {
                if (BallsArray[index].Xdir == 1) {
                    if ((BallsArray[index].Xmax == BallsArray[i].Xmin)) {
                        if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
                       ((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
                            BallsArray[index].Xdir = -BallsArray[index].Xdir;
                        }
                    }
                } else if (BallsArray[index].Xdir == -1) {
                    if ((BallsArray[index].Xmin == BallsArray[i].Xmax)) {
                        if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
                       ((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
                            BallsArray[index].Xdir = -BallsArray[index].Xdir;
                        }
                    }
                }

        }
    }
}
0 голосов
/ 25 июля 2013

Похоже, вы забыли проверить, если

BallsArray[index].Xmin <= BallsArray[i].Xmax)

Если вы добавите это в это работает. Также стоит отметить, что вам не нужен разный код для двух разных направлений X, так как это поведение симметрично. Независимо от того, в какую сторону он движется, у вас есть обратное направление. Это также симметрично в направлении Y, так что если вы просто добавите:

BallsArray[index].Ydir = -BallsArray[index].Ydir;

к «тогда» части if вам понадобится только одна, если вы позаботитесь обо всех четырех видах столкновений.

Вы также можете добавить оператор break, чтобы в случае одновременного столкновения шара с двумя другими шарами направление движения изменялось только один раз.

Для более реалистичной симуляции вы можете умножить на отрицательное число в интервале (0, 1), однако, если вы не сделаете что-то еще, ваша система будет медленно переходить в устойчивое состояние, пока не начнутся ошибки округления, и это уроды.

0 голосов
/ 24 июля 2013

Вот несколько фрагментов обнаружения попаданий, которые вы можете посмотреть:

ball.hitTestCircle = function(obj) {
    var dx = this.x - obj.x;
    var dy = this.y - obj.y;
    var distance = (dx * dx) + (dy * dy);

    var area = (this.radius + obj.radius)*(this.radius + obj.radius);
    return (area / distance);
};

, если вызов возвращает 1 или больше, если вы столкнулись, и вы даже можете использовать эту информацию, чтобы исправить разницу.

Вот базовый сценарий обнаружения попадания прямоугольника:

ball.hitTestRect = function(b) {
    var difference = {};
    difference.x = this.x - b.x - b.width;
    difference.y = this.y - b.y - b.height;
    difference.height = this.height + b.height;
    difference.width = this.width + b.width;

    if (difference.x < 0 && difference.y <= 0 && difference.height + difference.y >= 0 && difference.width + difference.x >= 0) return true;
    return false;
};

Я бы назвал любой из них что-то вроде:

for(var i=0;i!=balls.length;i++){
    for(var j=0;j!=balls.length;j++){
       if(j!=i){
           if(balls[i].hitTestRect(balls[j])){
               // all your reversing motion code
           }
       }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...