Oop lab/bullets

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
หน้านี้เป็นส่วนหนึ่งของ oop lab

ในปฏิบัติการนี้ เราจะทดลองใช้ interface Entity และทดลองสร้าง subclass นอกจากนี้เรายังจะได้ใช้ collection LinkedList เพื่อเก็บข้อมูล entity ด้วย

เริ่มต้น

สร้างโปรเจ็ค bulletgame จากนั้นสร้างคลาส BulletGame ที่ extends มาจาก BasicGame ตามที่เราเคยสร้างตามปกติ เพิ่มเมท็อดที่ต้อง implement ทั้งหมด (init, update, render) จากนั้นทดลองรันให้โปรแกรมแสดงหน้าจอว่าง ๆ

Gitmark.png เก็บเวอร์ชั่นหน้าจอว่างโดยการ commit

interface Entity

ในลักษณะเดียวกับที่เราทำในคลิป YouTube เรื่อง interface เราจะสร้าง interface Entity เพื่อใช้ระบุเมท็อดพื้นฐานทั้งหมดที่ "ของ" ที่จะอยู่บนหน้าจอเกมของเราจะต้องเขียน

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

สังเกตว่าเมท็อด render จะส่ง Graphics g มาด้วย และเมท็อด update ก็จะส่ง delta มาให้ด้วยเช่นกัน

เราจะประกาศ interface ทิ้งไว้ก่อน ส่วนโค้ดที่เรียกใช้งานนั้น เราจะเขียนหลักเขียนคลาส Bullet แล้ว

คลาส Bullet

คลาส Bullet นี้จะเป็นคลาสพื้นฐานของกระสุนทั้งหมด โดยทำหน้าที่หลักเพียงแค่วาดรูปกระสุนด้วยวงกลม และสามารถขยับกระสุนไปในทิศทางแกน y เท่านั้น

สังเกตว่าในคลาสนี้ เราให้ field x และ y เป็น private แต่เราสร้าง getters/setters ดังนี้

  • getX, getY เป็น public
  • setXY เป็น protected เพราะว่าเราต้องการให้ subclass คำนวณการเคลื่อนที่ของ Bullet ได้ แต่ต้องเรียกผ่านทางเมท็อดนี้
public class Bullet implements Entity {

  private static final float BULLET_SIZE = 5;
  private float x;
  private float y;

  public Bullet(float x, float y) {
    this.setXY(x,y);    
  }
  
  @Override
  public void render(Graphics g) {
    g.fillOval(getX(), getY(), BULLET_SIZE, BULLET_SIZE);
  }

  @Override
  public void update(int delta) {
    y += 10;
  }

  public float getX() {
    return x;
  }

  public float getY() {
    return y;
  }

  protected void setXY(float x, float y) {
    this.x = x;
    this.y = y;
  }
}

เพิ่ม Bullet ใน BulletGame

เราจะสร้าง bullet เพื่อทดลองในโปรแกรม ในคลาส BulletGame โดยในโปรแกรมจะพิจารณาวัตถุทั้งหมดเป็น Entity

เพิ่มฟิลด์ entities ในคลาส BulletGame

  private LinkedList<Entity> entities;

สังเกตว่าเราใช้ LinkedList ในการเก็บ entity เพราะว่าสุดท้าย เราจะต้องจัดการลบ entity ที่ไม่ได้ใช้งานออกจากระบบด้วย entity พวกนี้ เช่น กระสุนที่วิ่งออกไปนอกจอแล้ว เป็นต้น ถ้าเราใช้ ArrayList การลบข้อมูลดังกล่าวจะไม่ค่อยมีประสิทธิภาพเท่า LinkedList

ปรับ render และ update ให้เรียก render และ update ทุก ๆ entity ใน entities

  @Override
  public void render(GameContainer container, Graphics g) throws SlickException {
    for (Entity entity : entities) {
      entity.render(g);
    }
  }

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

สุดท้าย สร้างกระสุนใน init

  @Override
  public void init(GameContainer container) throws SlickException {
    entities.add(new Bullet(200,0));
  }

ทดลองเรียกโปรแกรมให้ทำงาน ดูว่ากระสุนวิ่งหรือไม่

Gitmark.png ถ้าโปรแกรมทำงานได้ ให้ commit งานของคุณด้วย

กระสุนแบบมีทิศทาง