2015年2月19日 星期四

pygtk Cairo動畫(續)碰撞信號處理實做

程式原碼下載



我寫的move_object.py這模組,算蠻強大的,後續會應用這模組,製造更多動畫,主程式下面以move_object.py我製造一張會抖動的太空背景,因ubuntu1410,我先關掉抖動,後續在改,若是debian可把
          #self.move_obj_b.set_move_speed(.5)
          #self.move_obj_b.set_move_type("背景")
打開,就會有抖動效果,按方向建右鍵增加移動飛碟,若飛碟相撞會產生爆炸,並從視窗消失,按方向建左鍵移走飛碟

    #畫出背景
    def draw_background(self):
          p="background.png"
          #ubuntu1410 bug座標不能0,0
          self.move_obj_b=move_object.move_object(self,self.framme1,self.darea,p,1,1)
          #self.move_obj_b.set_move_to_xy(0,0) ubuntu1410 don't work跑到0,0會X error
          #若不要背景移動,下面不要設定
          #self.move_obj_b.set_move_speed(.5)
          #self.move_obj_b.set_move_type("背景")

    #畫出隨機飛碟
    def generate(self):
          p="logo"+str(random.randint(1,3))+".png"
          move_obj=move_object.move_object(self,self.framme1,self.darea,p)
          speed=float(random.randint(1,100))/100
          move_obj.set_move_speed(speed)
          if(random.randint(1,100) >50 ):
              move_obj.set_move_type("亂數")
          else:
              move_obj.set_move_type("直線X")
          #加到列表list
          self.move_list_signal.move_list_append(move_obj)


再來重要的動畫碰撞信號實做,來看看如何實做,到目前程式很少就做出了很複雜動作,其實在於邏輯是否夠好,可行,程式就會簡潔有力,在move_object.py修改了SEND_MOVE_SIGNAL方法,碰撞時呼叫self.main_obj.RECEVER否則呼叫self.main_obj.RECEVER_MOVE

    #碰撞時透過thread發送信號,把本身和碰撞物當參數,否則送出本身       
    def SEND_MOVE_SIGNAL(self):
        if(self.is_check_collision):
            self.main_obj.RECEVER(self,self.c_obj)
        else:
            self.main_obj.RECEVER_MOVE(self)


在move_object.py增加了碰撞方法,碰撞產生時self.is_check_collision=True,此時SEND_MOVE_SIGNAL改成呼叫self.main_obj.RECEVER,一開始self.is_check_collision=False

    def check_collision(self,other_obj):

         

          xo,yo=other_obj.get_xy()
          xo_w,yo_h=other_obj.get_width_height()
          xo1=xo+xo_w
          yo1=yo+yo_h
          #本身座標和寬高
          xs,ys=self.get_xy()
          xs_w,ys_h=self.get_width_height()
          xs1=xs+xs_w
          ys1=ys+ys_h
          #print(xo,yo,xo1,yo1,xs,ys,xs1,ys1)
          if(self.is_collision(xo,yo,xo1,yo1,xs,ys,xs1,ys1)):
              self.is_check_collision=True
              self.c_obj=other_obj
              self.set_move_type=None#碰撞後不要在移動了

在來看主程式,如何接收信號,非碰撞時接收RECEVER_MOVE,然後將移動物參數送給move_list_signal(類似界面),move_list_signal這個類,會將移動物送給各個移動物,做碰撞判斷,若主程式收到碰撞信號RECEVER,會透過move_list_signal這個類,會將移動物和被碰撞物刪除,並產生爆炸畫面,簡單邏輯,就能造成強大效果,做出複雜的動作,很神奇吧!


    #接收移動動畫信號,移動物移動時會收到信號,送到move_list_signal作檢查,參數為移動物
    def RECEVER_MOVE(self,move_object):

        #檢查碰撞,若不要檢查,忽略
        self.move_list_signal.check_collision(move_object)

    #接收移動動畫信號,移動物,和碰撞物碰撞時會收到信號,參數為移動物和碰撞物
    def RECEVER(self,move_object,c_object):
        #print(move_object.get_name())
        #從list中移走移動物,和碰撞物,True代表產生爆炸畫面,若不要爆炸畫面設False
        self.move_list_signal.kill_move_obj(move_object,True)
        self.move_list_signal.kill_move_obj(c_object,True)
  其餘看程式註解,下面是執行畫面

沒有留言: