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: Часть 4 - onTouchEvent и определение столкновений

Добрый день/вечер, в этой части мы будем рассматривать работу с сенсорным экраном и проверка столкновений координат касания пальца к экрану с координатами человечков (будем убивать наших славных ботов:)).

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

  1. Пишем игру под Android: Часть 1 — Рисуем картинки на SurfaceView
  2. Пишем игру под Android: Часть 2 — Создаем первый спрайт
  3. Пишем игру под Android: Часть 3 — Спрайтовая анимация, работа с несколькими спрайтами
  4. Пишем игру под Android: Часть 4 — onTouchEvent и определение столкновений
  5. Пишем игру под Android: Часть 5 — Создание полноценной 2D игры
  6. Пишем игру под Android: Часть 6: Добавление звука
  7. Пишем игру под Android: Часть 7: Меню для игры и окно приветствия
  8. Пишем игру под Android: Часть 8: Фоновая музыка в игре


Если Вы уже прочитали эти статьи то прошу под кат, там Вы узнаете много нового (надеюсь).


onTouchEvent() — событие касания к экрану


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

GameView.java
/**Обработка косания по экрану*/
public boolean onTouchEvent(MotionEvent event) {
     for (int i = sprites.size()-1; i >= 0; i--) 
     {
         Sprite sprite = sprites.get(i);
          if (sprite.isCollition(event.getX(),event.getY())) 
          {
                      sprites.remove(sprite);
          }
      }
    return super.onTouchEvent(event);
}


Теперь метод onDraw() рисует спрайт из списка, удаленные спрайты рисоваться не будут. Результат обработки события onTouchEvent() является как бы раздавливае персонажа своим пальцем :) Мы очень жестоки…

Определение столкновений


Чтобы заставить его работать, мы должны реализовать метод isCollition() в классе Sprite. Этот метод должен вернуть true, если (х, у) координаты указывают на нашего человечка.

Sprite.java
/**Проверка на столкновения*/
public boolean isCollition(float x2, float y2) {
      return x2 > x && x2 < x + width && y2 > y && y2 < y + height;
}


Если х2 не больше х, это означает, что касание было слева от спрайта. если х2 больше, чем х + width, это означает, что касание было — справа от спрайта. 

Если х2 > х & & 2 <х + width, что означает, что прикосновение в том же столбце, но все же мы должны проверить, если он находится в той же строке. у2> у & & 2 <у + height проверяет ряд столкновений таким же образом.

Запустим и глянем что происходит:


Как вы можете видеть при нажатии на человечка, которому соответствует координата касания на экране — удаляется . 

Ограничение по количеству кликов


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

GameView.java
for(int i = sprites.size()-1; i >= 0; i--) {
           Sprite sprite = sprites.get(i);
           if (sprite.isCollition(event.getX(),event.getY())) 
           {
                   sprites.remove(sprite);
                   break;
           }
}


Я забыл о синхронизации. События обрабатываются в потоке, не похожем на поток рисования и обновления. Это может привести к конфликту, если мы обновляем данные, которые были разработаны в одно и то же время. Решение довольно простое — обернуть весь код внутри onTouchEvent() с тем же объектом SurfaceHolder который мы использовали в классе GameManager. 

Вспомним что мы использовали для синхронизации цикла:

GameManager.java
canv = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
      view.onDraw(canv);
}


А теперь мы добавляем вместо старого кода в onTouchEvent():

GameView.java
synchronized (getHolder()) {
        for (int i = sprites.size()-1; i > 0; i--) 
        {
                Sprite sprite = sprites.get(i);
                if (sprite.isCollision(event.getX(),event.getY())) 
                {
                     sprites.remove(sprite);
                     break;
                }
        }
}

при помощи этого мы можем избежать ошибки, которая появляется и очень раздражает. :)

Если мы запустим его снова, и увидим что проблема все еще не устранена. На этот раз проблема не в потоке и не синхронизации, проблема в том что событие вызывается сильно быстро и нам его нужно ограничить. Создаем метод который будет ограничивать количество кликов в 300 миллисекунд, тогда эта ошибка исчезнет и человечки будут убиваться по одному раз в 300 мс. Добавляем чуть выше кода в onTouchEvent().

GameView.java
if (System.currentTimeMillis() - lastClick > 300) {
      lastClick = System.currentTimeMillis()
//скобочка закрывается перед return true; иф - охватывает весь метод


Теперь запустите его снова, и вы увидите разницу.

Исходные коды & Скачать с Git

Читать дальше
Twitter
Одноклассники
Мой Мир

материал с dajver.blogspot.ru

2

      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
          • домен blogspot.ru
          • домен dajver.blogspot.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

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