HTML5 усложнение разработки Canvas-игр - PullRequest
1 голос
/ 13 февраля 2012

Я создаю игру, используя HTML5 canvas.

Вы можете найти его здесь вместе с исходным кодом: www.techgoldmine.com .

Я бы сделал jsFiddle, но, честно говоря, мой объем внимания слишком мал (а я в основном слишком глуп), чтобы понять, как это работает.

В настоящее время я застрял в функции, которая смотрит на расположение определенных элементов по обе стороны холста и перемещает их так, чтобы область оси y, которую они покрывают, не перекрывалась. Я называю их турбинами, но тонкие белые прямоугольники были бы более точными. Я предлагаю несколько раз освежиться, чтобы визуально понять, что происходит.

Это функция, которая порождает турбины:

function gameStateNewLevel(){
    for (var i = 0; i < 4; i++){
        turbine = {};
        turbine.width = 10;
        turbine.height = 150;
        turbine.y = Math.floor(Math.random()*600)
        if (Math.random()*10 > 5){
            turbine.side = leftSide;
        }else{
            turbine.side = rightSide;
        }
        turbine.render  = function (){
            context.fillStyle = "#FFFFFF"
    context.fillRect(turbine.side, turbine.y, turbine.width,turbine.height);
        }
        turbine.PositionTop = turbine.y;
        turbine.PositionBottom = turbine.y + turbine.height;

        turbines.push(turbine);

    }
    context.fillStyle = "#FFFFFF"       
    switchGameState(GAME_STATE_PLAYER_START);

}  

Пока что я создал (с помощью вас, замечательных людей) функцию (которая является частью цикла), которая выбирает каждую из этих турбин и начинает сравнивать их друг с другом. Я совершенно озадачен, когда речь заходит о том, как заставить их двигаться и останавливаться при необходимости:

function updateTurbines(){
var l = turbines.length-1; 
    for (var i = 0; i < l; i++){
    var tempTurbine1 = turbines[i];
     tempTurbine1.PositionTop = tempTurbine1.y; 
     tempTurbine1.PositionBottom = tempTurbine1.y +    tempTurbine1.height;
     for (var j = 0; j < l; j++) { 
      var tempTurbine2 = turbines[j];
      tempTurbine2.PositionTop = tempTurbine2.y;
      tempTurbine2.PositionBottom = tempTurbine2.y + tempTurbine2.height;
      if ((tempTurbine1 !== tempTurbine2) && FIXME == true){
       if(tempTurbine1.PositionBottom >=    tempTurbine2.PositionTop){
                        turbines[j].y -=2;
                                            //A while loop breaks the browser :(

                    }

                }
            }FIXME = false;
        }
}

Любые идеи или просьбы о дополнительных объяснениях и информации приветствуются. У меня также есть чувство, что я слишком сильно усложняю это. Черт, моя голова болит. Будьте здоровы.

1 Ответ

0 голосов
/ 13 февраля 2012

Боюсь, ваш код немного запутан, но я решил начать с чистого листа.

  • Используйте методы получения / установки для bottom и right.Вы можете рассчитать их по значениям left / width и top / height соответственно.Это избавит вас от изменения дополнительной переменной right при изменении, например, left.
  • Вы, похоже, ищете алгоритм обнаружения столкновений для прямоугольников.Это довольно легко, если прямоугольники имеют одинаковую x-координату - два таких прямоугольника не сталкиваются, если нижняя часть первого находится над вершиной другого, или если верхняя часть первого находится поддно другого.Используйте этот алгоритм вместе с циклом while для генерации новой турбины, пока они сталкиваются.

Это то, что я закончил (это отдельный фрагмент кода, как я уже говорил, так что выпридется смешать это с вашей игрой): http://jsfiddle.net/eGjak/249/.

var ctx = $('#cv').get(0).getContext('2d');

var Turbine = function(left, top, width, height) {
    this.left = left;
    this.top = top;
    this.width = width;
    this.height = height;
};

Object.defineProperties(Turbine.prototype, {
    bottom: {
        get: function() {
            return this.top + this.height;
        },
        set: function(v) {
            this.top = v - this.height;
        }
    },
    right: {
        get: function() {
            return this.left + this.width;
        },
        set: function(v) {
            this.left = v - this.width;
        }
    }
});

var turbines = [];

function turbineCollides(tn) {
    for(var i = 0; i < turbines.length; i++) {
        var to = turbines[i];
        // they do not collide if if one's completely under
        // the other or completely above the other
        if(!(tn.bottom <= to.top || tn.top >= to.bottom)) {
            return true;
        }
    }

    return false; // this will only be executed if the `return true` part
                  // was never executed - so they the turbine does not collide
}

function addTurbine() {
    var t, h;

    do { // do while loop because the turbine has to be generated at least once

        h = Math.floor(Math.random() * 300);
        t = new Turbine(0, h, 15, 100);

    } while(turbineCollides(t));

    turbines.push(t);
}

// add two of them (do not add more than 4 because they will always collide
// due to the available space! In fact, there may be no space left even when
// you've added 2.)
addTurbine();
addTurbine();

function draw() {
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, 400, 400);
    ctx.fillStyle = "white";

    for(var i = 0; i < turbines.length; i++) {
        var turbine = turbines[i];
        ctx.fillRect(turbine.left, turbine.top,
                     turbine.width, turbine.height);
    }
}

draw();​
...