Header Ads

[Android Game] Bài 6: Xét va chạm


Phần này ta sẽ xét va chạm giữa các đối tượng.

Theo thuật toán ta thấy rằng 2 hình chữ nhật chạm nhau khi thỏa 2 điều kiện (cho 2 trục x,y là).
·        Kích thước từ tâm của HCN_A đến tâm của HCN_B  theo trục  x <= nửa rộng HCN_A + nửa rộng HCN_B
·        Kích thước từ tâm của HCN_A đến tâm của HCN_B theo trục y <= nửa cao HCN_A + nửa cao HCN_B
Các đại lượng này ta đều có thể tính được vì ta có tọa độ x,y của từng HCN và có kích thước của từng HCN.

Phần 1: Sửa class Enemies và Bullet

Giờ ta phải bổ sung cho 2 class là Bullet và Enemies các hàm để lấy được chiều rộng và chiều cao của đối tượng, và thêm hàm để lấy tâm theo trục X, tâm theo trục Y.
1.      Mở file Bullet và thêm 4 hàm như sau:
publicint getWidth()
{
     returnbitmap.getWidth();
}
publicint getHeight()
{
     returnbitmap.getHeight();
}
publicint gettamX()
{
     //tam x=toa do x congvoinuarong
     returnx+(bitmap.getWidth()/2);
}
publicint gettamY()
{
     //tam y=toa do y congnuacao
     returny+(bitmap.getHeight()/2);
}
2.      Copy đoạn 4 hàm vừa tạo trong Bullet, mở class Enemies và paste 4 hàm này vào.

Phần 2: Xây dựng hàm va chạm trong GamePanel

1.      Mở file GamePanel.java ta tạo ra một hàm mới vc_b_e, hàm này dùng để xét va chạm giữa bullet và enemies. Nó nhận vào 1 bullet và một enemies sau đó tính ra các thông tin cần thiết rồi xét điều kiện, nếu thỏa điều kiện tức là có va chạm nó trả về true, ngược lại không có va chạm thì trả về false, (có thể viết ngắn hơn nhưng chẻ ra cho nó dễ hiểu ;-)  )
publicboolean vc_b_e(Bullet bullet,Enemies enemies)
{
    
     float nuarong_b=(float)bullet.getWidth()/2;
     int nuacao_b=bullet.getHeight()/2;
     float nuarong_e=(float)enemies.getWidth()/2;
     int nuacao_e=enemies.getHeight()/2;
     //khoangcach 2 tamtheo x
     int kc_ht_x=Math.abs(bullet.gettamX()-enemies.gettamX());
     //khoangcach 2 tamtheo y
     int kc_ht_y=Math.abs(bullet.gettamY()-enemies.gettamY());
     if(kc_ht_x<=nuarong_b+nuarong_e && kc_ht_y<=nuacao_b+nuacao_e)
          returntrue;
     else
          returnfalse;
}
2.      Tiếp theo ta xây một hàm mới tên “xetvacham” hàm này sẽ duyệt tất cả bullets và tương ứng với mỗi bullets sẽ duyệt tất cả enemies để xét xem nó có va chạm không, nếu có va chạm giữa một bullets và một enemies nào đó sẽ xóa 2 thằng đó ra khỏi ArrayList. Chỗ này nên để trong try catch.
publicvoid xetvacham(Canvas canvas)
{
     try{
          for(int i=0;i<bullets.size();i++)
              for(int j=0;j<enemies.size();j++)
              {
                   if(vc_b_e(bullets.get(i), enemies.get(j))==true)
                   {
                        bullets.remove(i);
                        enemies.remove(j);
                   }
              }
     }catch(Exception e)
     {
          Log.d("loi",e.toString());
     }
    
}
3.      Cuối cùng trong hàm onDraw, sau khi vẽ bullet và enemies xong ta gọi hàm xetvacham để bỏ các đối tượng đã va chạm với nhau.
          if(myelement!=null)
          {
              myelement.doDraw(canvas);//ve may bay
              this.doDrawBullet(canvas); //ve tap hop viendan
              this.doDrawEnemies(canvas);//ve tap hop Enemies
              xetvacham(canvas);//xetvacham
          }


No comments:

Powered by Blogger.