繁体   English   中英

AndEngine:添加Sprite时在UpdateThread上获取NullPointerException

[英]AndEngine: Getting a NullPointerException on UpdateThread when adding a Sprite

添加Sprite时在UpdateThread上获取NullPointerException

我正在AndEngine中创建我的第一个游戏,而我只是想向我的GameScene类添加一个Sprite。 由于应用程序在启动屏幕后一直崩溃,因此我已经花了几个小时来修改它,这本应在以后加载我的GameScene。 我将其范围缩小到我的drawPanel()方法中的代码:

selectPanel[0] = new Sprite(0, 0, resourceManager.ballTextureRegionArray[0], vbom) {
    @Override
    protected void preDraw(GLState pGLState, Camera pCamera) {
        super.preDraw(pGLState, pCamera);
        pGLState.enableDither();
    }
};
selectPanel[0].setPosition(240, 400);
attachChild(selectPanel[0]);

这是我的ResourceManager类,其中加载了球纹理:

    ballTexture = new BitmapTextureAtlas(act.getTextureManager(), 64, 576);

    ballTextureRegionArray[0] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "red_ball.png", 0, 0);
    ballTextureRegionArray[1] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "blue_ball.png", 0, 64);
    ballTextureRegionArray[2] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "green_ball.png", 0, 128);
    ballTextureRegionArray[3] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "purple_ball.png", 0, 192);
    ballTextureRegionArray[4] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "yellow_ball.png", 0, 256);
    ballTextureRegionArray[5] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "orange_ball.png", 0, 320);
    ballTextureRegionArray[6] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "black_ball.png", 0, 384);
    ballTextureRegionArray[7] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "white_ball.png", 0, 448);
    ballTextureRegionArray[8] = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(ballTexture, act, "select_ball.png", 0, 512);

    ballTexture.load(); // load ballTexture to the scene

...当然还有错误。

11-28 17:44:44.750: E/AndroidRuntime(2119): FATAL EXCEPTION: UpdateThread
11-28 17:44:44.750: E/AndroidRuntime(2119): java.lang.NullPointerException
11-28 17:44:44.750: E/AndroidRuntime(2119):     at   com.eklypze.android.mastermdhd.GameScene.drawPanel(GameScene.java:188)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at     com.eklypze.android.mastermdhd.GameScene.createScene(GameScene.java:68)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at     com.eklypze.android.mastermdhd.BaseScene.<init>(BaseScene.java:38)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at com.eklypze.android.mastermdhd.GameScene.<init>(GameScene.java:28)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at com.eklypze.android.mastermdhd.SceneManager.createGameScene(SceneManager.java:120)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at com.eklypze.android.mastermdhd.BaseActivity$1.onTimePassed(BaseActivity.java:84)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at org.andengine.engine.handler.timer.TimerHandler.onUpdate(TimerHandler.java:94)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at org.andengine.engine.handler.UpdateHandlerList.onUpdate(UpdateHandlerList.java:47)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at org.andengine.engine.Engine.onUpdateUpdateHandlers(Engine.java:618)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at org.andengine.engine.Engine.onUpdate(Engine.java:605)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at org.andengine.engine.Engine.onTickUpdate(Engine.java:568)
11-28 17:44:44.750: E/AndroidRuntime(2119):     at org.andengine.engine.Engine$UpdateThread.run(Engine.java:858)

这是我的GameScene.java类:

package com.eklypze.android.mastermdhd;

import java.util.Random;

import javax.microedition.khronos.opengles.GL10;

import org.andengine.engine.camera.Camera;
import org.andengine.entity.modifier.AlphaModifier;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.util.GLState;

import android.util.Log;

import com.eklypze.android.mastermdhd.SceneManager.SceneType;

public class GameScene extends BaseScene {
    /*** DECLARATIONS ***/
    /* Settings */
    protected static final int CAMERA_WIDTH = 480;
    protected static final int CAMERA_HEIGHT = 800;
    /* Sprites */
    Sprite[] selectPanel = new Sprite[8];
    Sprite boardPieces[] = new Sprite[40];
    Sprite bwPegs[] = new Sprite[10];
    Sprite nextSpot; // "next spot" cursor
    Sprite gameoverLose, gameoverWin; // REPLACE with scenes
    /* Game Options */
    private int turn = 0;
    private int turnCounter = 0; // per line turn counter
    private int currentX = 1;
    private int currentY = 13;
    private int[] code = new int[4]; // array to store generated code
    private int[] codeCopy = new int[4]; // for black&white peg use
    private int blackPegs = 0, whitePegs = 0;
    // remember to take currentX-1 as the array indexes
    private int[] currentXValues = new int[4];
    // dummy variable when drawing selectPanel for touch *don't delete*
    private int z = 0;
    Boolean gameOver = false;
    Boolean doublesAllowed = false;

    /************************************
     * ------------INHERITED------------
     ************************************/

    @Override
    /********************************
     * createScene()
     ********************************/
    public void createScene() {
        // create scene with bgSprite background
        setBackground(new SpriteBackground(resourceManager.bgSprite));
        // STEP 1: Start a New Game
        newGame();
        // STEP 2: Draw selectPanel
        drawPanel(); // debugging: game seems to work up until this point

    }

    @Override
    /********************************
     * onBackKeyPressed()
     ********************************/
    public void onBackKeyPressed() {
        System.exit(0);
    }

    @Override
    /********************************
     * getSceneType()
     ********************************/
    public SceneType getSceneType() {
        return SceneType.SCENE_GAME;
    }

    @Override
    /********************************
     * disposeScene()
     ********************************/
    public void disposeScene() {
        this.detachSelf();
        this.dispose();
    }

    /************************************
     * -----------GAME METHODS-----------
     ************************************/

    /********************************
     * newGame()
     * Description: Initialize game
     * settings for a new session.
     ********************************/
    private void newGame() {
        /* [START] Generate New Code Combination
        for (int x = 0; x < 4; x++) {
            Random r = new Random();
            // if doubles is not allowed check if new generated number is
            // a double, if yes, generate another number. NOTE: doubles are
            // defaulted to 'OFF' until feature is added.
            int randomNumber = r.nextInt(8); // why (7-0)+0?
            Log.v("randomR", "Number generated is " + randomNumber);
            code[x] = randomNumber;
            // write to log (debugging)
            Log.v("theCode", "Number generated for " + x + " is: " + code[x]
                    + " (" + resourceManager.ballColours[randomNumber] + ")");
            // if doubles is not allowed check if new generated number is
            // a double, if yes, generate another number. NOTE: doubles are
            // defaulted to 'OFF' until feature is added.
            if (!doublesAllowed && x > 0) {
                for (int y = x - 1; y >= 0; y--) {
                    // Log.v("theY", "y is "+y);
                    if (code[y] == randomNumber) {
                        x--;
                    }
                }
            }
        } [END] Generate New Code Combination */
        code = new int[] { 7, 1, 2, 3 };
        Log.v("theCode", "The Code Is: " + code[0] + "," + code[1] + ","
                + code[2] + "," + code[3] + ".");
        codeCopy = code.clone(); // copies code array for white/black peg use
    }

