- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为 Android 构建一个带有操纵杆(方向键)的 GUI。我让它在大部分情况下都能工作。有一个大问题:第一次在任何 Android 设备上打开 GUI 时,它不会加载。我已经找到了问题所在,但不清楚是什么原因造成的。
在JoystickGui
类中,我在构造函数中创建了一个joystick
对象。稍后,继承 Activity 的类会调用drawJoystickGUI()
,并将位图绘制到 Canvas 上。每次我第一次启动应用程序(或手动清空 RAM)时,我都会设法发现对操纵杆对象的引用为空,即使它是在构造函数中创建的。
在方法drawJoystickGUI()
中,我使用了System.Out.println
来查看joystick
对象是否实际存在并返回空。我必须使用 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);
}
}
编辑:
我通过初始化绘图函数中的“操纵杆”和“按钮”对象解决了这个问题,并使用一个简单的 boolean 值来防止不必要的 CPU 使用。但我仍然愿意接受实际的解决方案而不是解决方法。
最佳答案
我不确定你的代码有什么问题。
你试过吗AndEngine ?它是免费且开源的。您可以下载它的examples来自 Google Play 的应用程序。
其 joystick example是模拟的。它不像操纵杆代码示例那么简单,但如果您可以调整游戏以接收模拟输入,那么它就是一个开箱即用的示例。
关于java - 应用程序第一次启动时,自定义 GUI 不会显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15728906/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!