26
Trung tâm Đào tạo E-Learning Cơ hội hc tp cho mi người Lp trình thiết bdi động - Bài 8 Trang 1 BÀI 8: KTHUT PHÁT TRIN GAME TRONG ANDROID Mc tiêu: Trong bài này, Anh/Chcần đạt được nhng mc tiêu sau: 1. Giới thiệu các khái niệm cơ bản về nguyên lý xây dựng các ứng dụng trò chơi. 2. Sử dụng AndEngine để phát triển một ứng dụng game đơn giản. Ni dung: 8.1. Các nn tng phát trin game trên thiết bdi động Trong các bài học trước chúng ta đã làm quen với kthut xlý đồ ha trên J2ME, bài hc này chúng ta stp trung vào tìm hiu kthut xlý đồ ha trên android thông qua tiếp cn mt snn tng phát trin game và xây dng mt trò chơi đơn giản trên mt engine cth. Ktkhi máy tính xut hiện, game đã trở thành mt trong nhng ng dng phbiến nht trên thtrường. Trong cun sách Reality Is Broken, tác gi Jane McGonigal đã nêu ra 4 thuộc tính ca phn ln game trên thtrường: Mc tiêu: Game chra mt mục tiêu rõ ràng cho người chơi để hđạt được. Mc tiêu là nhng ththách đối với người chơi, nhưng họ có thvượt qua. Người chơi sẽ cm thy hng thú nht nếu mục tiêu đó phù hp vi khnăng của mình, không quá khó, không quá d. Mc tiêu rõ ràng, thú vcũng là yếu tquan trng thu hút người chơi đến vi game. Quy tắc: Game cũng có những quy tc bt buc mà tt cngười chơi phi tuân theo. Các quy tắc này thường làm cho việc đạt được mc tiêu nêu trên khó khăn hơn. Điều đó cũng khuyến khích ssáng to ca mi người. Phn hi: Game cn phn hồi cho người chơi biết rng hđang làm công vic ca mình tt hay không. Một điều đáng lưu ý rằng, hthng phn hồi chính là chìa khóa để làm trò chơi thú vị.

BÀI 8: KỸ THUẬT PHÁT TRIỂN GAME TRONG ANDROID

Embed Size (px)

Citation preview

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 1

BÀI 8: KỸ THUẬT PHÁT TRIỂN GAME TRONG ANDROID

Mục tiêu:

Trong bài này, Anh/Chị cần đạt được những mục tiêu sau:

1. Giới thiệu các khái niệm cơ bản về nguyên lý xây dựng các ứng dụng trò

chơi.

2. Sử dụng AndEngine để phát triển một ứng dụng game đơn giản.

Nội dung:

8.1. Các nền tảng phát triển game trên thiết bị di động

Trong các bài học trước chúng ta đã làm quen với kỹ thuật xử lý đồ họa trên

J2ME, bài học này chúng ta sẽ tập trung vào tìm hiểu kỹ thuật xử lý đồ họa trên

android thông qua tiếp cận một số nền tảng phát triển game và xây dựng một

trò chơi đơn giản trên một engine cụ thể.

Kể từ khi máy tính xuất hiện, game đã trở thành một trong những ứng dụng phổ

biến nhất trên thị trường. Trong cuốn sách Reality Is Broken, tác giả Jane

McGonigal đã nêu ra 4 thuộc tính của phần lớn game trên thị trường:

Mục tiêu: Game chỉ ra một mục tiêu rõ ràng cho người chơi để họ đạt

được. Mục tiêu là những thử thách đối với người chơi, nhưng họ có thể

vượt qua. Người chơi sẽ cảm thấy hứng thú nhất nếu mục tiêu đó phù

hợp với khả năng của mình, không quá khó, không quá dễ. Mục tiêu rõ

ràng, thú vị cũng là yếu tố quan trọng thu hút người chơi đến với game.

Quy tắc: Game cũng có những quy tắc bắt buộc mà tất cả người chơi

phải tuân theo. Các quy tắc này thường làm cho việc đạt được mục tiêu

nêu trên khó khăn hơn. Điều đó cũng khuyến khích sự sáng tạo của mỗi

người.

Phản hồi: Game cần phản hồi cho người chơi biết rằng họ đang làm công

việc của mình tốt hay không. Một điều đáng lưu ý rằng, hệ thống phản

hồi chính là chìa khóa để làm trò chơi thú vị.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 2

Tham gia một cách tự nguyện: một trò chơi sẽ không còn là một trò chơi

đúng nghĩa nếu bạn không thực sự thích chơi nó. Điều này ngụ ý rằng

người chơi phải chấp nhận được mục tiêu, các quy tắc, và hệ thống phản

hồi của trò chơi.

Các thể loại game cơ bản

Những người phát triển game không chủ động phân loại các trò chơi của họ.

Và tất nhiên, không có danh sách chuẩn nào về việc phân loại game. Mặc dù

vậy, theo thời gian, các trò chơi cũng dần được phân loại vào các lớp khác nhau

theo những cách khác nhau. Việc phân loại chính xác rất khó khăn. Tuy vậy,

chúng ta có thể kể đến một số loại game điển hình như sau:

Game hành động hay kỹ năng: Người chơi phải sử dụng một số kỹ năng

trong thời gian thực (VD: bắn vào một vật đang di chuyển ) để đạt được

mục tiêu.

Game về chiến lược: Người chơi ít phải sử dụng kỹ năng hơn, và chủ

yếu tập trung đưa ra những quyết định lựa chọn chiến lược hợp lý để

vượt qua màn chơi.

Game phiêu lưu hay có cốt truyện: Những game này được xây dựng dựa

trên một cốt truyện hấp dẫn, với các nhân vật được trau chuốt cùng với

một cốt truyện cụ thể. Cốt truyện đó cũng định nghĩa ra mục tiêu cho

người chơi trong thể loại game này.

Game mô phỏng: Thông thường, game thuộc thể loại này mô tả lại một

