Опубликован: 07.11.2006 | Уровень: специалист | Доступ: свободно
Лекция 8:

Обнаружение коллизий

  1. Это не слишком годится для достижения преследуемых нами целей, поэтому мы применим _root. Добавьте следующую новую строку в функцию move.
    function move() {
        this._x += this.velX;
        this._y += this.velY;
        if (this._x>right-(this._width/2)) {
        playerBounds = player_mc.getBounds(_root);

    Теперь playerBounds будет содержать четыре параметра, упомянутые ранее. Параметры, которые нас больше всего интересуют - это yMin и yMax. Если ball_mc._y находится между этими двумя значениями после передачи им точки, определенной выражением right-(this._width/2), то он ударяется о ракетку игрока.


  2. Добавим другое условное выражение с использованием логического оператора AND (&&). Имейте в виду, что при этом также учитывается ширина шарика, поэтому мы реализуем проверку не только относительно центра шарика. Таким образом, мы получим гораздо более реалистичный удар.
    function move() {
        this._x += this.velX;
        this._y += this.velY;
        if (this._x>right-(this._width/2)) {
          playerBounds = player_mc.getBounds(_root);
          upper = playerBounds.yMin - this._height/2;
          lower = playerBounds.yMax + this._height/2;
          if (this._y>upper && this._y<lower) {
            this.velX *= -1;
            this.velY += Math.random()*20 - 10;
            this._x = right-(this._width/2);
          }
        }
      }
  3. Внутри блока кода мы также добавим некоторую степень случайности фактора velY. В противном случае шарик будет просто отскакивать вперед-назад под одними и теми же углами. Мы также немного увеличим скорость - всего лишь на один процент - чтобы немного усложнить игру. Имейте в виду, что мы должны увеличить как текущую скорость velX, так и baseSpeed, чтобы на следующей "подаче" скорость шарика возрастала.
    if (this._y>upper && this._y<lower) {
        this.velX *= -1;
        this.velY += Math.random()*20-10;
        this._x = right-(this._width/2);
        baseSpeed *= 1.01;
        this.velX *= 1.01;
      }
  4. Теперь мы знаем, что будет, если шарик попадет в ракетку, но нам нужно также решить, что будет, если шарик пройдет мимо нее. Мы будем возвращать шарик на середину экрана, изменять его скорость и направление случайным образом и увеличивать количество очков оппонента. Это реализовано в блоке else.
    function move() {
        this._x += this.velX;
        this._y += this.velY;
        if (this._x>right-(this._width/2)) {
          playerBounds = player_mc.getBounds(_root);
          if (this._y>playerBounds.yMin && this._y<playerBounds.yMax) {
            this.velX *= -1;
            this._x = right-(this._width/2);
        } else {
          this._x = 275;
          this._y = 200;
          this.velX = 0;
          this.velY = 0;
          pcScore++;
          playerServe = true;
        }
      }

    Здесь вы можете реализовать все, что вам придет в голову. Мне хватило и того, что я добавил динамическое текстовое поле слева вверху рабочего места с именем переменной pcScore.


  5. Окончательный код игры.
    init();
      function init() {
        RIGHT = 500;
        LEFT = 50;
        TOP = 50;
        BOTTOM = 350;
        ball_mc.velX = 0;
        ball_mc.velY = 0;
        ball_mc.onEnterFrame = move;
        pc_mc. onEnterFrame = pcMove;
        player_mc.onEnterFrame = playerMove;
        Key.addListener(_root);
        _root.onKeyDown = serve;
        pcServe = true;
        baseSpeed = 10;
      }
      function move() {
        this._x += this.velX;
        this._y += this.velY;
        if (this._x>right-(this._width/2)) {
          playerBounds = player_mc.getBounds(_root);
          upper = playerBounds.yMin-this._height/2;
          lower = playerBounds.yMax+this._height/2;
          if (this._y>upper && this._y<lower) {
            this.velX *= -1;
            this.velY += Math.random()*20-10;
            this._x = right-(this._width/2);
            baseSpeed *= 1.01;
            this.velX *= 1.01;
          } else {
            this._x = 275;
            this._y = 200;
            this.velX = 0;
            this.velY = 0;
            pcScore++;
            playerServe = true;
          }
        }
        if (this._x<left+(this._width/2)) {
          pcBounds = pc_mc.getBounds (_root);
          if (this._y>pcBounds.yMin-this._height/2 &&
            Кthis._y<pcBounds.yMax+this._height/2) {
            this.velX *= -1;
            this.velY += Math.random()*20-10;
            this._x = left+(this._width/2);
            baseSpeed *= 1.01;
            this.velX *= 1.01;
          } else {
            this._x = 275;
            this._y = 200;
            this.velX = 0;
            this.velY = 0;
            playerScore++;
            pcServe = true;
          }
        }
        if (this._y>bottom-(this._height/2)) {
          this.velY *= -1;
          this._y = bottom-(this._height/2);
        }
        if (this._y<top+(this._height/2)) {
          this.velY *= -1;
          this._y = top+(this._height/2);
        }
      }
      function pcMove() {
        if (ball_mc.velX<0) {
          this._y += (ball_mc._y-this._y)/5;
        }
        if (this._y>bottom-this._height/2) {
          this._y = bottom-this._height/2;
          this.vy = 0;
        }
        if (this._y<top+this._height/2) {
          this._y = top+this._height/2;
          this.vy = 0;
        }
      }
      function playerMove() {
        if (Key.isDown(Key.UP)) {
          this._y -= 10;
        } else if (Key.isDown(Key.DOWN)) {
          this._y += 10;
        }
        if (this._y>bottom-this._height/2) {
          this._y = bottom-this._height/2;
          this.vy = 0;
        }
        if (this._y<top+this._height/2) {
          this._y = top+this._height/2;
          this.vy = 0;
        }
      }
      function serve() {
        if (Key.getCode() == Key. SPACE) {
          if (playerServe) {
            ball_mc.velX = -baseSpeed;
            ball_mc. velY = Math.random()*20-10;
            playerServe = false;
          } else if (pcServe) {
            ball_mc.velX = baseSpeed;
            ball_mc. vel Y = Math.random()*20-10;
            pcServe = false;
          }
        }
      }
    Пример 7.3.

    Я продублировал рассмотренные шаги для проверки попадания в другую ракетку, а также реализовал отображение очков игрока в динамическом текстовом поле с именем переменной playerScore. Теперь вы можете и поиграть.

    Можете смело экспериментировать с этой игрой. В коде на диске есть несколько дополнений, однако вы сами можете создать очень много интересного.

Игорь Хан
Игорь Хан
След не остается
Александр Коргапольцев
Александр Коргапольцев
Вопрос по содержанию лекции №2, курс Flash MX Studio
Евгения Новоселецкая
Евгения Новоселецкая
Россия
Станислав Бакулин
Станислав Бакулин
Эстония, Нарва