Pull to refresh

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

Reading time 4 min
Views 55K
Всем привет.
Сегодня я расскажу вам как с помощью AndEngine написать небольшую игру. Стаья получилась довольно большая и, чтобы не утомлять читателя, пока мы остановимся на первой ее части. Все что нужно от читателя — это знание java, ООП и умение обращаться с Eclipse и Android SDK. Забегая вперед, у нас получится что то похожее на Mirrors Maze либо Laser Logic.
Вторая часть статьи.
Третья часть статьи.

Как устанавливать Eclipse, Android SDK, создавать проекты и подключать библиотеки я не буду, так что сразу перейдем к делу.

Шаг 1: На любителя. Можно скачать исходники AndEngine и подключить к проекту как Android библиотеку. Либо взять из примеров уже готовый .jar. В обоих случаях вам понадобится Mercurial, на нем мы тоже не будем останавливаться.
Шаг 2: Проект создан, все библиотеки подключены. Теперь нам нужны изображения. Сздаем в проекте папку:

assets/gfx

Ну или кому как нравится и кидаем туда 2 изображения. Одно фоновое и наш лазер.
Больше никаких изображений не требуется. Пока.
Шаг 3: Ну и раз уж мы начали с изображений то напишем небольшой класс который будем нам их инициализировать.
public class Textures {
  
  private Texture mTexture;
  private TextureRegion mLaserGunTextureRegion, mBackgroundTextureRegion;
  
  public Textures(final BaseGameActivity activity, final Engine engine) {
    Log.i("Laser Logic", "onLoadResources");
    this.mTexture = new Texture(1024, 512,
        TextureOptions.BILINEAR_PREMULTIPLYALPHA);
    this.mLaserGunTextureRegion = TextureRegionFactory.createFromAsset(
        this.mTexture, activity, "gfx/laser_gun.png", 800, 0);
    this.mBackgroundTextureRegion = TextureRegionFactory.createFromAsset(
        this.mTexture, activity, "gfx/laser_logic_background.png", 0, 0);
    engine.getTextureManager().loadTexture(this.mTexture);
  }
  
  public TextureRegion getBackground(){
    return mBackgroundTextureRegion;
  }
  
  public TextureRegion getLaserGun(){
    return mLaserGunTextureRegion;
  }

}


* This source code was highlighted with Source Code Highlighter.


Что вообще происходит в этом коде? Для начала мы создаем mTexture, это будет наш атлас. Очень важно чтоб его размеры были кратны степеням двойки, так как OpenGL не понимает другие размеры текстур. Дальше мы добавляем на наш атлас изображения. И внимательно следим за тем чтобы они не пересекались. Для нашего лазера очень важен прозрачный фон, так что для него в любом случае мы используем PNG. А для background'a не принципиально в каком формате его хранить. Ну и после всех манипуляций вызываем метод loadTexture() после чего мы можем использовать наш атлас.

Шаг 4: Текстуры мы загрузили, теперь посмотрим что у нас получилось.

public class StageActivity extends BaseGameActivity {

  private static final int CAMERA_WIDTH = 800;
  private static final int CAMERA_HEIGHT = 480;
  private static final int NUMBER_OF_LAYERS = 2;

  private Camera mCamera;
  private Textures mTextures;

  @Override
  public void onLoadComplete() {}

  @Override
  public Engine onLoadEngine() {
    this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
    final EngineOptions options = new EngineOptions(true,
        ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(
            getScreenResolutionRatio()), this.mCamera);
    return new Engine(options);
  }

  @Override
  public void onLoadResources() {
    mTextures = new Textures(this, getEngine());
  }

  @Override
  public Scene onLoadScene() {
    Ln.i("OnLoadScene");
    this.mEngine.registerUpdateHandler(new FPSLogger());

    final Scene scene = new Scene(NUMBER_OF_LAYERS);
    scene.setBackground(new SpriteBackground(new Sprite(0, 0, mTextures
        .getBackground())));
    scene.getFirstChild().attachChild(new Sprite(0, 0, mTextures.getLaserGun()));
    return scene;
  }

  private float getScreenResolutionRatio() {
    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    return ((float) dm.widthPixels) / ((float) dm.heightPixels);
  }

}


* This source code was highlighted with Source Code Highlighter.

Это наше главное Activity, надеюсь не нужно объяснять что это, которое мы без промедления должны унаследовать от BaseGameActivity, иначе у нас ничего не выйдет. После этого IDE нам предложит переопределить 4 метода. Вызываются которые в порядке onLoadEngine->onLoadResources->onLoadScene->onLoadComplete. Начнем с начала цепочки здесь мы инициализируем камеру и сам движок. Особое внимание хочу обратить на метод getScreenResolutionRatio(). Благодаря ему получившаяся у нас картинка будет растягиваться на весь экран. При этом пропорции не будут соблюдаться. Либо можем оставить пропорции камеры и тогда наша игра не будет занимать весь экран на некоторых устройствах. Есть конечно и третий вариант — писать инициализацию для всех размеров экранов, но мы этого, естественно, не будем делать сейчас.

Далее, загружаем наши текстуры, которые потом используем в onLoadScene. FPSLogger — будет выводить фреймрейт в логи. А странная конструкция scene.getFirstChild() вернет нам ссылку на верхний слой нашей сцены. Мы конечно можем обойтись и без верхнего слоя добавляя объекты прямо в сцену, но знать на какой слой добавляеш объект все же удобнее.
Теперь мы можем увидеть что у нас получилось.


Для первой части достаточно. Код проекта вы можете найти на SourceForge.
Спасибо за внимание.
Tags:
Hubs:
+48
Comments 31
Comments Comments 31

Articles