1

我正在尝试为 android 构建一个带有操纵杆(d-pad)的 GUI。而且我大部分时间都在工作。有一个大问题:当我第一次在任何安卓设备上打开它时,GUI 不会加载。我已经找到了问题所在,但我不清楚是什么原因造成的。

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

在该方法drawJoystickGUI()中,我使用 aSystem.Out.println查看joystick对象是否实际存在并返回null。我必须使用tryandcatch来防止应用程序在启动时崩溃。

我真的希望有人可以向我解释导致这个问题的原因。

这是我的代码:

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();
}
}

应该正确运行游戏的引擎,我把所有非必要的东西都拿出来了。在 GameLoop 中调用 InitializeTouch。

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);
    } 
}

编辑:

我通过初始化绘图函数中的“操纵杆”和“按钮”对象解决了这个问题,并使用一个简单的布尔值来防止不必要的 cpu 使用。但我仍然愿意接受实际的解决方案,而不是变通办法。

4

1 回答 1

0

我不确定你的代码有什么问题。

你试过AndEngine吗?它是免费和开源的。您可以从 Google Play下载其示例应用程序。

它的操纵杆示例是模拟的。它不像您的操纵杆代码示例那么简单,但如果您可以调整您的游戏以接收模拟输入,那么它就是一个开箱即用的示例。

于 2013-03-31T13:40:12.043 回答