    /********************************
     * drawPanel()
     * Description: Draw the panels
     * required for user selection.
     ********************************/
    private void drawPanel() {
        int column = 7; // constant?
        int rowStart = 2;

        /* [START] Draw Selection selectPanel
        for (int i = 0; i < 8; i++) {
            final int j = i;
            selectPanel[i] = new Sprite(grid_xPixel(column),
                    grid_yPixel(rowStart),
                    resourceManager.ballTextureRegionArray[i], vbom) {
                @Override
                /* [START] Touch Detection
                public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
                        float pTouchAreaLocalX, float pTouchAreaLocalY) {
                    switch (pSceneTouchEvent.getAction()) {
                            // On Touch
                            case TouchEvent.ACTION_DOWN:
                                this.setScale(2.0f); // enlarge effect
                                z = j;
                                Log.v("thisIsZ", "Z: " + z);
                                break;
                            // On Move/Drag
                            case TouchEvent.ACTION_MOVE: {
                                /* to be implemented in the future
                                // this.setPosition(pSceneTouchEvent.getX() -
                                // this.getWidth()/2, pSceneTouchEvent.getY() -
                                // this.getHeight()/2);
                                break;
                            }
                            // On Release
                            case TouchEvent.ACTION_UP:
                                // z = j; // not needed
                                makeMove(z);
                                this.setScale(1.0f); // normal size
                                break;
                    }
                    return super.onAreaTouched(pSceneTouchEvent,
                            pTouchAreaLocalX, pTouchAreaLocalY);
                }
                [END] Touch Detection
            }; */

            // selectPanel[0] = new Sprite(200, 400,
            //      resourceManager.ballTextureRegionArray[0], vbom);
            //attachChild(selectPanel[0]);
        //registerTouchArea(selectPanel[i]);
        selectPanel[0] = new Sprite(0, 0, resourceManager.ballTextureRegionArray[0], vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }
        };
        selectPanel[0].setPosition(240, 400);
        attachChild(selectPanel[0]);
        //} /* [END] Draw Selection selectPanel */
        // setTouchAreaBindingOnActionDownEnabled(true);
    }

    /********************************
     * makeMove()
     * Description: Allow the player
     * to make their selection and
     * display pegs as a result.
     ********************************/
    private void makeMove(int inColor) {
        boardPieces[turn] = new Sprite(grid_xPixel(currentX),
                grid_yPixelBoard(currentY),
                resourceManager.ballTextureRegionArray[inColor], vbom);
        boardPieces[turn].setScale(0.75f); // set 75% size on board

        // store current line, compare values to code and generate B/W pegs
        currentXValues[currentX - 1] = inColor;
        if (currentXValues[currentX - 1] == codeCopy[currentX - 1]) {
            blackPegs++;
            // dummy variable so this isn't counted again as a white peg
            codeCopy[currentX - 1] = 999;
        }

        for (int i = 0; i < 4; i++) {
            if ((currentXValues[currentX - 1] == codeCopy[i])) {
                whitePegs++;
                // dummy variable so this isn't counted again as a white peg
                codeCopy[i] = 999;
            }
        }

        /* log for debugging */
        Log.v("pegs", "blackPegs: " + blackPegs);
        Log.v("pegs", "whitePegs: " + whitePegs);

        // Draw pieces to scene and advance to next turn & column
        attachChild(boardPieces[turn]);
        currentX++;
        turn++;

        // advance to next row, draw B/W pegs
        if (currentX > 4) {
            currentX = 1;
            currentY--;

            // Draw Pegs
            drawBWPegs(blackPegs, whitePegs);
            turnCounter++;

            // Reset pegs for next line
            blackPegs = 0;
            whitePegs = 0;

            // codeCopy is only used for counting black and white
            // pegs per line to ensure all cases work
            codeCopy = code.clone();
        }

        /* [START] Draw Blinking Cursor in Next Spot */
        nextSpot = new Sprite(grid_xPixel(currentX),
                grid_yPixelBoard(currentY),
                resourceManager.ballTextureRegionArray[8], vbom);
        nextSpot.setScale(0.75f);

        nextSpot.setBlendFunction(GL10.GL_SRC_ALPHA,
                GL10.GL_ONE_MINUS_SRC_ALPHA);
        nextSpot.registerEntityModifier(new LoopEntityModifier(
                new AlphaModifier(2, 0f, 1.0f)));
        attachChild(nextSpot);
        /* [END] Draw Blinking Cursor in Next Spot */

        /* *
         * GAME OVER (LOSE)
         *  If player reaches turn 40 and still has not received
         *  correct code, go to Game Over (Lose) scene.
         * */
        if (turn == 40) {
            // NOTE: I will replace this with a Game Over scene.
            GameOverWin(false);
            Log.v("Game Over", "You Lose");
            gameoverLose = new Sprite(CAMERA_WIDTH / 2 - 256,
                    CAMERA_HEIGHT / 2 - 64, resourceManager.loseTextureRegion,
                    vbom);
            attachChild(gameoverLose);
        }
    }

    /********************************
     * GameOverWin()
     * Description: Display GameOver
     * image as a result of the user
     * winning the game.
     ********************************/
    private void GameOverWin(boolean win) {
        // clear game
        detachChildren();
        turn = 0;

    }

    /********************************
     * drawBWPegs()
     * Description: Draw the black
     * and white pegs to the scene
     * based on game results.
     ********************************/
    private void drawBWPegs(int numBlack, int numWhite) {
        /* [START] if */
        // do not display if no pegs were counted
        if (numBlack > 0 || numWhite > 0) {
            int pegScore = 0;
            // determine pegScore
            if (numBlack == 1 && numWhite == 0) {
                pegScore = 0;
            } else if (numBlack == 1 && numWhite == 2) {
                pegScore = 1;
            } else if (numBlack == 1 && numWhite == 3) {
                pegScore = 2;
            } else if (numBlack == 0 && numWhite == 1) {
                pegScore = 3;
            } else if (numBlack == 2 && numWhite == 0) {
                pegScore = 4;
            } else if (numBlack == 2 && numWhite == 2) {
                pegScore = 5;
            } else if (numBlack == 0 && numWhite == 2) {
                pegScore = 6;
            } else if (numBlack == 3 && numWhite == 0) {
                pegScore = 7;
            } else if (numBlack == 3 && numWhite == 1) {
                pegScore = 8;
            } else if (numBlack == 0 && numWhite == 3) {
                pegScore = 9;
            } else if (numBlack == 4 && numWhite == 0) {
                pegScore = 10;
            } else if (numBlack == 0 && numWhite == 4) {
                pegScore = 11;
            } /* [END] if */
            // use pegScore to display corresponding image
            bwPegs[turnCounter] = new Sprite(grid_xPixel(5),
                    grid_yPixelBoard(currentY + 1),
                    resourceManager.pegTextureRegionArray[pegScore], vbom);
            bwPegs[turnCounter].setScale(0.80f);
            attachChild(bwPegs[turnCounter]);
        }
    }

    /********************************
     * ---------GRID SYSTEM---------
     ********************************/

    /************************************
     * grid_xPixel()
     * Description: Converts grid
     * coordinates to pixel coordinates
     * based on a 480 by 800 resolution
     * screen. Needs to be updated.
     ************************************/
    private int grid_xPixel(int x) {
        int pixel = 0;
        pixel = x * (CAMERA_WIDTH / 8 + 2) - 32;
        return pixel;
    }

    /************************************
     * grid_yPixel()
     * Description: Y-grid for user
     * selection panel.
     ************************************/
    private int grid_yPixel(int y) {
        int pixel = 0;
        pixel = y * (CAMERA_HEIGHT / 10) - 32;
        return pixel;
    }

    /************************************
     * grid_yPixelBoard()
     * Description: Y-grid for the main
     * game board.
     ************************************/
    private int grid_yPixelBoard(int y) {
        int pixel = 0;
        pixel = y * (CAMERA_HEIGHT / 15) - 32;
        return pixel;
    }
}

很抱歉,因为我也是StackOverflow的新手,并且不太了解如何正确设置代码格式。 另外,如果我缺少与问题相关的重要代码区域,请告诉我,因为我有很多行代码,并且不太知道从哪里开始。

提前致谢!

查看您的代码,我会说ballTextureRegionArray [0]是空指针,可能是因为它没有在您的resourceManager初始化中加载。

如果您的.png文件是资源,即在“ res”目录而不是“ asset”目录中,则需要使用.createFromResource而不是.createFromAsset加载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM