Đề tài framework for mobile game development
Trang 1TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ VIỄN THÔNG
®
ĐỒ ÁN TỐT NGHIỆP
ĐỀ TÀI:
FRAMEWORK FOR MOBILE GAME DEVELOPMENT
Giáo viên hướng dẫn : Th.S Vũ Song Tùng
Trang 2Hà Nội: 6 -2014
BỘ GIÁO DỤC VÀ ĐÀO TẠO CỘNG HÒA XÃ HÔI CHỦ NGHĨA VIỆT NAM TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
-Độc lập - Tự do - Hạnh phúc
-NHIỆM VỤ ĐỒ ÁN TỐT NGHIỆP Họ và tên sinh viên: ……….………….…… Số hiệu sinh viên: ……….
Khoá:……….Khoa: Điện tử - Viễn thông Ngành: ………
1 Đầu đề đồ án: ……… ………
……….
2 Các số liệu và dữ liệu ban đầu: ……… ……… …… ………
……….
……….… ……… ………
3 Nội dung các phần thuyết minh và tính toán: ………
… ………
……… ….………
……… ….………
4 Các bản vẽ, đồ thị ( ghi rõ các loại và kích thước bản vẽ ): ………
……… ….
………
………… ……….………
5 Họ tên giảng viên hướng dẫn: ……… ……….
6 Ngày giao nhiệm vụ đồ án: ……….……….
7 Ngày hoàn thành đồ án: ……… ……
Ngày tháng năm
Trang 3Sinh viên đã hoàn thành và nộp đồ án tốt nghiệp ngày tháng năm
Cán bộ phản biện
Trang 4BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
-BẢN NHẬN XÉT ĐỒ ÁN TỐT NGHIỆP Họ và tên sinh viên: Số hiệu sinh viên:
Ngành:
Khoá:
Giảng viên hướng dẫn:
Cán bộ phản biện:
1. Nội dung thiết kế tốt nghiệp:
2. Nhận xét của cán bộ phản biện:
Trang 5
Ngày tháng năm
Cán bộ phản biện
( Ký, ghi rõ họ và tên )
Trang 6LỜI NÓI ĐẦU
Với sự phát triển nhanh chóng của điện thoại đã làm cho thị trường game điện thoạingày càng đa dạng và hấp dẫn hơn bao giờ hết Đặc biệt game android vì hệ điều hànhandroid là một hệ điều hành mở cho phép những nhà lập trình tùy ý sáng tạo đồng thời nócũng là hệ điều hành chiếm thị phần lớn nhất trên thế giới Chính vì vậy nên ở một đấtnước còn nhiều khó khăn như nước ta cùng với những kiến thức mở được chia sẻ tự dotrên mạng thì đây chính là cơ hội cho những nhà lập trình tự do của ta có quyền mơ mộtgiấc mơ giản dị là tự do sáng tạo đam mê mà vẫn kiếm được tiền trang trải cuộc sống,thậm chí một giấc mơ xa hơn là game của mình viết ra có thể chỗ đứng ở thị trường nướcngoài khẳng định trình độ của các lập trình viên Việt Nam không hề thua kém các lậptrình viên nước ngoài Từ đó các ông lớn như Google có cái nhìn khác về chúng ta nhằm
gỡ bỏ các rào cản trong việc kiếm tiền bằng việc bán game trên Google Store Tuy nhiên
cơ hội luôn đi đôi với khó khăn thách thức, ở Việt Nam game bây giờ giống như mộtđống hỗn độn, các công ty lớn có tiền thì đua nhau về đồ họa, hình ảnh hay các nhật vậthầm hố, sexy một cách lố bịch Mặt khác các nhà lập trình tự do thì trình độ lập trình cònhạn chế có thể là do các engine hiện nay còn ít tài liệu hay quá phức tạp nên tạo ranhững sản phẩm không ổn định, không mang tính hướng tới người dùng mà chỉ đơn giản
là viết xong vứt lên Google Store rồi cầu cho ai đó tải xuống rồi kích và quảng cáo để cótiền hay tệ hơn là cướp tiền của người dùng bằng cách tự động nhắn tin đến số tổng đài
Từ đó chúng ta có thể thấy rằng có hai vấn đề chính ở thị trường game của ta là người
có tiền thì không thèm đầu tư nội dung, kẻ nghiệp dư thì viết game ra chỉ để cầu may cótiền Vấn đề đơn giản đối với những công ty có tiền họ chỉ cần đầu tư nhân sự về thiết kế
là hoàn toàn có nhiều cơ hội kiếm được nhiều lợi nhuận nhưng đối với những nhà lậptrình tự do mới chập chững vào nghề thì có cơ hội nào cho họ nghĩ về một tương lai sánghơn như Nguyễn Hà Đông đã từng làm được với Flappy Bird – một game có cốt truyệnđơn giản nhưng đầy tính hấp dẫn về độ khó của nó cho dù đồ họa của nó rất đơn giản.Không còn cách nào khác là những người bước vào con đường viết game này và coi nó
Trang 7như cần câu cơm phải học hỏi và năm vững ít nhất một ngôn ngữ – thông thạo ít nhất mộtengine game Tuy nhiên do sự hạn chế về mặt tiếng anh của đa phần lập trình viên hiệnnay thì việc nghiên cứu một engine đã gặp không ít khó khăn thậm chí đa phần nhữngengine game hiện nay đều rất phức tạp hoặc mất phí càng làm cho mọi thứ khó khăn hơn.
Để giải quyết vấn đề đó trong đồ án này chúng tôi đã quyết định viết một engine gamevới những thành phần cơ bản giúp những người lập trình có thể nhanh chóng nắm bắtđược kiến trúc, quy trình của việc làm game đồng thời cũng nhanh chóng xây dựng đượcnhững game đơn giản đồ họa khá và nhẹ nhàng với điện thoại
Trong quá trình thực hiện đồ án viết engine game này chúng tôi đã nhận được rấtnhiều sự giúp đỡ từ các thầy cô trong viện Điện Tử Viễn Thông, đặc biệt phải kể đến sựtận tâm nhiệt tình của Th.S Vũ Song Tùng – người đã trực tiếp hướng dẫn chúng tôihoàn thành đồ án này Chúng tôi xin gửi lời cảm ơn chân thành nhất đến Thầy cũng nhưthầy cô trong Viện Điện Tử Viễn Thông
Trang 8TÓM TẮT ĐỒ ÁN
Với việc phát triển ngày càng nhanh của thị trường game Việt Nam thì các lập trìnhviên ngày càng có nhu cầu tiếp cận công cụ viết game một cách nhanh chóng và đơn giảnnhất Công cụ viết game ở đây đa phần là các engine game – nó là nền tảng để các nhàlập trình dựa vào đó để xây dựng game cho mình Tuy nhiên hiện nay các engine gamechủ yếu còn phức tạp tài liệu ít mà viết chủ yếu bằng tiếng anh Điều đó khiến cho cáclập trình viên Việt Nam gặp rất nhiều khó khăn trong việc tiếp cận công nghệ
Chính vì vậy đồ án này của chúng em nhằm mục đích viết ra một engine game cơ bảnđầy đủ các thành phần giúp các lập trình viên có thể tiếp cận với kiến trúc và cách thứchoạt động của engine game để từ đó nắm bắt và tối ưu được game mình viết ra Ngoài ra
về mặt kinh tế dựa trên engine game này hoàn toàn có thể tạo ra các game có đồ họa đơngiản nội dung hấp dẫn để đưa lên Google Play
Trang 9ABSTRACT
Trang 10MỤC LỤC
Trang 11DANH SÁCH HÌNH VẼ
Hình 1.1 Kiến trúc Android [1]
Hình 1.2 Nhân Linux trên Android [1]
Hình 1.3 Hệ thống thư viện Android [1]
Hình 1.4 Các thành phần khung ứng dụng của Android [1]
Hình 1.5 Các thành phần ứng dụng của Android [1]
Hình 1.6 Các trục gia tốc trên điện thoại Android [15]
Hình 1.7 Lưới hiển thị và VRAM [15]
Hình 1.19 Các mẫu trong OpenGL ES [15]
Hình 1.20 Hệ tọa độ “world space” [15]
Hình 1.22 Quay mẫu 45 độ [15]
Hình 1.23 Mẫu được dãn 2 lần theo trục x và co một nửa theo trục y [15]
Hình 2.2 Sơ đồ lớp mô-đun input
Hình 2.3 Sơ đồ lớp mô-đun âm thanh
Hình 2.4 Sơ đồ lớp mô-đun đồ họa
Hình 2.5 Ảnh bitmap font
Trang 12Hình 2.8 Va chạm giữa 2 hình tròn [15]
Hình 2.9 Va chạm giữa hai hình chữ nhật [15]
Hình 2.10 Va chạm giữa hình tròn và hình chữ nhật [15]
Hình 2.11 Kiểm tra điểm nằm trong tam giác [15]
Hình 2.12 Kiểm tra va chạm giữa hình tròn và cạnh tam giác [15]
Hình 2.13 Sơ đồ lớp tổng quan của Framework
Hình 3.1 Texture (bên trái) và Texture Region (bên phải)
Hình 3.1 Minh họa cảnh trong Game
Hình 3.2 Va chạm của đối tượng trong Game
Trang 13DANH SÁCH CÁC TỪ VIẾT TẮT
Trang 14PHẦN MỞ ĐẦU
Trong vài năm gần đây nhờ sự phát triển mạnh mẽ cùng dòng điện thoại thông minhcũng như sự phát triển không ngừng của hệ điều hành Android mã nguồn mở làm cho thịtrường game trên điện thoại trở nên tiềm năng hơn bao giờ hết Trong khi thế giới với nềntảng phát triển hệ điều hành và game từ lâu họ hoàn toàn có thể nắm bắt và phát triểnnhanh chóng game đưa ra thị trường thì Việt Nam đang là một nước mới nổi – mới chậpchững vươn ra thế giới còn gặp rất nhiều khó khăn đặc biệt là việc tiếp cận công nghệ vìvốn tiếng anh người Việt không khá mà các công nghệ về game hay các engine game kháphức tạp
Mặt khác nếu làm game theo kiểu “ăn xổi” thì cũng khó theo kịp các nước phát triểngame khác nên điều quan trọng là chúng ta phải nắm được những điểm cốt lỗi hay nhữngnền tảng về engine game Nó là cái “xương sống” để xây dựng game, nắm bắt được nóchúng ta hoàn toàn có thể phát triển game lâu dài mà không thụt hậu về mặt công nghệ.Tuy nhiên một số khó khăn như đã nêu ở trên sẽ làm chúng ta khó tiếp cận công nghệ nênchúng tôi đã xây dựng đồ án này để giúp cho các lập trình viên mới chập chững vào nghề
có thể nắm bắt được những điểm cơ bản về cấu trúc hạ tầng và thượng tầng trong việcxây dựng game Đó là mục đích về mặt công nghệ của đồ án ngoài ra về mặt kinh tế bạnhoàn toàn có thể dựa trên engine cơ bản của chúng tôi xây dựng những game có đồ họakhông tồi chút nào Nếu bạn chịu khó đầu tư vào nội dung cốt truyện thì hoàn toàn bạn
có thể chinh phục người chơi như Nguyễn Hà Đông đã làm được
Trong phạm vi đồ án này chúng tôi sẽ trình bày làm 4 chương:
Trang 15CHƯƠNG I CƠ SỞ LÝ THUYẾT
1.1 Kiến trúc nền tảng Android
1.1.1 Kiến trúc tổng quát
Trang 16Như trên hình Android gồm 4 thành phần
Hình 1.2 Nhân Linux trên Android [1]
Android sử dụng nhân Linux 2.6 làm nhân cho các dịch vụ hệ thống như bảo mật,quản lý bộ nhớ, quản lý tiến trình (xử lý tiến trình, đa luồng), ngăn xếp mạng và trìnhđiều khiển thiết bị (giao tiếp USB, giao tiếp hồng ngoại, không đây, v.v…) Nhân Linuxnày cũng có vai trò như một lớp trừu tượng giữa phần cứng và phần mềm
1.1.3 Libraries
Android có một thư viện khá phong phú [9] cung cấp sẵn để người lập trình có thể sửdụng Hình 4 là sơ đồ tóm tắt về hệ thống thư viện này
Trang 17Hình 1.3 Hệ thống thư viện Android [1]
Android runtime
Android có một tập các thư viện nòng cốt để cung cấp hầu hết các chức năng sẵn cótrong thư viện cốt lõi của ngôn ngữ lập trình Java Android Runtime: Bao gồm máy ảoDalvik và các thư viện Android
Các thư viện cơ bản: Các ứng dụng Android được phát triển trên môi trường Java,nhưng Dalvik lại không phải là một Java VM Các thư viện cơ bản của Android cung cấphầu hết các chức năng có trong thư viện cơ bản của Java cũng như là thư viện riêng củaAndroid
Máy ảo Dalvik: Dalvik là máy ảo để chạy các ứng dụng trên Android, đã được tối ưu
để đảm bảo rằng một thiết bị có thể chạy được nhiều Instance một cách hiệu quả Nó dựavào nhân Linux để thực hiện đa luồng và quản lý bộ nhớ cấp thấp
Trang 18- android.database Cung cấp các lớp mức thất bắt buộc cho việc điều khiển cursor khilàm việc với các cơ sở dữ liệu
- android.content Các giao tiếp lập trình nội dung được dùng để quản lý truy cập dữliệu và xuất bản bằng cách cung cấp các dịch vụ thao tác với tài nguyên, ContentProvider, và các gói
- android.view View là lớp giao diện người dùng cơ bản nhất Tất cả giao diện ngườidùng được tạo ra đều phải sử dụng một tập các View để cung cấp cho các thành phầntương tác người dùng
- android.widget Xây dựng dựa trên gói View Những lớp Widget những thành phầngiao diện được tạo sẵn được sử dụng để tạo nên giao diện người dùng Các Widget baogồm danh sách, nút bấm, hộp nhập, các kiểu trình bày(layout)
- com.google.android.maps bộ API mức cao cung cấp truy cập đến điều khiển bản đồsẵn trong Androif từ ứng dụng được xây dựng Bao gồm cả lớp MapView cũng nhưOverlay và MapController để tương tác với bản đồ bên trong ứng dụng
- android.app Một gói thư viện bậc cao, cung cấp truy cập đến dữ liệu của ứng dụng.Gói ứng dụng cũng bao gồm lớp Activity và Service là thành phần cơ bản của mọi ứngdụng Android
- Android.provider Để tạo thuận lợi cho người phát triển truy cập đến các ContentProvider tiêu chuẩn(như là dữ liệu danh bạ), gói Cung cấp(Provider) bao gồm các lớp chophép truy cập đến cơ sở dữ liệu chuẩn trong tất cả các bản phân phối Android
- Android.telephony Các API điện đàm cung cấp khả năng tương tác trực tiếp với tầngđiện thoại trong các thiết bị, cho phép tạo, nhận, theo dõi các cuộc gọi, tình trạng cáccuộc gọi và tin nhắn SMS
- android.webkit Gói WebKit cung cấp các API để làm việc với các nội dung based bao gồm một lơp WebView để tạo ra giao diên web, nhúng trong ứng dụng và mộttrình quản lý cookie
Web-Cùng với các API của Android, còn có một tập các thư viện C/C++ như:
Trang 19- OpenGL Thư viện dùng để tạo ra các đồ họa 3D dựa vào chuẩn OpenGLES 1.0 API
- FreeType Hỗ trợ xử lý bitmap và font vector
- GGL Thư viện cơ bản, dùng để cung cấp các engine đồ họa 2D
- Libc Thư viện C chuẩn, được tối ưu cho các thiết bị Linux-based
- SQLite Engine cơ sở dữ liệu quan hệ gọn nhẹ, dùng để lưu trữ dữ liệu của ứng dụng
- SSL Hỗ trợ sử dụng giao thức mã hóa Secure Sockets Layer trong bảo mật truyềnthông Internet
Ngoài các thư viện chuẩn của Android, để đáp ứng tiêu chí phù hợp với nhiều thiết bịkhác nhau, Android còn có thể có các API phụ thuộc thiết bị như android.location,android.media, android.opengl, android.hardware, android.bluetooth, android.net.wifi, vàandroid.telephony
1.1.4 Application Framework
Hình 1.4 Các thành phần khung ứng dụng của Android [1]
Kiến trúc của Android khuyến khích khái niệm Thành phần sử dụng lại, cho phépcông bố và chia sẻ các Activity, Service, dữ liệu, với các ứng dụng khác với quyền truycập được quản lý bởi khai báo
Cơ chế đó cho phép người lập trình tạo ra một trình quản lý danh bạ hoặc trình quay
số điện thoại mà có các thành phần người khác có thể tạo mới giao diện và mở rộng chứcnăng thay vì tạo lại chúng
Những dịch vụ sau là những dịch vụ kiến trúc cơ bản nhất của tất cả các ứng dụng,cung cấp một framework cho mọi mọi phần mềm được xây dựng:
- Actitvity Manager: Điều khiển vòng đời của các Activity bao gồm cả quản lý các
Trang 20- Views: Được sử dụng để tạo lập các giao diện người dùng cho các Activity
- Notification Mamager: Cung cấp một cơ chế cố định và quy củ cho việc gửi cácthông báo đến người dùng
- Content Provider: Cho phép ứng dụng chia sẻ dữ liệu giữa các ứng dụng
- Resource Manager: Hỗ trợ các thành phần không thuộc mã nguồn như là chuỗi ký
tự, đồ họa được đặt bên ngoài
1.1.5 Applications
Hình 1.5 Các thành phần ứng dụng của Android [1]
Đây là lớp trên cùng của kiến trúc nền tảng Android Android sẽ hoạt động với một
bộ các ứng dụng bao gồm ứng dụng thư điện tử, gửi tin nhắn, lịch, bản đồ, trình duyệtweb, danh bạ v.v… Tất cả các ứng dụng được viết bằng ngôn ngữ Java Các ứng dụngnày có thể được cung cấp sẵn hoặc được phát triển bởi những lập trình viên
1.2 Tổng quan về các thành phần của framework
Phần này của đồ án sẽ trình bày tổng quan về các thành phần thường dùng để tạo nênGame Các thành phần thường được xây dựng dưới dạng các giao diện và được thực hiệnsau đó với các nền tảng cơ bản mà Android cung cấp Giao diện sẽ cho phép chúng ta tậptrung vào ngữ nghĩa mà không cần biết chi tiết phần thực hiện, đồng nghĩa chúng ta cóthể thay đổi phần thực hiện sau này
Mỗi Game cần dùng một framework để giảm thiểu việc giao tiếp với hệ điều hành bêndưới khi lập trình Một framework cơ bản thường chia thành các mô-đun như dưới đây:
o Ứng dụng và quản lý cửa sổ (Application and window management) : có nhiệm vụ tạo ramột cưa sổ và thực hiện việc đóng cửa sổ hay dừng / tiếp tục các ứng dụng Android
o Đầu vào (Input) : liên quan tới mô-đun quản lý cửa sổ, nó theo dõi các đầu vào từ ngườidùng ( như sự kiện chạm, nhấn bàn phím, đọc bộ đo gia tốc)
Trang 21o Vào ra File (File I/O) : cho phép lấy các byte tài nguyên cho chương trình từ đĩa
o Đồ họa (Graphics) : đây là mô-đun phức tạp nhất,nó chịu trách nhiệm tải tài nguyên đồhọa và vẽ lên màn hình
o Âm thanh (Audio) : chịu trách nhiệm tải và chơi các tài nguyên âm thanh
Tập hợp các thành phần trên lại tạo thành một Game Framework, giúp cho viết gametrở nên dễ dàng hơn
Mỗi thành phần bao gồm một hay nhiều giao diện Mỗi giao diện sẽ có ít nhất mộtthực hiện cụ thể dựa trên nền tảng cơ bản Android cung cấp Sau đây chúng ta sẽ đi cụthể hơn vào các thành phần trên
1.2.1 Ứng dụng và quản lý cửa sổ (Application and window management)
Một game cũng như một chương trình máy tính ở điểm có một giao diện người dùng(UI) Nó được chưa trong của sổ Cửa cổ giống như một thùng chứa, hay đơn giản là nơi
để vẽ lên nội dung của game Hệ điều hành cho phép người dùng tương tác với cửa sổtheo nhiều cách, như chạm vào màn hình hay nhấn các phím
Mô-đun chịu trách nhiệm thiết lập cửa sổ và đảm bảo nó được điền đầy bởi thànhphần giao diện người dùng (UI) duy nhất, hay là nơi để vẽ lên và nhận các tương tác từngười dùng Thành phần giao diện người dùng (UI) có thể được render qua CPU hay cóthể là qua phần cứng được tăng tốc trong trường hợp sử dụng OpenGL ES
1.2.2 Đầu vào (Input)
Người dùng sẽ tương tác với cửa sổ bằng một cách nào đó, sau đó cửa sổ sẽ gửi sựkiện đó đến thành phần giao diện đang được hiển thị Và điều cần quan tâm là làm thếnào để lấy được sự kiện từ thành phần giao diện người dùng đó Các API giao diện ngườidùng của hệ điều hành cung cấp một cơ cấu để móc vào hệ thống gửi sự kiện, do đó dễdàng để ghi lại sự kiện
Trang 22o Polling (thăm dò) : chỉ kiểm tra trạng thái hiện tại của đầu vào, mọi trậng thái giữa lầnkiểm tra hiện tại và lần kiểm tra cuối đều bị mất Cách xử lý đầu vào này chỉ thích hợpcho việc kiểm tra những thứ như xem người dùng chạm vào một nút cụ thể, không thíchhợp co việc theo dõi nhập văn bản.
o Dựa trên xử lý sự kiện: cung cấp đầy đủ thời gian của các sự kiện xảy ra từ lần kiểm tracuối cùng Đây là một cơ chế thích hợp để thực hiện nhập văn bản hay những bất kỳ côngviệc dựa trên thứ tự của sự kiện Nó cũng hữu ích để phát hiện khi một ngón tay chạmvào màn hình hoặc khi ngón tay đã được nhấc lên
Trong Android có ba phương thức vào là : chạm màn hình, nhấn phím, và đo gia tốc.Hai phương thức đầu dùng cả hai cơ chế xử lý ở trên, còn đo gia tốc chỉ dùng cơ chếPolling
Phương thức chạm màn hình chia làm 3 kiểu sự kiện:
o Sự kiện chạm xuống : xảy ra khi ngón tay chạm màn hình
o Sự kiện kéo : xảy ra khi ngón tay kéo trên màn hình, xảy ra sau sự kiện chạmxuống
o Sự kiện nhấc lên : xảy ra khi ngón tay nhấc lên khỏi màn hình
Mỗi sự kiện chạm màn hình có thêm hai thông tin là : vị trí tương đối so với gốc, vàchỉ số con trỏ dùng trong trường hợp cảm ứng đa điểm để phân biệt và theo dõi các ngóntay riêng biệt
Nhấn phím được chia làm hai loại sự kiện
o Nhấn xuống : khi phím được ấn xuống
o Nhấc lên : xảy ra khi một phím được nhấc lên
Các sự kiện với phím cũng có thêm các thông tin, sự kiện nhấn sẽ lưu một mã củaphím nhấn, sự kiến nhấc lên lưu một mã phím và một kí tự Unicode sự khác nhau giữa
mã phím và kí tự Unicode được tạo ra tự sự kiện nhấc phím Trạng thái của các phímkhác cũng được lưu lại, chẳng hạn như phím Shift, bằng cách này ta có thể nhận ra chữhoa và chữ thường trong sự kiện nhấc phím Còn trong sự kiện nhấn xuống ta chỉ biết
Trang 23 Bộ đo gia tốc : để dùng bộ đo gia tốc, ta sẽ luôn luôn thăm dò trạng thái của bộ đo Nó sẽbáo cáo gia tốc dưới tác dụng của lực hút Trái Đất trên một trong ba trục được gọi làx,y,z Trong vật lý một đối tượng có gia tốc 9.8 m/s2 khi rơi tự do trong Trái Đất Khi mộttrục hướng về phía tâm Trái Đất, gia tốc cực đại sẽ được áp dụng cho nó, ví dụ khi giữmáy thẳng ở chế độ chân dung, trục y sẽ có gia tốc 9.8 m/s2 trong hình dưới trục z sẽ cógia tốc là 9.8 m/s2 , còn trục y và x có gia tốc là 0.
Hình 1.6 Các trục gia tốc trên điện thoại Android [15]
1.2.3 Vào ra file (File I/O)
Đọc và ghi file khá cần thiết cho phát triển game Trong Java , điều quan tâm nhất làtạo ra các thể hiện InputStream và OutputStream, nhữn cơ cấu chuẩn của Java để đọc vàghi file cụ thể Trong phát triển game, điều được quan tâm nhất là đọc những file đượcđóng gói cùng game, như file cấp độ (level), hình ảnh, âm thanh, còn ghi file được dùng
ít thường xuyên hơn, chủ yếu dùng ghi file khi muốn lưu lại điểm cao hay thiết lập gamehay trạng thái của game
Các file sẽ được đọc từ file APK của game (trường hợp file được đóng gói theo game)hoặc đọc từ SD card ( các file được ghi vào SD card)
Trang 241.2.4 Âm thanh (Audio)
Lập trình âm thanh khá phức tạp nhưng đối với âm thanh trong game ta không đi sâuvào xử lý âm thanh, chỉ bao gồm chơi và phát lại các âm thanh hiệu ứng và nhạc được tải
từ các file âm thanh
Tính chất vật lý của âm thanh : âm thanh được mô hình hóa như tập hợp các sóng dichuyển trong môi trường như nước hay không khí Các sóng không phải các đối tượngvật lý thực tế nhưng là sự vân động của các phần tử trong môi trường Khi 1 âm thanhđược tạo ra, sẽ có các chuyển động cầu Tất cả các sóng âm thanh trong một môi trườngtập hợp lại thành các giai điệu Âm ượng của âm thanh được quyết định bởi bao nhiêunăng lượng được vận chuyển và sẽ suy hao khi tác động lên các phần tử kế tiếp cho đếnkhi tới tai người nghe
Ghi âm và phát âm thanh : âm thanh sẽ được ghi lại dưới dạng số, trạng thái của màngloa được đo à lưu trữ tại các bước thời gian rời rạc quá trình này gọi là lấy mẫu, lượngmẫu trong 1 đơn vị thời gian gọi là tỉ lệ lấy mẫu, nếu đơn vị thời gian là giây (s) tỉ lệ lấymẫu có đơn vị là Hz Tỉ lệ lấy mẫu càng cao thì chất lượng âm thanh càng cao Ngoài racách thức lưu các mẫu trạng thái cũng đóng vai trò quan trọng trong chất lượng âm thanh.Với một màng loa ta sẽ ghi được âm thanh mono, với hai màng loa ở vị trí khác nhau sẽghi lại được âm thanh stereo nhưng lượng mẫu cần lưu trữ là gấp đôi so với âm thanhmono Việc phát âm thanh cũng khá đơn giản Khi ta đã có các mẫu âm thanh dưới dạng
số cùng với tỉ lệ lấy mẫu và kiểu dữ liệu, ta sẽ đưa dữ liệu ra đơn vị xử lý âm thanh, nơichuyển đổi các thông tin thành một tín hiệu cho loa, loa sẽ phân tích và chuyển nó thành
sự rung của màng loa , tạo ra sự chuyển động của các phàn tử xung qoang trong khôngkhí và tạo sóng âm thanh
Chất lượng âm thanh và nén : có nhiều phương pháp nén để giảm dung lượng của file âmthanh được ghi, đồng nghĩa với việc tổn hao, một bộ phận của âm thanh ban đầu sẽ bịlược bỏ Các định dạng âm thanh thường được sử dụng trong game là MP3 hay OGG,
Trang 25tuy là âm thanh đã được nén nhưng chất lượng chấp nhận được và giải quyết vấn đề dunglượng.
Âm thanh chia làm âm hiệu ứng (Sound effect) và nhạc (Music) :
Nhạc: Thường có thời gian dài và chiếm nhiều bộ nhớ, vì vậy khi phát nhạc trong game,
ta thường truyền trực tiếp các mẫu âm thanh từ đĩa thay vì việc tải trước vào bộ nhớ rồimới phát Thông thường game chỉ có một file nhạc, nên ta chỉ cần truy nhập đĩa một lần
Các âm thanh hiêu ứng ngắn như tiếng nổ, tiếng va chạm : Ta thường sử dụng nhiều âmhiệu ứng cùng một thời điểm , do đó việc phát trực tiếp các mẫu từ đĩa cho mỗi âm hiệuứng là không hợp lý Nhưng các âm hiệu ứng này chỉ chiếm dung lượng bộ nhớ nhỏ, nên
ta có thể tải các mẫu âm hiệu ứng và bộ nhớ và có thể đồng thời phát chúng
1.2.5 Đồ họa
Đồ họa là mô-đun cuối cùng trong các mô-đun của framework Nó chịu trách nhiệm
vẽ ảnh lên màn hình Phần dưới đây sẽ trình bày các khái niệm cơ bản trong đồ họa
Rasters, Pixels (điểm ảnh) và Framebuffers
o Raster là một lưới hai chiều, có chiều dài và rộng giới hạn thể hiện số lượngđiểm ảnh (pixels) trên mỗi hàng, cột
o Mỗi điểm ảnh (pixel) có hai thuộc tính : vị trí trong lưới và màu Vị trí củađiểm ảnh là một tọa độ hai chiều trong hệ tọa độ, gốc của hệ tọa độ là góc tráibên trên của lưới
o Bộ xử lý đồ họa truy cập vào một vùng nhớ đăc biệt gọi là bộ nhớ truy cậpngẫu nhiên video (VRAM) Trong VRAM có một khu vực dành riêng để lưu
trữ các điểm ảnh sẽ được hiển thị lên màn hình, gọi là framebuffer Một màn
hình đầy đủ hình ảnh gọi là một Frame Mỗi điểm ảnh (pixel) trên lưới hiển thị
sẽ có tương ứng một địa chỉ ô nhớ chứa màu của điểm ảnh đó Khi muốn thayđổi hiển thị trên màn hình, chỉ cần thay đổi giá trị màu tại ô nhớ của pixeltương ứng
Trang 26Hình 1.7 Lưới hiển thị và VRAM [15]
Color (màu): về mặt vật lý màu là phản ứng của võng mạc và vỏ não thị giác với các
sóng điện từ Mỗi sóng được đặc trưng bởi bước sóng và cường độ của nó Con người cóthể nhìn các màu có bước sóng từ 400-700 nanomets (nm), còn gọi là phổ ánh sáng nhìnthấy Các màn hình sẽ phát các sóng điện từ tới mỗi điểm ảnh, và điểm ảnh sẽ hiển thịmàu sắc Mỗi điểm ảnh sẽ được sẽ được tạo thành từ ba hạt huỳnh quang khác nhau phátánh sáng đỏ, xanh lá cây, xanh biển Việc trộn ba màu cơ bản này với cường độ khácnhau sẽ tạo ra các màu khác nhau cho điểm ảnh, còn gọi là mô hình màu RGB Cường độcủa mỗi màu cơ bản có giá trị từ 0 tới 1 Màu đen sẽ được trộn với tỉ lệ (0,0,0) và màutrắng là (1,1,1)
Các loại mã hóa được sử dụng còn được gọi là độ sâu của màu Ảnh được tạo ra vàlưu trữ trong đĩa hay bộ nhớ có độ sâu được xác định Các loại màn hình hiện nay thường
có độ sâu màu mặc định là 24 bit, có thể được cấu hình để sử dụng ít hơn trong nhiềutường hợp
Trang 27 Định dạng ảnh và nén : để có chất lượng tốt nhất, phương pháp mã hóa RGB888 sẽ
được chọn, 24 bít cho mỗi điểm ảnh (pixel) Giả sử ảnh có kích thước 1024 x 1024pixels, nó có dung lượng khoảng 3MB Nếu dùng mã hóa RGB565 sẽ giảm xuống cònkhoảng 2MB Cũng như âm thanh, hình ảnh cũng có nhiều phương pháp nén nhằm giảmdung lượng Các định dạng phổ biến là JPG, PNG JPG là định dạng được nén và một sốthành phần gốc đã bị lược bỏ trong quá trình nén PNG là định dạng nén tổn hao ít nhất,
nó sẽ tái tạo ảnh với 100 % đúng với bản gốc Việc lựa chọn định dạng sẽ tùy thuộc vàodung lượng bộ nhớ Ảnh sẽ được giải nén khi tải vào bộ nhớ, sau khi giải nén nó sẽ ởdạng mảng các mầu của các pixel và được lưu trong RAM thông thường Khi ảnh đãđược load, nó có thể vẽ từ Ram lên Framebuffer bằng cách chuyển màu của các điểm ảnhcủa bức ảnh lên các vị trí tương ứng trên Framebuffer Việc này sẽ được hỗ trợ bởi cácAPI đã được cung cấp
Trộn màu ( Blending) :phần mềm đồ họa ngoài việc cho biết các giá trị RGB của các
điểm ảnh còn cho biết giá trị về độ trong suốt của điểm ảnh Nó được coi là một thànhphần thêm của màu của điểm ảnh, cũng có thể mã hóa như các thành phần RGB Phươngpháp mã hóa RGB888 là phương pháp mã hóa dùng kiểu số nguyên 32 bit, trong đó dùng
24 bit để lưu trữ bộ RGB Còn 8 bit chưa sử dụng , có thể dùng lưu trữ giá trị anpha ( đạidiện cho độ trong suốt của điểm ảnh) Anpha sẽ có dải giá trị từ 0-255, giá trị 0 là hoàntoàn trong suốt, còn 255 là hoàn toàn không trong suốt Phương pháp mã hóa này gọi làARGB8888 Khi vẽ các điểm ảnh có giá trị anpha bằng không sẽ bị bỏ qua, các điểm ảnh
có giá trị anpha là 255 sẽ được đè lên diểm ảnh đích, trương hợp anpha nằm trong khoảng0-255 điểm ảnh sẽ được trộn
Ví dụ trộn màu:
Trang 28Hình 1.8 Ví dụ về trộn màu (Blending)[15]
Những lưu ý khi trộn màu:
o Phương pháp trộn gồm hai đầu vào và một đầu ra, mỗi điểm được thể hiện bởi
bộ RGB và giá trị anpha
o Hai đầu vào gọi là nguồn và đích Điểm nguồn là điểm ảnh từ bức ảnh chúng
ta muốn vẽ lên đích (trên framebuffer) Điểm đích là điểm sẽ được trộn (từngphần) cùng với điểm nguồn
o Đầu ra cũng là điểm được thể hiện bởi bộ RGB và giá trị anpha Giá trị anpha
sẽ được bỏ qua ở đầu ra
o Để đơn giản, dải giá trị của RGB và anpha sẽ được lấy trong khoảng 0-1
o Phương trình trộn được định nghĩa để đạt được điểm ảnh như mong muốn,phương trình trộn đơn giản nhất như dưới đây:
red = src.red * src.alpha + dst.red * (1 – src.alpha)
blue = src.green * src.alpha + dst.green * (1 – src.alpha)
green = src.blue * src.alpha + dst.blue * (1 – src.alpha)
o Ví dụ với phương trình trên:
Trang 29o Các API đồ họa của Android cho phép người dùng xác định chính xác cách đểtrộn ảnh.
Các cảnh cần phải được quản lý, cần theo dõi cảnh hiện tại và cách thức chuyển sangcảnh khác
Game sẽ cấp quyền truy cập cho các cảnh tới các mô-đun như : đồ họa , âm thanh, đầuvào,…để có thể tải tài nguyên, nhận đầu vào, vẽ cảnh, phát âm thanh,…
Game được thực hiện trong thời gian thực, do đó các cảnh cần được cập nhật và vẽ càngthường xuyên càng tốt, hai việc này được thực hiện trong một vòng lặp chính (mainloop) Vòng lặp này sẽ chấm dứt khi người chơi thoát game
Game cũng cần theo dõi trạng thái của cửa sổ và thông báo cho cảnh hiện tại sự kiện củacửa sổ
Game framework sẽ thực hiện việc thiết lập cửa sổ và tạo thành phần giao diện ngườidùng (UI) để có thể vẽ lên và nhận đầu vào từ người dùng
Các ứng dụng giao diện người dùng (UI applications) thường làm việc trên mô hình dựatrên sự kiện, hề điều ành sẽ thông báo cho ứng dụng các sự kiện đầu vào, và ứng dụng cótrách nhiệm xử lý các thông báo đó Mọi việc được thực hiện trong một luồng chính gọi
là luồng UI Việc xử lý các thông báo sau lời gọi từ hệ điều hành được thực hiện càngsớm càng tốt, do đó vòng lặp chính thực hiện cập nhật và vẽ cảnh sẽ được thực hiện trongmột luồng khác Cần có cơ chế để đồng bộ giữa luồng chính (luồng UI) và luồng chạyvòng lặp chính)
1.3 Android cho phát triển game
1.3.1 Vòng đời Activity
Trang 30mô tả các trạng thái và sự chuyển đổi giữa các trạng thái với nhau của activity hoặc cóthể hiểu là sự xắp xếp các activity vào một Stack, activity nào ở trên thì ưu tiên hơnactivity ở dưới và tương tự như vậy.
1.3.1.1 Nguyên lý
Một Activity có thể ở một trong ba trạng thái sau:
Running: Trong trạng thái này thì activity đang được xếp ở đỉnh stack là giao diện
hiện trên màn hình tương tác trực tiếp với người dùng
Paused: Xảy ra khi activity này vẫn hiển thị trên màn hình nhưng bị che một phần bởi
một activity trong suốt hoặc một hộp thoại hoặc nếu màn hình bị khóa Activity ở trạng
thái paused có thể bị hủy bất cứ lúc nào bởi hệ thống android (ví dụ, khi thiếu bộ nhớ).
Tuy nhiên nếu không bị hủy thì Activity ở trạng thái này sẽ chờ cho đến khi được đẩy lên
đỉnh stack trở về trạng thái running.
Stopped: Điều này xảy ra khi activity hoàn toàn bị che bởi một activity khác và do đó
không còn có thể nhìn thầy trên màn hình Và một lần nữa hệ thống lại có thể quyết địnhhủy activity này bất cứ lúc nào khi chúng thiếu bộ nhớ
Ở trạng thái paused và stopped hệ thống có thể hủy activity bất cứ lúc nào bằng cách gọi hàm finish() hoặc âm thầm hủy process Mặt khác ở hai trạng thái này hoàn toàn có thể trở về trạng thái running và khi đó cũng giống như những đối tượng được lưu trong
bộ nhớ Java thì các biến thành phần của nó trở về đúng trạng thái ban đầu trước khi bị chuyển sang trạng thái running hoặc stopped.
Một activity có những phương thức chính sau mà chúng ta có thể ghi đè để lấy thôngtin khi trạng thái thay đổi:
• Activity.onCreate(): Hàm này được gọi khi activity của chúng ta được khởi chạy lần đầu
tiên Trong hàm này chúng ta sẽ thiết lập tất cả các thành phần của giao diện người dùng
và liên kết chúng với các biến đầu vào của hệ thống Phương thức này chỉ được gọi môtlần trong vòng đời của activity
• Activity.onRestart(): Phương thức này được gọi khi activity được khôi phục từ trạng thái
Trang 31• Activity.onStart(): Hàm này được gọi sau hàm onCreate() hoặc khi activity được khôi
phục từ trạng thái stopped – nó sẽ được gọi sau hàm onRestart().
• Activity.onResume(): Nó được gọi sau hàm onStart() hoặc khi activity được khôi phục từ
trạng thái paused (ví dụ khi màn hình được mở khóa)
• Activity.onPause(): Hàm này được gọi khi activity rơi vào trạng thái paused và nó có thể
là thông báo cuối cùng chúng ta nhận được vì hệ thống Android có thể hủy process củachúng ta một cách âm thầm
• Activity.onStop(): Hàm này được gọi khi activity rơi vào trạng thái stopped và hàm onPause() luôn được gọi trước hàm này.
• Activity.onDestroy: Hàm này được gọi khi kết thúc một vòng đời activity Chú ý rằng
hàm này có thể sẽ không bao giờ được gọi nếu hệ thống hủy process một cách âm thầm
Trang 32Hình 1.9 Vòng đời Android [1]
1.3.1.2 Một số đặc điểm của vòng đời activity
• Trước khi một activity bắt đầu nhảy vào trạng thái running thì nó luôn gọi hàm
onResume() hay bất cứ khi nào chúng ta khôi phục activity từ trạng thái paused và stopped Cũng vì vậy nên chúng ta không cần quan tâm đến hàm onRestart() và onStart().
• Activity có thể bị hủy một cách âm thầm sau khi gọi onPaused() nên chúng ta nên ghi đè vào hàm onPaused() thay vì ghi đè nên các hàm như onStop() hay onDestroy() Trong
hàm này chúng ta phải chắc chắn rằng tất cả những trạng thái chúng ta muốn lưu lại nhưđiểm cao nhất, cấp độ của nhân vật phải được lưu trữ ra bên ngoài ví dụ như thẻ SD bởi
vì sau hàm onPause() tất cả sẽ bị mất và chúng ta chưa biết liệu activity có thể chạy lại
một lần nữa hay không hay người dùng sẽ không bao giờ cho chạy lại
• Chúng ta biết rằng hàm onDestroy() có thể không bao giờ được gọi nếu hệ thống hủy activity sau hàm onPause() hoặc onStop() Tuy nhiên thỉnh thoảng chúng ta muốn biết activity thực sự đã bị hủy? hay hàm onDestroy() chưa được gọi? Lớp Activity có phương thức Activity.isFinishing() giúp chúng ta có thể kiểm tra xem activity đã bị hủy hay chưa? Trong hàm onPause() chúng ta cũng phải gọi hàm này để đảm bảo rằng activity
chưa bị hủy trước khi gọi hàm
1.3.1.3 Áp dụng trong game
Để đơn giản chúng ta có thể ghi đè 3 hàm chính là onCreate(), onResume(), onPause()
• onCreate(): Trong hàm này chúng ta sẽ thiết lập cửa sổ (màn hình chính) và các thành
phần giao diện mà chúng ta sẽ vẽ dựa trên những thành phần đầu vào
• onResume(): Trong hàm này chúng ta sẽ bắt đầu (Start) hay lặp lại (Restart) luồng chính.
• onPause(): Hàm này đơn giản chúng ta dùng để dừng luồng chính, và nếu hàm isFinish()
trả về true thì chúng ta phải lưu lại tất cả những trạng thái cần thiết
1.3.2 Xử lý đầu vào
Ở phần này chúng ta sẽ bàn đến việc lấy thông tin từ nhiều đầu vào khác nhau và cáchlàm việc với chúng
Trang 331.3.2.1 Đơn chạm
Khi chúng ta chạm vào màn hình thì trong Android có một giao diện (interface) lắngnghe (listener) sự kiện đó và báo lại với chúng ta Sự kiện chạm xảy ra thì nó sẽ được đưa
đến OnTouchListener interface và đăng ký chúng với View OnTouchListener interface
chỉ có một phương thức khai báo duy nhất là:
Public abstract boolean onTouch (View v, MotionEvent event)
Một OnTouchListener có thể được đăng ký với bất kỳ View nào thông qua hàm
View.setOnTouchListener() và sẽ được gọi trước khi MotionEvent được gửi đến View.
Chúng ta có thể tương tác với View bằng cách thực hiện (implementation) trong hàm
onTouch().
Đối tượng MotionEvent gồm có 3 phương thức cần quan tâm:
• MotionEvent.getX() và MotionEvent.getY(): Hai phương thức này cho phép chúng ta lấy
tọa độ X và Y của sự kiện chạm Tọa độ của hệ thống được xác định với gốc nằm ở đỉnh
bên trái của view chiều trục x là sang phải còn trục y là đi xuống Lưu ý là tọa độ ở đây
trả về dưới dạng floats
• MotionEvent.getAction(): Phương thức này trả về hành động của sự kiện chạm Nó được
định nghĩa bằng các hằng số nguyên tương ứng với MotionEvnet.ACTION_DOWN,
MotionEvent.ACTION_MOVE, MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_UP.
Cụ thể MotionEvent.ACTION_DOWN xảy ra khi tay chúng ta chạm lên màn hình.
Tiếp theo khi tay chúng ta di chuyển không dời trên màn hình (vuốt) thì đó là sự kiện
MotionEvent.ACTION_MOVE Có một điểm lưu ý ở đây là chúng ta luôn xảy ra sự kiện MotionEvent.ACTION_MOVE vì tay chúng ta không thể giữ im thật sự trên màn hình.
Khi chúng ta nhấc tay lên khỏi màn hình thì sẽ xảy ra sự kiện
MontionEvent.ACTION_UP.
1.3.2.2 Đa chạm
Trang 34thể lấy đối tượng MotionEvent để đọc dữ liệu hay xử lý các hành động như DOWN,
UP…Tuy nhiên cũng có một số điểm khác nhau mà chúng ta cần bàn đến
Con trỏ nhận dạng và các chỉ số
Con trỏ nhận dạng (pointer ID) hay các chỉ số (indices) là hai thành phần tạo nên sựkhác biệt giữa việc xử lý đa chạm và đơn chạm Cụ thể trong đơn chạm khi chúng ta
muốn lấy tọa độ của điểm chạm thì hai phương thức MotionEvent.getX() và
MotionEvent.getY() sẽ trả về tọa độ x,y tương ứng còn đối với đa chạm chúng ta sẽ sử
dụng một biến thể của hai phương thức trên:
event.getX(pointerIndex);
event.getY(pointerIndex);
Ở đây thường người ta sẽ hy vọng rằng pointerIndex tương ứng với một ngón tay chạm trên màn hình (ví dụ một ngón tay chạm có chỉ số con trỏ pointerIndex = 0 và một ngón tiếp theo sẽ có chỉ số con trỏ pointerIndex = 1 và ….) tuy nhiên thật không may là
mọi thứ lại khác
Cụ thể thì các pointerIndex là chỉ số mảng nội bộ của MotionEvent Chúng sẽ giữ tọa
độ tương ứng với từng ngón tay cụ thể khi chạm vào màn hình Mỗi ngón tay trên màn
hình có một số nhận dạng được gọi là pointer indentifier Chúng là một số tùy ý - xác
định duy nhất một thể hiện của một con trỏ chạm vào màn hình Để sử dụng nó nhậndạng các thao tác chạm của người dùng trên màn hình chúng ta có thể sử dụng hàm riêng
biệt MotionEvent.getPointerIdentifier(int pointerIndex) Hàm này sẽ trả về con trỏ nhận
dạng (pointer indentifier) dựa trên chỉ số con trỏ (pointer index) Một con trỏ nhận dạnggiống như một ngón tay chúng ta khi chạm lên màn hình Từ đó cơ bản chúng ta có thểthấy sự khác biệt giữa xử lý đơn chạm và đa chạm về mặt lý thuyết
1.3.2.3 Xử lý sự kiện từ bàn phím
Để bắt được sự kiện từ bàn phím chúng ta implement một giao diện listener khác
được gọi là OnKeyListener Nó có một phương thức đơn được gọi là OnKey():
Trang 35Public boolean onKey(View view, int keyCode, KeyEvent event)
Lớp View ở đây sẽ nhận sự kiện từ bàn phím, đối số keyCode là một hằng số được xác định bởi lớp KeyEvent Cụ thể mỗi phím trên bàn phím màn hình và mỗi phím trên bàn
phím hệ thống có một số duy nhất gán với nó
Tiếp theo chúng ta nói đến lớp KeyEvent Lớp này tương tự như lớn MotionEvent – nó
cũng gồm ai phương thức chính:
• KeyEvent.getAction(): Hàm này sẽ trả về KeyEvent.ACTION_DOWN,
KeyEvent.ACTION_UP và KeyEvent.ACTION_MULTIPLE Chúng ta nên tránh loại cuối
cùng vì chúng ta nên không nên ấn hai phím trên màn hình một lúc Chúng ta chỉ cần hailoại đầu khi chúng ta ấn phím và nhả phím
• KeyEvent.getUnicodeChar(): Hàm này sẽ trả về ký tự Unicode của phím mà ta chạm vào.
Để nhận được các sự kiện từ bán phím thì View cần phải được focus Ta có thể tiến
Cũng như đơn chạm với đa chạm thì chúng ta đề phải đăng ký một bộ lắng nghe
(listener) Giao diện chúng ta cần implement được gọi là SensorEventListener – gồm hai
phương thức cần ghi đè:
Trang 36public void onAccuracyChanged(Sensor sensor, int accuracy);
Phương thức đầu tiên được gọi khi một sự kiện gia tốc được gửi tới Phương thức thứhai được gọi khi độ chính xác của gia tốc thay đổi Tuy nhiên để hai hàm này chạy đượcthì trước hết chúng ta phải chắc chắn rằng là chiếc điện thoại của chúng ta đã cài đặt cảmbiến gia tốc
Để sử dụng được cảm biến gia tốc trên thiết bị thì điều đầu tiên chúng ta phải làm là
phải có một thể hiện của SensorManager.
SensorManager manager =
(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
SensorManager là dịch vụ hệ thống (system service) nó cung cấp bởi hệ thống
Android Android gồm rất nhiều dịch vụ hệ thống, mỗi dịch vụ khác nhau cung cấp những thông tin khác nhau của hệ thống khi người dùng yêu cầu
Khi chúng ta có SensorManager thì chúng ta có thể kiểm tra xem cảm biến gia tốc đã có
sẵn hay chưa?
Boolean hasAccel =
manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size()>0
Nếu trả về true nghĩa là cảm biến gia tốc đã được cài đặt và chúng ta có thể lấy nó từ
SensorManager và đăng ký chúng với SensorEventListener như sau:
Sensor sensor = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0); Boolean success = manager.registerListener(listener, sensor,
SensorManager.SENSOR_DELAY_GAME);
Đối số SensorManager.SENSOR_DELAY_GAME chỉ rõ cách bộ lắng nghe cập nhật
trạng thái mới nhất của cảm biến gia tốc Đây là một hằng số đặc biệt được thiết kế chogame vì vậy chúng ta nên sử dụng nó Ngoài ra phương thức thứ hai trả về kiểu boolean
Trang 37để chỉ ra quá trình đăng ký có làm việc hay không Vì thế nên chúng ta phải kiếm tra kếtquả trả về để chắc chắn rằng chúng ta lấy được bất kỳ sự kiện nào từ cảm biến.
Khi chúng ta đã đăng ký bộ lắng nghe thì chúng ta sẽ nhận được SensorEvents trong phương thức SensorEventListener.onSensorChanged() Phương thức này ngụ ý rằng nó
chỉ được gọi khi trạng thái của cảm biến thay đổi
1.3.3 Xử lý File
Android cung cấp cho chúng ta một số cách để đọc và ghi file Ở đây chúng ta sẽ đềcâp đến làm sao để truy nhập vào bộ nớn goài, đọc dữ liệu trong thư mục assets và
shared preferences.
1.3.3.1 Đọc dữ liệu từ thư mục Assets
Thư mục Assets là nơi lưu trữ những tập tin cần thiết khi chúng ta khởi chạy game Ví
dụ như hình ảnh nhân vật, hình ảnh nền của game, nhạc hay âm thanh của game…
Chúng ta giao tiếp với các file trong thư mục Assets thông qua lớp gọi là
AssetManager Dưới đây chúng ta sẽ lấy tham chiếu nó:
AssetManager assetManager = context.getAccess();
Trong đó context là thể hiện của giao diện Context còn giao diện Context được implement từ lớp Activity Tiếp theo là chúng ta sẽ mở file trong thư mục Assets như sau:
InputSream inputStream = assetManager.open(“dir/dir2/filename.txt”);
Phương thức này sẽ trả về đối tượng InputStream, chúng ta có thể sử dụng nó để đọc
bất kỳ một loại file nào Còn phần trong ngoặc kép là đường dẫn tương đối tới file
1.3.3.2 Truy nhập vào bộ nhớ ngoài
Việc load dữ liệu như ảnh âm thanh trong Assets rất thuận lợi cho game khi khởi chạylần đầu tiên Tuy nhiên có một số dữ liệu chúng ta cần sử dụng lại sau khi chơi ví dụ như
là điểm cao … Chính vì vậy chúng ta sẽ phải để cập đến lý thuyết về việc đọc ghi vào bộnhớ bên ngoài
Trang 38Trong Android có nhiều cách để lưu trữ dữ liệu như sử dụng shared preferences, sử
dụng SQLite … Những lựa chọn trên có một điểm chung là không thể xử lý tốt nhữngfile bit lớn Vì vậy phương pháp tối ưu nhất là sử dụng thẻ nhớ SD để lưu trữ dữ liệungoài
Điều đầu tiên để giao tiếp với thẻ nhớ SD là chúng ta phải yêu cầu truy nhập bộ nhớ
ngoài trong file manifest.
<users-permission
android:name=“androd.permission.WRITE_EXTERNAL_STORAGE”/>
Tiếp theo là chúng ta phải kiểm tra chắc chắn rằng là bộ nhớ ngoài đang ở trạng tháisẵn sàng hoạt động Ví dụ, khi chúng ta tạo máy ảo mà khi thiết lập lại không cấp bộ nhớngoài thì chúng ta không thể có thao tác đọc ghi nào được Một lý do khác nữa không thểtruy nhập vào bộ nhớ đó là bộ nhớ đang bị truy nhập bởi một thiết bị khác ( điển hìnhchính là khi người dùng đang truy vấn trên bộ nhớ ngoài như đang tìm kiếm hay mở hộpthoại bộ nhớ ngoài) Vì vậy cách để chúng ta kiểm tra trạng thái của bộ nhớ ngoài là:
String state = Enviroment.getExternalStoreageState();
Chúng ta sẽ nhận được kết quả trả về là String Nếu chuỗi String này trùng với một hằng số (String) mà lớp Environment định nghĩa được gọi là Enviroment.MEDIA_MOUNTED thì chúng ta sẽ có đầy đủ tính năng đọc ghi vào bộ nhớ
ngoài Chú ý là ở đây chúng ta so sánh String bằng hàm equals() chứ không dùng dấu
“=” vì dấu “=” nó không hoạt động trong mọi trường hợp
Khi chúng ta xác định được là chúng ta chắc chắn có thể truy nhập vào bộ nhớ ngoàithì việc tiếp theo đó là xác định dường dẫn đến thư mục là chúng ta muốn lưu file Trướchết ta phải lấy được đường dẫn thư mục root bằng cách thực hiện như sau:
File externalDir = Environment.getExternalStorageDirectory();
Sau khi có đường dẫn thư mục root ta có thể tự triển khai đường dẫn đến các thư mục
Trang 391.3.3.3 Shared Preferences
Android có cung cấp một API đơn gian để lưu cặp giá trị Nó được gọi là
SharedPreferences – API này rất thuận tiện cho việc lưu trữ tạm thời các dạng text hay
để truyền giữa các activity với nhau Dưới đây là hai cách điển hình để lấy một thể hiện
của SharedPreferences từ activity:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
Phương thức đầu tiên trả lại cho ta một SharedPreferences phổ biến còn phương thức thứ hai lại cho phép chọn chế độ riêng tư Chế độ riêng tư Context.MODE_PRIVATE là
mặc định ngoài ra ta có thể chọn hai chế độ khác là
Context.MODE_WORLD_READABLE và Context.MODE_WORLD_WRITEABLE Tuy
nhiên hai chế độ không cần thiết đối với việc xây dựng game của chúng ta
Điều đầu tiên để sử dụng sharedPreferences là chúng ta phải tạo editor:
Editor editor = prefs.edit();
Tiếp theo là thêm các các giá trị tương ứng với khóa (key):
editor.putString(“key1”, “obama”);
editor.putInt(“key2”, 5);
Và cuối cùng là chúng ta sẽ lưu lại những gì vừa thêm vào:
editor.commit();
Để lấy lại dữ liệu thì chúng ta làm như sau:
String value1 = prefs.getString(“key1”, null);
int value2 = prefs.getInt(“key2”,0);
Trang 40Kết quả trả về thì value1 sẽ là obama còn value2 sẽ là 5 Nếu mà chúng ta gõ key sai
và không tìm thấy thì nó sẽ trả về giá trị mặc định chính là đối số thứ hai chúng ta truyền
vào Cụ thể chính là null và 0.
1.3.4 Xử lý âm thanh
Về Audio thì Android cung cấp API giúp người dùng dễ dàng tạo ra các hiệu ứng âmthanh hay nhạc nền trong game Dưới đây là những điểm quan trọng việc xử lý âm thanhtrong game
1.3.4.1 Điều khiển âm lượng
Âm lượng trong Android cần lưu ý rằng khi chúng ấn nút tăng giảm âm lượng thì nó
sẽ điều khiển những âm lượng khác nhau phụ thuộc vào ứng dụng mà chúng ta đangchạy Ví dụ khi chúng ta nghe gọi thì ấn nút tăng giảm thì sẽ tăng giảm âm lượng cuộcgọi, khi chúng ta xem video trên youtube thì nút tăng giảm sẽ điều khiển âm lượng củavideo hay khi chúng ta đang ở màn hình chính thì nút tăng giảm sẽ điểu khiển âm lượngcủa hệ thống như là chuông hay tiếng của tin nhắn …
Android có những luồng audio khác nhau cho những mục đích khác nhau Rõ ràng
nhất là khi bạn gõ dòng code AudioManager thì sẽ có nhiều gợi ý tiếp theo về các loại stream Ở đây chúng ta sẽ dùng music stream Trước khi chơi nhạc chúng ta phải đảm
bảo rằng nút tăng giảm âm lượng sẽ điều khiển đúng luồng audio bằng cách như sau:
Context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
1.3.4.2 Hiệu ứng âm thanh
Android đã cung cấp sẵn cho chúng một lớp để chơi hiệu ứng âm thanh dễ dàng đó là
lớp SoundPool Đầu tiên chúng ta tạo đổi tượng như sau:
SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
Tham số đầu tiên là số lượng hiệu ứng âm thanh tối đa có thể chơi cùng một lúc Điều
đó không có nghĩa chúng ta không thể nạp hơn 20 hiệu ứng âm thanh mà nó chỉ hạn chế
tối đa là 20 âm thanh phát đồng thời Tham số thứ hai chúng ta chọn music stream nơi mà