Java 应用程序启动时,自定义GUI不会在第一次显示

Java 应用程序启动时,自定义GUI不会在第一次显示,java,android,Java,Android,我正在尝试为android构建一个带有操纵杆d-pad的GUI。我让它在很大程度上发挥作用。有一个大问题:我第一次在任何android设备上打开GUI时,它都不会加载。我已经找到了问题所在,但不清楚是什么原因造成的 在JoystickGui类中,我在Constructor中创建了一个操纵杆对象。稍后,扩展活动的类将调用drawJoystickGUI,它将在画布上绘制位图。每次我第一次启动应用程序或手动清空RAM时,我都会设法发现对操纵杆对象的引用为空,即使它是在构造函数中创建的 在drawJoy

我正在尝试为android构建一个带有操纵杆d-pad的GUI。我让它在很大程度上发挥作用。有一个大问题:我第一次在任何android设备上打开GUI时,它都不会加载。我已经找到了问题所在,但不清楚是什么原因造成的

在JoystickGui类中,我在Constructor中创建了一个操纵杆对象。稍后,扩展活动的类将调用drawJoystickGUI,它将在画布上绘制位图。每次我第一次启动应用程序或手动清空RAM时,我都会设法发现对操纵杆对象的引用为空,即使它是在构造函数中创建的

在drawJoystickGUI方法中,我使用了System.Out.println来查看操纵杆对象是否实际存在,并返回null。我不得不使用try-and-catch来防止应用程序在启动时崩溃

我真的希望有人能向我解释是什么导致了这个问题

这是我的密码:

public class JoystickGUI implements OnTouchListener {

// Screen size for positioning purposes
private float screenWidth, screenHeight;

// Used to determine if the Joystick Graphical User Interface is actually
public static boolean use;

private boolean useButtons = true;

// Will hold all non-Joystick objects
private ArrayList<Button> buttons = new ArrayList<Button>();

// Joystick object
private Joystick joystick;

Display display;

// Touch input identification
private int jsPointerID;
final private int INVALID_POINTER_ID = -1;

@SuppressWarnings("deprecation")
public JoystickGUI() {
    if(use){

        display = ((WindowManager) GameEngine.getAppContext().getSystemService(
            Context.WINDOW_SERVICE)).getDefaultDisplay();

        screenWidth = display.getWidth();
        screenHeight = display.getHeight();

        System.out.println("ScreenWidth: " + screenWidth + ". ScreenHeight: "
                + screenHeight + ".");

        joystick = new Joystick(100, screenHeight - 100);

        if (useButtons) {

            Sprite buttonA = new Sprite("buttonajoystickgui");
            buttons.add(new RoundButton(buttonA, screenWidth - 125,
                    screenHeight - 75));
            Sprite buttonB = new Sprite("buttonbjoystickgui");
            buttons.add(new RoundButton(buttonB, screenWidth - 75,
                    screenHeight - 125));

        }

        setTransparency(150);

        Log.d("JoystickGUI", "Initialized");
    }

}

/**
 * The following methods are used for handling the touch input
 */

public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            buttonPressed(event);
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            buttonPressed(event);
            break;
        case MotionEvent.ACTION_MOVE:
            buttonMoved(event);
            break;
        case MotionEvent.ACTION_UP:
            buttonReleased(event, 0);
            break;
        case MotionEvent.ACTION_POINTER_UP:
            buttonReleased(event, event.getActionIndex());
            break;
        default:
            break;

    }
    return true;
}

public void buttonPressed(MotionEvent e) {

    for (int p = 0; p < e.getPointerCount(); p++) {
        if (joystick.isWithinJoystick(e, p) && !Joystick.isActive) {
            Joystick.isActive = true;
            jsPointerID = e.getActionIndex();
        }
        for (int i = 0; i < buttons.size(); i++) {
            if (buttons.get(i).isPressed(e, p) && !buttons.get(i).isActive) {
                buttons.get(i).setActive(true);
                buttons.get(i).setPointerID(e.getActionIndex());
                Log.d("JoystickGUI", "Button #" + i + " pressed.");
            }
        }
    }

}

public void buttonMoved(MotionEvent e) {

    for (int p = 0; p < e.getPointerCount(); p++) {
        if (Joystick.isActive && e.getPointerId(p) == jsPointerID) {
            joystick.updateButtonPos(e, p);
        }

    }

}

public void buttonReleased(MotionEvent e, int pointerIndex) {
    if (Joystick.isActive && e.getPointerId(pointerIndex) == jsPointerID) {
        Joystick.isActive = false;
        joystick.resetJoystick();
        jsPointerID = INVALID_POINTER_ID;

    }

    for (int i = 0; i < buttons.size(); i++) {
        if (buttons.get(i).isActive
                && e.getPointerId(pointerIndex) == buttons.get(i)
                        .getPointerID()) {
            buttons.get(i).setActive(false);
            buttons.get(i).resetPointerID();
        }
    }

}

