Phát triển game đơn giãn trên máy tính nhanh nhất

41 499 0
Phát triển game đơn giãn trên máy tính nhanh nhất

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Lập trình game Lập trình game đơn giảnLập trình game nhanh nhấtcách Lập trình game Lập trình game trên máy tínhCách lập trình game đơn giảnLàm game onlineHướng dẫn làm gameLOLlàm game Liên minh online

Phát triển game đơn giãn Mobile(P1) Giới thiệu: Bài nhằm mục tiêu cung cấp hướng dẫn, giới thiệu cách thức để phát triển trò chơi đơn giãn J2ME Trước đọc này, khuyên bạn nên tìm hiểu sơ lược platform J2ME.Đây platform Java sử dụng để phát triển ứng dụng thiết bị nhúng, mobile…Bây giờ, tìm hiểu phần Phần một: Ngõ vào ứng dụng(entry point): Trong tất ứng dụng J2ME, để chạy ứng dụng phải extends từ lớp ảo(abstract) MIDlet gói javax.microedition.midlet, tương tự tạo applet phải extend từ lớp java.applet.Applet Và entry point phương thức startApp(), tương tự phương thức main() J2SE Ví dụ: Ta có lớp MyMidlet publicclass MyMidlet extends MIDlet{ // invoked when the application starts and each time is resumed protectedvoid startApp() throws MIDletStateChangeException {} // invoked when the MIDlet needs to be destroyed protectedvoid destroyApp(boolean uncondicional) throws MIDletStateChangeException {} // invoked when the MIDlet needs to be paused (Some phones ignore pauseApp().) protectedvoid pauseApp() {} } Nếu bạn tạo project chạy file hiển thị hình blank Tiếp theo, để trình bày nội dung ứng dụng, bạn cần sử dụng lớp Display Lớp Display điều khiển tất xảy hình MIDlet, MIDlet có đối tượng Display truy cập thơng qua việc sử dụng phương thức tĩnh getDisplay() Để biểu diễn đối tượng hình, bạn cần phải sử dụng phương thức setCurrent() lớp Displayable Ví dụ: ta có lớp Alert, lớp kế thừa từ lớp Displayable, ví dụ sử dụng Alert để hiển thị câu thông báo đơn giãn lên hình Alert alert; //entry point for the application protectedvoid startApp() throws MIDletStateChangeException { // creates alert alert = new Alert("Hello World"); // shows alert in the screen Display.getDisplay(this).setCurrent(alert); } Nếu chạy chương trình, bạn thấy hiển thị thơng điệp sau: Tiếp theo, để thêm command cho ứng dụng, commad exit, bạn xử lý sau: Command comExit; [ ] protectedvoid startApp() throws MIDletStateChangeException { [ ] // create command comExit = new Command("Exit", Command.EXIT, 1); // add a command to exit the Midlet alert.addCommand(comExit); [ ] } Đoạn code show cho bạn command exit lên hình, bạn click vào, khơng làm bạn cần thêm CommandListener vào Alert để đăng ký listener publicclass MyMidlet extends MIDlet implements CommandListener{ publicvoid startApp() { [ ] // adds a listener to the alert alert.setCommandListener(this); } publicvoid commandAction(Command cmd, Displayable display) { // check what command was selectedif (cmd == comExit) { notifyDestroyed(); } } } Với thay đổi này, có MIDlet hoàn chỉnh Ở phần tiếp theo, có nhìn chi tiết phần tử giao diện người dùng như: Alert, Display, CommandListener Phát triển game đơn giãn Mobile(P2) Ở phần này, ta tìm hiểu thành phần giao diện người dùng(UI) có sẵn J2ME nhằm tạo tương tác người dùng với điện thoại, vấn đề quan trọng kích thước hình điện thoại giới hạn J2ME cung cấp đặc tả MIDP chứa thành phần giao diện đồ họa, có nhiều phiên MIDP 3.0, nhiên xét MIDP 2.0 Ta tìm hiểu sơ đồ phân lớp nó: MIDP 2.0 cung cấp lớp UI gói javax.microedition.lcdui, lcdui viết tắt liquid crystal display user interface(LCD UI) Để show phần tử UI lên hình, bạn phải sử dụng lớp Displayable Ví dụ, lớp Displayable có title, ticker, command liên kết với Lớp Display quản lý hiển thị lên hình Phương thức static getDisplay(MIDlet midlet) cho phép bạn truy cập vào Display MIDlet Sau đó, bạn sử dụng phương thức setCurrent(Displayable element) để lựa chọn đối tượng extend từ Displayable hiển thị lên hình Tại thời điểm, có đối tượng Displayable hiển thị hình Hãy xem lại ví dụ từ trước: Display.getDisplay(this).setCurrent(alert); Trong MIDP, phân chia lớp thành thành phần: thành phần giao diện cấp cao(highlevel interface component) cấp thấp(low-level) Các thành phần high-level thực thi thông qua lớp extends từ class Screen, thành phần low-level thực thi thông qua lớp extends từ class Canvas Và tất chúng extends từ class Displayable Bất kỳ ứng dụng kết hợp thành phần giao diện high-level lowlevel để phục vụ cho mục đích ứng dụng Ví dụ, ứng dụng game, List Form sử dụng để chọn lựa hay cấu hình game, Canvas (hay GameCanvas) sử dụng cho thành phần tương tác game tạo nhân vật chuyển động, ảnh background Lớp Command: Một MIDlet tương tác với người dùng thông qua Command Một Command tương đương với menu item ứng dụng thông thường, kết hợp với phần tử UI Displayable Lớp Displayable cho phép người dùng attacth Command cách sử dung phương thức addCommand(Command command) Một đối tượng Displayable cón nhiều Command bên nó.Lớp Command nắm giữ thơng tin command Thơng tin đóng gói thuộc tính: short label, optional long label, command type priority Ví dụ, sử dụng lớp Command để tạo đối tượng command thông qua cung cấp giá trị Constructor: // adds a command to exit the MIDlet comExit = new Command("Exit", Command.EXIT, 1); Lưu ý command không thay đổi chúng tạo Nếu xác định command type, bạn cho phép thiết bị chạy MIDlet ánh xạ(map) phím định sẵn thiết bị vào command Ví dụ, command với kiểu OK ánh xạ vào phím OK thiết bị Trong MIDP 2.0, có sẵn kiểu command sau: BACK, CANCEL, EXIT, HELP, ITEM, SCREEN STOP Kiểu SCREEN liên quan đến command map ứng dụng cho hiền thời Cả SCREEN ITEM khơng có phím ánh xạ thiết bị.Để nhận phản hồi từ người dùng, bạn cần phải listen từ command, điều thực thông qua thực thi giao diện CommandListener Trong ví dụ Hello World, Interface thực thi thơng qua phương thức commandAction() Ví dụ: alert.addCommand(comExit); // adds a listener to the form alert.setCommandListener(this); [ ] publicvoid commandAction(Command cmd, Displayable display) { if (cmd == comExit) { exit(); } } Như bạn thấy, phương thức commandAction() nhận tham số: Command thực thi Displayable hiển thị Giao diện người dùng cấp cao(High-level User Interface): Các API giao diện người dùng cấp cao thiết kế cho ứng dụng kinh doanh khách hàng mà thành phần client chạy thiết bị di động Đối với loại ứng dụng này, tính linh động(portability) qua nhiều thiết bị quan trọng Để đạt tính linh động vậy, API mức cao trừu tượng hóa(abstraction) cung cấp điều khiển look anh feel Điều cho phép thiết bị sử dụng look and feel giao diên người dùng tự nhiên(native) để hiển thị thay cho thành phần giao diện MIDP high-level Điều có nghĩa mơt ứng dụng viết API high-level, look and feel cách tự động sử dụng look and feel thiết bị mà ứng dụng chạy, người dùng cuối, điều cung cấp tương tác với người dùng cách liền mạch, ứng dụng MIDP làm việc ứng dụng native thiết bị Tóm lại, sử dụng API high-level, bạn có thể: • • • Vẽ để hiển thị hệ thống phần mềm thiết bị Ứng dụng không định nghĩa giao diện trực quan hình dáng, màu sắc… thành phần high-level Điều hướng, cuộn, tương tác nguyên thủy khác với thành phần giao diện người dùng thực thiết bị Tuy nhiên, ứng dụng không nhận biết tương tác Ứng dụng truy cập vào kỹ thuật input cụ thể, phím nhấn cụ thể Alert: Ứng dụng Hello World sử dụng alert Phần tử đại diện cho hình(Screen) dùng để show liệu đến người dùng đợi thời gian trước xử lý đối tượng Displayable Một Alert chứa mơt chuỗi text image.Thông thường, Alert sử dụng để thông báo lỗi hay ngoại lệ khác TextBox: Kế thừa từ lớp Screen, cho phép người dùng nhập chỉnh sửa text Lớp cấu hình để thích nghi với nhu cầu bạn.Bạn giới hạn maximum ký tự hiển thị TextBox Ngồi ra, bạn ràng buộc kiểu nhập cho TextBox cách sử dụng flag định nghĩa lớp TextField Có ràng buộc(constrain) để giới hạn nội dung hiển thị, là: ANY, EMAILADRR, NUMBERIC, PHONENUMBER, URL DECIMAL Có ràng buộc ảnh hưởng tới kiểu nhập: PASSWORD, UNEDITABLE, SENSITIVE, NON_PREDICTIVE, INITIAL_CAPS_WORD, INITIAL_CAPS_SENSITIVE Ví dụ, cho phép địa email phép nhập TextBox, bạn thiết lập flag TextField.EMAILADRR sử dụng phương thức setConstrains(), để kết hợp nhiều ràng buộc lúc, bạn sử dụng toán tử OR flag Ví dụ: setConstraints(TextField.EMAILADDR | TextField.UNEDITABLE); List: Một List chứa danh sách chọn lựa Khi List biểu diễn hình, người dùng tương tác với cách chon lựa phần tử, di chuyển qua lại phần tử List Nó có kiểu cấu hình sau: • • Choice.EXCLUSIVE: có phần tử chọn lựa Choice.MULTIPLE: có nhiều phần tử chọn lựa • Choice.IMPLICIT: phần tử hightlight chọn lựa Form: Nó chứa nhiều item, lớp extends từ lớp Item để chứa Form Việc thực thi xử lý layout, traversal, scrolling Nội dung Form cuộn lại với Các loại Item thêm vào Form: StringItem: label không cho phép người dùng sửa lên Item chứa tiêu đề text, hai null DateField: cho phép người dùng nhập ngày date/time dạng sau: DATE, TIME DATE_TIME TextField: Tương tự TextBox ChoiceGroup: Tương tự List Gauge: sử dụng để mơ process bar, nhiên sử dụng kiểu tương tác người dùng, ví dụ bạn muốn dùng để show Volume Control ImageItem: Nắm giữ image CustomItem: lớp ảo abstract cho phép subclass tạo giao diện riêng, tương tác riêng chế thông báo riêng Nếu bạn muốn phần tử UI khác so với phần tử cung cấp bạn tạo subclass Giao diện người dùng cấp thấp(Low-level User Interface): Các API low-level user interface( lớp Canvas) thiết kế cho ứng dụng cần đặt điều khiển phần tử graphics cách xác truy cập vào lowlevel input event Ví dụ điển hình game board, chart object hay graph Sử dụng lowlevel user interface, ứng dụng có thể: • • Kiểm sốt vẽ hình Điều khiển kiện primitive kiện nhấn phím(key press) nhả phím(key release) • Truy cập vào cụ thể phím thiệt bị đầu vào khác Ngồi ra, MIDP 2.0 cịn cung cấp javax.microediton.lcdui.game Gói bao gồm class dùng để thiết kế cho game, : GameCanvas, LayerManger, Layer, Sprite TiledLayer Bạn tìm hiểu phần sau Ví dụ giao diện người dùng: Đối với hình game, tạo phương thức init[ScreenName] để khởi tạo hình trả đối tượng Displayable tạo ra: Đối với Main Menu, bạn sử dụng component List để biểu diễn main options Ví dụ: public Displayable initMainForm() { if (mainForm == null) { // creates a implicit List where the current element is // the selected mainForm = newList("Menu", List.IMPLICIT); // append list options mainForm.append("New Game", null); mainForm.append("Options", null); mainForm.append("Scores", null); mainForm.append("Help", null); mainForm.append("Exit", null); // adds a select Command comSelect = new Command("Select", Command.ITEM, 1); mainForm.setSelectCommand(comSelect); // adds a listener to the form mainForm.setCommandListener(this); } return mainForm; } Đối với Menu Settings, bạn chọn phần tử Form, thêm đối tượng ChoiceGroup để tùy chỉnh âm thanh: public Displayable initSettingsForm() { // check if already created if (settingsForm == null) { settingsForm = new Form("Settings"); settingsForm.addCommand(initBackCommand()); settingsForm.setCommandListener(this); // creates a choice Group for sound options soundChoice = new ChoiceGroup("Sound", List.EXCLUSIVE); soundChoice.append("On", null); soundChoice.append("Off", null); // appends the choice to the form settingsForm.append(soundChoice); } return settingsForm; } Đối với Help Screen, bạn chọn phần tử Form với static message: public Displayable initHelpForm() { if (helpForm == null) { helpForm = new Form("Help"); helpForm append("User cursors to move your pad, don't let "+ "the ball go by you, hit all the bricks!"); helpForm.setCommandListener(this); helpForm.addCommand(initBackCommand()); } return helpForm; } Để giới thiệu High Score, bạn sử dụng Form với item TextField DateField: public Displayable initNewHighScore(int score, int pos) { if (newHighScoreForm == null) { newHighScoreForm = new Form("New High Score"); newHighScoreForm.setCommandListener(this); // create items highScoreName = newTextField("Name", "", 20, TextField.ANY); highScoreValue = new StringItem("Score", Integer.toString(score)); highScorePosition = new StringItem("Position", Integer.toString(pos)); // create save command highScoreSave = new Command("Save", Command.OK, 1); // append command and itens to screen newHighScoreForm.addCommand(highScoreSave); newHighScoreForm.append(highScoreName); newHighScoreForm.append(highScoreValue); newHighScoreForm.append(highScorePosition); } // update score highScoreValue.setText(Integer.toString(score)); // update pos highScorePosition.setText(Integer.toString(pos)+1); return newHighScoreForm; } Màn hình game đề cập Bây giờ, tạo phương thức giả lập kết thúc game sử dụng để thay thế: publicvoid endGame(int lifes, int score, int time) { Displayable nextScreen = initMainForm(); String message; if (lifes == 0) { message = "Game Over!!"; } else { message = "You Win!"; } int pos = isHighScore(score); if (pos != -1) { nextScreen = initNewHighScore(score, pos); } display(new Alert(message, message, null, AlertType.INFO), nextScreen); } Bây giờ, tất phương thức tạo ra, bạn link chúng đến phương thức commandAction() Rewrite code: publicvoid commandAction(Command cmd, Displayable display) { // check what screen is being displayed if (display == mainForm) { // check what command was used if (cmd == comSelect) { switch (mainForm.getSelectedIndex()) { case (0): // At the moment just go directly to the end of the game endGame(1, 200, 50); break; case (1): display(initSettingsForm()); break; case (2): display(initScoreForm()); break; case (3): display(initHelpForm()); break; case (4): exit(); break; } } } elseif (display == highScoreForm) { if (cmd == comBack) { display(initMainForm()); } } elseif (display == settingsForm) { if (cmd == comBack) { soundOn = soundChoice.getSelectedIndex() == 0; display(initMainForm()); } } elseif (display == helpForm) { if (cmd == comBack) { display(initMainForm()); } } elseif (display == newHighScoreForm) { if (cmd == highScoreSave) { int pos = Integer.parseInt(highScorePosition.getText())-1; // advance all the scores for ( int i = scores.length-1; i > pos ; i ){ scores[i].name = scores[i-1].name; scores[i].value = scores[i-1].value; scores[i].when = scores[i-1].when; } // insert new score scores[pos].name = highScoreName.getString(); scores[pos].value = Integer.parseInt(highScoreValue.getText()); scores[pos].when = newDate(); display(initScoreForm()); } } }Tất logic menu cho MIDlet xác định bên phương thức commandAction() Quyết định làm phụ thuộc vào hình hiển thị command chọn lựa Từ menu chính, tơi đơn giãn chuyển hướng người dùng đến hình cụ thể Các hình có back command, form NewHighScores có command save dùng để lưu thông tin điểm số(score) Bạn lưu ý cách thức sử dụng phương thức display(), cách đơn giãn để kích hoạt đối tượng Displayable publicvoid display(Displayable display) { // shows display in the screen Display.getDisplay(this).setCurrent(display); } Bài mô tả làm để cài đặt Game Screen Phát triển game đơn giãn Mobile(P3) Ở trước, hoàn thành giao diện menu cho game.Tuy nhiên, hình Game Screen chưa tạo Mục đích sinh Game Screen có giao diện hình dưới: Các thành phần giao diện cấp cao sử dụng cho game screen phải điều khiển tất phần tử game chúng vẽ làm để game tương tác trở lại với keypad Để làm điều này, phải sử dụng class giao diện low-level Các class thuộc nhóm low-level cho phép bạn kiểm soát chi tiết phần tử kiện hình game.Sử dụng class này, bạn xác định rõ vị trí, màu sắc kích thước.Cũng vậy, bạn phải thiết kế hình game screen cho loại hình ứng với thiết bị Diagram sau cho biết lớp giao diện low-level : 10 options.addRecord(data, 0, data.length); } // closes the record store options.closeRecordStore(); } catch (RecordStoreException ex) { } } publicbyte[] saveOptions() { // create a byte array stream to store data temporarily ByteArrayOutputStream baos = newByteArrayOutputStream(); DataOutputStream dos = newDataOutputStream(baos); try { dos.writeBoolean(soundOn); // write scores for (int i =0; i < scores.length; i++){ dos.writeInt(scores[i].value); dos.writeUTF(scores[i].name); dos.writeLong(scores[i].when.getTime()); } // push all the data to the byte array stream dos.flush(); } catch (IOException ex) { } // returns bytes from stream returnbaos.toByteArray(); } Trong ví dụ trên, tên RecordStore “options” dùng để lưu trữ settings high scores Đối với trình lưu trữ, DataOutputStream với ByteArrayOutputStream để convert liệu sang mảng nhị phân Bây bạn cần cài đặt việc đọc liệu: publicvoid loadData() { try { RecordStore options = RecordStore.openRecordStore(“options”, true); // check if record store not empty if (options.getNumRecords() != 0) { loadOptions(options.getRecord(1)); } options.closeRecordStore(); } catch (RecordStoreException ex) { } } 27 publicvoid loadOptions(byte[] data) { // create a byte array stream to store data temporarily ByteArrayInputStream bais = newByteArrayInputStream(data); // creates a data input stream to read from DataInputStream dis = newDataInputStream(bais); try { soundOn = dis.readBoolean(); // read scores for (int i = 0; i < scores.length; i++) { int value = dis.readInt(); String name = dis.readUTF(); Date date = newDate(dis.readLong()); scores[i] = new Score(value, name, date); } dis.close(); } catch (IOException ex) { } } Ở đoạn code trên, bạn cần mở RecordStore kiểm tra xem tạo hay chưa.Nếu có, lấy liệu sử dụng DataInputStream kết hợp với ByteArrayInputStream Bây giờ, bạn cần đưa chúng vào phần startup shutdown MIDlet publicvoid initOptions() { soundOn = true; if (scores == null) { scores = new Score[10]; for (int i = 0; i < scores.length; i++) { scores[i] = new Score(0, “Empty”, newDate()); } } // loads data in record stores if available loadData(); } publicvoid exit() { // store high scores and setting to record store saveData(); notifyDestroyed(); } Đến lúc này, bạn lưu trữ high score settings player Trong tiếp theo, tìm hiểu cách sử dụng settings thêm vào âm cho game 28 Phát triển game đơn giãn Mobile(P6) Bài viết trước mô tả làm để lưu cài đặt trò chơi, bao gồm âm bật / tắt hình, khơng có âm phát Bài viết mô tả Java Mobile Multimedia API (MMAPI) giải thích làm để thêm âm vào game MMAPI cung cấp tập khả đa phương tiện cho thiết bị di động, bao gồm phát lại ghi âm liệu âm video từ nhiều nguồn khác nhau.Tất nhiên, tất thiết bị di động hỗ trợ tất tùy chọn này, MMAPI thiết kế để tận dụng khả có sẵn thiết bị bỏ qua mà khơng hỗ trợ Thông tin MMAPI Các MMAPI xây dựng dựa trừu tượng cấp cao tất thiết bị đa phương tiện Sự trừu tượng cài đặt(implement) ba lớp hình thành lõi(core) hoạt động mà bạn làm với API Những lớp interface Player Control, lớp Manager Một lớp khác, lớp trừu tượng DataSource, sử dụng để xác định vị trí tài nguyên, bạn định nghĩa phương pháp để đọc liệu, bạn khơng cần sử dụng cách trực tiếp Tóm lại, lớp Manager sử dụng để tạo thể Player cho media khác cách xác định thể DataSource Như vậy, thể Player tạo cấu hình cách sử dụng thể Control.Ví dụ, hầu hết thể Player hỗ trợ VolumeControl để điều khiển âm lượng Player Kiểm tra sơ đồ sau đây: 29 Lớp Manager factory player hỗ trợ phương thức sau đây: • • createPlayer(DataSource source): tạo player dựa DataSource createPlayer(InputStream stream, String type): tạo player sử dụng input stream nguồn giả định kiểu media cung cấp Để biết thêm kiểu media, bạn vào địa chỉ: http://www.iana.org/assignments/media-types/ để kiểm tra • createLayer(String url): tạo player sử dụng url để xác định liệu nguồn Phương thức cuối cho phép bạn phân bổ loại media khác nhau, tùy thuộc vào giao thức URL chọn chọn Các loại sau hỗ trợ: • • Midi Player – “device://midi”: tạo a midi Player Tone Player – “device://tone”: tạo a tone Player • Capture Audio – “capture://audio”: cho phép capture audio từ thiết bị • Capture Video – “capture://video”: cho phép capture video từ thiết bị • Capture Radio – “capture://radio?f=105.1&st=stereo”: cho phép capture radio Để tìm hiểu kiểu nội dung giao thức hỗ trợ thiết bị, bạn sử dụng phương thức lớp Manager: • • getSupportedContentTypes(): cung cấp danh sách kiểu nội dung sẵn có cho tất giao thức hay giao thức cụ thể getSupportedProtocols(): cung cấp danh sách giao thức sẵn có cho tất kiểu nội dung hay kiểu nội dung cụ thể 30 Sau bạn tạo player, bạn bắt đầu sử dụng cách đơn giản gọi phương thức start () Khi đạt đến kết thúc media stop cách tự động Đây nhìn đơn giản lớp Player Trên thực tế lớp có năm tiểu trạng thái: • • UNREALIZED: trạng thái Player thu từ lớp Manager REALIZED: Khi phương thức realized() gọi, Player chuyển sang trạng thái để thu nhận thơng tin cần thiết để có nguồn media.Q tình realized Player tài nguyên trình tiêu tốn thời gian Player phải giao tiếp với server, đọc file hay tương tác với tập đối tượng • PREFETCHED: Sau player realized, cần tài nguyên khan hay độc quyền, fill đệm với liệu media hay thực tiến trình start-up khác Và điều thực cách gọi phương thức prefetch() để chuyển đổi sang trạng thái • STARTED: Khi gọi phương thức start(), Player bắt đầu play tài nguyên media đạt đến kết thúc media • CLOSED: gọi phương thức close(), Player chuyển đổi sang trạng thái này, giải phóng tất tài nguyên nắm giữ Và khơng thể sử dụng lại lần Hình cho biết nhiều trạng thái khác chuyển tiếp chúng: Nếu ứng dụng bạn cần thông tin chuyển đổi trạng thái, bạn cần implements giao diện PlayerListener Play a sound Trong game này, ý tưởng để play sound Ball di chuyển chạm vào Brick hay Pad Để làm điều này, tạo lớp gọi Multimedia với phương thức playSound(): 31 //multimedia libraries import javax.microedition.media.Manager; import javax.microedition.media.Player; import javax.microedition.media.MediaException; publicclass Multimedia { publicvoid playSound(String file, String format) { try { InputStream is = getClass().getResourceAsStream(file); Player p = Manager.createPlayer(is, format); p.start(); } catch (IOException ioe) { } catch (MediaException me) { } } Bây cần sử dụng phương thức bên va chạm Ball thực thể khác phát Cho mục đích này, tơi tạo sound có tên click.wav phải sẵn có tài nguyên ứng dụng publicvoid updateGameState(){ … byte colision = ball.colided(pad); if (colision != Entity.COLLISION_NONE){ if (midlet.soundOn){ midlet.multimedia.playSound(“click.wav”, “audio/X-wav”); } } … } Nếu chạy ứng dụng, bạn nghe vài âm play game Capture Video Bây giờ, game có âm thanh, bạn chụp ảnh người chơi người đạt điểm số cao nhất.Để làm điều này, bạn cần truy cập vào camera video show vào player.Phương thức chụp ảnh video lưu vào item Player p; VideoControl vc; public Item showVideo(String url){ Item result = null; try { p = Manager.createPlayer(url); p.realize(); // Grab the video control 32 vc = (VideoControl)p.getControl(“VideoControl”); if (vc != null) { // create the Item with the video image result =((Item)vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, null)); // add a label result.setLabel(“Photo”); } // start capture p.start(); } catch (IOException ioe) { } catch (MediaException me) { } return result; } VideoControl sử dụng để tạo Item sử dụng Form: public Displayable initNewHighScore(int score, int pos) { newHighScoreForm.append(multimedia.showVideo("capture://video")); } Bây giờ, sử dụng VideoControl để chụp image từ camera publicImage captureVideo(){ Image result = null; try { // grab data byte[] imageData = vc.getSnapshot(“encoding=png”); // create image; result = Image.createImage(imageData, 0, imageData.length); } catch (MediaException me) { me.printStackTrace(); } return result; } Sau đó, gọi phương thức high score lưu // we added an extra field to Score to store the image scores[pos].image = multimedia.captureVideo(); Sau đó, show image hình high score Chạy ứng dụng để test chức Bài thảo luận network mobile 33 Phát triển game đơn giãn Mobile(P7 – Phần cuối) Ở trước, bạn hướng dẫn để tạo game, phần bàn đến network.Một đặc điểm mobile, khả kết nối nơi lúc Bên cạnh việc bạn đạt điểm số cao(high score); kết trả chia internet Với JavaME, bạn dễ dàng truy cập vào đặc điểm giao tiếp sau: • • HTTP Socket • SMS • Bluetooth Bài viết giải thích cách sử dụng giao thức HTTP để gửi liệu high score đến server làm để sử dụng chức gửi SMS để mời người khác tham gia game Connector Đặc điểm sử dụng chức network lớp Connector Lớp cho phép tạo đối tượng Connection thông qua phương thức tĩnh: • • open(String name) open(String name, int mode) 34 Tham số name chuỗi URL để xác định kết nối mà bạn muốn tạo ra.Tương ứng với giao thức URL kiểu đối tượng Connection tạo Sau danh sách URL đối tượng Connection tương ứng: • • “http://www.server.com“: Trả kết nối HTTP sử dụng lớp HttpConnection “socket://server.com:8080″: trả kết nối TCP/IP • “btsp://2343434d3434″: trả kết nối Bluetooth • “sms://+351910000000″: trả kết nối SMS đến số điện thoại +351910000000 Trong giao thức kể trên, giao thức HTTP tất thiết bị hỗ trợ JavaME hỗ trợ; giao thức khác phụ thuộc vào thiết bị.Tuy nhiên hầu hết loại điện thoại hỗ trợ tất giao thức Lưu ý bạn cố gắng mở loại kết nối nào, người dùng ứng dụng thông báo từ hệ thống quản lý ứng dụng cung cấp tùy chọn để chấp nhận từ chối yêu cầu kết nối.Nếu bị từ chối yêu cầu kết nối, ứng dụng nhận SecurityException kết nối không thiết lập HTTP Có thể nói, kết nối HTTP loại kết nối phổ biến tất loại kết nối Để tạo kết nối HTTP J2ME, bạn làm sau: import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection; publicclass Network { publicbyte[] httpConnection(String url, byte[] dataToSend) throwsIOException { HttpConnection hc = null; // Prepare Connection hc = (HttpConnection) Connector.open(url, Connector.READ_WRITE); [ ] } } Các kết nối HTTP đại diện lớp HttpConnection Lớp có ba trạng thái: • • Setup nơi mà tham số yêu cầu định nghĩa Connected nơi mà bạn gửi nhận liệu Bạn cần gửi liệu trước bạn nhận trả lời • Closed sau bạn đọc liệu kết nối kết thúc Khi bạn nhận đối tượng HttpConnection từ Connector, rơi vào trạng thái Setup.Sau đó, bạn cấu hình tham số u cầu Một lựa chọn phương thức yêu cầu HTTP(POST, GET HEAD) 35 publicbyte[] httpConnection(String url, byte[] dataToSend) throwsIOException { [ ] if (dataToSend == null){ hc.setRequestMethod( HttpConnection.GET ); } else { hc.setRequestMethod( HttpConnection.POST ); } [ ] } Bạn cấu hình thuộc tính u cầu, chẳng hạn kiểu nội dung mà bạn gửi trường hợp POST: hc.setRequestProperty("Content-type", "application/octet-stream" ); Sau bạn cấu hình kết nối, bạn bắt đầu gửi liệu.Khi bạn bắt đầu q trình này, bạn khơng thể thay đổi tham số yêu cầu.Nếu kết nối thiết lập, bạn bắt đầu nhận liệu publicbyte[] httpConnection(String url, byte[] dataToSend) throwsIOException { [ ] if (dataToSend != null){ // Write Data OutputStream os = hc.openOutputStream(); os.write( dataToSend ); os.close(); } // gets answer from server int rc = hc.getResponseCode(); // check http response if (rc == HttpConnection.HTTP_OK){ // Read Data InputStream in = hc.openInputStream(); ByteArrayOutputStream tmp = newByteArrayOutputStream(); int ch; while ((ch = in.read()) != -1) { tmp.write(ch); } data = tmp.toByteArray(); in.close(); hc.close(); } return data; } 36 Xây dựng phương thức httpConnection() coi xong, cài đặt game để gửi high score đến server Bạn thêm command vào hình high score: public Displayable initScoreForm() { [ ] cmdSendHighScore = new Command("Send to Server", Command.ITEM, 1); highScoreForm.addCommand(cmdSendHighScore); [ ] } Tiếp theo, bạn tạo phương thức sử dụng Command lựa chọn: publicString sendScore(String user, int score) { String result = “No Answer”; // server to send data String url = “http://www.sergioestevao.com/midpAdventures/post.php”; // prepare http request String urlTotal = url + “?user=” + user + “&score=” + score; byte[] data = null; try { data = network.httpConnection(urlTotal, null); } catch (IOException e) { result = “Communication Problems”; e.printStackTrace(); } catch (SecurityException s) { // user denied access to communication result = “You need to allow communications in order to send the highscore to server.”; s.printStackTrace(); } // check data return if (data != null) { result = newString(data); } return result; } Và gọi Command sử dụng: if (cmd == comInviteSend) { result = sendScore(scores[0].name, scores[0].value); display(new Alert("Result", result, null, AlertType.INFO)); } Nếu bạn sử dụng đoạn code này, bạn nhận cảnh báo: Warning: To avoid potential deadlock, operations that may block, such as networking, should be performed in a different thread than the commandAction() handler 37 Hãy nhớ bạn thực thi đoạn mã câu trả lời cho kiện mà người sử dụng thực thi thread UI Nếu đoạn mã block thời gian dài để thực hiện, ứng dụng gặp khó khăn Để tránh vấn đề này, bạn nên sử dụng thread để làm công việc liên quan đến network Hãy bắt đầu khai báo thread biến trạng thái để điều khiển hoạt động thread privatestaticfinalint ACTION_SEND_HIGHSCORE = 0; publicThread workThread; publicboolean active = false; Bất lúc có kiện làm tốn nhiều thời gian(như việc kết nối mạng thành cơng hay thất bại, điều phụ thuộc yêu tố bên ngồi đường truyền mạng…), bạn nên sử dụng thread chuyên biệt để kích hoạt hoạt động publicvoid doAction(int action) { // stores action to this.action = action; // check if thread is already created if (workThread == null) { workThread = newThread(this); workThread.start(); active = true; } // wakes up thread to work synchronized (this) { notify(); } } Thread thực thi phương thức run(): publicvoid run() { while (active) { // check what action to switch (action) { case (ACTION_SEND_HIGHSCORE): // send the first score to the server result = sendScore(scores[0].name, scores[0].value); commandAction(cmdReceiveHighScore, highScoreForm); break; } // waits for action to synchronized (this) { try { wait(); 38 } catch (InterruptedException e) { e.printStackTrace(); } } } } Để start thread này, cần khai báo giao diện Runnable MIDlet: publicclass MyMidlet extends MIDlet implements CommandListener, Runnable { Bây giờ, bạn gọi phương thức doAction() người dùng chọn command ‘Send high score’ Lưu ý rằng, phương thức run() gọi command cmdReceiveHighScore Điều sử dụng để hiển thị kết giao tiếp với người dùng if (cmd == cmdSendHighScore) { doAction(ACTION_SEND_HIGHSCORE); } if (cmd == cmdReceiveHighScore) { display(new Alert("Result", result, null, AlertType.INFO)); } SMS Một trường hợp sử dụng cho giao tiếp Java ME để mời bạn bè tham gia chơi game Bạn có cạnh tranh bảng điểm số cao Thứ nhất, cài đặt phương thức gửi tin nhắn SMS lớp network publicboolean sendSms(String number, String message){ boolean result = true; try { //sets address to send message String addr = “sms://”+number; // opens connection MessageConnection conn = (MessageConnection) Connector.open(addr); // prepares text message TextMessage msg = (TextMessage)conn.newMessage(MessageConnection.TEXT_MESSAGE); //set text msg.setPayloadText(message); // send message conn.send(msg); } catch (Exception e) { result = false; } 39 return result; } Từ đoạn code ví dụ trên, bạn cần sử dụng phương thức open() lớp Connector với định dạng URL “sms://number” Sau tạo TextMessage gửi thơng qua Connection.Kích thước message giới hạn 160 ký tự Tiếp theo, bạn tạo form để nhận tên số điện thoại từ người dùng sau: public Displayable initInviteForm() { if (inviteForm == null) { inviteForm = new Form(“Invite”); inviteForm.setCommandListener(this); inviteForm.addCommand(initBackCommand()); inviteName = newTextField(“Name:”, “”, 20, TextField.ANY); inviteNumber = newTextField(“Number:”, “”, 20, TextField.PHONENUMBER); inviteForm.append(inviteName); inviteForm.append(inviteNumber); comInviteSend = new Command(“Invite”, Command.ITEM, 1); inviteForm.addCommand(comInviteSend); } return inviteForm; } Tiếp theo, phương thức commandAction(), bạn cài đặt code để hiển thị form gửi message: publicvoid commandAction(Command cmd, Displayable display) { [ ] elseif (display == inviteForm) { if (cmd == comBack) { display(initMainForm()); } if (cmd == comInviteSend) { doAction(ACTION_SEND_INVITE); } } [ ] } Cuối cùng, phương thức run(), bạn gọi phương thức sendSms() để gửi message: publicvoid run() { [ ] case (ACTION_SEND_INVITE): // invite another player to play 40 String inviteMessage = ” invites you to play Transnoid!”; network.sendSms(inviteNumber.getString(), inviteName.getString() + inviteMessage); break; } [ ] } 41 ... tả làm để cài đặt Game Screen Phát triển game đơn giãn Mobile(P3) Ở trước, hoàn thành giao diện menu cho game. Tuy nhiên, hình Game Screen chưa tạo Mục đích sinh Game Screen có giao diện hình... ảnh để có trị chơi tìm kiếm tốt 18 Phát triển game đơn giãn Mobile(P4) Trong trước, lớp GameCanvas xây dựng với tất tương tác element Bây giờ, tất element gameplay xây dựng, lúc cải thiện giao... chơi(high-score) 22 Phát triển game đơn giãn Mobile(P5) Để lưu điểm số high-score, trước tiên bạn cần hiểu Input Output MIDlet cách sử dụng RecordStores Streams Hãy bắt đầu với operation IO đơn giãn Các

Ngày đăng: 21/08/2015, 13:01

Mục lục

  • Phát triển game đơn giãn trên Mobile(P2)

  • Phát triển game đơn giãn trên Mobile(P3)

  • Phát triển game đơn giãn trên Mobile(P4)

  • Phát triển game đơn giãn trên Mobile(P5)

  • Phát triển game đơn giãn trên Mobile(P6)

  • Phát triển game đơn giãn trên Mobile(P7 – Phần cuối)

Tài liệu cùng người dùng

Tài liệu liên quan