html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Пишем игру для Android c помощью AndEngine. Часть 4

Привет всем!

Четвертая чать обещает быть очень интересной. В ней я собираюсь рассмотреть создание лазерных пушек, зеркал и отражений. Перед прочтением ознакомьтесь с предыдущими частями.

Часть 1.
Часть 2.
Часть 3.

Интересно?

Шаг 1. Ограничения.
Начнем немного из далека. Как все знают идеальный лазер движется со скоростью света и если не его пути нет препятствий врядли он когда либо остановится. Наш LaserLine не будет идеальным и первое что нужно сделать, это не дать ему возможности «улететь» за пределы игрового поля. Для этого добавим в класс GameObjectsMap метод:
public static boolean outOfArea(Point pos) {
  return pos.x < 0 || pos.y < 0 || pos.x > WIDTH - 1
      || pos.y > HEIGHT - 1;
}


* This source code was highlighted with Source Code Highlighter.

Будем проверять положения лазера этим методом при его построении.
Шаг 2. LaserGun.
Надеюсь все помнят вторую часть статьи, где помимо класса лазера у нас был класс лазерной пушки которая могла поворачиваться и препятствовать движению лазера. Добавим к ней поле:

private LaserLine mLaserLine;

В конструктор добавим:

mLaserLine = new LaserLine(new Point(posX, posY), angle);

В attachTo метод добавим:

scene.getChild(GameObjectsMap.LASER_LAYER).attachChild(mLaserLine);

Ну вот теперь у нашей пушки есть лазер, вот только его не видно. Чтоб его видеть нужно задать ему последовательность точек через которые он будет проходить. Для этого в классе LaserGun напишем метод:
public void buildLaser(GameObject[][] map) {
  mLaserLine.setAngle(getAngle());
  mLaserLine.build(map);
}


* This source code was highlighted with Source Code Highlighter.


Здесь на первый взгляд все понятно, путь лазера зависит от первоначального направления и от объектов на его пути, как раз для этого нам и понадобилась карта. Но метода LaserLine.build() еще не существует. Займемся им.
public void build(GameObject[][] map) {
  sBuilder.buildPath(this, map);
  buildLines();
}


* This source code was highlighted with Source Code Highlighter.

Метод короткий но про sBuilder я еще не рассказывал. Там то и скрыта магия. Не забываем добавить в класс LaserLine:

private static LaserLineBuilder sBuilder = new LaserLineBuilder();

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

Шаг 3. LaserBuilder
Пришло время показать как выглядит построение лазера:
public class LaserLineBuilder {

  private static final int MAX_STEPS = 200;

  public void buildPath(LaserLine laserLine, GameObject[][] map) {
    laserLine.clearPoints();
    int step = 0;
    int angle = laserLine.getAngle();
    Point position = new Point(laserLine.getStartPosition());
    GameObject gameObject;
    while (step < MAX_STEPS) {
      nextPosition(position, angle);
      if (GameObjectsMap.outOfArea(position)) {
        laserLine.addPoint(position);
        return;
      }
      gameObject = map[position.x][position.y];
      if (gameObject == null) {
        continue;
      } else {
        laserLine.addPoint(position);
        int reflection = gameObject.onLaser(angle);
        if (reflection < 0) {
          return;
        } else {
          angle = reflection;
        }
      }
    }
    laserLine.addPoint(position);
  }

  private void nextPosition(Point position, final int angle) {
    switch (angle) {
    case DynamicGameObject.DEG_0:
      position.x++;
      break;
    case DynamicGameObject.DEG_90:
      position.y++;
      break;
    case DynamicGameObject.DEG_180:
      position.x--;
      break;
    case DynamicGameObject.DEG_270:
      position.y--;
      break;
    case DynamicGameObject.DEG_45:
      position.x++;
      position.y++;
      break;
    case DynamicGameObject.DEG_135:
      position.x--;
      position.y++;
      break;
    case DynamicGameObject.DEG_225:
      position.x--;
      position.y--;
      break;
    case DynamicGameObject.DEG_315:
      position.x++;
      position.y--;
      break;
    default:
      break;
    }
  }
}