yếu tố có trong thực tế (VD như lái một chiếc xe, chơi tennis,…)

Game dạng câu đố: Một số trò chơi truyền tải trực tiếp câu đố đến với

người chơi. Tuy nhiên, trong một số game phức tạp, những câu đố này

có thể ẩn dưới nhiều hình thức khác nhau. Có thể hiểu như một game

nhỏ, trong một game lớn hơn.

Việc phát triển các sản phẩm game trên điện thoại di động chưa bao giờ là điều

đơn giản. Một sản phẩm game hoàn chỉnh yêu cầu lập trình viên phải dành rất

nhiều thời gian và công sức để hoàn thiện nó. Để giảm thiểu thời gian và công

việc trong quá trình phát triển game, ngày nay, đã có rất nhiều các thư viện hỗ

trợ phát triển game (Game Engine) trên thiết bị di động được ra đời.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 3

Trong bài học này, chúng ta cùng tìm hiểu những thư viện game (Game Engine)

trên các thiết bị di động được đánh giá tốt nhất hiện nay.

Unity 3D

Unity 3D là phần mềm phát triển ứng dụng game trực tiếp theo thời gian thực.

Đây là một trong những nền tảng phát triển game tốt nhất, cung cấp một môi

trường phát triển tích hợp trực quan bằng các thao tác kéo thả tùy biến giao

diện một cách nhanh chóng. Unity 3D hỗ trợ hầu hết các định dạng đồ họa được

tạo ra bởi các phần mềm đồ họa chuyên nghiệp như: 3D Max, Blender, Modo,

Autodesk FBX, LightWave, Maya, Cinema 4D,Cheetah 3D.

Một trong những đặc điểm nổi bật nhất của Unity 3D là bộ thư viện vật lý được

tích hợp sẵn. Với thư viện vật lý này, lập trình viên sẽ giảm thiểu được rất nhiều

công việc tính toán và viết code cho các chuyển động (bao gồm cả va chạm)

trong game.

Với Unity, sau khi bạn design được một game thì bạn có thể xuất được ra một

file.exe và có thể chạy và chơi được trên PC khác.

Một thế mạnh nữa của Unity là bạn có thể chạy demo game của bạn ngay trong

khi design, nó có hỗ trợ hai chế độ là Scene và Game, rất thuận tiện cho việc

test thử các modulGame.

Hiện Unity 3D cung cấp cả hai phiên bản miễn phí và mất phí. Bạn có thể dễ

dàng tải phần mềm làm game này tại địa chỉ: http://www.unity3d.com.

Corona SDK

Corona được coi là một trong những nền tảng phát triển game 2D tốt nhất hiện

nay. Corona hỗ trợ đa nền tảng, điều đó có nghĩa là bạn chỉ cần phát triển game

một lần duy nhất và dễ dàng biên dịch sang các nền tảng di động khác nhau.

Đặc biệt Corona SDK sử dụng LUA làm ngôn ngữ chính để phát triển game.

Dưới đây là những đặc trưng của SDK này:

Corona SDK giúp phát triển ứng dụng nhanh hơn 10 lần. Với hệ thống

thư viện hỗ trợ phong phú và được thiết kế rất tốt, lập trình viên có thể

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 4

dễ dàng xây dựng các thao tác (hành động) trong game chỉ bằng một vài

dòng code.

Corona hỗ trợ đa nền tảng. Bạn chỉ cần phát triển game một lần, sau đó

có thể dễ dàng biên dịch ứng dụng sang các nền tảng khác như Android,

iOS, Kindle Fire, Nook và Windows Phone một cách dễ dàng. Không

những vậy Corona còn hỗ trợ chuyển đổi với những thiết bị có kích cỡ

và độ phân giải khác nhau một cách dễ dàng.

Đạt các tiêu chuẩn của ngành công nghiệp game. Hiện Corona SDK cung

cấp 4 phiên bản:

o Starter: Xây dựng và xuất bản các ứng dụng miễn phí.

o BASIC, PRO, Enterprise: tính phí, có thêm các tính năng tiên tiến,

tích hợp thêm các thư viện địa phương, hỗ trợ linh hoạt tối đa. Bạn

có thể xem chi tiết về Corona SDK tại địa chỉ:

http://coronalabs.com/products/corona-sdk/

Game Salad

GameSalad là phần mềm phát triển các ứng dụng game được đánh giá là dễ

nhất so với các sản phẩm cùng loại. Với GameSalad, nhà phát triển chỉ cần dựa

vào giao diện kéo thả để xây dựng game mà gần như không cần kỹ năng lập

trình. GameSalad nhắm tới những đối tượng khách hàng có ý tưởng phát triển

trò chơi nhưng thiếu kỹ năng lập trình. Thống kê hiện nay có khoảng hơn

700.000 nhà phát triển với hơn 200.000 trò chơi trên toàn thế giới. Trong đó có

rất nhiều trò chơi hay và được đánh giá rất cao, thậm chí còn đạt được top 70-

100 trên các kho ứng dụng.

Hiện nay GameSalad hỗ trợ các nền tảng: Android, iOS, Windows Phone,

HTML5. Chi tiết về GameSalad tại địa chỉ: http://gamesalad.com

Sprite Kit

Sprite Kit là thư viện hỗ trợ phát triển game di động của Apple. Các lập trình

viên khi sử dụng Sprite Kit không cần phải tải thêm bất kỳ thư viện nào do

Sprite Kit đã được tích hợp sẵn trong Xcode. Thư viện này không những cung

cấp khá đầy đủ các tính năng để phát triển game trên nền 2D mà còn được tích

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 5

hợp một bộ thư viện vật lý khá tốt, giúp các nhà phát triển có thể lập trình hành

động nhân vật một cách đơn giản và nhanh chóng.

Một số ưu điểm:

Đây là một thư viện được xây dựng ngay trong IOS nên không cần phải

tải thêm bất kì một thư viện số (Extra Libray) hay một mã nguồn nào bên

ngoài nữa. Ngoài ra, nó được viết và phát triển bởi chính Apple nên

chúng ta có thể biết được rằng nó sẽ được Apple hỗ trợ và cập nhật

thường xuyên sớm nhất có thể.

Có sẵn các công cụ để cắt và thể hiện hiệu ứng ngay trong Xcode (particle)

Giúp bạn lập trình và quản lý game một cách dễ dàng do cấu trúc của

Sprite Kit được thiết kế để làm chuyện đó. Hỗ trợ các dạng video và

hiệu ứng hình ảnh đơn giản nhưng chắc chắn sẽ được cải thiện trong

tương lai.

Nhược điểm:

Một khi sử dụng Sprite Kit nghĩa là cuộc sống của bạn sẽ gắn liền với hệ

sinh thái của Apple. Nếu bạn muốn đưa game của bạn lên các hệ điều

hành khác như Android thì nó gần như là viết lại từ đầu.

Sprite Kit đang ở thời kì đầu của nó, việc nó thành công hay thất bại là

thứ hoàn toàn không chắc chắn. Thêm vào đó, Sprite Kit chưa hỗ trợ cho

bạn tham gia vào việc tuỳ chỉnh các mã OpenGL nên đối với những lập

trình viên có thâm niên cao thường không thích thú lắm.

Những thứ bạn đã viết được trên các engine khác như Corona, Cocos2D

không phù hợp với Sprite Kit điều đó có nghĩa là bạn đang bắt đầu từ

vạch xuất phát cùng với tất cả mọi người.

Thông tin chi tiết về game engine này tại địa chỉ sau:

https://developer.apple.com/library/ios/documentation/GraphicsAnimation/C

onceptual/SpriteKit_PG/Introduction/Introduction.html.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 6

Cocos2d-x

Cocos2D-X là nền tảng phát triển các ứng dụng game mã nguồn mở theo giấy

phép MIT. Cocos2d-x phù hợp trong những dự án xây dựng các trò chơi, ứng

dụng và các chương trình đa nền tảng.

Hiện tại, Cocos2d-x cho phép các nhà phát triển thực hiện dự án với các ngôn

ngữ C++, LUA và JavaScript cùng các nền tảng hỗ trợ như: iOS, Android,

Windows Phone, Mac OS X, Windows PC và Linux PC. Cocos2d-x cung cấp

một môi trường phát triển nhanh chóng, tiết kiệm thời gian, công sức và chi

phí. Cocos2d-x đang là nền tảng phát triển game phổ biến được ưa chuộng

rộng rãi từ nhà phát triển cá nhân cho đến những công ty phát triển game lớn.

Có thể kể đến các công ty lớn sử dụng cocos2d-x như: Zynga, Wooga, Glu,

IGG, Big Fish Games, Fingersoft, Gamevil, GREE, DeNA, Konami, CJ E &

M, NHN, LINE, Square Enix, Disney.

Để biết thêm thông tin của Cocos2d-x, bạn có thể truy cập địa

chỉ: http://www.cocos2d-x.org

AndEngine

AndEngine là một nền tảng phát triển game 2D mã nguồn mở cho phép xây

dựng các ứng dụng trò chơi trên Android một cách nhanh chóng và dễ dàng.

Đặc biệt AndEngine hỗ trợ đầy đủ các thuộc tính quan trọng của OpenGL, nhờ

đó lập trình viên có thể dựng hình, tạo vật thể, quản lý các thiết bị đầu vào

(sensor cảm ứng, màn hình cảm ứng …) và âm thanh khá thuận tiện và hiệu

quả. Dưới đây là những tính năng cơ bản AndEngine cung cấp:

Hỗ trợ các thiết bị với những độ phân giải khác nhau.

Hỗ trợ cảm ứng đa điểm.

Hỗ trợ bộ thư viện vật lý Box2D.

Hỗ trợ bản đồ map Tiled

Một số đánh giá về Andengine:

Chi phí giá thành: Hoàn toàn free.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 7

Hiệu năng: Tương đối tốt, tuy nhiên chậm hơn so với các Engine khác

(như LibGDX ở phần trên).

Cộng đồng: tương đối tốt, số lượng người sử dụng khá nhiều.

Tài liệu và ví dụ: không có tài liệu cụ thể. Đây là một trong những khó

khăn khi chúng ta làm quen với Andengine. Tuy nhiên có các ví dụ và

các bài viết hướng dẫn của các lập trình viên (có thể tìm được qua

Internet). Do đó nếu bạn muốn sử dụng Andengine hãy chuẩn bị tam lý

là sẽ tìm hiểu bằng các ví dụ là chủ yếu.

Mã nguồn mở, thiết kế sử dụng nhiều phương thức abstract và kế thừa.

Hướng đối tượng tốt, tuy nhiên chưa thật sự tốt với nền tảng di động

Android.

Tính năng: Có đầy đủ hầu hết các tính năng cơ bản để xây dựng một ứng

dụng game. Tuy nhiên vẫn chưa có nhiều tính năng giống như LibGDX.

Điểm cộng dành cho Andengine chính là ở việc dễ sử dụng và dễ học hơn các

Engine khác, đồng thời các tính năng cơ bản cũng khá đầy đủ cho việc xây

dựng một game 2D đơn giản. Hãy nhớ, Andengine chỉ thích hợp cho Game 2D.

Nếu yêu cầu về hiệu năng của bạn thật sự cao và game co nhiều hình ảnh phức

tạp, cũng như hình ảnh vật thể là 3D, hãy tìm một Engine khác.

Để biết thêm thông tin về game enigne này, bạn có thể truy cập địa chỉ

sau: http://www.andengine.org

LibGDX

LibGDX là nền tảng phát triển game mã nguồn mở được đánh giá rất cao về

hiệu năng. LibGDX hỗ trợ đa nền tảng trên Desktop, Android, iOS, HTML5 và

BlackBerry. Sử dụng LibGDX đồng nghĩa với việc cho phép lập trình viên Java

phát triển các dự án game trên máy tính cá nhân và thiết bị di động bằng cách

sử dụng cơ sở mã giống nhau. Điểm được đánh giá cao nhất của LibGDX là

hiệu năng nền tảng này có được nhờ mã nguồn sử dụng cả Java và C để phát

triển. Ngoài khả năng tương đồng nhiều game engine khác như tạo hình, xử lý

đồ họa 2D-3D, quản lý thiết bị đầu vào, quản lý tệp tin hệ thống, LibGDX còn

nổi bật với các công cụ hỗ trợ tạo bản đồ, ảnh đi kèm như Texture Packer và

Particle Editor.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 8

Một số ưu điểm của Libgdx như sau:

Đa nền tảng: chúng ta chỉ cần viết code 1 lần nhưng có thể chạy trên

được nhiều nền tảng khác nhau. Một ứng dụng của tính năng này đó là

phát triển các ứng dụng cho Android. Để phát triển một ứng dụng cho

Android, khi chạy thử ứng dụng, chúng ta cần chạy ứng dụng trên

Emulator hoặc trên thiết bị thật. Việc này rất mất thời gian do Emulator

chạy rất chậm và quá trình cài đặt cũng như chạy ứng dụng trên thiết bị

thật cũng không khá hơn. Với LibGDX, chúng ta có thể chạy ứng dụng

trên PC, sau đó chỉ cần với vài dòng code, chúng ta có thể chạy ứng dụng

này trên Android với hiệu năng tương đương. Điều này giúp chúng ta

kiểm thử và tìm lỗi ứng dụng nhanh hơn và hiệu quả hơn.

Hiệu năng: Hiệu năng của LibGDX thực sự rất ấn tượng do LibGDX sử

dụng cả Java và mã nguồn C để tạo nên ứng dụng.

Cộng đồng: cộng đồng sử dụng LibGDX rất tuyệt vời với số lượng người

dùng lớn. Các lập trình viên luôn đóng góp và giúp đỡ cho cộng đồng.

Việc sửa lỗi cũng được cập nhật rất thường xuyên.

Tài liệu và ví dụ: rất đầy đủ với Javadoc. LibGDX cũng cung cấp rất

nhiều các ví dụ và demo với đầy đủ các chức năng từ đơn giản đến

phức tạp.

Mã nguồn: mã nguồn mở với thiết kế rất rõ ràng và phù hợp với việc

phát triển ứng dụng cho di động. LibGDX cho phép người lập trình khả

năng sử dụng các API từ các lớp thấp đến cao, tùy theo yêu cầu của người

sử dụng.

Tính năng: LibGDX có rất nhiều tính năng như tạo hình, xử lý đồ họa

2D, 3D, xử lý âm thanh, quản lý các thiết bị vào ra, quản lý file hệ thống.

Cùng với đó là các công cụ đi kèm rất hữu ích như Texture Packer và

Particle Editor.

Để biết thêm thông tin chi tiết về nền tảng game nổi tiếng này, bạn có thể truy

cập địa chỉ: http://libgdx.badlogicgames.com

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 9

8.2. Lập trình game với AndEngine

8.2.1. Các thành phần cơ bản của AndEngine

1. Camera

Các "camera" của trò chơi xác định giao diện được trình bày cho người chơi.

Nó giống như một máy quay phim trong không gian hai chiều. Chiếc máy quay

này có thể giãn và phóng trên các cảnh để thay đổi khung nhìn trình bày. Sự co

giãn và phóng to có thể được thực hiện dưới sự kiểm soát của người chơi hoặc

được điều khiển theo chương trình.

2. Scene

Một trò chơi, giống như một bộ phim, bao gồm một loạt các cảnh nơi hành

động diễn ra. Trong một bộ phim, những cảnh được biên tập lại với nhau theo

một cách cố định. Trong trò chơi, trình tự của cảnh được dẫn dắt bởi lối chơi

của trò chơi. Trò chơi giống như bộ phim được chỉnh sửa từ trên cao nhìn xuống.

3. Layer

Cảnh bao gồm các lớp đồ họa. Các lớp được chồng lên nhau, giống như các tế

bào hoạt hình được sử dụng để tạo phim hoạt hình theo nghề ngày xưa. Các lớp

cũng có thể được sử dụng để giới thiệu 2 ½ D hiệu ứng, ở đâu, như giãn máy

quay, các lớp gần hơn chuyển động nhanh hơn các lớp ở xa nhiều hơn.

4. Sprite

Những Sprite là những đại diện trực quan của các diễn viên trong bộ phim của

chúng ta. Dù cho các sprite là hình động hay tĩnh, chúng vẫn thường di chuyển

trong những màn chơi. Kết cấu Sprite thường được nạp từ một hình ảnh lớn mà

bao gồm một tập hợp các hình ảnh họa tiết, được gọi là một sprite sheet.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 10

5. Entity

Trong AndEngine, các thực thể là tất cả những thứ được vẽ trên màn hình. Các

thực thể có thể là các sprite, các hình dạng hình học, hay các dòng kẻ trên màn

hình. Tất cả các thực thể đều có các thuộc tính, chẳng hạn như màu sắc, góc

quay, độ lớn, vị trí, và có thể được thay đổi bằng các Modifier.

6. Modifier

Các modifier thay đổi các thuộc tính của một thực thể, và chúng rất mạnh mẽ

trong AndEngine. Chúng có thể được sử dụng trên bất kỳ thực thể nào, và sự

thay đổi mà chúng gây ra có thể là trực tiếp hoặc diễn ra từ từ trong một thời

gian nhất định. Trong trò chơi của chúng ta, chúng ta sẽ sử dụng các modifier

thường xuyên để tạo hiệu ứng với các sprite và các thực thể khác.

7. Texture

Một texture là một kết cấu 2D, thường là đồ họa dạng bitmap. Textures xác

định hình dạng các thực thể, và phần lớn môi trường đồ họa OpenGL được xây

dựng xung quanh việc sử dụng các texture.

8. Texture Region

Một texture định nghĩa một hình ảnh bitmap hoàn tất, và một texture region

định nghĩa một tập hợp con các vùng texture đó.

9. Engine

Mỗi scene được chạy trên một engine. Nó điều khiển các hình ảnh động và các

modifier biết khi nào phải cập nhật trạng thái, điều phối các bản vẽ thực tế, xử

lý các sự kiện đầu vào người dùng (cảm ứng, phím, bộ cảm biến), và nói chung

là quản lý tiến trình của trò chơi. Engine cũng giống như các nhà sản xuất/đạo

diễn của bộ phim của chúng ta, nói với mọi người những gì họ cần phải làm.

10. BaseGameActivity

Lớp này, được mở rộng của lớp Activity Android, sẽ là cơ sở của mỗi scene

trong trò chơi của chúng ta. BaseGameActivity làm các công việc chung cho

tất cả các scene, thiết lập các công cụ trò chơi, phù hợp với các yêu cầu vòng

đời hoạt động Android.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 11

11. Physics Connector

AndEngine bao gồm khả năng vật lý cơ bản trong engine cơ bản, nhưng Box2D

động cơ vật lý được mở rộng phần lớn vào những khả năng đó. Chúng ta kết

nối với đối tượng AndEngine Box2D thông qua một kết nối vật lý. Nếu game

của bạn không sử dụng Box2D vật lý, bạn sẽ không có một kết nối vật lý.

12. Box2D Physics Engine

Physics Box2D là một thành phần mở rộng của AndEngine, nó hỗ trợ việc

mô phỏng sự tương tác thực tế giữa các đối tượng vật lý trong các trường

hợp sau đây:

Mô phỏng các tính chất vật lý của các vật rắn.

Ổn định xếp chồng.

Trọng lượng.

Các đơn vị được người dùng xác định.

Giải quyết hiệu quả cho sự tương tác / liên lạc.

Trượt ma sát.

Làm việc với các hình học: hình hộp, hình tròn, đa giác.

Một số loại liên kết: khoảng cách, lăng trụ, ròng rọc,…

Trạng thái ngủ (loại bỏ cơ thể bất động từ các mô phỏng cho đến khi

chạm vào).

8.2.2. Ví dụ thiết kế và xây dựng game đơn giản.

Bài toán tháp Hà Nội:

Cho 3 cái đĩa và ba cái trục: A là trục nguồn, B là trục đích, và C là trục trung

chuyển. Những cái đĩa có kích cỡ khác nhau và có lỗ ở giữa để có thể lồng vào

trục, theo quy định "nhỏ trên lớn dưới". Đầu tiên, những cái đĩa này được xếp

tại trục A. Vậy làm thế nào để chuyển toàn bộ các đĩa sang trục B, với điều kiện

chuyển từng cái một và luôn phải đảm bảo quy định "nhỏ trên lớn dưới", biết

rằng trục C được phép sử dụng làm trục trung chuyển?

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 12

a) Cài đặt các gói AndEndgine

Trước hết ta cần cài đặt AndEngine. Ở đây chúng ta cùng cài đặt AndEngine

và tích hợp với Eclipse.

Ta sẽ tạm chia thành 3 bước cài đặt : bước 1 là cài đặt egit - tool quản lý source

phân tán, bước 2 là import các project đã có của Andengine thành các thư viện

của mình , bước 3 là thêm thư viện mới import vào project.

Bước 1: Cài đặt Git

Trong giao diện của Eclipse, tại thanh menu chọn help -> install new software

Tại cửa sổ Install hiện ra, click vào button add sẽ hiện ra tiếp 1 cửa sổ con nữa

tên là add repository, tại hộp textbox location, điền vào đường dẫn sau :

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 13

“http://download.eclipse.org/egit/updates”

Mục name là để điền tên (ta tự đặt) cho gói cài, chúng ta có thể bỏ trống, sau

đó chọn OK.

Sau khi chọn ok sẽ hiện ra bảng chọn các mục sẽ được cài đặt, ở đây ta chọn

cả 2 mục “Eclipse Git Team Provider” và “JGIT”, sau đó chọn next =>…=>

next => finish.

Bước 2 : Import các project của AndEngine thành các thư viện của mình

Trong giao diện eclipse, chọn file => import => chọn thư mục Git => project

from git => URI, lúc này sẽ hiện ra cửa sổ có tên import projects from git nhập

vào url sau vào text box URI :

"https://github.com/nicolasgramlich/AndEngine"

Chọn tiếp next => next ... cho đến khi finish và chờ chương trình download

xong thư viện. Sau khi download về xong, project thường sẽ có lỗi, đó là do

chưa xét Platform hoặc chưa cài đặt trình biên dịch cho nó, thường thì nó sẽ có

lỗi dấu chấm than màu đỏ như hình:

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 14

Lúc này bạn cần chọn vào project mới import, click chuột phải chọn Properties

(hoặc tổ hợp phím Alt + Enter) và làm như sau :

Ở mục Android chọn platform Android 4.0, tick vào ô is Library, ấn OK

Ở mục Java Buil Path, tab order and export, chọn tất cả và ấn OK

Ở mục Java Compiler, chọn như hình, lưu ý chỗ khoanh đỏ nếu có dấu tick

thì bỏ đi (sẽ tự động tick lại khi build), còn nếu chưa có thì tick vào, sau đó

chọn Ok.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 15

Click chuột phải vào project, chọn build project (hoặc tổ hợp Ctrl + B) để

build lại các file của project.

Như vậy đã import thành công thư viện này.

Trên đây là thư viện cơ bản nhất, để có thể sử dụng đầy đủ các tính năng của

AndEngine, chúng ta cần build thêm các thư viện khác bao gồm cả ví dụ. Dưới

đây là các đường link của các project đó :

1. https://github.com/nicolasgramlich/AndEngineScriptingExtension.git

2. https://github.com/nicolasgramlich/AndEngineAugmentedRealityExtension.git

3. https://github.com/nicolasgramlich/AndEngineMODPlayerExtension.git

4. https://github.com/nicolasgramlich/AndEngineSVGTextureRegionExtension.git

5. https://github.com/nicolasgramlich/AndEnginePhysicsBox2DExtension.git

6. https://github.com/nicolasgramlich/AndEngineTexturePackerExtension.git

7. https://github.com/nicolasgramlich/AndEngineMultiplayerExtension.git

8. https://github.com/nicolasgramlich/AndEngineLiveWallpaperExtension.git

9. https://github.com/nicolasgramlich/AndEngineTMXTiledMapExtension.git

10.https://github.com/nicolasgramlich/AndEngineExamples.git

Khi tiến hành import cái AndEngineExample trước 9 gói còn lại ta sẽ thấy báo

lỗi vì cái project này đã kế thừa các project còn lại, vì thế nên tiến hành import

9 cái kia trước, cái Example để sau cùng, Sau khi cài đặt thì project này vẫn sẽ

bị lỗi, lỗi này là lỗi lập trình, tiến hành sửa như sau:

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 16

Mở Package org.andengine.examples:

trong lớp Class BoundCameraExample.java:

- Dòng số 220, câu lệnh:

final AnimatedSprite face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion,

this.getVertexBufferObjectManager()).animate(100);

chuyển thành:

final AnimatedSprite face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion,

this.getVertexBufferObjectManager());

face.animate(100);

Trong lớp Class HullAlgorithmExample.java:

- Dòng số 11, câu lệnh:

import org.andengine.entity.primitive.vbo.DrawMode;

chuyển thành:

import org.andengine.entity.primitive.DrawMode;

Trong lớp Class SplitScreenExample.java

- Dòng số 179, câu lệnh:

final AnimatedSprite face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion,

this.getVertexBufferObjectManager()).animate(100);

Chuyển thành :

final AnimatedSprite face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion,

this.getVertexBufferObjectManager());

face.animate(100);

Trong lớp Class TextBreakExample.java

- Dòng số 106, câu lệnh :

this.mText = new Text(50, 40, this.mFont, "", 1000, new TextOptions(AutoWrap.LETTERS,

AUTOWRAP_WIDTH, Text.LEADING_DEFAULT, HorizontalAlign.CENTER),

vertexBufferObjectManager);

Chuyển thành :

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 17

this.mText = new Text(50, 40, this.mFont, "", 1000, new TextOptions(AutoWrap.LETTERS,

AUTOWRAP_WIDTH, HorizontalAlign.CENTER, Text.LEADING_DEFAULT),

vertexBufferObjectManager);

Bước 3 : Sử dụng các thư viện trên vào project của mình.

Click vào project cần thêm thư viện, ấn alt + enter hoặc click chuột phải chọn

properties, chọn Java Build Path, chọn tab Projects, chọn Add và thêm thư viện

mà bạn muốn sử dụng kèm vào.

b) Xây dựng chương trình

Các bước thực hiện chương trình:

Bước 1. Tạo 1 project mới tên “TowerOfHanoi”, tên activiy mới này là

“TowerOfHanoiActivity”.

Bước 2. Thêm thư viện AndEngine vào project, Right-click trên project =>

Properties => Android như hình bên dưới, click Add và thêm thư viện AndEngine

vào và click Apply.

Bước 3: Soạn thảo mã lệnh

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 18

Mở TowerOfHanoiActivity.java, thay vì activity này thừa kế từ class Activity,

ta sửa lại để nó thừa kế từ class SimpleBaseGameActivity và thêm vào các

import sau:

import org.andengine.ui.activity.SimpleBaseGameActivity;

import org.andengine.engine.options.EngineOptions;

import org.andengine.entity.scene.Scene;

SimpleBaseActivity cung cấp các phương thức để callback và chứa mã

lệnh để hoạt động với vòng đời của Activity. Mỗi callback cung cấp một

mục đích khác nhau, và do thừa kế từ SimpleBaseActivity nên phải

override lại các method đó.

onCreateEngineOptions: hàm này được gọi khi tạo một instance của engine.

onCreateResources: đây là chức năng sẽ tải tất cả các tài nguyên cần thiết của

Activity vào VRAM.

onCreateScene: hàm này sẽ được gọi khi 2 hàm trên thực hiện xong. Đây là nơi

sẽ khởi tạo các cảnh của game và sử dụng các cấu trúc đã được load vào VRAM.

Thêm đoạn code khai báo các biến sau vào TowerOfHaNoi class

private static int CAMERA_WIDTH = 800;

private static int CAMERA_HEIGHT = 480;

Hai biến trên định nghĩa kích thước của camera mà engine sử dụng.

Thêm các import sau để có thể viết code tạo instance cho engine:

import org.andengine.engine.camera.Camera;

import org.andengine.engine.options.ScreenOrientation;

import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;

Thay thế nội dung của hàm onCreateEngineOptions bằng đoạn code sau:

final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,

new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);

đoạn code trên sẽ tạo một instance của camera, sau đó ta sẽ dùng đối tượng

camera này để tạo đối tượng EngineOption. Các tham số cần để khởi tạo đối

tượng EngineOptions là:

FullScreen: kiểu boolean dùng để xác định engine có được FullScreen hay

không.

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 19

ScreenOrientation: xác định hướng của màn hình khi game chạy.

ResolutionPolicy: xác định độ mở rộng sử dụng tài nguyên khi thay đổi kích

thước màn hình.

Camera: định nghĩa chiều dài và rộng của màn chơi cuối.

Vì Android có rất nhiều thiết bị và kích thước màn hình, nên sẽ không biết

trước kích thước màn hình sẽ được sử dụng. AndEngine đưa ra một giải pháp

duy nhất đó là sẽ mở rộng màn hình của game.

Ví dụ nếu game được thiết kế với độ phân giản 480×320 và được chạy trên màn

hình 800×400, AndEngine sẽ tự động giãn màn hình game ra đến kích thước

720×480 với margin là 80px. Như vậy AndEngine sẽ giữ nguyên tỉ lệ của game.

Bước 4: Load Game Assets vào VRAM

Bạn cần đưa các ảnh của trò chơi vào thư mục assets của project:

ảnh “background.png” ảnh “tower.png”

ảnh “ring1.png” ảnh “ring2.png” ảnh “ring3.png”

Để load các tài nguyên, ta đến method onCreateResources, thay thế nội dung

của hàm hiện tại bằng nội dung sau:

try {

// 1 - Set up bitmap textures

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 20

ITexture backgroundTexture = new

BitmapTexture(this.getTextureManager(), new IInputStreamOpener() {

@Override

public InputStream open() throws IOException {

return getAssets().open("gfx/background.png");

}

});

ITexture towerTexture = new BitmapTexture(this.getTextureManager(),

new IInputStreamOpener() {

@Override

public InputStream open() throws IOException {

return getAssets().open("gfx/tower.png");

}

});

ITexture ring1 = new BitmapTexture(this.getTextureManager(), new

IInputStreamOpener() {

@Override

public InputStream open() throws IOException {

return getAssets().open("gfx/ring1.png");

}

});

ITexture ring2 = new BitmapTexture(this.getTextureManager(), new

IInputStreamOpener() {

@Override

public InputStream open() throws IOException {

return getAssets().open("gfx/ring2.png");

}

});

ITexture ring3 = new BitmapTexture(this.getTextureManager(), new

IInputStreamOpener() {

@Override

public InputStream open() throws IOException {

return getAssets().open("gfx/ring3.png");

}

});

// 2 - Load bitmap textures into VRAM

backgroundTexture.load();

towerTexture.load();

ring1.load();

ring2.load();

ring3.load();

} catch (IOException e) {

Debug.e(e);

}

Sau khi thay đổi nội dung của hàm ở trên bạn cần phải add thêm các import:

import org.andengine.opengl.texture.ITexture;

import org.andengine.opengl.texture.bitmap.BitmapTexture;

import org.andengine.util.adt.io.in.IInputStreamOpener;

import org.andengine.util.debug.Debug;

import java.io.IOException;

import java.io.InputStream;

Trong hàm onCreateResources, ta tạo một đối tượng kiểu ITexture. ITexture là

một interface, và đối tượng được khởi tạo là BitmapTexture, được dùng để load

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 21

bitmap của gam vào VRAM. Đoạn code khởi tạo ITexture ở trên dùng cho tất

cả các tài nguyên download và load tất cả vào VRAM.

Bước 5: Tạo màn của game

Chúng ta thêm import này vào TowerOfHaNoiActivity class:

import org.andengine.entity.sprite.Sprite;

Tiếp theo là thay thế nội dung method onCreateScene bằng các lệnh:

// 1 - Create new scene

final Scene scene = new Scene();

Sprite backgroundSprite = new Sprite(0, 0, this.mBackgroundTextureRegion,

getVertexBufferObjectManager());

scene.attachChild(backgroundSprite);

return scene;

đoạn code ở trên đầu tiên tạo một Scene object, sao đó tạo một Sprite object có

tên backgroundSprite và gắn vào scene. Method này yêu cầu trả về một scene

object. Sprite object là một đối tượng chứa nhiều layers, mỗi layer chứa nhiều

sprites (TextureRegions).

Khi khởi tạo một sprite object cần truyền vào các tham số sau:

xCoordinate: xác định vị trí của sprite th trục X. Hệ thống tọa độ của

AndEngine có trục tọa độ nằm ở vị trí trái-trên của màn hình.

yCoordinate: xác định vị trí của sprite theo trục Y.

TextureRegion: định nghĩa một phần texture của sprite dùng để vẽ chính nó.

VertexBufferObjectManager: Vertex buffer có thể được hiểu như một mảng

lưu có tọa độ của texture. Các tọa độ này được truyền cho OpenGL ES pipeline

và cuối cùng định nghĩa những gì sẽ được vẽ. VertexBufferObjectManager

chứa tất cả các điểm sẽ được vẽ lên màn hình.

Bước 6: Dựng 3 trụ trong game

Thêm 3 biến sau vào TowerOfHaNoiActiviy class:

private Sprite mTower1, mTower2, mTower3;

Thêm đoạn code sau vào hàm onCreateScene (phía trước lệnh return)

// 2 - Add the towers

mTower1 = new Sprite(192, 63, this.mTowerTextureRegion,

getVertexBufferObjectManager());

mTower2 = new Sprite(400, 63, this.mTowerTextureRegion,

getVertexBufferObjectManager());

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 22

mTower3 = new Sprite(604, 63, this.mTowerTextureRegion,

getVertexBufferObjectManager());

scene.attachChild(mTower1);

scene.attachChild(mTower2);

scene.attachChild(mTower3);

Lúc này khi chạy chương trình sẽ thấy giao diện như sau

Bước 7: Thêm các vòng vào trụ

Để tạo các vòng trong, ta cần phải tạo một class thừa kế từ class Sprite.

Đầu tiên, tạo một class có tên Ring trong package com.tutorial.towerofhanoi

thừa kế trực tiếp từ org.andengine.entity.sprite.Sprite

Nội dung của class Ring vừa tạo như sau

private int mWeight;

private Stack mStack; //this represents the stack that this ring

belongs to

private Sprite mTower;

public Ring(int weight, float pX, float pY, ITextureRegion

pTextureRegion, VertexBufferObjectManager

pVertexBufferObjectManager)

{

super(pX, pY, pTextureRegion, pVertexBufferObjectManager);

this.mWeight = weight;

}

public int getmWeight()

{

return mWeight;

}

public Stack getmStack()

{

return mStack;

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 23

}

public void setmStack(Stack mStack)

{

this.mStack = mStack;

}

public Sprite getmTower()

{

return mTower;

}

public void setmTower(Sprite mTower)

{

this.mTower = mTower;

}

Sau khi có class Ring, bây giờ ta cần tạo 3 vòng để thêm vào các trụ. Để làm

được, thêm đoạn code sau vào ngay phía trên lệnh return.

// 3 - Create the rings

Ring ring1 = new Ring(1, 139, 174, this.mRing1,

getVertexBufferObjectManager());

Ring ring2 = new Ring(2, 118, 212, this.mRing2,

getVertexBufferObjectManager());

Ring ring3 = new Ring(3, 97, 255, this.mRing3,

getVertexBufferObjectManager());

scene.attachChild(ring1);

scene.attachChild(ring2);

scene.attachChild(ring3);

Lúc này, khi chạy game, sẽ có giao diện như sau:

Bước 8: Viết mã lệnh xử lý thao tác người chơi

Thêm 3 biến sau vào TowerOfHaNoiActivity class:

private Stack mStack1, mStack2, mStack3;

Chúng ta phải khởi tạo 3 biến trên trong method onCreateResources:

// 4 - Create the stacks

this.mStack1 = new Stack();

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 24

this.mStack2 = new Stack();

this.mStack3 = new Stack();

Khi game chạy, 3 vòng đều phải nằm ở trụ thứ nhất, để làm được điều này,

thêm đoạn code sau vào method onCreateScene:

// 4 - Add all rings to stack one

this.mStack1.add(ring3);

this.mStack1.add(ring2);

this.mStack1.add(ring1);

// 5 - Initialize starting position for each ring

ring1.setmStack(mStack1);

ring2.setmStack(mStack1);

ring3.setmStack(mStack1);

ring1.setmTower(mTower1);

ring2.setmTower(mTower1);

ring3.setmTower(mTower1);

// 6 - Add touch handlers

scene.registerTouchArea(ring1);

scene.registerTouchArea(ring2);

scene.registerTouchArea(ring3);

scene.setTouchAreaBindingOnActionDownEnabled(true);

Ta cần phải ghi đè (override) hàm onAreaTouch của Sprite class, đây là vị trí

sẽ xử lý logic di chuyển của các vòng. Tuy nhiên, khi di chuyển các vòng giữa

các trụ, ta cũng cần phải kiểm tra xem có bị xung đột với logic của game hay

không, có nghĩa là vòng nhỏ phải nằm trên vòng lớn, không được có ngoại lệ.

Để thực hiện việc kiểm tra này, ta thêm vào TowerOfHaNoiActiviy class hàm

sau.

private void checkForCollisionsWithTowers(Ring ring) {

Stack stack = null;

Sprite tower = null;

if (ring.collidesWith(mTower1) && (mStack1.size() == 0 ||

ring.getmWeight() < ((Ring) mStack1.peek()).getmWeight())) {

stack = mStack1;

tower = mTower1;

} else if (ring.collidesWith(mTower2) && (mStack2.size() == 0 ||

ring.getmWeight() < ((Ring) mStack2.peek()).getmWeight())) {

stack = mStack2;

tower = mTower2;

} else if (ring.collidesWith(mTower3) && (mStack3.size() == 0 ||

ring.getmWeight() < ((Ring) mStack3.peek()).getmWeight())) {

stack = mStack3;

tower = mTower3;

} else {

stack = ring.getmStack();

tower = ring.getmTower();

}

ring.getmStack().remove(ring);

if (stack != null && tower !=null && stack.size() == 0) {

ring.setPosition(tower.getX() + tower.getWidth()/2 -

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 25

ring.getWidth()/2, tower.getY() + tower.getHeight() -

ring.getHeight());

} else if (stack != null && tower !=null && stack.size() > 0) {

ring.setPosition(tower.getX() + tower.getWidth()/2 -

ring.getWidth()/2, ((Ring) stack.peek()).getY() -

ring.getHeight());

}

stack.add(ring);

ring.setmStack(stack);

ring.setmTower(tower);

}

Sau đó ta sẽ override lại method onAreaTouch của class Sprite bằng cách thay

thế các dòng khởi tạo Ring ở onCreateSene (3 dòng đầu tiên của #3) bằng đoạn

code khởi tạo sau:

Ring ring1 = new Ring(1, 139, 174, this.mRing1,

getVertexBufferObjectManager()) {

@Override

public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float

pTouchAreaLocalX, float pTouchAreaLocalY) {

if (((Ring) this.getmStack().peek()).getmWeight() !=

this.getmWeight())

return false;

this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,

pSceneTouchEvent.getY() - this.getHeight() / 2);

if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {

checkForCollisionsWithTowers(this);

}

return true;

}

};

Ring ring2 = new Ring(2, 118, 212, this.mRing2,

getVertexBufferObjectManager()) {

@Override

public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float

pTouchAreaLocalX, float pTouchAreaLocalY) {

if (((Ring) this.getmStack().peek()).getmWeight() !=

this.getmWeight())

return false;

this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,

pSceneTouchEvent.getY() - this.getHeight() / 2);

if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {

checkForCollisionsWithTowers(this);

}

return true;

}

};

Ring ring3 = new Ring(3, 97, 255, this.mRing3,

getVertexBufferObjectManager()) {

@Override

public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float

pTouchAreaLocalX, float pTouchAreaLocalY) {

if (((Ring) this.getmStack().peek()).getmWeight() !=

this.getmWeight())

return false;

this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,

Trung tâm Đào tạo E-Learning Cơ hội học tập cho mọi người

Lập trình thiết bị di động - Bài 8 Trang 26

pSceneTouchEvent.getY() - this.getHeight() / 2);

if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {

checkForCollisionsWithTowers(this);

}

return true;

}

};

Bây giờ chương trình đã hoàn thành. Bạn hãy chạy và thử di chuyển các vòng

giữa các cột.

Chúc Anh/ Chị học tập tốt!