/**
 * The following methods are used for drawing all button-objects to the
 * canvas.
 * 
 * @param canvas
 */

public void drawJoystickGUI(Canvas canvas) {
    if(use){

        try {
            joystick.drawJoystick(canvas);
        } catch (Exception e) {
            System.out.println(joystick);
            Log.d("JoystickGUI", "Drawing joystick failed!");
        }

        for (int i = 0; i < buttons.size(); i++) {
            try {
                buttons.get(i).drawButton(canvas);
            } catch (Exception e) {
                Log.d("JoystickGUI", "Drawing Button " + i + " failed");
                System.out.println(buttons.get(i));
            }
        }
    }

}

private void setTransparency(int alpha) {

    joystick.setAlpha(alpha);
    for (int i = 0; i < buttons.size(); i++) {
        buttons.get(i).setAlpha(alpha);
    }

}

/**
 * The following (static) methods are used to get input.
 * 
 * @return
 */

public static boolean isJoystickActive() {
    return Joystick.isActive;
}

public static  double getJoystickAngle() {
    return Joystick.getAngle();
}

public static  float getPower() {
    return Joystick.getPower();
}
}
应该能正常运行游戏的引擎,我取出了所有不必要的东西。InitializeTouch在GameLoop中调用

public abstract class GameEngine extends Activity {

/**
 * Gameloop is a gameThread that handles the timing of the game
 */
private GameLoop gameloop;
/**
 * View deals with the proper rendering of the game
 */
private static GameView view;
/**
 * The width and height of the device
 */
private static int screenWidth, screenHeight;
/**
 * JoystickGUI handles input by touch via the joystick interface
 */
public JoystickGUI joystickGUI;

/**
 * A vectorlist that holds all the active GameObjects. Can be used if you
 * mannualy want to delete/change GameObjects. For instance, you could loop
 * through this list and remove health of every GameObject.
 */
public static Vector<GameObject> items;
/**
 * A vectorlist that holds all the newly created GameObjects during this
 * cycle of the game loop. At the end of the cycle, all items in this list
 * will be moved to the items-list and the object become active
 */
public static Vector<GameObject> newItems;
/**
 * A vectorlist that holds all the active alarms. Can be used if you
 * manually want to delete/change alarms.
 */
public static Vector<Alarm> gameAlarms;


/**
 * Holds context of the application
 */
private static Context appContext;
/**
 * The main thread of the gameloop
 */
private Thread gameThread;




@Override
protected final void onCreate(Bundle savedInstanceState) {

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setFlags(
            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED,
            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);

    vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    appContext = getApplicationContext();

    joystickGUI = new JoystickGUI(); // Added

    screenWidth = getWindow().getWindowManager().getDefaultDisplay()
            .getWidth();
    screenHeight = getWindow().getWindowManager().getDefaultDisplay()
            .getHeight();

    gameloop = new GameLoop(this);
    gameThread = new Thread(gameloop);
    gameThread.setPriority(7);

    view = new GameView(this, gameThread);
    gameloop.setView(view);

    setContentView(view);
    view.setKeepScreenOn(true);

    super.onCreate(savedInstanceState);

}


/**
 * Initialize the Listener for the screen (general touch OR screenButtons)
 */
protected void initializeTouch() {

    if (JoystickGUI.use) { // added
        Log.d("JoystickEnabled", "USING JOYSTICK");
            view.setOnTouchListener(joystickGUI);
        }
}

public final void drawInterface(Canvas canvas) {
    if(JoystickGUI.use){
        joystickGUI.drawJoystickGUI(canvas);
    } 
}
编辑:


我已经通过初始化draw函数中的“操纵杆”和“按钮”对象解决了这个问题,使用了一个简单的布尔值来防止不必要的cpu使用。但我对实际的解决方案持开放态度,而不是采取变通办法

我不确定你的代码出了什么问题

你试过了吗?它是免费的,开源的。你可以从Google Play下载它的应用程序


它是模拟的。这并不像游戏杆代码示例那样简单,但如果您可以调整游戏以接收模拟输入,这是一个开箱即用的非常好的示例

感谢您的awnser,但提供的游戏引擎是必须的,尽管我们我的合作伙伴和我必须对其进行修改,以便能够制作我们想要的游戏。此外,我们正在制作的操纵杆是为了获得额外的积分,因此使用外部源对我们没有任何好处。任何想法为什么会在构造函数中创建一个对象,并在以后的函数中说它不存在?最奇怪的是,它在关闭并重新启动后才能工作。我的猜测是,初始化需要在活动的onResume中完成,以便可以在UI被绘制之前绘制UI,但这只是我的猜测,部分基于您自己的解决方案。我会尝试,我目前不在家。我只是不认为这会有什么不同,因为引擎的默认ui是以相同的方式初始化的。如果你的建议起了作用,我会告诉你的。