* This source code was highlighted with Source Code Highlighter.

Идем по порядку. Ограничение на 200 шагов лазера думаю понятно зачем. Далее, первая точка лазера добавляется при создании и совпадает с координатами LaserGun, остальные же точки добавляются при выходе из игровой зоны, при остановке и при отражении. Замечу что изначально точки добавлялись по прохождению каждой клетки, в Mirrors Maze до сих пор так. Но там и не был использван AndEngine.
nextPosition, надеюсь, не нуждается в объяснении.

Шаг 4. Зеркало.
До сих пор у нас не было объектов позволяющих отражать лазеры. Теперь нам нужно сделать один такой, и проверить все ли работает как задуманно. Не забываем добавить нужных текстур.
public class Mirror extends DynamicGameObject {

  public Mirror(final int posX, final int posY, final int angle,
      final TextureRegion region) {
    super(posX, posY, angle, region);
  }

  @Override
  void attachTo(Scene scene) {
    scene.getChild(GameObjectsMap.GAME_OBJECTS_LAYER).attachChild(
        getSprite());
  }

  @Override
  int onLaser(int angle) {
    int a = getAngle() % 4;
    if (angle == (a + 1) % 8) return (a + 7) % 8;
    if (angle == (a + 7) % 8) return (a + 1) % 8;
    if (angle == (a + 3) % 8) return (a + 5) % 8;
    if (angle == (a + 5) % 8) return (a + 3) % 8;
    return -1;
  }

}


* This source code was highlighted with Source Code Highlighter.

Создать новый игровой объект очень просто. Обойдемся без спойлеров и я предоставлю заинтересованному читателю самому разобраться в том, как работает метод onLaser. Двустороннее зеркало готово. Осталось добавить его инициализацию в GameObjectsMap.
Шаг 4.Инициализация лазера.
После всех манипуляций метод add теперь выглядит так:
public void add(Type type, final int posH, final int posW, final int angle) {
    GameObject object = null;
    switch (type) {
    case lasergun:
      LaserGun l = new LaserGun(posH, posW, angle, mTextures
          .getLaserGun());
      mLaserGuns.add(l);
      object = l;
      break;
    case mirror:
      object = new Mirror(posH, posW, angle, mTextures.getMirror());
      break;
    case target:

      break;
    default:
      break;
    }
    mMap[posH][posW] = object;
  }


* This source code was highlighted with Source Code Highlighter.

Но мы не ограничлись добавлением зеркала, еще для более удобной работы и пушками нам понадобится:

private LinkedList mLaserGuns;
и
public void buildLasers() {
  for (LaserGun gun : mLaserGuns) {
    gun.buildLaser(mMap);
  }
}


* This source code was highlighted with Source Code Highlighter.

Ну вот теперь посмотрим что у нас получилось. Добавим с StageActivity код:
private void initMap() {
  mGameObjectsMap = new GameObjectsMap(mTextures);
  mGameObjectsMap.add(Type.lasergun, 0, 0, 3);
  mGameObjectsMap.add(Type.lasergun, 3, 2, 7);
  mGameObjectsMap.add(Type.lasergun, 3, 4, 4);
  mGameObjectsMap.add(Type.mirror, 3, 3, 3);
  mGameObjectsMap.addToScene(mEngine.getScene());
  mGameObjectsController = new GameObjectsController(mGameObjectsMap, this);
  final Scene scene = getEngine().getScene();
  mGameObjectsMap.buildLasers();
}


* This source code was highlighted with Source Code Highlighter.

В итоге мы увидим что то на пободие:
image

На сегодня достаточно. Спасибо за внимание. Буду рад вопросам, советам и предложениям.
Исходный код.
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

3

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • Chrono
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции