Tải bản đầy đủ (.docx) (33 trang)

đồ án công nghệ .net

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.71 MB, 33 trang )

XNA
ĐẠI HỌC QUỐC GIA TPHCM
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA CÔNG NGHỆ PHẦN MỀM
o0o
XNA
Công nghệ .Net
GVHD : Phạm Thi Vương
Sinh viên :
Văn Đỗ Phước Đạt - 07520074
Đỗ Minh Huy – 07520152
2 | T r a n g
Nguyễn Hoàng Minh - 07520229
NHẬN XÉT CỦA GIÁO VIÊN






















3 | T r a n g
4 | T r a n g
Contents
5 | T r a n g
Giới thiệu
Microsoft DirectX là tập hợp các APIs (application programming interfaces) để quản lý tác vụ liên
quan tới multimedia đặc biệt là trong lãnh vực game. DirectX 1.0 là phiên bản đầu tiên được xuất
hiện lần đầu vào năm 1995, phiên bản gần đây nhất được phát hành là DirectX 11.Ngày nay thì
DirectX được sử dụng rộng rãi trong việc phát triển game trên hệ điều hành Microsoft Windows và
trên các hệ mấy XBOX.
OpenGL được Silicon Graphics phát triển và xuất hiện rộng rãi vào năm 1992, OpenGL đã từng được
sử dụng trong hệ điều hành Window 95. Tuy nhiên ngày nay thì OpenGL được coi là đối thủ cạnh
tranh lớn nhất với DirectX trong mảng xử lý đồ họa. Khác với DirectX, OpenGL là tập hợp các cross-
platform API để quản lý mảng đồ họa máy tính 2D và 3D. Do đó OpenGL có thể chạy trên nhìu nền
tảng khác nhau như các thiết bị cầm tay, Play Station, UNIX …
Trước đây khi chưa có các API đồ họa hỗ trợ thì việc lập trình game là rất khó khăn. Người lập trình
viên rất khó khăn khi tiếp xúc với nhiều loại phần cứng thể hiện đồ họa khác nhau. Do đó khi DirectX
hay OpenGL ra đời nó tạo ra những giao diện thống nhất giúp người lập trình viên ko còn phải quan
tâm quá nhiều vào các loại phần cứng khác nhau mà chỉ tập trung vào lập trình nâng cao chất lượng
của game.Tuy nhiên do được phát triển từ khá lâu (tuổi thọ hơn 15 năm) nên việc lập trình trên các
thư viện DirectX và OpenGL tương đối khô khăn hơn các công nghệ hiện nay,nhất là khi làm việc với
các hàm APIs đồ họa và lại thường được sử dụng chủ yếu với ngôn ngữ C/C++ đã có từ rất lâu, đây
cũng là lý do mà hầu hết những lập trình viên, sinh viên cảm thấy áy náy và ngại tiếp xúc với việc lập
trình game.
Khi DirectX 9 được phát hành thì có một vài sự thay đổi, ngoài phiên bản chính thống, Microsoft còn
giới thiệu tới các lập trình viên khái niệm Managed DirectX. Khái niệm mới này đi kèm với một loạt

các ngôn ngữ mới như C#, VB và các thuật ngữ CLR, garbage collector … Managed DirectX là một
ngôn ngữ dễ hiểu và trong sáng hơn so với DirectX nguyên thủy. Nó tránh được các APIs phức tạp và
các vấn đề rắc rối của C++ do đó rất được sự ủng hộ từ cộng đồng. Vấn đề lớn nhất đối với Managed
DirectX (và thậm chí ngày nay vẫn thường được nhắc tới) đó là tốc độ thực thi. Ko ai tin hoặc hoài
nghi rằng tốc độ của Managed DirectXcó thể chạy nhanh.Do đó việc Managed DirectX bị đi vào quên
lãng và ko phát triển tiếp là điều tất yếu (chấm dứt vào khoảng năm 2005)
Tuy nhiên sau đó một thời gian thì Microsoft giới thiệu XNA Game Studio. Đây là thư viện mang
được đặc tính dễ sử dụng của Managed DirectX và mạnh mẽ trên kiến trúc của DirectX. Nó hỗ trợ
thêm rất nhiều nền tảng khác nhau như Xbox 360, Zune HD và mới nhất là Window Phone 7. Không
giống như Managed Microsoft, XNA Game Studio được hỗ trợ và phát triển rất mạnh song song với
DirectX. Chưa thể đánh giá rõ ràng được tương lai của XNA Game Studio như thế nào trong tương
lai,tuy nhiên với sự phát triển mạnh mẽ như hiện nay đặc biệt là phiên bản 4.0 mới nhất hỗ trợ phát
triển game trên Window Phone 7 là một sự bổ sung tuyệt vời mang lại nhiều phương pháp làm game
tốt nhất trên các hệ máy di động trong lúc mà cuộc chiến giữa các điện thoại, máy tính bảng đang sôi
động nhất, XNA hứa hẹn sẽ trở thành một trong những thư viện lập trình game tốt nhất trong tương
lai.
6 | T r a n g
Lịch sử
XNA được phát triển bởi Microsoft trong một vài năm trước tuy nhiên mãi tới GDC (Game Developer
Conference) năm 2004 thì XNA mới được công bố lần đầu tiên. XNA ban đầu được coi là từ viết tắt
của Xbox New Architecture, nhưng sau khi XBOX360 ra đời thì XNA được hiểu như một tên riêng.
XNA Game Studio là một môi trường lập trình cho phép ta sử dụng Visual Studio để tạo ra game trên
Window Phone, Xbox 360 và trên môi trường hệ điều hành Window. Nó hoàn toàn miễn phí và có
thể download về PC thoải mái. XNA Game Studio bao gồm XNA Framework là một tập thư viện phát
triển game dựa trên nền tảng Microsoft .NET Framework 2.0. Cho tới hiện nay thì đã bao gồm 5
phiên bản XNA Game Studio xuất hiện.
• XNA Game Studio Express : đây là phiên bản đầu tiên được giới thiệu và chính thức có thể
download vào ngày 30 tháng 8 năm 2006. Vào ngày 24 tháng 4 năm 2007 thì Microsoft có
phát hành 1 bản update gọi là XNA Game Studio Express 1.0 Refresh cho phiên bản này.
• XNA Game Studio 2.0 : phát hành vào ngày 13 tháng 12 năm 2007, có thể sử dụng với tất cả

các phiên bản Visual Studio 2005
• XNA Game Studio 3.0 : phát hành vào ngày 30 tháng 10 năm 2008, XNA Game Studio 3.0
cho phép phát triển game trên nền tảng Zune. Phiên bản này hỗ trợ đầy đủ C# 3.0, LINQ và
có thể dùng Visual Studio 2008 để lập trình.
• XNA Game Studio 3.1 : phát hành vào 11 tháng 7 nằm 2009 giúp người lập trình có thể phát
triển một vài chức năng mới trên Xbox 360.
• XNA Game Studio 4.0 : được giới thiệu lần đầu vào ngày 9 tháng 3 nằm 2010 ở GDC và phát
hành vào 16 tháng 9 nằm 2010. Phiên bản này hỗ trợ phát triển trên hệ điều hành Windows
Phone 7. Đi kèm thêm một loạt chức năng mới và có thể kết hợp sử dụng Visual Studio 2010
để phát triển game.
Thành phần
XNA cho phép chúng ta làm rất nhiều thứ, nó được xây dựng để cho lập trình viên có thể quản lý và
thao tác dễ dàng tới tất cả các thành phần có thể tồn tại trong 1 ứng dụng game. Có thể điểm qua
các namespace được gói bên trong XNA Game Studio 4.0 như
• Microsoft.Xna.Framework : Framework tổng quát chứa các objects, các phép tính toán và
các đặc điểm chung của một chương trinh game
• Microsoft.Xna.Framework.Graphics : Hỗ trợ tất cả các đặc điểm liên quan tới đồ họa 2D và
3D
• Microsoft.Xna.Framework.Audio : Hỗ trợ phần âm thanh
• Microsoft.Xna.Framework.Input : Hỗ trợ quản lý các thiết bị nhập (như gamepad, keyboard
và mouse)
• Microsoft.Xna.Framework.GameServices : Hỗ trợ các truy cập tới XBOX LIVE
• Microsoft.Xna.Framework.Media : Các phương thức đa phương tiên cho hình ảnh, âm thanh

• Microsoft.Xna.Framework.Content : Thư viện vùng lưu trữ các tài nguyên trong game
• Microsoft.Xna.Framework.Net : Hỗ trợ các thiết lập network
• Microsoft.Xna.Framework.Storage : Các lưu trữ với thiết lập định dạng cao cấp
7 | T r a n g
Phần mềm yêu cầu
XNA Game Studio 4.0: Có thể download trên trang chủ của Microsoft

(www.microsoft.com/downloads)
Microsoft Visual Studio 2010 : Đây là môi trường để lập trình game, XNA Game Studio 4.0 có thể sử
dụng trong hầu hết các phiên bản Microsoft Visual Studio 2010 như
• Microsoft Visual Studio 2010 Express for Window Phone
• Microsoft Visual C# 2010 Express Edition
• Microsoft Visual Studio 2010 Standard Edition
• Microsoft Visual Studio 2010 Professional Edition
Microsoft .NET Framework 4.0 : XNA Game Studio 4.0 đòi hỏi phải có Microsoft .NET Framework 4.0
Ngoài ra cần có 1 card màn hình hỗ trợ tối thiểu DirectX 9.
Cài đặt XNA Game Studio
Quá trình cài đặt XNA rất đơn giản, sau khi chọn file cài đặt, ta đọc kỹ các điều khoản sử dụng trong
màn hình ENU Setup.
Sau đó bấm Accept nếu muốn tiếp tục cài đặt, tiếp theo chọn Install và chờ đợi cho đến khi ứng
dụng được cài đặt thành công
8 | T r a n g
9 | T r a n g
Ứng dụng Game với XNA
Khởi động Visual Studio, trong Visual Studio chọn File->New->Project. Sau khi cửa sổ New Project
hiện lên, bên thanh “Installed Templates” trái chọn Visual C#->XNA Game Studio 4.0. Bên phía phải
cửa sổ ta có thể tùy chọn nhiều tùy chọn khác nhau tùy theo mục đích, ở đây ta chọn Windows
Game (4.0) và đặt tên cho nó ở phần Name (ví dụ ở đây ta đặt là Collision), địa chỉ chứa project ở
phần Location.
Sau khi chương trình hoàn tất khởi tạo, ở thanh Tool ta chọn Debug->Start Debugging để chạy
chương trình, kết quả là ta có ứng dụng game hiện ra màn hình.
Như vậy như ta thấy thì khác với khi làm việc với DirectX hay OpenGL đòi hỏi ta phải tự thiết lập cấu
hình để chạy ứng dụng Game thì XNA đã thiết lập sẵn hết, các vấn đề khác như độ phân giải hay
thiết lập ứng dụng chạy ở dạng fullscreen ta có thể dễ dàng thay đổi bằng đối tượng
GraphicDeviceManager. Trong chương trình vừa được khởi tạo, ta thấy phía bên cửa sổ Solution
10 | T r a n g
Explorer có 2 projects là Collision và CollisionContent. Bên trong Collision chứa tất cả các file thực

thi của chương trình còn CollisionContent sẽ chứa các resource của ứng dụng, khi cần thao tác tới
một resource bên trong CollisionContent thì ta sẽ sử dụng đối tượng ContentManager để load nó
lên(chi tiết sẽ đề cập ở sau). Click vào file Game1.cs bên trong project Collision, chúng ta sẽ thấy
được ngoài hàm khởi tạo thì có 5 hàm chính như sau : Initialize, LoadContent, Update, Draw,
UnloadContent.Đây là 5 hàm chính thể hiện cấu trúc của một ứng dụng XNA
Cấu trúc
Initialize : Đây là nơi dùng để khởi tạo biến và các đối tượng quan trọng cần thiết để thiết lậpứng
dụng. Những đối tượng này thường là SpriteBatch để quản lý việc render hình ảnh 2D, Content
Manager quản lý các tài nguyên trong game và các đối tượng tổng quát trong game như score, items
… Các audio cũng thường được load lên trong giai đoạn này. Một điểm lưu ý là các thành phần
graphics không được load lên tại đây, công việc này sẽ được thực hiện ở hàm LoadContent. Hàm
Initialize sẽ được gọi một lần duy nhất khi bắt đầu vào chương trình.
LoadContent : Được gọi ngay sau hàm Initialize, hàm này được thực thi bất cứ khi nào các nội dung
graphics, sounds, models, … cần được load lên bộ nhớ.
GameLoop : Hầu hết các tiến trình trong game đều được xứ lý ở game loop. Tại đây, game sẽ tính
toán các công việc input, animation, artificial intelligence, collision, render … Có 2 hàm được gọi để
thực thi trong GameLoop là Update và Draw. Trong GameLoop thì 2 hàm này được gọi liên tục trong
suốt quá trình chơi. Thường thì Update được gọi thường xuyên hơn hàm Draw, tuy nhiên việc này đã
được XNA framework hỗ trợ quản lý.
Update : Trong đây chứa đựng đoạn code để quản lý việc update các thuộc tính của đối
tượng như vị trí, va chạm, tốc độ, animation … quản lý việc input của người chơi, bộ đếm
thời gian, cập nhật điểm, AI …
Draw :Quản lý việc render và tất cả các hành vi liên quan tới việc xử lý đồ họa lên màn hình.
Các chức năng cơ bản như clear màn hình, thiết lập màu sắc, các hiệu ứng phức tạp trong
game …
UnloadContent : Trong hàm này, nếu các objects cần được hủy hoặc gỡ khỏi bộ nhớ trước khi thoát
ra khỏi game hoặc để chuẩn bị cho việc load một level mới, hàm UnLoadContent sẽ xử lý việc này.
11 | T r a n g
12 | T r a n g
Game2D với XNA

Game là một trong những ngành công nghệ phát triển cực mạnh vào thời điểm hiện nay. Với tốc
độchóng mặt nâng cao chất lượng các thiết bị đồ họa và hàng loạt các studio ngày đêm nghiêm cứu
phát triển game thì ta có hàng tá những sản phẩm 3D chất lượng được phát hành trong từng ngày.
Tuy nhiên điều này không phải là tình trạng phản ảnh sự lụi tàn của thể loại game 2D trên thị trường.
Mặc khác thời gian gần đây với sự phát triển bất ngờ của các thể hệ điện thoại di động, máy tính
bảng, mạng xã hội … lại tạo ra môi trường cực kỳ màu mỡ cho các game 2D. Ta có thể điểm danh
hàng loạt các sản phẩm game 2D đình đám và thu về hàng triệu $ cho các nhà phát triển.
Sprite
Lập trình 2D trong XNA đi liền với khái niệm Sprite (tương tự cho DirectX). Một sprite là một cấu trúc
để quản lý việc thể hiện hình ảnh. Sprite luôn đi kèm với 1 đối tượng Texture2D. Texture là đối
tượngđại diện hình ảnh, ta sẽ load hình ảnh lên Texture. Sprite trong XNA hỗ trợ ta rất nhiều thao
tác từ cơ bản đến phức tạp như scale (kéo giãn ảnh) rotation (xoay hình) transparent (làm mờ ảnh)
depth layer (sắp xếp ảnh theo chiều sâu)
Hệ trục tọa độ
Để có thể render lên màn hình, sprite sử dụng 2 biến integer để xác định tọa độ X và Y của bức ảnh
cần render. Tọa độ này sẽ dựa trên tọa độ của màn hình mà góc tọa độ nằm ở góc trái trên
Như hình trên ta thấy có 3 điểm A, B, C lần lượt ở tọa độ (10, 20)(10, 20) và (20, 20).
13 | T r a n g
Load Resouce và render image
Ví dụ đầu tiên về việc sử dụng Sprite là load một file image và render nó ra màn hình. Đầu tiên ta
khởi tạo project Window Game (4.0) và đặt tên là Demo1. Mở file Game1.cs, ta thấy có 2 biến được
khởi tạo sẵn là GraphicsDeviceManager và SpriteBatch, đây là 2 thành phần cơ bản nhất trong 1
ứng dụng XNA. GraphicsDeviceManager được dùng để thiết đặt cấu hình cho ứng dụng Game (coi
chi tiết trong các ví dụ) còn SpriteBatch chính là Sprite mà chúng ta đang nói tới, ta sẽ dùng nó để
render các ảnh.
Đầu tiên chúng ta thử sử dụng GraphicsDeviceManager, trong Game1.cs thì biến graphics được khởi
tạo kiểu này. Chúng ta vào trong hàm khởi tạo Game1 và thêm 2 dòng code
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 800;
2 dòng lệnh trên thay đổi kích thước của ứng dụng theo chiều ngang là 800px và chiếu dọc là 600px.

Tiếp theo chúng ta chuẩn bị sẵn 1 file hình ảnh và đưa vào thư mục Demo1Content trong project
Demo1 (Demo1\Demo1\Demo1Content). Ở đây ta dùng file oaktree.png
Tiếp theo ta sẽ đưa file oaktree.png vào project bằng cách click chuột phái vào Demo1Content chọn
Add->Existing Item… và chọn file oaktree.png
Sau khi đã add file oaktree.png vào Demo1Content, chúng ta tiến hành load hình ảnh lên. Đầu tiên
chúng ta phải khởi tạo 1 Texture để quản lý hình ảnh này. Ở đây ta dùng kiểu đối tượng Texture2D.
Đầu tiên ta khởi tạo một đối tượng dạng Texture2D đặt tên là texture.
Texture2D texture;
Sau đó trong hàm LoadContent ta thêm hàm
texture = Content.Load<Texture2D>(@"oaktree");
Chúng ta dùng đối tượng Content đã khởi tạo sẵn trong ứng dụng XNA để Load 1 Texture2D tên là
oaktree lên đối tượng texture của chúng ta. Sau khi đã load hình ảnh lên, công việc tiếp theo của
14 | T r a n g
chúng ta là render nó, chúng ta sẽ thực hiện công việc này ở hàm Render.Ta thêm các dòng lệnh này
sau hàm Clear.
spriteBatch.Begin();
spriteBatch.Draw(texture, Vector2.Zero, Color.White);
spriteBatch.End();
Ta đặt các hàm Draw của spriteBatch bên trong 2 hàm Begin và End, việc này là quy định để XNA có
thể báo cho device render các ảnh 2D như thế nào. Trong hàm Draw ta thấy có 3 tham số, thứ nhất
là texture (hình ảnh) cần render, tham số thứ 2 là vị trí đặt ảnh,tham số thứ ba là màu pha với ảnh,
nếu ta chọn màu trắng thì ảnh sẽ hiển thị màu sắc thực của nó. Chạy chương trình và ta sẽ có được
kết quả như sau
Scale image
Vấn đề ở đây ta thấy được trong Demo1 là hình ảnh được load lên có kích thước quá lớn hơn so với
ứng dụng XNA mà ta khởi tạo. Cũng may là XNA đã hỗ trợ cho ta khả năng scale (co giãn) hình ảnh lại
cho phù hợp với kích thước của màn hình. Ta sử dụng tham số scale trong hàm Draw, ví dụ ta có kích
thước tấm ảnh là 1280 x 800, kích thước này sẽ được giữ nguyên khi tham số scale là 1.0, tuy nhiên
khi scale là 0.625 thì kích thước của ảnh sẽ thay đổi lại là 800 * 500. Có một cách khác scale ảnh là
thiết đặt vùng hiển thị trong màn hình để ảnh tự động scale lại. Ta xem cách thực hiện này trong

Demo2.
Demo2 cơ bản có cấu trúc y như Demo1, riêng hàm Draw ở thông số thứ 2 ta chỉnh lại là
spriteBatch.Draw(texture, new Rectangle(0, 0, 800, 600), Color.White);
Sau đó chạy lại ứng dụng, ta thấy hình ảnh được scale nhỏ lại vừa khít với ứng dụng.
15 | T r a n g
Quay trở lại với hàm Draw, ta thấy là nó thay đổi ở tham số thứ 2, thay vì tham số thứ 2 trong
Demo1 là vị trí của imagine được hiện lên thì trong Demo2 nó thay thế bằng 1 khung rectangle gồm
4 thông số là tọa độ X, Y đặt hình ảnh lên ứng dụng và chiều rộng, cao của hình ảnh được hiện ra.
Trong ví dụ ta đặt hình ảnh ở tọa độ (0, 0) và có kích thước 800x600 vừa khít với kích thước cửa sổ
ứng dụng.
Ta thử thay đổi một chút trên hàm khởi tạo bằng việc thêm dòng lệnh
graphics.IsFullScreen = true;
Sau đó chạy lại chương trình thì ta thấy lúc này ứng dụng được thiết lập ở chế độ fullscreen. Qua 2 ví
dụ thì ta có thể hình dung được ta có thể thiết lập lại ứng dụng một cách dễ dàng bằng đối tượng
GraphicsDeviceManager bằng cách thay đổi các thuộc tính của nó.Rõ ràng đây là một lợi thế rất lớn
khi sử dụng XNA.
Animation
Như vậy ta đã thấy việc load hình ảnh và render nó thực hiện rất dễ dàng với XNA, tuy nhiên để có
thể gọi là 1 game hoàn chỉnh thì không thể chỉ có load những tấm hình tĩnh lên, chúng ta cần những
tấm hình mà nó có thể chuyển động hay gọi là animation.Đầu tiên ta nói một chút về animation,
thực ra đây chỉ là một chuỗi thay đổi các hình ảnh tạo cho người xem cảm giác như vật thể đang
thay đổi. Một ví dụ như hình bên dưới đây
16 | T r a n g
Ta thấy hình trên là một chuỗi gồm nhiều hình mô tả các trạng thái khác nhau của một vật thể, như
vậy bằng cách ghép nó lại với nhau ở từng thời điểm khác nhau lập đi lập lại thì ta sẽ tạo cho người
xem cảm giác như vật thể đó đang chuyển động.
Ta sẽ sử dụng các kỹ thuật trong XNA để thực hiện điều này, nhớ lại các Demo trên ta chỉ đơn giản vẽ
toàn bộ một tấm hình lên ứng dụng, tuy nhiên đối với ví dụ này thì ta cần phải vẽ 1 phần của bức
ảnh. Rất may mắn là XNA đã hỗ trợ rất tốt cho ta thực hiện điều này.
Ta sẽ xây dựng ứng dụng Demo3 để thực hiện điều này, đầu tiên tạo ứng dụng, sau đó thêm

