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