Autore Topic: [Facile] AndEngine: Sprite animato che si muove e rimbalza  (Letto 8384 volte)

Offline blackgin

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1387
  • Respect: +164
    • Google+
    • blackgins
    • blackginsoft
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Sistema operativo:
    Mac OSX 10.8
[Facile] AndEngine: Sprite animato che si muove e rimbalza
« il: 28 Aprile 2011, 14:10:01 CEST »
+3
Livello di difficoltà: facile
Target SDK: 4
Min SDK: 4
Link al file compresso del progetto eclipse: file in allegato

Con questo tutorial vedremo come fare muovere e rimbalzare uno sprite con AndEngine, senza usare un motore fisico esterno.

É necessario aver letto questo tutorial per potere capire anche il corrente.

Possiamo infatti partire direttamente da quel tutorial e fare le modifiche del caso.

Il codice java diventa
Codice (Java): [Seleziona]
package com.commabit.tutorialmovingsprite;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.physics.PhysicsHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;

public class TutorialMovingSprite extends BaseGameActivity {

    // ===========================================================
    // Costanti
    // ===========================================================

    private final int CAMERA_WIDTH = 480;

    private final int CAMERA_HEIGHT = 720;

    private final float VELOCITY = 150f;

    // ===========================================================
    // Membri
    // ===========================================================

    private Camera camera;

    private Texture faceTexture;

    private TiledTextureRegion faceTextureRegion;

    // ===========================================================
    // Metodi della classe madre
    // ===========================================================

    @Override
    public Engine onLoadEngine() {
        camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
        EngineOptions eo = new EngineOptions(true, ScreenOrientation.PORTRAIT,
                new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
        return new Engine(eo);
    }

    @Override
    public void onLoadResources() {
        faceTexture = new Texture(128, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

        /*
         * Inizializziamo l'oggetto faceTextureRegion che questa volta é istanza
         * della classe TiledTextureRegion. Passiamo al costruttore, oltre ai
         * soliti parametri, anche due interi che indicano in quante parti
         * dividere l'immagine in larghezza e altezza. Ogni parte sarà un frame
         * dell'animazione
         */

        faceTextureRegion = TextureRegionFactory.createTiledFromAsset(faceTexture, this,
                "gfx/face.png", 0, 0, 4, 1);
        mEngine.getTextureManager().loadTexture(faceTexture);
    }

    @Override
    public Scene onLoadScene() {
        Scene scene = new Scene(1);

        final int x = ((CAMERA_WIDTH - faceTextureRegion.getWidth()) / 2);
        final int y = ((CAMERA_HEIGHT - faceTextureRegion.getHeight()) / 2);

        /* Istanziamo face come oggetto dell classe Ball (che creiamo sotto) */
        final Ball face = new Ball(x, y, faceTextureRegion);

        /* Settiamo la velocità */
        face.setVelocity(VELOCITY, VELOCITY);

        scene.getLastChild().attachChild(face);

        return scene;
    }

    @Override
    public void onLoadComplete() {

    }

    // ===========================================================
    // Classi interne
    // ===========================================================

    /* Classe Ball che gestisce il movimento dello Sprite */
    private class Ball extends AnimatedSprite {
        private PhysicsHandler ballHandler;

        public Ball(float pX, float pY, TiledTextureRegion pTextureRegion) {
            super(pX, pY, pTextureRegion);
            /*
             * Inizializiamo il componente che si occupa di gestire la parte
             * fisica (velocità, accelerazione, etc)...
             */

            ballHandler = new PhysicsHandler(this);
            /* ...e gli diamo la gestione degli update */
            registerUpdateHandler(ballHandler);

            /*
             * Avviamo l'animazione impostando per quanti millisecondi verrà
             * visualizzato ogni frame della nostra animazione
             */

            animate(100);
        }

        /* Questo metodo viene chiamato ad ogni update */
        @Override
        protected void onManagedUpdate(final float pSecondsElapsed) {
            /*
             * Tramite questi if gestiamo il rimbalzo. Quando infatti lo sprite
             * si trova ai bordi dello schermo la velocità (su x o y) viene
             * invertita. Come vedete usiamo il PhysicsHandler.
             */

            if (this.mX < 0)
                ballHandler.setVelocityX(VELOCITY);
            else if (this.mX + this.getWidth() > CAMERA_WIDTH)
                ballHandler.setVelocityX(-VELOCITY);

            if (this.mY < 0)
                ballHandler.setVelocityY(VELOCITY);
            else if (this.mY + this.getHeight() > CAMERA_HEIGHT)
                ballHandler.setVelocityY(-VELOCITY);

            super.onManagedUpdate(pSecondsElapsed);
        }

        /* Metodo per potere settare la velocità anche dall'esterno */
        public void setVelocity(float vx, float vy) {
            ballHandler.setVelocity(vx, vy);
        }
    }
}

Come vedete la gestione della parte fisica é delegata alla classe PhysicsHandler. Questo non é altro che un semplice motore fisico presente direttamente dentro AndEngine. Ottimo per cose semplici, ma poco potente. In casi più complessi si usa Box2D che può essere incluso in AndEngine tramite apposita estensione.


[NB] Tutti i files usati li trovate nei sorgenti allegati. [/NB]
[NB2] Il tutorial appena presentato si basa su uno degli esempi ufficiali (in particolare MovingBallExample.java). In realtà però il sorgente originale contiene un errore. Vengono infatti creati due PhysicsHandler (uno dentro la classe Ball e uno all'esterno) che inevitabilmente vanno in conflitto, annullando di fatto l'effetto di rimbalzo.  [/NB2]

Bibliografia:
Qui trovate i sorgenti degli esempi creati dallo sviluppatore di AndEngine.
Postate il LogCat LogCat LogCat LogCat LogCat

Offline Bartoloni

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Epad
Re:[Facile] AndEngine: Sprite animato che si muove e rimbalza
« Risposta #1 il: 08 Luglio 2012, 02:18:21 CEST »
0
Utilizzando l'ultima versione di andengine.jar (folder "libs") si presentano 2 errori: (dopo aver rimosso gli @override)

Description   Resource   Path   Location   Type
Cannot instantiate the type Texture   TutorialMovingSprite.java   /com.commabit.tutorialmovingsprite.TutorialMovingSprite/src/com/commabit/tutorialmovingsprite   line 53   Java Problem

Description   Resource   Path   Location   Type
The method createTiledFromAsset(Texture, TutorialMovingSprite, String, int, int, int, int) is undefined for the type TextureRegionFactory   TutorialMovingSprite.java   /com.commabit.tutorialmovingsprite.TutorialMovingSprite/src/com/commabit/tutorialmovingsprite   line 62   Java Problem

la linea 53 e':
        faceTexture = new Texture (128, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
e la linea 62 e':
        faceTextureRegion = TextureRegionFactory.createTiledFromAsset(faceTexture, this,

come si puo' ovviare al problema? grazie in anticipo :)

Zate

  • Visitatore
Re:[Facile] AndEngine: Sprite animato che si muove e rimbalza
« Risposta #2 il: 08 Luglio 2012, 12:11:48 CEST »
0
Con le ultime versioni di AndEngine Texture è diventata BitmapTextureAtlas e TextureRegionFactory è diventata BitmapTextureAtlasTextureRegionFactory. Prova a vedere se funziona.
Codice (Java): [Seleziona]
package com.commabit.tutorialmovingsprite;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.physics.PhysicsHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;

public class TutorialMovingSprite extends BaseGameActivity {

    // ===========================================================
    // Costanti
    // ===========================================================

    private final int CAMERA_WIDTH = 480;

    private final int CAMERA_HEIGHT = 720;

    private final float VELOCITY = 150f;

    // ===========================================================
    // Membri
    // ===========================================================

    private Camera camera;

    private BitmapTextureAtlas faceTexture;

    private TiledTextureRegion faceTextureRegion;

    // ===========================================================
    // Metodi della classe madre
    // ===========================================================

    @Override
    public Engine onLoadEngine() {
        camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
        EngineOptions eo = new EngineOptions(true, ScreenOrientation.PORTRAIT,
                new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
        return new Engine(eo);
    }

    @Override
    public void onLoadResources() {
        faceTexture = new BitmapTextureAtlas(128, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

        /*
         * Inizializziamo l'oggetto faceTextureRegion che questa volta é istanza
         * della classe TiledTextureRegion. Passiamo al costruttore, oltre ai
         * soliti parametri, anche due interi che indicano in quante parti
         * dividere l'immagine in larghezza e altezza. Ogni parte sarà un frame
         * dell'animazione
         */

        faceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(faceTexture, this,
                "gfx/face.png", 0, 0, 4, 1);
        mEngine.getTextureManager().loadTexture(faceTexture);
    }

    @Override
    public Scene onLoadScene() {
        Scene scene = new Scene(1);

        final int x = ((CAMERA_WIDTH - faceTextureRegion.getWidth()) / 2);
        final int y = ((CAMERA_HEIGHT - faceTextureRegion.getHeight()) / 2);

        /* Istanziamo face come oggetto dell classe Ball (che creiamo sotto) */
        final Ball face = new Ball(x, y, faceTextureRegion);

        /* Settiamo la velocità */
        face.setVelocity(VELOCITY, VELOCITY);

        scene.getLastChild().attachChild(face);

        return scene;
    }

    @Override
    public void onLoadComplete() {

    }

    // ===========================================================
    // Classi interne
    // ===========================================================

    /* Classe Ball che gestisce il movimento dello Sprite */
    private class Ball extends AnimatedSprite {
        private PhysicsHandler ballHandler;

        public Ball(float pX, float pY, TiledTextureRegion pTextureRegion) {
            super(pX, pY, pTextureRegion);
            /*
             * Inizializiamo il componente che si occupa di gestire la parte
             * fisica (velocità, accelerazione, etc)...
             */

            ballHandler = new PhysicsHandler(this);
            /* ...e gli diamo la gestione degli update */
            registerUpdateHandler(ballHandler);

            /*
             * Avviamo l'animazione impostando per quanti millisecondi verrà
             * visualizzato ogni frame della nostra animazione
             */

            animate(100);
        }

        /* Questo metodo viene chiamato ad ogni update */
        @Override
        protected void onManagedUpdate(final float pSecondsElapsed) {
            /*
             * Tramite questi if gestiamo il rimbalzo. Quando infatti lo sprite
             * si trova ai bordi dello schermo la velocità (su x o y) viene
             * invertita. Come vedete usiamo il PhysicsHandler.
             */

            if (this.mX < 0)
                ballHandler.setVelocityX(VELOCITY);
            else if (this.mX + this.getWidth() > CAMERA_WIDTH)
                ballHandler.setVelocityX(-VELOCITY);

            if (this.mY < 0)
                ballHandler.setVelocityY(VELOCITY);
            else if (this.mY + this.getHeight() > CAMERA_HEIGHT)
                ballHandler.setVelocityY(-VELOCITY);

            super.onManagedUpdate(pSecondsElapsed);
        }

        /* Metodo per potere settare la velocità anche dall'esterno */
        public void setVelocity(float vx, float vy) {
            ballHandler.setVelocity(vx, vy);
        }
    }
}