avatar

Пишем игру под Android: Часть 2 - Создаем первый спрайт

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

Спрайт является частично прозрачным 2D растровым изображением, которое обычно помещается на фоновое изображение. Спрайты используются в видео-играх. Обычно существует более одного спрайта на экране в одно и то же время. Они могут представлять ИИ (искусственный интеллект) или главного героя которого контролирует игрок.

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



Сделать похожий спрайт можно здесь. Сайт сам по себе корейский, но то не беда, Google переведет все :)

Рисуем спрайт на сцене


Растровое изображение создано, и нам нужно вставить его в наш проект. Создаем класс Sprite.java

Пишем в него вот такую красоту:

Sprite.java
import android.graphics.Bitmap;
import android.graphics.Canvas;
 
public class Sprite 
{
    /**Объект класса GameView*/
    private GameView gameView;
    
    /**Картинка*/
    private Bitmap bmp;
    
    /**Позиция по Х=0*/
    private int x = 5;
    
    /**Скорость по Х=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;
       }
 
       /**Перемещение объекта, его направление*/
       private void update() 
       {
             if (x > gameView.getWidth() - bmp.getWidth() - xSpeed) {
                    xSpeed = -5;
             }
             if (x + xSpeed< 0) {
                    xSpeed = 5;
             }
             x = x + xSpeed;
       }

      /**Рисуем наши спрайты*/
       public void onDraw(Canvas canvas) 
       {
             update();
             canvas.drawBitmap(bmp, x , 10, null);
       }
}  


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

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

Bitmap используем для рисования на холсте.

Открываем наш GameView.java выделяем старый код, удаляем (потому что я изменил сам класс приходится переделывать и Вам) и пишем следующий код:

GameView.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
public class GameView extends SurfaceView 
{
	private Bitmap bmp;
    private SurfaceHolder holder;
    private GameManager gameLoopThread;
    private Sprite sprite;
   
     /**Загружаем спрайт*/
     private Bitmap bmp;
	
    /**Поле рисования*/
    private SurfaceHolder holder;
    
    /**объект класса GameView*/
    private GameView gameLoopThread;
    
    /**Объект класса Sprite*/
    private Sprite sprite;
   
    /**Конструктор*/
    public GameView(Context context) 
    {
          super(context);
          gameLoopThread = new GameView(this);
          holder = getHolder();
          
          /*Рисуем все наши объекты и все все все*/
          holder.addCallback(new SurfaceHolder.Callback() 
          {
        	  	/*** Уничтожение области рисования */
                 public void surfaceDestroyed(SurfaceHolder holder) 
                 {
                        boolean retry = true;
                        gameLoopThread.setRunning(false);
                        while (retry) 
                        {
                               try 
                               {
                                     gameLoopThread.join();
                                     retry = false;
                               } catch (InterruptedException e) 
                               {
                               }
                        }
                 }

                 /** Создание области рисования */
                 public void surfaceCreated(SurfaceHolder holder) 
                 {
                        gameLoopThread.setRunning(true);
                        gameLoopThread.start();
                 }

                 /** Изменение области рисования */
                 public void surfaceChanged(SurfaceHolder holder, int format,
                               int width, int height) 
                 {
                 }
          });
          bmp = BitmapFactory.decodeResource(getResources(), R.drawable.bad1);
          sprite = new Sprite(this,bmp);
    }

    /**Функция рисующая все спрайты и фон*/
    protected void onDraw(Canvas canvas) 
    {
          canvas.drawColor(Color.BLACK);
          sprite.onDraw(canvas);
    }
}


Если сделали все правильно то у Вас должно получиться что то похожее на это:


Превращаем спрайт в анимацию


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

Добавляем вот эти переменные в Sprite.java
/**Рядков в спрайте = 4*/
       private static final int BMP_ROWS = 4;
       
       /**Колонок в спрайте = 3*/
       private static final int BMP_COLUMNS = 3;


Обновляем метод update():

Sprite.java
private void update() 
      {
             if (x > gameView.getWidth() - width - xSpeed) {
                    xSpeed = -5;
             }
             if (x + xSpeed < 0) {
                    xSpeed = 5;
             }
             x = x + xSpeed;
             currentFrame = ++currentFrame % BMP_COLUMNS;
       }


Обновляем метод onDraw():

Sprite.java
public void onDraw(Canvas canvas) 
      {
             update();
             int srcX = currentFrame * width;
             int srcY = 1 * 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);
       }


И обновляем конструктор:

public Sprite(GameView gameView, Bitmap bmp) 
       {
             this.gameView = gameView;
             this.bmp = bmp;
             this.width = bmp.getWidth() / BMP_COLUMNS;
             this.height = bmp.getHeight() / BMP_ROWS;
       }


В конструкторе мы рассчитываем ширину и высоту спрайта. В методе update() фиксируем границы и добавляем текущие изменения значения кадра. В текущем кадре может быть только значения 0, 1 или 2.

В методе OnDraw() мы используем метод canvas.drawBitmap (BMP, SRC, DST, NULL);

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

По традиции рекламирую свой блог :) Заходим не стесняемся
0 комментариев RSS
Нет комментариев
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.