Oop lab/bullets
- หน้านี้เป็นส่วนหนึ่งของ oop lab
ในปฏิบัติการนี้ เราจะทดลองใช้ interface Entity และทดลองสร้าง subclass นอกจากนี้เรายังจะได้ใช้ collection LinkedList เพื่อเก็บข้อมูล entity ด้วย
หมายเหตุ: การใช้ inheritance ในการเพิ่มประสิทธิภาพของคลาสนั้น ในบางมุมพิจารณาว่าเป็นเทคนิคที่อาจจะไม่ได้ดีที่สุดในการออกแบบคลาส อย่างไรก็ตาม ในส่วนนี้เพื่อฝึกเขียน เราจะใช้วิธีดังกล่าวไปก่อน
เนื้อหา
เริ่มต้น
สร้างโปรเจ็ค 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));
}
ทดลองเรียกโปรแกรมให้ทำงาน ดูว่ากระสุนวิ่งหรือไม่