Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/186.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-为乒乓球游戏创建计时器循环_Android_Loops_Timer_Android Asynctask_Pong - Fatal编程技术网

Android-为乒乓球游戏创建计时器循环

Android-为乒乓球游戏创建计时器循环,android,loops,timer,android-asynctask,pong,Android,Loops,Timer,Android Asynctask,Pong,我有一个用Java编写的Pong游戏,我正在尝试将它移植到Android上。(这是我的第一款Android游戏;) 在Java中,我使用了一个定时器对象,它基本上更新了游戏值(球/桨位置),然后重新绘制屏幕 我试图在Android中实现相同的功能,但我遇到了一些错误 我的程序由一个PongView类和一个PongDriverActivity类组成,前者是游戏的可视部分,后者使用PongView作为视图。如果我有一个循环线程使PongView无效,我会得到一个错误,因为该线程无法触及在另一个线程上

我有一个用Java编写的Pong游戏,我正在尝试将它移植到Android上。(这是我的第一款Android游戏;)

在Java中,我使用了一个
定时器
对象,它基本上更新了游戏值(球/桨位置),然后重新绘制屏幕

我试图在Android中实现相同的功能,但我遇到了一些错误

我的程序由一个
PongView
类和一个
PongDriverActivity
类组成,前者是游戏的可视部分,后者使用
PongView
作为视图。如果我有一个循环线程使
PongView
无效,我会得到一个错误,因为该线程无法触及在另一个线程上生成的视图

我假设我需要执行某种
异步任务
,但我不确定如何循环该任务


有什么建议是最好的实现方法吗?

有很多方法。Android确实支持普通的Java
Thread
对象,您可以使用这些对象。你可以搜索(SO)android游戏循环,可能会找到很多例子。但是,如果您想尝试
AsyncTask
,下面是一个示例实现:

public class PongView extends View {

    public PongView(Context context) {
        super(context);
    }    
    public void setBallPosition(int x, int y) {
        // relocate the ball graphic
    }    
}
然后,您的活动:

public class PongDriverActivity extends Activity implements OnSeekBarChangeListener {

    private enum GameSpeed { SLOW, MEDIUM, FAST };

    private PongView mGameView;
    private PongDriverTask mWorker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mGameView = new PongView(this);
        mWorker = new PongDriverTask(GameSpeed.MEDIUM);

        // if you need to pass some data to the worker:
        mWorker.execute("one", "two", "three");  
        // else, declare the AsyncTask's first generic param as Void, and do:
        //mWorker.execute();

        setContentView(mGameView);
    }

    // you would connect this up to a button, to allow the user to stop  
    public void onStopClicked(View sender) {
        if (mWorker.isRunning()) {
            mWorker.stopRunning();
        }
    }

    // you could connect this up to a slider, to allow the user to control the paddle
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        // you may need to convert progress to a y-coordinate
        mWorker.setPaddlePosition(progress);
    }
然后(可能在PongDriverActivity.java内部,一个内部类):

私有类PongDriverTask扩展了AsyncTask{
私人国际机场;
私有布尔值mRunning=true;
私有int mpadley=0;
公共PongDriverTask(游戏速度){
如果(速度==游戏速度.慢){
mDelay=100;
}否则如果(速度==游戏速度.MEDIUM){
平均寿命=50;
}else if(速度==GameSpeed.FAST){
mDelay=10;
}
}
公共同步布尔值正在运行(){
返回运行;
}
公共同步的void stopRunning(){
mRunning=假;
}
公共同步无效设置位置(int y){
mpadley=0;
}
私有同步int-getPablePosition(){
返回mpadley;
}
@凌驾
受保护的void onPostExecute(整数分数){
super.onPostExecute(分数);
//在这里,您可以显示一个显示最终分数的UI
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
mGameView.setBallPosition(0,0);
//在这里,你可以抛出一些显示
//在比赛真正开始之前
}
@凌驾
受保护的void onProgressUpdate(整数…参数){
super.onProgressUpdate(参数);
//从params检索更新的游戏坐标
mGameView.setBallPosition(参数[0],参数[1]);//x,y
}
@凌驾
受保护的整数doInBackground(字符串…args){
//如果您有一些信息要传递给后台工作人员,
//它将以args[0]、args[1]等形式传递。
//它不必是字符串数据。您可以更改泛型
//将字符串以外的内容作为第一个参数,其中
//在这种情况下,doInBackground()将获取一个长度可变的列表
//其他数据类型。
int-ballX=0;
int-ballY=0;
智力得分=0;
while(isRunning()){
//使用游戏引擎重新计算球的位置
//在这个背景线程上
int-palley=getpalleposition();
ballX+=1;
ballY+=2;
分数++;
//现在,更新UI,这必须发生在UI线程上
出版进度(ballX,ballY);
试一试{
线程。睡眠(mDelay);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
返回分数;
}
}
任务的
doInBackground()
方法将在后台线程上运行,因此不能从那里直接修改UI。但是,我上面覆盖的所有其他
AsyncTask
方法都是在UI线程上调用的,因此在其中任何一个线程中执行UI工作都是安全的

此代码假定拨杆由搜索栏控制,您将使您的
活动成为更改侦听器。还有很多其他的方法

我刚刚实现了一个粗糙的游戏停止机制,你可以挂上一个按钮。如果希望允许用户暂停和恢复,可以搜索暂停/恢复线程的实现,这在这里也应该适用。例如:

更多阅读。。。


有很多方法可以做到这一点。Android确实支持普通的Java
Thread
对象,您可以使用这些对象。你可以搜索(SO)android游戏循环,可能会找到很多例子。但是,如果您想尝试
AsyncTask
,下面是一个示例实现:

public class PongView extends View {

    public PongView(Context context) {
        super(context);
    }    
    public void setBallPosition(int x, int y) {
        // relocate the ball graphic
    }    
}
然后,您的活动:

public class PongDriverActivity extends Activity implements OnSeekBarChangeListener {

    private enum GameSpeed { SLOW, MEDIUM, FAST };

    private PongView mGameView;
    private PongDriverTask mWorker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mGameView = new PongView(this);
        mWorker = new PongDriverTask(GameSpeed.MEDIUM);

        // if you need to pass some data to the worker:
        mWorker.execute("one", "two", "three");  
        // else, declare the AsyncTask's first generic param as Void, and do:
        //mWorker.execute();

        setContentView(mGameView);
    }

    // you would connect this up to a button, to allow the user to stop  
    public void onStopClicked(View sender) {
        if (mWorker.isRunning()) {
            mWorker.stopRunning();
        }
    }

    // you could connect this up to a slider, to allow the user to control the paddle
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        // you may need to convert progress to a y-coordinate
        mWorker.setPaddlePosition(progress);
    }
然后(可能在PongDriverActivity.java内部,一个内部类):

私有类PongDriverTask扩展了AsyncTask{
私人国际机场;
私有布尔值mRunning=true;
私有int mpadley=0;
公共PongDriverTask(游戏速度){
如果(速度==游戏速度.慢){
mDelay=100;
}否则如果(速度==游戏速度.MEDIUM){
平均寿命=50;
}else if(速度==GameSpeed.FAST){
mDelay=10;
}
}
公共同步布尔值正在运行(){
返回运行;
}
公共同步的void stopRunning(){
mRunning=假;
}
公共同步无效设置位置(int y){
mpadley=0;
}
私有同步int-getPablePosition(){
返回mpadley;
}
@凌驾
受保护的void onPostExecute(整数分数){
super.onPostExecute(分数);
//在这里,您可以显示一个显示最终分数的UI
}
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
mGameView.setBallPosition(0,0);
//给你