綁定帳號登入

Android 台灣中文網

打印 上一主題 下一主題

[求助] Thread與ArrayList問題

[複製連結] 查看: 3505|回覆: 6|好評: 0
跳轉到指定樓層
樓主
n790303 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2011-8-3 11:04

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
本帖最後由 n790303 於 2011-8-3 11:05 編輯

小弟是在ANDROID初學者
大學三年級開始要做專題 我想說要做遊戲
我要做類似有個人物可以不斷踩著東西往上跳之類的
但現在卡到一個問題?
整個往上跳的邏輯已經寫出來了
但在RUN時有時候很順 但有時候玩到一半會出現"未正常終止的訊息"
我個人覺得是執行緒問題  但怎麼是還是會有這個問題

程式架構:
我把SENSOR偵測跟顯示寫在一起 就是每次偵測到的值會丟到一個副程式去做人物得移動跟人物碰撞東西得邏輯判斷和東西螢幕捲動的索引判斷

我額外有兩個執行緒一個是負責不斷刷新畫面 另一個MOVETHREAD則負責闖關過程的東西的移動和東西超過螢幕的清空刪除(不包括人物本身

  1. public  class GameView extends Activity implements SensorEventListener {
  2.   private SensorManager sensorManager;
  3.   MySurfaceView view;
  4.   
  5.   @Override
  6.     public void onCreate(Bundle savedInstanceState) {
  7.         super.onCreate(savedInstanceState);     
  8.         
  9.         requestWindowFeature(Window.FEATURE_NO_TITLE);    //設定不顯示標題
  10.       getWindow().setFlags(                //設定為全螢幕模式
  11.         WindowManager.LayoutParams.FLAG_FULLSCREEN,
  12.         WindowManager.LayoutParams.FLAG_FULLSCREEN
  13.       );

  14.     sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
  15.     view = new MySurfaceView(this);
  16.     setContentView(view);
  17.   }
  18.   @Override
  19.   protected void onResume() {
  20.   
  21.     super.onResume();
  22.     List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
  23.     if (sensors.size() > 0) {
  24.       sensorManager.registerListener(this, sensors.get(0), SensorManager.SENSOR_DELAY_GAME);
  25.     }
  26.   }
  27.   @Override
  28.   protected void onPause() {
  29.    
  30.     super.onPause();
  31.     sensorManager.unregisterListener(this);
  32.   }
  33.   @Override
  34.   public void onAccuracyChanged(Sensor sensor, int accuracy) {
  35.   }
  36.   @Override
  37.   public void onSensorChanged(SensorEvent event) {
  38.     view.onValueChanged(event.values);   //Sensor改變值傳入onValueChanged
  39.   }
  40.   class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {   
  41.     private Bitmap bitmap[]=new Bitmap[2],cloud1,cloud2,bb;
  42.     private float x,y,mov,mov_t,t_x;
  43.     int z=0,w=0;
  44.     int index=0;   
  45.     boolean upstate=true;
  46.     private TutorialThread thread;
  47.     MoveThread moveThread;
  48.    
  49.     ArrayList<cloud> clouds;
  50.    
  51.     public MySurfaceView(Context context) {
  52.       super(context);
  53.       getHolder().addCallback(this);
  54.        this.thread = new TutorialThread(getHolder(), this);
  55.        this.moveThread=new MoveThread(this);
  56.        clouds= Map.getFirst();
  57.       initpic();      

  58.     }
  59.     public void initpic(){  //初始化圖片
  60.       
  61.       Paint paint = new Paint();        
  62.       paint.setColor(Color.BLUE);  
  63.       paint.setAntiAlias(true);
  64.       bitmap[0] = BitmapFactory.decodeResource(getResources(), R.drawable.android);
  65.       bitmap[1] = BitmapFactory.decodeResource(getResources(), R.drawable.android);
  66.       cloud1 = BitmapFactory.decodeResource(getResources(), R.drawable.cloud);
  67.       cloud2 = BitmapFactory.decodeResource(getResources(), R.drawable.cloud);
  68.       bb = BitmapFactory.decodeResource(getResources(), R.drawable.bg);      
  69.       cloud1 = Bitmap.createScaledBitmap(cloud1, 95, 58, false);
  70.       cloud2 = Bitmap.createScaledBitmap(cloud2, 95, 58, false);
  71.       bb = Bitmap.createScaledBitmap(bb,320 ,800 , false);
  72.       
  73.       for(cloud cd : clouds){//為雲朵初始化圖片
  74.         if(cd.type == 1){
  75.           cd.bitmap = cloud1;
  76.         }
  77.         else if(cd.type == 2){
  78.           cd.bitmap = cloud2;
  79.         }
  80.       }      
  81.     }
  82.     @Override
  83.     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  84.       x = (getWidth() - bitmap[z].getWidth()) / 2;
  85.       y = getHeight()-bitmap[z].getHeight() ;
  86.       onValueChanged(new float[3]);
  87.     }
  88.     @Override
  89.     public void surfaceCreated(SurfaceHolder holder) {
  90.           this.thread.setFlag(true);//啟動更新視框執行緒
  91.           this.thread.start();
  92.           this.moveThread.setFlag(true);
  93.           moveThread.start();
  94.     }
  95.     @Override
  96.     public void surfaceDestroyed(SurfaceHolder holder) {
  97.           boolean retry = true;
  98.           this.thread.setFlag(false);
  99.           this.moveThread.setFlag(false);
  100.           while (retry) {  
  101.               try {
  102.                   thread.join();
  103.                   moveThread.join();
  104.                   retry = false;
  105.               }
  106.               catch (InterruptedException e) {//不斷地迴圈,直到更新視框執行緒結束
  107.               }
  108.           }
  109.     }
  110.    
  111.      void  onValueChanged(float[] values) { //Sensor值改變時進去判斷
  112.       
  113.       
  114.       
  115.       x -= values[0]*ConstantUtil.move_value;

  116.       if(t_x<x|x==(getWidth() - bitmap[z].getWidth())){    //sensor方向辦斷主角頭的轉向
  117.         z=1;
  118.       }else z=0;
  119.       t_x=x;

  120.       if(x>(getWidth() - (bitmap[z].getWidth()/2))){  //邊界判斷
  121.         x=( 0-bitmap[z].getWidth()/2);
  122.           }
  123.       if(x< 0 - (bitmap[z].getWidth()/2)){
  124.         x=(getWidth() - (bitmap[z].getWidth()/2));
  125.           }
  126.       
  127.       mov-=2;
  128.       if(y>=(getHeight()-bitmap[z].getHeight())){ //底部碰撞裝置        
  129.         mov=ConstantUtil.Jump_value;
  130.         }      
  131.         mov_t=mov;
  132.         
  133.          synchronized(this){           
  134.            try{
  135.         for(int i=1;i<=Math.abs(mov_t);i++){
  136.           if(mov>=0){
  137.           y--;
  138.           upstate=true;
  139.           }else {
  140.             y++;
  141.             upstate=false;
  142.           }
  143.           if(y<=(ConstantUtil.screenHeight/2)-bitmap[z].getHeight()){  //索引判斷(人物超過螢幕中線 索引值++            
  144.             if(upstate==true){
  145.               index++;              
  146.             }
  147.             y=(ConstantUtil.screenHeight/2)-bitmap[z].getHeight();  //因為雲動 人物要靜止         
  148.         }
  149.          
  150.           for(cloud cd : clouds){  
  151.             
  152.               cd.y+=index;    //雲執行索引相減  
  153.               if(cd.y>=(-1*ConstantUtil.cloud_height_1)){
  154.                 cd.status=true;
  155.                
  156.               }
  157.             if(y+bitmap[z].getHeight()==cd.y&(x+bitmap[z].getWidth()/2)<=(cd.x+ConstantUtil.cloud_width_1)&(x+bitmap[z].getWidth()/2)>=cd.x&cd.status==true&upstate==false){
  158.               mov=ConstantUtil.Jump_value;
  159.               y=cd.y-bitmap[z].getHeight();
  160.               break;
  161.             }            
  162.           }
  163.           index=0;//索引歸零
  164.         }
  165.            }catch(Exception e){
  166.             
  167.              e.printStackTrace();
  168.            }         
  169.         }        
  170.         onDraw();            
  171.     }

  172.       void onDraw(){
  173.       Canvas canvas = getHolder().lockCanvas();
  174.       if (canvas != null) {
  175.         canvas.drawBitmap(bb, 0, 0, null);

  176.         for(cloud cd:clouds){
  177.           if(cd.status == true){
  178.             cd.draw(canvas);
  179.           }
  180.         }         
  181.         canvas.drawBitmap(bitmap[z], x, y, null);   
  182.         getHolder().unlockCanvasAndPost(canvas);
  183.       }
  184.     }
  185.     class TutorialThread extends Thread{//更新視框執行緒
  186.       private int sleepSpan = 100;//睡眠的毫秒數
  187.       private SurfaceHolder surfaceHolder;
  188.       private  MySurfaceView veiw;
  189.       private boolean flag = false;
  190.        public TutorialThread(SurfaceHolder surfaceHolder  , MySurfaceView veiw) {//建構式
  191.               this.surfaceHolder = surfaceHolder;
  192.               this.veiw = veiw;
  193.           }
  194.           public void setFlag(boolean flag) {//設定迴圈標記位元
  195.             this.flag = flag;
  196.           }
  197.           @Override
  198.       public void run() {
  199.         
  200.               while (this.flag) {  
  201.                 synchronized(this){
  202.                   try {
  203.                     // 鎖定整個畫布,在記憶體要求比較高的情況下,建議參數不要為null
  204.                       synchronized (this.surfaceHolder) {
  205.                         veiw.onDraw();//繪製
  206.                       }
  207.                   }finally {
  208.                   }
  209.                   try{
  210.                     Thread.sleep(sleepSpan);//睡眠指定毫秒數
  211.                   }
  212.                   catch(Exception e){
  213.                     
  214.                     e.printStackTrace();//列印堆疊資訊
  215.                   }
  216.               }
  217.               }
  218.       }
  219.     }
  220.     }
  221. }
複製代碼
movethread執行緒部分

  1. public class MoveThread extends Thread {
  2.   private int sleepSpan = 0;//睡眠的毫秒數
  3.   private boolean flag = true;//迴圈旗標位元
  4.   MySurfaceView View;//GameView的引用
  5.   ArrayList<cloud> deletecloud = new ArrayList<cloud>();
  6.   
  7.   public MoveThread(MySurfaceView view){//建構式
  8.     this.View = view;
  9.   }
  10.   public void setFlag(boolean flag){
  11.     this.flag = flag;
  12.   }
  13.   @Override
  14.   public void run(){
  15.     while(flag){
  16.       synchronized(this){
  17.         try{         

  18.       for(cloud cd : View.clouds){//雲移動;索引移動        
  19.         cd.move();   

  20.         if(cd.y>(ConstantUtil.screenHeight)){
  21.           deletecloud.add(cd);
  22.         }
  23.         }      
  24.       
  25.       View.clouds.removeAll(deletecloud);
  26.       deletecloud.clear();
  27.       View.onDraw();      
  28.    
  29.       }catch(Exception e){}
  30.       }
  31.       
  32.       try{//睡眠休息
  33.         Thread.sleep(sleepSpan);
  34.       }catch(Exception e){        
  35.         e.printStackTrace();
  36.       }
  37.    
  38.     }
  39.    
  40.   }

  41. }

複製代碼
拜託各位專家幫我解決
以下圖是我的Message error
「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)
收藏收藏3 分享分享 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
沙發
zx999966 | 收聽TA | 只看該作者
發表於 2012-2-25 13:08
可能很難幫道妳囉!!
我是C++的
但還是個初學><
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

板凳
a8699334 | 收聽TA | 只看該作者
發表於 2012-3-5 20:57

好東西,謝謝分享!
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

地板
 樓主| n790303 | 收聽TA | 只看該作者
發表於 2012-3-5 21:06
以解決
最後我用
java裡的
try...catch
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

5
shawn00 | 收聽TA | 只看該作者
發表於 2012-6-12 19:23
我不是寫jAVA的 不過
try catch能少用就少用
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

6
ColorWeal | 收聽TA | 只看該作者
發表於 2012-6-25 10:18
在android中建議用AsyncTask去替代Thread,畢竟這是適用於android架構的
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

7
fttp123 | 收聽TA | 只看該作者
發表於 2012-11-30 22:42
哈哈~沒想到他老婆已經變成魔鬼妹妹了
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則