- 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/
我正在使用两个 MjpegView(扩展 SurfaceView 的自定义 View )构建一个应用程序。问题是有时我看不到第二个摄像机 View ,因为它位于第一个摄像机 View 后面。流媒体工作
我有一个自定义相机应用程序,我希望任何预览尺寸都以全屏模式显示,而不会拉伸(stretch)相机预览图像。为此,我需要使surfaceView 大于屏幕以保持纵横比,因此实际上用户看到的比相机实际捕获
我收到从 SurfaceView.onAttachedToWindow 引发的异常。看起来 SurfaceView 正在尝试引用 mParent,但它是 null。有谁知道为什么不设置父级但会调用 o
我已经将 SurfaceView 子类化并在 Activity 的 onCreate 中实例化它。生成了预览,但控件永远不会进入 onDraw(),它在 SurfaceView 的子类中被重写。这是为
我的应用在 Android 8.0 上遇到了一些奇怪的问题。我有自己的可滚动小部件,代码是 available on github .它有两个 child ,可以无限期地逐一滚动。 在屏幕上,棋盘是一
我用两种方式编写了同一个程序。 一个使用 Surfaceview,另一个使用自定义 View 。根据 android SDK 开发指南,使用表面 View 更好,因为您可以生成一个单独的线程来处理图形
我想做的是 在开始播放视频之前在 SurfaceView 上显示背景图像。 我尝试只绘制一个 jpeg 图像作为 SurfaceView 的背景。有效。 我还尝试在 SurfaceView 上播放视频
我遇到了讨厌的 Android SurfaceView 行为: 当你离开一个带有 SurfaceView 的 Activity 并快速返回时,SurfaceView 之前的内容并没有消失,而是显示在新
我正在创建一个 FrameLayout 类型的布局,我在其中添加了两个 View 。两个 View 分别是 GLSurfaceView 和 SurfaceView 的对象。根据有关 SurfaceVi
我有一个 Activity 调用一个扩展 SurfaceView 并实现 Runnable 的类并将 Activity 类的 contentView() 设置为 surfaceview 类的实例。最小
由于某种原因,我的程序中的摄像头画面是横向的。如果我从底部将手指放在相机上,它会在表面 View 中显示为来自右侧。 我有一个非常标准的实现 surfaceView = (SurfaceVie
我想在我的 SurfaceView 顶部添加一个自定义 ImageButton,这样它基本上可以随 View 滚动。 Canvas 使用矩阵滚动和缩放。我该怎么做呢?谢谢。 最佳答案 假设我正确理解了
在 SurfaceView 上绘图时,我在拦截“后退”按键时遇到问题。我的 onKeyDown 事件似乎只在第二次和随后的按键事件中被调用——这对后退键没有用,因为 Activity 已经暂停或终止。
在我正在进行的项目中,我决定使用 SurfaceView 而不是自定义双缓冲介质。它提供了我需要的一切,而且它已经是双缓冲的。 问题是它不会让我指定多个脏矩形来重绘。 SurfaceView.lock
我正在创建一个小游戏我有一个 Activity : GameActivity.java: public class GameActivity extends Activity { public
这很可能是一件微不足道的事情,但我找不到解决方案。事情很简单,用户按下屏幕,当他的手指放在屏幕上时,我想要执行一段代码。 这是一个代码示例: @Override public boolean
我正在使用 Android SurfaceView 编写测试应用程序。我想看看这是否是一种可行的 2D 游戏开发方法。目前性能不是太好。 似乎每隔 15 秒左右就会出现微小的抖动和减速。我只在屏幕上画
我有一个 SurfaceView,我在其中显示了一个比 SurfaceView 的实际区域大得多的位图,因此我实现了一种方法,让用户可以在位图上滑动手指并上下移动它。这样做时,我希望能够显示垂直滚动条
我正在向 SurfaceView 提供的 Canvas 绘制一些自定义内容。这包含在具有其他 View 的 Activity 中。 我的 Activity 中的一个状态需要隐藏 SurfaceView
所以我在 Android Studio 中做的项目中一直遇到 NullPointerException。我需要让图像显示在我称为 DrawSurface 的自定义类中。我似乎找不到与我的问题相关的任何
我是一名优秀的程序员,十分优秀!