Oop lab/bullets
- หน้านี้เป็นส่วนหนึ่งของ oop lab
ในปฏิบัติการนี้ เราจะทดลองใช้ interface Entity และทดลองสร้าง subclass นอกจากนี้เรายังจะได้ใช้ collection LinkedList เพื่อเก็บข้อมูล entity ด้วย
เนื้อหา
เริ่มต้น
สร้างโปรเจ็ค bulletgame จากนั้นสร้างคลาส BulletGame ที่ extends มาจาก BasicGame ตามที่เราเคยสร้างตามปกติ เพิ่มเมท็อดที่ต้อง implement ทั้งหมด (init, update, render) จากนั้นทดลองรันให้โปรแกรมแสดงหน้าจอว่าง ๆ
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));
}
ทดลองเรียกโปรแกรมให้ทำงาน ดูว่ากระสุนวิ่งหรือไม่