- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在谷歌、各种 android 博客、各种游戏开发博客和其他有关 android 表面 View 的教程网站上进行搜索后,我希望对表面 View 有一个完整的了解。我在 Safaribooks 上看过几本关于 android 和 surface views 的书,但是它们提供的信息太少,或者使用其他 SDK,例如 AndEngine。我希望严格地学习表面 View 。我玩过 Lunar Lander 示例项目以及我发现的其他项目,并创建了骨架表面 View 的一些代码。它仅由 3 个骨架类组成。
MainActivity 类:
package com.learning.svlearning;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Set FullScreen Mode - No title bars!!
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Screen created with pure java - Say no to xml (atleast for this demo)
setContentView(new MainGamePanel(this));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.layout_game_window, menu);
return true;
}
}
这门课非常简单。主游戏 Activity 窗口,要求全屏显示,没有标题栏。真正的游戏应该是怎样的:)这个类通过传递“这个”(MainActivity)类的上下文来调用我们的下一个 View 类。
MainGamePanel 类:
package com.learning.svlearning;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainGamePanel extends SurfaceView {
final static public String tag = "Tracer";
private GameThread gameThread; // For our thread needed to do logical processing without holding up the UI thread
private SurfaceHolder holder; // For our CallBacks.. (One of the areas I don't understand!)
public MainGamePanel(Context context) {
super(context);
Log.d(tag, "Inside MainGamePanel");
gameThread = new GameThread(this); //Create the GameThread instance for our logical processing
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
// Since we are using the SurfaceView, we need to use, at very least, the surfaceDestroyed and surfaceCreated methods.
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
Log.d(tag, "Inside SurfaceHolder Callback - surfaceDestroyed");
gameThread.setRunning(false); // Stop the Thread from running because the surface was destroyed. Can't play a game with no surface!!
while (retry) {
try {
Log.d(tag, "Inside SurfaceHolder Callback - surfaceDestroyed - while statement");
gameThread.join();
retry = false; //Loop until game thread is done, making sure the thread is taken care of.
} catch (InterruptedException e) {
// In case of catastrophic failure catch error!!!
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// let there be Surface!
Log.d(tag, "Inside SurfaceHolder Callback - surfaceCreated");
gameThread.setRunning(true); // Now we start the thread
gameThread.start(); // and begin our game's logical processing
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// The code to resize the screen ratio when it flips from landscape to portrait and vice versa
}
});
}
@Override
protected void onDraw(Canvas canvas) {
//This is where we draw stuff.. since this is just a skeleton demo, we only draw the color Dark Grey so we can visibly see that we actually accomplished something with the surfaceview drawing
Log.d(tag, "Inside onDraw");
canvas.drawColor(Color.DKGRAY); // You can change the Color to whatever color you want, for this demo I just used Color.DKGRAY
}
}
这个类主要是用onDraw方法处理我们的资源/图片的绘制,处理当我们的surface被创建和销毁时发生的事情(还有当屏幕改变时,但我暂时没有写任何代码来处理它),并调用我们的 GameThread 类来处理我们的游戏逻辑。
游戏线程类:
package com.learning.svlearning;
import android.graphics.Canvas;
import android.util.Log;
public class GameThread extends Thread{
final static public String tag = "Tracer";
private MainGamePanel view;
private boolean running = false;
static final long FPS = 30; // To help limit the FPS when we draw, otherwise we would kill the CPU and increase the Battery Consumption.
public GameThread(MainGamePanel view){
Log.d(tag, "inside GameThread");
this.view = view;
}
public void setRunning(boolean run){
Log.d(tag, "inside GameThread - setRunning");
running = run; // For starting / stoping our game thread
}
@Override
public void run() {
long ticksPS = 1000 / FPS; // Limit the frames per second
long startTime;
long sleepTime;
Log.d(tag, "inside GameThread - run");
while(running){ // Our Main Game Loop is right here
Canvas c = null; // build our canvas to draw on
Log.d(tag, "inside GameThread - run - while loop");
startTime = System.currentTimeMillis(); //get the current time in milliseconds - this is for helping us limit the FPS
try{
c = view.getHolder().lockCanvas(); //Before we can draw, we always have to lock the canvas, otherwise goblins will invade your app and destroy everything!
synchronized (view.getHolder()){ // we have to synchronize this because we need to make sure that the method runs when at the proper time.
view.onDraw(c); // this is where we pass our drawing information. The canvas gets passed to the onDraw method in our MainGamePanel class.
}
}finally{
if(c != null) {
view.getHolder().unlockCanvasAndPost(c); // Once we are done drawing, we unlock our canvas and post. which means we drew on the canvas, and now the devices screen will display our drawing.
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime); // this is where we calculace how long we need this thread to sleep (again with the FPS) we want it limited to 30 FPS as defined in our FPS variable.
try {
if (sleepTime > 0){
sleep(sleepTime); // night night, sleep to limit the fps and save our batteries!
}
else{
sleep(10); // Incase something goes crazy, we still want to sleep the thread to save the battery.
}
}catch(Exception e){
}
}
}
}
此类处理处理游戏逻辑并将任何可绘制信息发送到 MainGamePanel 类中的绘制方法。例如,如果我们有一个移动的角色,我们可以将 x 和 y 坐标发送到我们的 draw 方法以在不同的位置绘制我们的角色。
现在我还没有完全理解这些类(class)的某些部分。就像回调一样,当阅读谷歌 android 开发者页面上的信息时,我只是对它是什么以及我们为什么使用它感到更加困惑。另外,如果有人对此有任何补充,或者看到我可能误解的任何内容,请随时纠正我。我喜欢和 android 一起工作,虽然这很困难,但当你开始弄清楚事情时,它是非常有益的!
最佳答案
SurfaceHolder 回调的目的是处理这 3 个事件。 surfaceCreated()、surfaceDestroyed() 和 surfaceChanged()。
如果您阅读代码,您会发现 surfaceCreated() 处理创建表面时需要发生的事情等等...
这是您问题的答案还是还有更多?
关于android - Surfaceview骨架教程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11751538/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!