ผลต่างระหว่างรุ่นของ "Oop lab/การลบ entity"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
 
(ไม่แสดง 4 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน)
แถว 3: แถว 3:
 
จากแลบ [[oop lab/bullets]] เราได้เว้นส่วนที่ลบ bullet ที่ออกนอกหน้าจอไป ในส่วนนี้เราจะพัฒนาส่วนดังกล่าว
 
จากแลบ [[oop lab/bullets]] เราได้เว้นส่วนที่ลบ bullet ที่ออกนอกหน้าจอไป ในส่วนนี้เราจะพัฒนาส่วนดังกล่าว
  
== Entities ==
 
 
เราเก็บ entities ใน LinkedList เพื่อที่จะได้ลบ entity ที่ไม่ต้องการออกจากโครงสร้างได้รวดเร็ว  (สำหรับส่วนนี้อ่านเพิ่มเติมที่ [[oop lab/java collections|Java collections]])
 
เราเก็บ entities ใน LinkedList เพื่อที่จะได้ลบ entity ที่ไม่ต้องการออกจากโครงสร้างได้รวดเร็ว  (สำหรับส่วนนี้อ่านเพิ่มเติมที่ [[oop lab/java collections|Java collections]])
  
 
ในการเขียนโปรแกรมแบบ oop งานหลักของนักพัฒนาคือการเลือกว่ากิจกรรมใดจะดำเนินการที่ใด และ object ต่าง ๆ จะร่วมมือกันดำเนินการกิจกรรมที่ต้องการได้อย่างไร  สำหรับการลบ entity ออกจาก linked list entities นี้ เรามีทางเลือกในการดำเนินการหลายแบบ
 
ในการเขียนโปรแกรมแบบ oop งานหลักของนักพัฒนาคือการเลือกว่ากิจกรรมใดจะดำเนินการที่ใด และ object ต่าง ๆ จะร่วมมือกันดำเนินการกิจกรรมที่ต้องการได้อย่างไร  สำหรับการลบ entity ออกจาก linked list entities นี้ เรามีทางเลือกในการดำเนินการหลายแบบ
 +
 +
== วิธีที่ 1: ลบใน update loop ==
  
 
ลองพิจารณาเมท็อดที่เกี่ยวข้องกับ entities ในคลาส BulletGame ก่อน
 
ลองพิจารณาเมท็อดที่เกี่ยวข้องกับ entities ในคลาส BulletGame ก่อน
แถว 24: แถว 25:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
เมท็อดนี้จะต้องมีวิธีการที่จะทราบได้ว่า entity ใด ควรจะถูกลบ เพื่อการแจ้งข้อมูลดังกล่าว เราจะเพิ่ม interface Entity ให้มีเมท็อด <tt>isDeleted</tt> ด้วย ดังนี้
+
เมท็อดนี้จะต้องมีวิธีการที่จะทราบได้ว่า entity ใด ควรจะถูกลบ เพื่อการแจ้งข้อมูลดังกล่าว เราจะเพิ่ม interface Entity ให้มีเมท็อด <tt>isDeletable</tt> ด้วย ดังนี้
  
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
แถว 30: แถว 31:
 
   void render(Graphics g);
 
   void render(Graphics g);
 
   void update(int delta);
 
   void update(int delta);
   boolean isDeleted();
+
   boolean isDeletable();
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
จากนั้นเราจะแก้เมท็อด update ให้เรียกเมท็อด isDeleted ดังกล่าว และลบข้อมูลจากลิงก์ลิสต์  การลบข้อมูลในลิงก์ลิสต์ให้รวดเร็ว เราจะต้องใช้ iterator ในการวิ่งไปในลิสต์และลบผ่านทาง iterator (อ่าน [[oop lab/java collections|Java Collections]]) โดยโค้ดของเมท็อด update เป็นดังนี้
+
จากนั้นเราจะแก้เมท็อด update ให้เรียกเมท็อด isDeletable ดังกล่าว และลบข้อมูลจากลิงก์ลิสต์  การลบข้อมูลในลิงก์ลิสต์ให้รวดเร็ว เราจะต้องใช้ iterator ในการวิ่งไปในลิสต์และลบผ่านทาง iterator (อ่าน [[oop lab/java collections|Java Collections]]) โดยโค้ดของเมท็อด update เป็นดังนี้
  
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
แถว 43: แถว 44:
 
       Entity entity = iterator.next();
 
       Entity entity = iterator.next();
 
       entity.update(delta);
 
       entity.update(delta);
       if (entity.isDeleted()) {
+
       if (entity.isDeletable()) {
 
         iterator.remove();
 
         iterator.remove();
 
       }
 
       }
แถว 50: แถว 51:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== isDeleted ของ Bullet ==
+
=== isDeletable ของ Bullet ===
 +
จากนั้นเราเพิ่มการ implement เมท็อด isDeletable ในคลาส Bullet โดยเราจะลบกระสุนได้เมื่อออกนอกจอ
  
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
แถว 58: แถว 60:
 
   }
 
   }
 
    
 
    
   public boolean isDeleted() {
+
   public boolean isDeletable() {
 
     return isOutOfScreen();
 
     return isOutOfScreen();
 
   }
 
   }
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== isDeleted ของ StarBullet ==
+
=== isDeletable ของ StarBullet ===
 +
 
 +
ในกรณีของ StarBullet นั้นอาจจะแตกต่างไป เพราะว่าเราจะลบได้เมื่อกระสุนทุกลูกออกนอกจอไปแล้ว
  
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
 
   @Override
 
   @Override
   public boolean isDeleted() {
+
   public boolean isDeletable() {
     boolean allDeleted = true;
+
     boolean allDeletable = true;
 
     for (DirectionalBullet bullet : bullets) {
 
     for (DirectionalBullet bullet : bullets) {
       if (!bullet.isOutOfScreen()) {
+
       if (!bullet.isDeletable()) {
         allDeleted = false;
+
         allDeletable = false;
 
       }
 
       }
 
     }
 
     }
     return allDeleted;
+
     return allDeletable;
 
   }
 
   }
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== วิธีที่ 2 ==

รุ่นแก้ไขปัจจุบันเมื่อ 03:01, 22 กันยายน 2557

หน้านี้เป็นส่วนหนึ่งของ oop lab.

จากแลบ oop lab/bullets เราได้เว้นส่วนที่ลบ bullet ที่ออกนอกหน้าจอไป ในส่วนนี้เราจะพัฒนาส่วนดังกล่าว

เราเก็บ entities ใน LinkedList เพื่อที่จะได้ลบ entity ที่ไม่ต้องการออกจากโครงสร้างได้รวดเร็ว (สำหรับส่วนนี้อ่านเพิ่มเติมที่ Java collections)

ในการเขียนโปรแกรมแบบ oop งานหลักของนักพัฒนาคือการเลือกว่ากิจกรรมใดจะดำเนินการที่ใด และ object ต่าง ๆ จะร่วมมือกันดำเนินการกิจกรรมที่ต้องการได้อย่างไร สำหรับการลบ entity ออกจาก linked list entities นี้ เรามีทางเลือกในการดำเนินการหลายแบบ

วิธีที่ 1: ลบใน update loop

ลองพิจารณาเมท็อดที่เกี่ยวข้องกับ entities ในคลาส BulletGame ก่อน

  • public void render(GameContainer container, Graphics g)
  • public void update(GameContainer container, int delta)

ในที่นี้ งานของเราน่าจะเกี่ยวกับการปรับตำแหน่งของ entity (ส่วน update) ดังนั้นเราจะจัดการเกี่ยวกับการลบ entity ในเมท็อด update ซึ่งเมท็อดเดิมเป็นดังนี้:

  @Override
  public void update(GameContainer container, int delta) throws SlickException {
    for(Entity entity : entities) {
      entity.update(delta);
    }
  }

เมท็อดนี้จะต้องมีวิธีการที่จะทราบได้ว่า entity ใด ควรจะถูกลบ เพื่อการแจ้งข้อมูลดังกล่าว เราจะเพิ่ม interface Entity ให้มีเมท็อด isDeletable ด้วย ดังนี้

public interface Entity {
  void render(Graphics g);
  void update(int delta);
  boolean isDeletable();
}

จากนั้นเราจะแก้เมท็อด update ให้เรียกเมท็อด isDeletable ดังกล่าว และลบข้อมูลจากลิงก์ลิสต์ การลบข้อมูลในลิงก์ลิสต์ให้รวดเร็ว เราจะต้องใช้ iterator ในการวิ่งไปในลิสต์และลบผ่านทาง iterator (อ่าน Java Collections) โดยโค้ดของเมท็อด update เป็นดังนี้

  @Override
  public void update(GameContainer container, int delta) throws SlickException {
    Iterator<Entity> iterator = entities.iterator();
    while (iterator.hasNext()) {
      Entity entity = iterator.next();
      entity.update(delta);
      if (entity.isDeletable()) {
        iterator.remove();
      }
    }
  }

isDeletable ของ Bullet

จากนั้นเราเพิ่มการ implement เมท็อด isDeletable ในคลาส Bullet โดยเราจะลบกระสุนได้เมื่อออกนอกจอ

  public boolean isOutOfScreen() {
    return (getX() < 0) || (getX() > BulletGame.GAME_WIDTH) ||
        (getY() < 0) || (getY() > BulletGame.GAME_HEIGHT);
  }
  
  public boolean isDeletable() {
    return isOutOfScreen();
  }

isDeletable ของ StarBullet

ในกรณีของ StarBullet นั้นอาจจะแตกต่างไป เพราะว่าเราจะลบได้เมื่อกระสุนทุกลูกออกนอกจอไปแล้ว

  @Override
  public boolean isDeletable() {
    boolean allDeletable = true;
    for (DirectionalBullet bullet : bullets) {
      if (!bullet.isDeletable()) {
        allDeletable = false;
      }
    }
    return allDeletable;
  }

วิธีที่ 2