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: Часть 3 - Спрайтовая анимация, работа с несколькими спрайтами

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

  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: Фоновая музыка в игре

Если Вы прочли эти статьи, значит Вы можете продолжать дальше, начнем с первой части названия статьи.


Спрайтовая анимация

Открываем наш проект и пишем следующий код:

Sprite.java
import java.util.Random;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
 public class Sprite {
       /**Рядков в спрайте = 4*/
    private static final int BMP_ROWS = 4;
    
    /**Колонок в спрайте = 3*/
    private static final int BMP_COLUMNS = 3;
    
    /**Объект класса GameView*/
    private GameView gameView;
    
    /**Картинка*/
    private Bitmap bmp;
    
    /**Позиция по Х=0*/
    private int x = 5;
    
    /**Позиция по У=0*/
    private int y = 0;
    
    /**Скорость по Х=5*/
    private int xSpeed = 5;
    
    private int ySpeed = 5;
    
    /**Текущий кадр = 0*/
    private int currentFrame = 0;
    
    /**Ширина*/
    private int width;
    
    /**Ввыоста*/
    private int height;

    /**Конструктор*/
     public Sprite(GameView gameView, Bitmap bmp) 
     {
           this.gameView = gameView;
           this.bmp = bmp;
           this.width = bmp.getWidth() / BMP_COLUMNS;
           this.height = bmp.getHeight() / BMP_ROWS;
           
           Random rnd = new Random();
           xSpeed = rnd.nextInt(10)-5;
           ySpeed = rnd.nextInt(10)-5;
     }

     /**Перемещение объекта, его направление*/
     private void update() 
     {
         if (x >= gameView.getWidth() - width - xSpeed || x + xSpeed <= 0) 
         {
             xSpeed = -xSpeed;
         }
         
         x = x + xSpeed;
         
         if (y >= gameView.getHeight() - height - ySpeed || y + ySpeed <= 0) 
         {
             ySpeed = -ySpeed;
         }
         
         y = y + ySpeed;
         currentFrame = ++currentFrame % BMP_COLUMNS;
     }

     /**Рисуем наши спрайты*/
     public void onDraw(Canvas canvas) 
     {
         update();
         int srcX = currentFrame * width;
         int srcY = getAnimationRow() * height;
         Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
         Rect dst = new Rect(x, y, x + width, y + height);
         
         canvas.drawBitmap(bmp, src, dst, null);
     }
}


Наш спрайт содержит 4 анимации с 3 кадрами в каждой строке.

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

Нам нужна функция, которая получает в качестве параметров xSpeed ​​и ySpeed ​​и возвращает строку, которую мы будем использовать для создания анимации [0,1,2,3]

Мы собираемся использовать функцию Math.atan2(xSpeed​​, ySpeed​​) для расчета направления спрайтов во время выполнения функции.

atan2(х, у) дает угол радиана в double из (-PI до PI), но мы просто хотим получить результат в int — от 0 до 3, чтобы узнать, какую анимацию мы должны использовать.

Давайте рассмотрим следующий рисунок, я описываю координатами (х, у) каждое направление на спрайте, что у нас имеется: вверх (0, -1), вправо (1,0), вниз (0,1) и влево (0, -1).

Когда результат равен углу одного из заданных направлений спрайта мы будем использовать соответствующее движение — вверх, вправо, вниз или влево. Для этого я использую Math.round функции.

Хорошо, теперь самая сложная часть, я решил это с помощью этой функции и одной константы массива:

Sprite.java
// direction = 0 up, 1 left, 2 down, 3 right,
// animation = 3 up, 1 left, 0 down, 2 right
int[] DIRECTION_TO_ANIMATION_MAP = { 3, 1, 0, 2 };
 private int getAnimationRow() {
 double dirDouble = (Math.atan2(xSpeed, ySpeed) / (Math.PI / 2) + 2);
 int direction = (int) Math.round(dirDouble) % BMP_ROWS;
 return DIRECTION_TO_ANIMATION_MAP[direction];
}


Ниже я пытаюсь объяснить Вам, что я делаю в этой функции:

  1. с atan2(xSpeed​​, ySpeed​​) Я получаю радиан угла из (-PI до PI)
  2. Я делю угол PI / 2 и получаю вдвое больше по сравнению с (-2 до 2)
  3. Я добавляю 2 для изменения диапазона от (0 до 4)
  4. Я использую %, чтобы уменьшить диапазон (от 0 до 3) (0 и 4, были в том же направлении)
  5. Задаем на карте каждой строке — направление, к нужной анимации с использованием массива {3, 1, 0, 2}

Добавляем в конец класса Sprite.java код который я написал выше и переходим к следующей части названия статьи.

Работа с несколькими спрайтами


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

Для начал изменим наш главный класс рисования — GameView.java для внесения в него списка спрайтов. Добавим в начало класса:
private List<Sprite> sprites = new ArrayList<Sprite>();

Нам нужно скопировать все спрайты которые Вы создали в каталоге drawable, как мы делали с bad1.png во втором уроке. Затем мы создадим новый спрайт с каждым изображением.

GameView.java
sprites.add(createSprite(R.drawable.bad1));
sprites.add(createSprite(R.drawable.bad2));
sprites.add(createSprite(R.drawable.bad3));
sprites.add(createSprite(R.drawable.bad4));
sprites.add(createSprite(R.drawable.bad5));
sprites.add(createSprite(R.drawable.bad6));
sprites.add(createSprite(R.drawable.good1));
sprites.add(createSprite(R.drawable.good2));
sprites.add(createSprite(R.drawable.good3));
sprites.add(createSprite(R.drawable.good4));
sprites.add(createSprite(R.drawable.good5));
sprites.add(createSprite(R.drawable.good6));


Создаем новый метод который будет возвращать изображение спрайта:

GameView.java
private Sprite createSprite(int resouce) {
 Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
 return new Sprite(this,bmp);
}

и обновляем onDraw():

GameView.java
for(Sprite sprite : sprites) {
 sprite.onDraw(canvas);
}


Если мы запустим игру то увидим что все спрайты расползаются с одной точки, это наверно нужно исправить :) 


Добавляем простые две строчки в конструктор Sprite.java:

Sprite.java
x = rnd.nextInt(gameView.getWidth() - width);
y = rnd.nextInt(gameView.getHeight() - height);


Но если Вы сейчас запустите проект то получите сообщение об ошибке потому что width у нас равен 0. Если Вы помните, мы используем метод в surfaceCreated, который знает когда запущена сцена и когда можно рисовать. Для исправления проблемы нам нужно записать в surfaceCreated() метод создания спрайтов, т.е. createSprites();

GameView.java
public void surfaceCreated(SurfaceHolder holder) {
 createSprites();
 gameLoopThread.setRunning(true);
 gameLoopThread.start();
}


Все, проблема решена, игра работает. Запускаем и смотрим как человечки бегают по экрану :)

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

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

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

1

      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

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