我是Android开发的新手,并试图实现一个用表面视图和画布实现的简单游戏。我使用LunarView示例作为草稿。
这个想法是让一个人(由触摸事件控制的运动)和跟随他的僵尸。
到目前为止,我有以下类(我从我的观点中删除了无用的代码):
1)MainActivity
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
2)ZombieView与内置类ZombieThread和Person(Person仅用于保存数据)
public class ZombieView extends SurfaceView implements SurfaceHolder.Callback {
//Thread Class that performs drawing on Canvas
class ZombieThread extends Thread {
class Person {
...
}
private final SurfaceHolder surfaceHolder;
private ZombieView zombieView;
private Context context;
private boolean running = false;
//Canvas info
private int mCanvasWidth = 1;
private int mCanvasHeight = 1;
private Bitmap mBackgroundImage;
private final Drawable mHumanImage;
private final Drawable mZombieImage;
private Resources res;
//Game Variables
double hSpeed = 1;
double zSpeed = 0.8;
Person zombie;
Person human;
public ZombieThread(SurfaceHolder holder, ZombieView zombie, Context context) {
this.surfaceHolder = holder;
this.zombieView = zombie;
this.context = context;
this.zombie = new Person(100, 100, hSpeed);
this.zombie.setRunning(true); //zombie always walks
this.human = new Person(100, 200, zSpeed);
res = context.getResources();
mHumanImage = context.getResources().getDrawable(R.drawable.green_circle);
mZombieImage = context.getResources().getDrawable(R.drawable.red_circle);
mBackgroundImage = BitmapFactory.decodeResource(res,R.drawable.background);
}
@Override
public void run() {
Canvas c = null;
while (this.running) {
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
play();
onDraw(c);
checkCollision();
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void checkCollision() {
//do something
}
public void play() {
...
}
public void onDraw(Canvas c) {
//Do your drawing here...
// c.drawColor(Color.rgb(10, 0, 0));
c.drawBitmap(mBackgroundImage, 0, 0, null);
c.save();
//draw human and zombie
int width = mHumanImage.getIntrinsicWidth();
int height = mHumanImage.getIntrinsicHeight();
mHumanImage.setBounds((int) human.getX() - (width / 2), (int) human.getY() - (height / 2),
(int) human.getX() + (width / 2), (int) human.getY() + (height / 2));
mHumanImage.draw(c);
width = mZombieImage.getIntrinsicWidth();
height = mZombieImage.getIntrinsicHeight();
mZombieImage.setBounds((int) zombie.getX() - (width / 2), (int) zombie.getY() - (height / 2),
(int) zombie.getX() + (width / 2), (int) zombie.getY() + (height / 2));
mZombieImage.draw(c);
c.restore();
}
public boolean doTouchEvent(MotionEvent e) {
//do something
}
}
//ZombieView variables
private ZombieThread thread;
private final SurfaceHolder surfaceHolder;
private Context context;
public ZombieView(Context context) {
super(context);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
this.context = context;
setFocusable(true); //makes sure we receive key-events
}
public ZombieView(Context context, AttributeSet attrs) {
super(context, attrs);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
this.context = context;
setFocusable(true); //makes sure we receive key-events
}
public ZombieView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
this.context = context;
setFocusable(true); //makes sure we receive key-events
}
public ZombieThread getThread() {
return thread;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new ZombieThread(surfaceHolder, this, context);
thread.setRunning(true);
thread.start();
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<com.example.zombierun.zombierun.ZombieView android:background="#ccc"
android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="20dp"
android:paddingBottom="40dp"
android:focusable="true"
android:visibility="visible"
android:id="@+id/customView" />
所以现在我的问题如下: 当我启动应用程序时,我看到Activity和一个灰色区域,它应该是canvas / surfaceview。不幸的是,这一切都是。但是当我通过按下主页按钮来最小化应用程序时,我会看到应用程序最小化时的画布(带有图像和背景颜色)。 logcat中没有显示错误。
我认为画布不知何故停留在背景中或者不同的视觉之间有叠加?这可能吗?
希望有人能帮我正确显示画布。
提前致谢
答案 0 :(得分:2)
你不能使用android:background =&#34; x&#34;使用SurfaceView时。您必须在onDraw(Canvas c)调用中手动绘制颜色,在本例中为canvas.drawColor(Color.GREY)。否则,您正在做的是将您设置的背景颜色绘制在曲面视图的表面上,使其呈现不透明的灰色。调用onPause时,视图会被拆除,您可以立即看到视图的窗口覆盖层下方的表面,其中绘制了#ccc。
另外:你为什么每帧睡眠1/10秒?你应该删除这一行。或者,如果您尝试以帧速率为目标:实现1000 ms / 100 ms = 10帧,即您以10 fps绘制。