resource vào Content như các phần Demo trên đã thực hiện, ở đây ta sử dụng hình ảnh như ví dụ
trên.Ta thực hiện các thao tác load hình ảnh thành texture2D và dùng spriteBatch để render nó ra
màn hình như các Demo trên đã thực hiện.
17 | T r a n g
Ta thấy hiện tại chúng ta vẫn chỉ render toàn bộ ảnh, bây giờ chúng ta chỉnh lại hàm Draw của
spriteBatch như sau
spriteBatch.Draw(texture, Vector2.Zero, new Rectangle(0, 0, 43, 43),
Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
Chạy lại chương trình ta thấy lúc này ứng dụng của chúng ta đã tách ra render 1 phần nhỏ của ảnh
Giải thích một chút về Draw, thứ tự các tham số trong hàm như sau
1. Texture2D là hình ảnh cần render
2. Vị trí của hình ảnh cần render, ở đây ta đặt tại gốc tọa độ (0, 0)
3. Phần renctangle trong texture2D cần render, ta thấy trong hình có tất cả 48 hình nhỏ vàta
render phần hình nhỏ ở góc trên cùng bên trái. Phần hình này nằm ở tọa độ 0, 0 và có độ
rộng và cao là 43.
4. Đây là màu sắc trộn với ảnh, ta để màu white để hình ảnh thể hiện màu sắc chính xác của nó.
5. Tham số thứ 5 là gốc xoay của ảnh, ở đây ta để mặc định là 0
6. Tham số thứ 6 là gốc origin của ảnh, gốc origin là điểm không thay đổi của ảnh khi ta thực
hiện scale (kéo giãn) hoặc rotate (xoay).
7. Tham số này là độ scale (co giãn) của tấm ảnh, ta để giá trị 1 để ảnh hiển thị đúng kích thước
của nó, giá trị càng cao thì ảnh sẽ càng được phóng to.
8. Giá trị SpriteEffect là hiệu ứng của ảnh, trong ví dụ này ta không xài hiệu ứng gì.
9. Giá trị cuối cùng là layerDepth, giá trị này ảnh hưởng tới việc ảnh render nằm trong hay nằm
ngoài, nếu ảnh nằm bên ngoài thì nó sẽ che các ảnh nằm bên trong nó.
Tiếp theo chúng ta sẽ coi cách để có thể thay đổi từng ảnh nhỏ khác khi hiển thị như thế nào. Chú ý
tới tham số thứ 3 trong hàm Draw, nếu ta thay đổi tham số này thì ta sẽ dễ dàng render được các
ảnh nhỏ khác nhau. Vấn đề ta cần quan tâm tiếp theo là chúng ta sẽ render thay đổi các ảnh theo tốc
độ thời gian như thế nào.
18 | T r a n g
Chúng ta sẽ xây dựng bộ thay đổi thời gian như sau. Đầu tiên ta thêm 2 biến timeSinceLastFrame và

milisecondsPerFrame, 2 biến này sử dụng giá trị milisecond.
int timeSinceLastFrame = 0;
int millisecondsPerFrame = 16;
Biến timeSinceLastFrame là trị thời gian mà ứng dụng đã trôi quatính từ lần render frame gần nhất.
Trong khi đó milisecondsPerFrame là trị thời gian tối thiểu giữa 2 Frame. Điều này có nghĩa là khi
timeSinceLastFrame lớn hơn milisecondPerFrame thì ta sẽ vẽ frame kế tiếp, đồng thời ta gán lại giá
trị cho timeSinceLastFrame bằng 0 khi vừa render 1 frame. Chú ý ở đây frame có thể hiểu đơn giản là
ảnh hiển thị tại một thời điểm, trong game chúng ta còn có khái niệm FPS (frames per second) tức là
số frame hiển thị trong 1 giây. Ta có thể mô tả ý tưởng trên bằng hình sau
Ta thấy tại mỗi đoạn màu đỏ ứng với giá trị milisecondsPerFrame là khoảng thời gian mà các frame
sẽ thay đổi, còn ứng với mỗi đoạn màu xanh lá cây ta sẽ render 1 frame mới ứng với ảnh mới, đồng
thời tại đó thì timeSinceLastFrame sẽ gán lại là 0. Như vậy ta thấy nếu milisecondsPerFramecàng nhỏ
thì tốc độ thay đổi frame sẽ càng nhanh, điều này làm cho ta có cảm giác vật thể di chuyển nhanh
hơn
Ta có thể thay đổi trị số milisecondsPerFrame nếu muốn thay đổi tốc độ. Ví dụ như
milisecondsPerFrame là 50, tức là sau 50ms thì ta render 1 frame. Như vậy ta sẽ thấy tốc độ của nó
chậm hơn khi ta chỉnh milisecondsPerFrame là 16. Ngoài ra để tính khoảng thời gian mà ứng dụng đã
trôi qua kể từ lần cập nhật Frame trước thì ta có thể sử dụng hàm có sẵn trong đối tượng
GameTime. Đây là đối tượng quản lý thời gian mà XNA cung cấp sẵn.
timeSinceLastFrame += gameTime.ElapsedGameTime.Miliseconds;
Như ví dụ trên ta thấy gameTime trả về số lượng miliseconds đã trôi qua kể từ lần cập nhật frame
trước.
Bây giờ chúng ta đã có phần quản lý thời gian và chúng ta biết được sau bao nhiêu thời gian thì cần
render 1 frame mới. Tiếp theo chúng ta cần xác định tại frame đó chúng ta cần render hình ảnh nào.
Quay lại với tham số trong hàm Draw, ta có thể thay đổi rectangle để xác định vùng ảnh cần render.
Trong hình thì ta có 48 ảnh nhỏ, và ta sẽ render nó theo chiều từ trái sang phải, từ trên xuống dưới
và lặp lại quá trính này.
19 | T r a n g
Ta sẽ lập công thức để tìm ra vùng rectangle thích hợp tại mỗi vị trí trong hình.Chúng ta sẽ dùng các
biến Point như sau

Point frameSize = new Point(75, 75);
Point currentFrame = new Point(0, 0);
Point sheetSize = new Point(6, 8);
frameSize là kích thước của mỗi ảnh con, trong ví dụ này là 75x75 pixel. currentFrame là vị trí hiện tại
của ảnh đang được render, ví dụ vị trí (4, 5) ứng với hình ở số 30. sheetSize là số lượng ảnh nhỏ theo
chiều ngang và dọc có trong hình.
Bây giờ ta sẽ sửa lại tham số trong hàm Draw như sau
spriteBatch.Draw(texture, Vector2.Zero, new Rectangle(currentFrame.X * frameSize.X,
currentFrame.Y * frameSize.Y, frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
Ta thấy là tham số thứ 3 lúc này sẽ được trả về là vùng rectangle ứng với vị trí của currentFrame hiện
tại. Sau khi đã chỉnh lại hàm Draw, ta thêm phần quản lý thời gian vào hàm Update
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame)
{
timeSinceLastFrame= 0;
++currentFrame.X;
if (currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
++currentFrame.Y;
if (currentFrame.Y >= sheetSize.Y)
currentFrame.Y = 0;
}
}
Ta thấy nếu như thời gian trôi qua tính từ frame trước (timeSinceLastFrame) lớn hơn khoảng thời
gian cách giữa 2 frame (millisecondsPerFrame) thì ta sẽ cập nhật lại currentFrame sang vị trí mới.
Sau khi đã chỉnh sữa lại, ta có thể chạy Demo3 để thấy được sự thay đổi
20 | T r a n g
Input

Chúng ta đã có được một vật thể hoạt động, sẽ hấp dẫn hơn nếu vật thể của chúng ta có thể di
chuyển được. Khi nói tới điều này ta sẽ nghĩ ngay tới việc thay đổi tham số vị trí trong hàm Draw của
spriteBatch. Việc này là tương đối đơn giản, nhưng nó sẽ hấp dẫn hơn nếu chúng ta có thể điều
khiển việc di chuyển vật thể này bằng chuột hay bàn phím.
XNA hỗ trợ rất tốt việc quản lý Input từ người sử dụng, chúng ta có thể kiểm soát các tác vụ từ
keyboard, mouse hoặc Xbox 360 controller … một cách dễ dàng. Chúng ta sẽ tìm hiểu tiếp theo sau
với Demo4 mô tả cách quản lý Input với XNA.Trong Demo4 này chúng ta sẽ thực hiện việc quản lý
keyboard kết hợp với những gì ta đã thực hiện từ các Demo trước.
Đầu tiên chúng ta tạo project Window Game tên Demo4 và thực hiện tất cả các thao tác đã làm với
Demo3 để có được một vật thể animation như hình phía trên. Tiếp theo chúng ta sẽ bắt các sự kiện
của keyboard.
Keyboard
XNA cung cấp sẵn cho ta class Keyboard để thao tác với keyboard, class Mouse để thao tác với
mouse và class GamePad để thao tác với Xbox360 gamepad. Đối với Keyboard class, nó có sẵn một
hàm static GetState để nhận về tình trạng của keyboard hiện tại dưới cấu trúc KeyboardState. Cấu
trúc KeyboardState chứa đựng 3 hàm để ta có thể kiểm soát các input từ keyboard như sau
Phương thức Miêu tả
Keys[] GetPressedKeys () Trả về một mảng các phím được ấn tại thời điểm
gọi hàm
bool IsKeyDown (Keys key) Trả về true hoặc false kiểm tra xem phím đang
ấn hay không tại thời điểm gọi hàm
Bool IsKeyUp (Keys key) Trả về true hoặc false kiểm tra xem phím đang
thả hay không tại thời điểm gọi hàm
Chúng ta coi 1 ví dụ về việc kiểm tra xem phím “A” có được bấm hay không.
if(Keyboard.GetState( ).IsKeyDown(Keys.A))
{

21 | T r a n g
}
Nhắc lại một chút trong Demo3, chúng ta có biến milisecondsPerFrame để điều chỉnh tốc độ

animation nhanh hay chậm của vật thể. Bây giờ chúng ta sẽ sử dụng keyboard để quản lý tốc độ này.
Đầu tiên ta thêm vào trong hàm Update đoạn code để bắt sự kiện bấm phím Left hoặc Right
if(Keyboard.GetState( ).IsKeyDown(Keys.Left))
{

}
if(Keyboard.GetState( ).IsKeyDown(Keys.Right))
{

}
Sau đó ta quy định nếu bấm Left thì sẽ tăng trị milisecondsPerFrame lên, điều này đồng thời làm
giảm tốc độ animation của vật, ngược lại khi bấm Right chúng ta giảm trị milisecondsPerFrame, điều
này làm animation của vật tăng lên. Tất nhiên chúng ta cần thêm cận cho milisecondsPerFrame.
Chúng ta có đoạn code như sau
if (Keyboard.GetState().IsKeyDown(Keys.Left) && millisecondsPerFrame < 100)
millisecondsPerFrame++;
if (Keyboard.GetState().IsKeyDown(Keys.Right) && millisecondsPerFrame > 10)
millisecondsPerFrame ;
Mouse
Tương tự như việc quản lý Keyboard, XNA cung cấp class Mouse để phục vụ cho việc quản lý mouse.
Mouse class cũng có hàm static GetState trả về cấu trúc MouseState thể hiện trạng thái của mouse.
Cấu trúc MouseState có một vài properties giúp cho chúng ta thao tác với mouse dễ dàng như
Property Kiểu Miêu tả
LeftButton Button State Trả về trạng thái của nút nhấn trái chuột
MiddleButton Button State Trả về trạng thái của nút nhấn giữa chuột
RightButton Button State Trả về trạng thái của nút nhấn phải chuột
ScrollWheelValue Int Trả về số lượng chuyển động của con lăn chuột so
với trạng thái lúc trước của nó.
X Int Trả về tọa độ X của chuột so với góc trái trên của
cửa sổ game

Y Int Trả về tọa độ Y của chuột so với góc trái trên của
cửa sổ game
Chúng ta sẽ làm ví dụ nho nhỏ cho việc quản lý mouse trong Demo4 của chúng ta. Đầu tiên để quản
lý mouse phải nhận cấu trúc MouseState của nó. Chúng ta đặt đoạn code trong hàm Update
MouseState mouseState = Mouse.GetState();
Tiếp theo chúng ta sẽ di chuyển vật thể theo tọa độ di chuyển của chuột, chúng ta làm điều này bằng
cách thay đổi tham số tọa độ render vật thể (tham số thứ 2) trong hàm Draw thành tọa độ của
mouse.
22 | T r a n g
spriteBatch.Draw(texture, new Vector2(mouseState.X, mouseState.Y), new
Rectangle(currentFrame.X * frameSize.X,
currentFrame.Y * frameSize.Y, frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
Chạy lại Demo4 để coi kết quả mà ta có được
Âm thanh
Tới đây thì chúng ta đã nắm được các kỹ thuật cơ bản quản lý việc xử lý hình ảnh trong XNA, chúng
ta đã có thể bắt đầu xây dựng một game 2D đơn giản. Bây giờ chúng ta sẽ quan tâm tới một kỹ thuật
khác là kỹ thuật quản lý âm thanh trong XNA. Tương tự như những kỹ thuật khác đã trình bày, âm
thanh cũng là một phần được XNA hỗ trợ rất tốt.
Đầu tiên chúng ta coi việc load một file âm thanh vào project XNA như thế nào. Công việc này cũng
thực hiện y chang như việc load một file hình ảnh. Đầu tiên ta đưa file âm thanh vào thư mục chứa
resource bên trong Content,sau đó đưa nó vào Content Solution của project, chúng ta thực hiện y
chang như khi thực hiện với file hình ảnh. XNA hỗ trợ tốt các định dạng file âm thanhphổ biến hiện
nay, ở Demo5 chúng ta sẽ coi cách để chơi file nhạc định dạng wav, ngoài ra XNA còn có thể chơi các
định dạng phức tạp hơn như mp3 hay wma.
Trong hình ta thấy là chúng ta đưa vào project file wav tên start. Tiếp theo chúng ta sẽ làm cho file
này chạy trong ứng dụng game. Để làm được việc đó XNA cung cấp cho ta class SoundEffect để quản
lý file nhạc. Đầu tiên ta có thể tạo một đối tượng SoundEffect
23 | T r a n g
SoundEffect sound = null;

Tiếp theo đó trong hàm LoadContent ta sẽ load file nhạc lên đối tượng SoundEffect này, công việc
này thực hiện y chang như khi ta load file hình ảnh
sound = Content.Load<SoundEffect>(@”Audio\start”);
Bây giờ trong hàm Update, ta thực hiện việc chạy file nhạc, công việc này hết sức đơn giản là chỉ vần
gọi hàm Play của đối tượng SoundEffect. Tuy nhiên chúng ta sẽ kết hợp với phím P để play nhạc, tức
là khi bấm phím P thì đoạn nhạc sẽ được chơi. Đoạn code thực thi sẽ như sau
if (Keyboard.GetState().IsKeyDown(Keys.P))
sound.Play();
Chạy và kiểm tra ứng dụng bằng cách ấn phím P, ta sẽ thấy đoạn nhạc được nổi lên.
24 | T r a n g
Công nghệ .Net
GVHD : Phạm Thi Vương
Sinh viên :
Văn Đỗ Phước Đạt - 07520074
Đỗ Minh Huy – 07520152
Nguyễn Hoàng Minh - 07520229
25 | T r a n g

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×