• LibGDX详细介绍一


    Libgdx 是一个Java framework 提供了跨平台 API 的游戏开发框架. 你开发的游戏直接就可以在Android和桌面运行,不需要修改。当然你可能会觉得桌面的是个鸡肋。不过它对实时调试作用很大。

    下面我们通过Hello world的Demo进入底层看看LibGDX的整个生命周期:

    public class HelloWorldAndroid extends AndroidApplication {
        @Override
        public void onCreate (Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            initialize(new HelloWorld()false);
        }

     Android 的Hello World只有这么几行,重点在上面红色部分,具体实现在下面

      public class HelloWorld implements ApplicationListener { 

        SpriteBatch spriteBatch;
        Texture texture;
        BitmapFont font;
        Vector2 textPosition = new Vector2(100, 100);
        Vector2 textDirection = new Vector2(1, 1);

        @Override
        public void create () {
            font = new BitmapFont();
            font.setColor(Color.RED);
            texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));
            spriteBatch = new SpriteBatch();
        }

        @Override
        public void render () {
            int centerX = Gdx.graphics.getWidth() / 2;
            int centerY = Gdx.graphics.getHeight() / 2;

            Gdx.graphics.getGL10().glClear(GL10.GL_COLOR_BUFFER_BIT);

            // more fun but confusing :)
            
    // textPosition.add(textDirection.tmp().mul(Gdx.graphics.getDeltaTime()).mul(60));
            textPosition.x += textDirection.x * Gdx.graphics.getDeltaTime() * 60;
            textPosition.y += textDirection.y * Gdx.graphics.getDeltaTime() * 60;

            if (textPosition.x < 0) {
                textDirection.x = -textDirection.x;
                textPosition.x = 0;
            }
            if (textPosition.x > Gdx.graphics.getWidth()) {
                textDirection.x = -textDirection.x;
                textPosition.x = Gdx.graphics.getWidth();
            }
            if (textPosition.y < 0) {
                textDirection.y = -textDirection.y;
                textPosition.y = 0;
            }
            if (textPosition.y > Gdx.graphics.getHeight()) {
                textDirection.y = -textDirection.y;
                textPosition.y = Gdx.graphics.getHeight();
            }

            spriteBatch.begin();
            spriteBatch.setColor(Color.WHITE);
            spriteBatch.draw(texture, centerX - texture.getWidth() / 2, centerY - texture.getHeight() / 2, 0, 0, texture.getWidth(),
                texture.getHeight());
            font.draw(spriteBatch, "Hello World!", (int)textPosition.x, (int)textPosition.y);
            spriteBatch.end();
        }

        @Override
        public void resize (int width, int height) {
            spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
            textPosition.set(0, 0);
        }

        @Override
        public void pause () {

        }

        @Override
        public void resume () {

        }

        @Override
        public void dispose () {

        }

     若讲生命周期的话,这里我们只关心creat()和reader()是谁在调用。其他的先不用看。

    HelloWorldAndroid继承了AndroidApplication,并调用了它的initialize(new HelloWorld()false)方法

        public void initialize (ApplicationListener listener, boolean useGL2IfAvailable) {
            AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
            config.useGL20 = useGL2IfAvailable;
            initialize(listener, config);

        } 

     继续进入红色的部分往下看

    public void initialize (ApplicationListener listener, AndroidApplicationConfiguration config) {
            graphics = new AndroidGraphics(this, config, config.resolutionStrategy == null ? new FillResolutionStrategy()
                : config.resolutionStrategy);
            input = new AndroidInput(this, graphics.view, config);
            audio = new AndroidAudio(this);
            files = new AndroidFiles(this.getAssets());
            this.listener = listener;
            this.handler = new Handler();

            Gdx.app = this;
            Gdx.input = this.getInput();
            Gdx.audio = this.getAudio();
            Gdx.files = this.getFiles();
            Gdx.graphics = this.getGraphics();

            try {
                requestWindowFeature(Window.FEATURE_NO_TITLE);
            } catch (Exception ex) {
                log("AndroidApplication", "Content already displayed, cannot request FEATURE_NO_TITLE", ex);
            }
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            setContentView(graphics.getView(), createLayoutParams());
            createWakeLock(config);

        } 

     继续往下看,graphicsAndroidGraphics的实例,它的getView()方法返回一个GLSurfaceView在构造器里由createGLSurfaceView()初始化

    private View createGLSurfaceView (Activity activity, boolean useGL2, ResolutionStrategy resolutionStrategy) {
            EGLConfigChooser configChooser = getEglConfigChooser();

            if (useGL2 && checkGL20()) {
                GLSurfaceView20 view = new GLSurfaceView20(activity, resolutionStrategy);
                if (configChooser != null)
                    view.setEGLConfigChooser(configChooser);
                else
                    view.setEGLConfigChooser(config.r, config.g, config.b, config.a, config.depth, config.stencil);
                view.setRenderer(this);
                return view;
            } else {
                config.useGL20 = false;
                configChooser = getEglConfigChooser();
                if (Integer.parseInt(android.os.Build.VERSION.SDK) <= 4) {
                    GLSurfaceViewCupcake view = new GLSurfaceViewCupcake(activity, resolutionStrategy);
                    if (configChooser != null)
                        view.setEGLConfigChooser(configChooser);
                    else
                        view.setEGLConfigChooser(config.r, config.g, config.b, config.a, config.depth, config.stencil);
                    view.setRenderer(this);
                    return view;
                } else {
                    android.opengl.GLSurfaceView view = new DefaultGLSurfaceView(activity, resolutionStrategy);
                    if (configChooser != null)
                        view.setEGLConfigChooser(configChooser);
                    else
                        view.setEGLConfigChooser(config.r, config.g, config.b, config.a, config.depth, config.stencil);
                    view.setRenderer(this);
                    return view;
                }
            }

        } 

    注意这里的AndroidGraphics是实现了renderer接口的所以view.setRenderer(this),

    public void onSurfaceChanged (javax.microedition.khronos.opengles.GL10 gl, int width, int height) {
            this.width = width;
            this.height = height;
            updatePpi();
            gl.glViewport(0, 0, this.width, this.height);
            if (created == false) {
                app.listener.create();
                created = true;
                synchronized (this) {
                    running = true;
                }
            }
            app.listener.resize(width, height);

        } 

    这里就是调用了我们上面所说的creat(), 

    public void onSurfaceCreated (javax.microedition.khronos.opengles.GL10 gl, EGLConfig config) {
            setupGL(gl);
            logConfig(config);
            updatePpi();

            Mesh.invalidateAllMeshes(app);
            Texture.invalidateAllTextures(app);
            ShaderProgram.invalidateAllShaderPrograms(app);
            FrameBuffer.invalidateAllFrameBuffers(app);

            Gdx.app.log("AndroidGraphics", Mesh.getManagedStatus());
            Gdx.app.log("AndroidGraphics", Texture.getManagedStatus());
            Gdx.app.log("AndroidGraphics", ShaderProgram.getManagedStatus());
            Gdx.app.log("AndroidGraphics", FrameBuffer.getManagedStatus());

            Display display = app.getWindowManager().getDefaultDisplay();
            this.width = display.getWidth();
            this.height = display.getHeight();
            mean = new WindowedMean(5);
            this.lastFrameTime = System.nanoTime();

            gl.glViewport(0, 0, this.width, this.height);

        } 

     这里设置了Viewport,下面到重点中的重点了

    public void onDrawFrame (javax.microedition.khronos.opengles.GL10 gl) {
            long time = System.nanoTime();
            deltaTime = (time - lastFrameTime) / 1000000000.0f;
            lastFrameTime = time;
            mean.addValue(deltaTime);

            boolean lrunning = false;
            boolean lpause = false;
            boolean ldestroy = false;
            boolean lresume = false;

            synchronized (synch) {
                lrunning = running;
                lpause = pause;
                ldestroy = destroy;
                lresume = resume;

                if (resume) {
                    resume = false;
                }

                if (pause) {
                    pause = false;
                    synch.notifyAll();
                }

                if (destroy) {
                    destroy = false;
                    synch.notifyAll();
                }
            }

            if (lresume) {
                app.listener.resume();
                Gdx.app.log("AndroidGraphics", "resumed");
            }

            if (lrunning) {
                synchronized (app.runnables) {
                    for (int i = 0; i < app.runnables.size(); i++) {
                        app.runnables.get(i).run();
                    }
                    app.runnables.clear();
                }
                app.input.processEvents();
                app.listener.render();
            }

            if (lpause) {
                app.listener.pause();
                ((AndroidApplication)app).audio.pause();
                Gdx.app.log("AndroidGraphics", "paused");
            }

            if (ldestroy) {
                app.listener.dispose();
                ((AndroidApplication)app).audio.dispose();
                ((AndroidApplication)app).audio = null;
                Gdx.app.log("AndroidGraphics", "destroyed");
            }

            if (time - frameStart > 1000000000) {
                fps = frames;
                frames = 0;
                frameStart = time;
            }
            frames++;

        } 

     onDrawFrame是被系统不断自动调用的,它里面调用了我们上面所说的render(),这就是Hello World呈现在我们面前的整个步骤。

     这张图显示了整个生命周期:

     

  • 相关阅读:
    Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies
    Educational Codeforces Round 55 (Rated for Div. 2)
    Educational Codeforces Round 55 (Rated for Div. 2) A
    洛谷 P1061 Jam的计数法
    Codeforces Round #523 (Div. 2) B Views Matter
    Codeforces Round #523 (Div. 2) C Multiplicity (DP)
    2018.11.26 QLU新生赛部分题解
    动态规划:分组背包和有依赖的背包
    动态规划:二维费用背包
    动态规划:混合背包
  • 原文地址:https://www.cnblogs.com/shangdahao/p/2280454.html
Copyright © 2020-2023  润新知