我正在嘗試用android遊戲杆(d-pad)構建GUI。我大部分都在工作。有一個大問題:第一次在任何Android設備上打開它時,GUI不會加載。我已經查明瞭這個問題,但是我不清楚是什麼導致了這個問題。自定義GUI將不會在第一次啓動應用程序時顯示
在JoystickGui
類中,我在構造器中創建了一個joystick
對象。稍後drawJoystickGUI()
由擴展Activity的類調用,它將在畫布上繪製位圖。每次我第一次啓動應用程序(或手動清空RAM)時,我都設法發現對遊戲杆對象的引用是空的,即使它是在構造函數中創建的。
在該方法中drawJoystickGUI()
我使用了一個System.Out.println
看有無joystick
對象實際上exitst並返回空。我不得不使用try
和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);
}
}
編輯:
我已經初始化「操縱桿」和「按鈕」繪製函數中的對象,有一個簡單的布爾以防止不必要的CPU使用率解決了這個問題。但我只是開始尋求真正的解決方案而不是解決方案。
感謝您的維修人員,但所提供的遊戲引擎是強制性的,儘管我們(我的合作伙伴和我)必須對其進行更改才能製作出我們想要的遊戲。另外我們製作的遊戲杆是額外的功勞,所以使用外部來源對我們沒有好處。 – Alexander
任何想法如何在構造函數中創建一個對象,並據說在函數中稍後不存在?最奇怪的是,它關閉它並重新啓動後才能正常工作。 – Alexander
我的猜測是初始化需要在活動的onResume()中完成,以便可以在繪製UI之前繪製UI,但這僅僅是部分基於您自己的解決方案的猜測。 –