ผลต่างระหว่างรุ่นของ "Oop lab/maze game"
Jittat (คุย | มีส่วนร่วม) |
Jittat (คุย | มีส่วนร่วม) |
||
แถว 65: | แถว 65: | ||
=== คลาส Maze === | === คลาส Maze === | ||
เราจะสร้างคลาส Maze ที่แสดงแผนที่ โดยในการแสดงแผนที่เราจะแสดงโดยใช้รูปเล็ก ๆ ขนาด 40 x 40 มาประกอบกันเพื่อแสดงเป็นแผนที่ ดังนั้นในขั้นแรกให้สร้างไฟล์ wall.png ที่เป็นรูปกำแพงขนาด 40 x 40 และเก็บไว้ในไดเร็กทอรี res | เราจะสร้างคลาส Maze ที่แสดงแผนที่ โดยในการแสดงแผนที่เราจะแสดงโดยใช้รูปเล็ก ๆ ขนาด 40 x 40 มาประกอบกันเพื่อแสดงเป็นแผนที่ ดังนั้นในขั้นแรกให้สร้างไฟล์ wall.png ที่เป็นรูปกำแพงขนาด 40 x 40 และเก็บไว้ในไดเร็กทอรี res | ||
+ | |||
+ | ก่อนที่เราจะจัดการเรื่องการเก็บข้อมูลต่าง ๆ เรามาทำคลาส Maze ให้แสดงรูปนี้ให้ได้ก่อน คลาส Maze จะมี constructor เราจะสร้าง Image ของช่องที่จะเป็นผนัง | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | public class Maze { | ||
+ | private Image wallImage = null; | ||
+ | |||
+ | public Maze() { | ||
+ | try { | ||
+ | wallImage = new Image("res/wall.png"); | ||
+ | } catch (SlickException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // ... | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | เราจะสร้างเมท็อด render เพื่อให้คลาส MazeGame มาเรียกให้ Maze แสดงผล เราจะแสดงผลแบบง่าย ๆ ก่อน ดังนี้ | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | public void render() { | ||
+ | wallImage.draw(100, 100); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | จากนั้นในคลาส MazeGame เราก็ไปเพิ่มการสร้าง maze และการสั่งให้ maze แสดงผล | ||
+ | |||
+ | ด้านล่างแสดงโค้ดในคลาส '''MazeGame''' ที่เราแก้ไข | ||
+ | |||
+ | <syntaxhighlight lang="java"> | ||
+ | private Maze maze; | ||
+ | // ... | ||
+ | |||
+ | @Override | ||
+ | public void init(GameContainer container) throws SlickException { | ||
+ | maze = new Maze(); | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void render(GameContainer container, Graphics g) throws SlickException { | ||
+ | maze.render(); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
สำหรับเกมนี้ เพื่อความง่าย เราจะระบุขนาดของแผนที่ให้เหมาะสมกับหน้าจอของเกมของเราไปเลย สังเกตว่าหน้าจอของเราขนาด 640 x 480 ถ้าช่องของเราขนาด 40 x 40 เราจะแสดง maze ได้ 12 แถว x 16 คอลัมน์ เราจะเว้นแถวบนกับแถวล่างไว้เพื่อใช้แสดงข้อมูลอื่น ๆ ดังนั้นเราจะได้ว่าเราจะใช้แผนที่ขนาด 16 คอลัมน์ x 10 แถว | สำหรับเกมนี้ เพื่อความง่าย เราจะระบุขนาดของแผนที่ให้เหมาะสมกับหน้าจอของเกมของเราไปเลย สังเกตว่าหน้าจอของเราขนาด 640 x 480 ถ้าช่องของเราขนาด 40 x 40 เราจะแสดง maze ได้ 12 แถว x 16 คอลัมน์ เราจะเว้นแถวบนกับแถวล่างไว้เพื่อใช้แสดงข้อมูลอื่น ๆ ดังนั้นเราจะได้ว่าเราจะใช้แผนที่ขนาด 16 คอลัมน์ x 10 แถว | ||
+ | |||
+ | |||
เราจะเริ่มสร้างคลาส Maze โดยเริ่มจากกำหนดค่าคงที่ของคลาสก่อน ดังนี้ | เราจะเริ่มสร้างคลาส Maze โดยเริ่มจากกำหนดค่าคงที่ของคลาสก่อน ดังนี้ | ||
แถว 100: | แถว 150: | ||
MAP[r].charAt(c) | MAP[r].charAt(c) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== ตัว Pacman และการเคลื่อนที่ == | == ตัว Pacman และการเคลื่อนที่ == |
รุ่นแก้ไขเมื่อ 08:54, 4 ตุลาคม 2557
- หน้านี้เป็นส่วนหนึ่งของ oop lab
- เนื้อหาส่วนนี้ ถ้าต้องการดูเป็นภาษา JavaScript กรุณาดูที่ 01219245/cocos2d/Maze
ในส่วนนี้เราจะพิจารณาการเขียนเกมที่เป็นตารางและผู้เล่นเครื่องที่ไปมาในตาราง เกมที่เป็นตัวอย่างคลาสสิกของเกมตระกูลนี้คือ PacMan หน้าตาของเกมนี้แสดงดังด้านล่าง
เนื้อหา
ขั้นตอน
เราจะค่อย ๆ เขียนโปรแกรมไปทีละขั้น ๆ ดังนี้
- แสดงแผนที่
- แสดงตัวผู้เล่นและขยับตัวผู้เล่น แบ่งเป็นขั้นย่อย ๆ หลายขั้น
- แสดงตัวผู้เล่น
- ขยับตัวผู้เล่นตามการกดปุ่ม โดยไม่สนใจแผนที่
- ขยับตัวผู้เล่นให้ตรงช่องแผนที่ แต่อาจวิ่งทะลุกำแพง
- ขยับตัวผู้เล่นให้ตรงแผนที่และไม่วิ่งทะลุกำแพง
- แสดงจุด และให้ผู้เล่นกินจุดได้
ในหลาย ๆ ขั้นตอนสามารถเขียนได้หลายแบบ โดยมีข้อดีและข้อเสียแตกต่างกันไป ดังนั้นในการเขียนจริง ผู้เขียนอาจจะเลือกเขียนไม่เหมือนในเอกสารนี้ก็ได้
โค้ดทั้งหมดอยู่ที่: https://github.com/jittat/slick2d-mazegame
แสดงแผนที่
หน้าจอเปล่า/คลาส MazeGame
เช่นเคย เราจะเริ่มโดยสร้างโปรแกรมที่แสดงหน้าจอเปล่า
public class MazeGame extends BasicGame {
public static final int GAME_WIDTH = 640;
public static final int GAME_HEIGHT = 480;
public MazeGame(String title) {
super(title);
}
@Override
public void init(GameContainer container) throws SlickException {
}
@Override
public void render(GameContainer container, Graphics g) throws SlickException {
}
@Override
public void update(GameContainer container, int delta) throws SlickException {
}
public static void main(String[] args) {
try {
MazeGame game = new MazeGame("Maze Game");
AppGameContainer container = new AppGameContainer(game);
container.setDisplayMode(GAME_WIDTH, GAME_HEIGHT, false);
container.setMinimumLogicUpdateInterval(1000 / 60);
container.start();
} catch (SlickException e) {
e.printStackTrace();
}
}
}
คลาส Maze
เราจะสร้างคลาส Maze ที่แสดงแผนที่ โดยในการแสดงแผนที่เราจะแสดงโดยใช้รูปเล็ก ๆ ขนาด 40 x 40 มาประกอบกันเพื่อแสดงเป็นแผนที่ ดังนั้นในขั้นแรกให้สร้างไฟล์ wall.png ที่เป็นรูปกำแพงขนาด 40 x 40 และเก็บไว้ในไดเร็กทอรี res
ก่อนที่เราจะจัดการเรื่องการเก็บข้อมูลต่าง ๆ เรามาทำคลาส Maze ให้แสดงรูปนี้ให้ได้ก่อน คลาส Maze จะมี constructor เราจะสร้าง Image ของช่องที่จะเป็นผนัง
public class Maze {
private Image wallImage = null;
public Maze() {
try {
wallImage = new Image("res/wall.png");
} catch (SlickException e) {
e.printStackTrace();
}
}
// ...
}
เราจะสร้างเมท็อด render เพื่อให้คลาส MazeGame มาเรียกให้ Maze แสดงผล เราจะแสดงผลแบบง่าย ๆ ก่อน ดังนี้
public void render() {
wallImage.draw(100, 100);
}
จากนั้นในคลาส MazeGame เราก็ไปเพิ่มการสร้าง maze และการสั่งให้ maze แสดงผล
ด้านล่างแสดงโค้ดในคลาส MazeGame ที่เราแก้ไข
private Maze maze;
// ...
@Override
public void init(GameContainer container) throws SlickException {
maze = new Maze();
}
@Override
public void render(GameContainer container, Graphics g) throws SlickException {
maze.render();
}
สำหรับเกมนี้ เพื่อความง่าย เราจะระบุขนาดของแผนที่ให้เหมาะสมกับหน้าจอของเกมของเราไปเลย สังเกตว่าหน้าจอของเราขนาด 640 x 480 ถ้าช่องของเราขนาด 40 x 40 เราจะแสดง maze ได้ 12 แถว x 16 คอลัมน์ เราจะเว้นแถวบนกับแถวล่างไว้เพื่อใช้แสดงข้อมูลอื่น ๆ ดังนั้นเราจะได้ว่าเราจะใช้แผนที่ขนาด 16 คอลัมน์ x 10 แถว
เราจะเริ่มสร้างคลาส Maze โดยเริ่มจากกำหนดค่าคงที่ของคลาสก่อน ดังนี้
public class Maze {
static public int ROWS = 10;
static public int COLS = 16;
static public int BLOCK_SIZE = 40;
// ...
}
เกม maze จำนวนมากมายสามารถเปลี่ยนแผนที่ได้ สำหรับเกมนี้แม้เรายังไม่ได้พัฒนาไประดับนั้น แต่เราก็จะเก็บแผนที่แยกไว้เป็นค่าคงที่ของคลาส ถ้าในอนาคตต้องการเปลี่ยนแผนที่ก็น่าจะทำได้โดยง่าย ในคลาส Maze ประกาศค่าคงที่ของคลาสเพิ่มเติมเป็นแผนที่ โดยเราจะเก็บเป็นอาร์เรย์ของสตริง ดังนี้
static private String[] MAP = {
"################",
"#..............#",
"#.#.###..###.#.#",
"#...#......#...#",
"#.#...#..#...#.#",
"#.#...#..#...#.#",
"#...#......#...#",
"#.#.###..###.#.#",
"#..............#",
"################"
};
ในการเก็บข้อมูลดังกล่าว ถ้าต้องการทราบข้อมูลของแผนที่แถวที่ r คอลัมน์ที่ c (นับดัชนีเริ่มที่ 0) เราสามารถสั่งได้ดังนี้
MAP[r].charAt(c)