[Phần 1] Tự sáng tạo trò chơi với phần mềm Game Maker
Nếu bạn đang ôm mơ ước thiết kế cho riêng mình những trò chơi máy tính độc đáo nhưng lại chẳng thể có thời gian theo khoá học nào thì hãy đến với chương trình Game Maker. Với phần mềm này, bạn sẽ không phải tốn công viết mã lệnh mà lại được thoả thuê phát huy trí tưởng tượng, và điều thú vị nhất là niềm vui vô bờ khi tạo ra được một trò chơi.
Bạn có thể sáng tạo game với vô số nền khác nhau, đồ hoạ "động đậy", các hiệu ứng âm thanh nổi tưng bừng và thậm chí là game 3D! Và đến khi bạn đã có tràn trề kinh nghiệm thì còn có thể "bán" các sản phẩm của mình nữa...
Bây giờ hãy bắt tay vào tải phần mềm tại đây hay cả @thuốc phần 8 tại http://www.mediafire.com/?wjzdzmqriul.
Sau khi tải về rồi, install phần mềm trong máy tính của bạn. Bạn sẽ thấy giao diện của chương trình như dưới đây:
Chương trình sáng tạo Game Maker. Chương trình chạy trên nền Windows phiên bản 98 SE, 2000, ME, XP và cao hơn nữa. Muốn sử dụng phần mềm, bạn phải có card đồ hoạ tối thiểu là DirectX 8 và ít nhất là 16 MB bộ nhớ video (tốt hơn hết là 32 BM trở lên); card âm thanh cũng ít nhất là DirectX 8 (bản DirectX 8.0 có thể tải về tại đây).
Ở thư mục đầu tiên, bạn sẽ nhìn thấy chữ Sprites. Đây chính là phần thể hiện đồ hoạ các đối tượng mà bạn tạo ra trong game. Một sprite là hình ảnh đơn (tĩnh) hoặc một tập hợp các hình ảnh nối tiếp nhau để tạo thành hình động. Ví dụ như dưới đây là hình Pacman động đang quay mặt sang phải.
Khi làm game, thường thì bạn chọn những sprite xinh xắn ngay trên trang Game Maker hoặc trên mạng dưới dạng file gif động.
Để thêm vào một sprite mới, bạn hãy nhấn chuột phải vào chữ Sprite, kích vào Add Sprite. Hộp thoại Sprite sẽ hiện lên như sau:
Tại ô đầu tiên bạn sẽ xác định tên của sprite. Mặc dù điều này không đòi hỏi quá khắt khe, nhưng tốt hơn hết bạn hãy cho chúng những cái tên khác nhau và bắt đầu bằng chữ cái, không sử dụng phím space (phím cách).
Để tải một sprite, bạn hãy nhấn vào nút Load Sprite. Sau đó, bạn sẽ thấy hộp thoại chỉ dẫn nguồn sprite để bạn chọn lựa. Game Maker có thể tải rất nhiều loại file đồ hoạ khác nhau. Khi tải file gif động, những hình ảnh đơn khác nhau sẽ tạo thành sprite đó. Khi sprite này được tải về thì hình ảnh đơn đầu tiên sẽ xuất hiện ở bên phải. Tại hộp có tên Transparent, nếu có đánh dấu thì có nghĩa là nền (background) của sprite là "trong suốt" và hầu hết các sprite là trong suốt. Nền này bị quyết định bằng màu của điểm ảnh ở góc trái dưới cùng. Do đó, hãy đảm bảo không có điểm ảnh nào của hình ảnh thực sự có màu này. (Chú ý rằng các file gif thường xác định màu trong suốt của mình. Màu này không được dùng trong Game Maker). Với nút Edit Sprite, bạn có thể chỉnh sửa sprite hay thậm chí là tạo ra một sprite hoàn toàn mới. Những hình ngộ nghĩnh đó có thể quay ngược, quay xuôi, thêm màu mè mới... tuỳ theo ý bạn.
Mục thứ hai là Sound. Hầu hết các game đều có những hiệu ứng âm thanh và nhạc nền và bạn có thể tìm thấy các hiệu ứng rất hữu ích ngay trên trang của Game Maker và các trang web khác.
Để thêm một nguồn âm thanh cho trò chơi, bạn hãy dùng chức năng Add Sound (nhấn chuột phải vào mục Sound, chọn Add Sound hoặc ngay trên thanh công cụ) và bảng dưới đây sẽ hiện ra.
Để tải âm thanh, nhấn vào Load Sound. Sau đó một hộp thoại hiện ra để bạn có thể chọn file âm thanh. Ở đây có hai loại là file wave và midi. File wave được dùng cho những hiệu ứng ngắn còn file midi có khả năng thể hiện âm nhạc theo nhiều kiểu khác nhau.
Sau khi tải nhạc về, bạn có thể nhấn vào hình tam giác màu xanh bên cạnh để nghe và dùng chức năng Save Sound để lưu file nhạc hiện thời.
Mục thứ ba là Backgrounds. Đây là những phông nền làm nơi diễn ra trò chơi. Bạn có thể đưa vào vô số mẫu hình cho background.
Các chức năng Add và Load hình nền giống như các mục trên. Game Maker hỗ trợ rất nhiều định dạng ảnh, nhưng tất nhiên là hình nền thì không thể là hình động được. Ô Transparent nếu có đánh dấu thì có nghĩa là hình nền "trong suốt". Phần lớn các background đều "hiện hình" và có màu là màu điểm ảnh góc tận cùng bên trái được sử dụng. Bạn có thể thay đổi hay tạo mới hình nền bằng cách dùng chức năng Edit Background với giao diện khá giống phần mềm Paint trong Windows.
[Phần 2] Tự sáng tạo trò chơi với phần mềm Game Maker
Những nguồn hình ảnh và âm thanh mà các bạn đã làm quen ở phần trước là yếu tố khởi đầu của Game Maker. Tuy nhiên, nguồn quan trọng nhất của chương trình chính là các object. Đây chính là những thực thể làm nên một trò chơi. Thường thì chúng được thể hiện bằng hình ảnh để bạn nhìn thấy; chúng có những "hành vi" vì phải "phản ứng" lại một số "sự kiện". Tất cả những gì bạn nhìn thấy trong game chính là các object (tất nhiên trừ background). Nói một cách chính xác hơn, background là khoảng cách giữa các object. Các nhân vật, những con quái vật, gờ tường, vũ khí... là các object. Có một số object bạn không nhìn thấy nhưng nó có chức năng điều khiển trong quá trình chơi.
Chúng ta hãy phân biệt sự khác nhau giữa sprite và object. Sprite là những hình ảnh (tĩnh hoặc động) nhưng không có "hành vi" nào. Object thì có cả sprite để thể hiện đồ hoạ và cả "hành vi" nữa. Nếu không có "hành vi" thì sẽ không có game.
Cũng cần phải phân biệt sự khác nhau giữa object và instance. Object mô tả cả một loại thực thể nào đó, ví dụ như một con quái vật. Và có rất nhiều trường hợp riêng lẻ (instance) của đối tượng này trong game. Do đó, khi nói đến instance là ám chỉ đến một đối tượng cụ thể của object.
Để thêm một object vào game, chọn chức năng Add Object và hộp thoại sau đây sẽ hiện ra.
Chức năng này khá phức tạp. Ở bên trái có một số thông tin chung về object. Ở giữa là danh sách các "sự kiện" có thể xảy ra với các object. Ở bên phải là những hành động khác nhau mà một object có thể thực hiện. các "sự kiện" và hành động sẽ được nói ở phần sau.
Trước hết, bạn hãy đặt tên cho object. Sau đó, chọn sprite cho object. Nhấp chuột trái vào hộp sprite hoặc biểu tượng bên cạnh đó thì bạn sẽ thấy một cửa sổ bé hiện lên để bạn chọn các sprite có sẵn. Nếu chưa có sprite nào, hãy nhấn nút New để thêm sprite mới. Cũng vậy, dùng chức năng Edit, bạn sẽ thay đổi được sprite và làm thế này thì nhanh hơn là chọn nguồn trong danh sách rồi chỉnh sửa ngay trong đó.
Ngay bên dưới có hai hộp trạng thái. Visible nếu được đánh dấu thì có nghĩa là instance của object này có thể nhìn thấy. Ví dụ như bạn có thể dùng chúng làm điểm di chuyển cho một con quái vật chẳng hạn. Những object không nhìn thấy sẽ "phản ứng" với các "sự kiện" và những instance khác sẽ "va chạm" với chúng. Hộp trạng thái Solid nếu được đánh dấu thì có nghĩa là object đó thuộc dạng "cứng" (như bờ tường chẳng hạn). Những va chạm đối với các object "cứng" được xử lý khác so với những object "mềm". Bạn nên dùng trạng thái solid đối với các object không di chuyển.
Khái niệm về event ('sự kiện')
Game Maker sử dụng phương pháp xử lý theo event và hoạt động như sau: Bất cứ khi nào có một điều gì đó xảy ra trong game, các instance của object có "sự kiện" (loại thông điệp cho biết có sự kiện xảy ra). Sau đó, những instance này có thể "phản ứng" với những thông điệp này bằng cách thực hiện một số hành động nào đó. Đối với mỗi object, bạn phải chỉ ra nó phải "phản ứng" với sự kiện nào và phải thực hiện hành động nào. Điều này nghe có vẻ phức tạp nhưng thực ra rất dễ dàng. Trước hết, đối với hầu hết các sự kiện thì object không phải làm gì cả, còn những sự kiện yêu cầu phải có hành động gì đó thì bạn chỉ cần sử dụng cách kéo-thả để xác định hành động là được.
Ở ô giữa là danh sách các sự kiện mà object phải phản ứng lại. Bạn có thể thêm vào bằng cách nhấn phím Add Event. Tại đây, bạn có thể chọn các loại sự kiện khác nhau như Alarm (báo động), Collision (va đập)... và mỗi mục lại có vô số lựa chọn khác nhau.
Tiếp theo là phần Actions tương ứng với các event. Để thêm các hành động vào danh sách, bạn hãy kéo biểu tượng bên phải và thả vào hộp Actions này. Chúng sẽ được đặt nối tiếp nhau với một mô tả ngắn ở bên cạnh. Đối với mỗi action, bạn sẽ phải chọn các thông số (điều này sẽ được thảo luận kỹ ở phần dưới). Như vậy, sau khi lựa chọn, bạn sẽ có kết quả ví dụ như thế này:
lúc này bạn có thể bắt đầu thêm action cho những event khác. Dùng chuột trái nhấn vào đúng event cần thêm hành động rồi áp dụng các thao tác "kéo-thả".
Khi chọn Add Event, bạn sẽ thấy hiện ra hộp thoại sau:
Create event
Event này diễn ra khi một instance của object được tạo ra. Chức năng này thường được dùng để thiết lập instance chuyển động hoặc các trạng thái khác nhau của instance.
Destroy event
Event này được tạo ra khi instance bị phá huỷ. Nói chính xác hơn là nó xảy ra ngay trước khi instance bị phá huỷ, vì vậy trong quá trình xảy ra event này thì instance vẫn tồn tại. Thường thì event này không được sử dụng, nhưng bạn có thể dùng để thay đổi điểm số hay tạo object khác.
Alarm events
Mỗi instance có 12 đồng hồ báo động. Bạn có thể đặt các đồng hồ này bằng cách sử dụng những action (hành động) nào đó (xem phần sau). Đồng hồ báo động sau đó sẽ đếm ngược cho đến khi bằng 0 và tại thời điểm này, "sự kiện" báo động được tạo ra. Để xác định những hành động cho một đồng hồ báo động nào đó, bạn cần phải chọn từ menu. Đồng hồ này rất hữu dụng và bạn có thể dùng để tạo ra những hoạt động liên tục, ví dụ như làm cho một con quái vật cứ 20 bước lại đổi hướng đi một lần. (Trong trường hợp như vậy, mỗi hành động trong event phải thiết lập đồng hồ báo động lại).
Step events
'"Sự kiện" step diễn ra ở mỗi bước đi trong game. Tại đây bạn có thể thiết lập những hành động cần thực hiện liên tục. Ví dụ: nếu một object phải đi theo một object khác, bạn có thể áp dụng hướng chuyển động đối với object mà mình đang đi theo. Hãy cẩn thận với việc này. Bạn không nên thiết lập quá nhiều hành động phức tạp trong "sự kiện" step của những object có nhiều instance. Nếu làm như thế, tốc độ của game sẽ diễn ra rất chậm. Nói chính xác hơn là có 3 "sự kiện" step khác nhau là Step, Begin Step, End Step. Begin Step được thực hiện vào lúc bắt đầu step, trước khi bất kỳ sự kiện nào khác xảy ra. Step được thực hiện ngay trước khi các instance được đặt vào các vị trí mới. End Step được thực hiện vào cuối mỗi step và thường được dùng để thay đổi sprite tuỳ theo hướng chuyển động hiện thời.
Collision events
Bất cứ khi nào hai instance "đụng" nhau (thực chất là các sprite chồng lên nhau), thì "sự kiện" collision xuất hiện. Nói chính xác hơn là hai sự kiện collision xảy ra, mỗi collision cho một instance. Instance có thể phản ứng lại với sự kiện này. Trên thực đơn, bạn có thể chọn object mà bạn muốn áp dụng sự kiện này. Sau đó bạn có thể thiết lập các hành động tại đây.
Có một sự khác biệt giữa những gì diễn ra khi instance "đụng độ" với một object dạng "cứng" và dạng "mềm". Trước hết, khi không có hành động nào trong sự kiện collision thì không có gì xảy ra cả. Instance hiện thời đơn giản là cứ di chuyển, thậm chí khi object kia ở dạng "cứng". Còn khi sự kiện này có các hành động thì những điều sau đây sẽ xảy ra:
Khi object kia thuộc dạng "cứng", instance được đặt lại vị trí cũ (trước khi sự kiện collision diễn ra). Sau đó sự kiện được thực hiện. Cuối cùng, instance được di chuyển đến vị trí mới. Do đó, ví dụ nếu một sự kiện, chẳng hạn như quay ngược hướng chuyển động, thì instance cứ va vào tường mãi. Còn nếu có sự kiện collision thì instance vẫn ở vị trí trước đó và ngừng di chuyển.
Khi object kia thuộc dạng "mềm" thì instance không được đặt ngược lại. Sự kiện này đơn giản được thực hiện với instance ở vị trí hiện tại và không được kiểm tra lần hai. Có rất nhiều cách sử dụng sự kiện collision và các instance có thể dùng nó để va đập vào các gờ tường. Bạn cũng có thể sử dụng nó để phá huỷ các object khi chúng bị dính đạn chẳng hạn.
Keyboard events
Khi người chơi nhấn một phím nào đó, sự kiện keyboard diễn ra đối với tất cả các instance của mọi object. Đối với mỗi phím thì có một sự kiện. Trong thanh menu, bạn có thể chọn phím nào đó cho các object mà bạn muốn. Bạn có thể thiết lập sự kiện cho mỗi step miễn là người chơi nhấn phím liên tục. Ở đây có hai loại sư kiện keyboard đặc biệt là <No key> (Không nhấn phím) và <Any key> (Nhấn bất kỳ phím nào). Khi người chơi nhấn nhiều phím, các sự kiện dành cho tất cả những phím được nhấn đó đều xảy ra. Chú ý một điều là những phím trong khoảng phím số trên keyboard chỉ tạo ra các sự kiện tương ứng khi đèn Numlock sáng.
Mouse events
Sự kiện về chuột diễn ra đối với một instance bất cứ khi nào con trỏ chuột nằm trong sprite thể hiện instance này. Tuỳ vào những phím chuột nào được nhấn, bạn có thể có sự kiện "không nhấn chuột", "chuột trái", "chuột phải" hay "chuột giữa". Các sự kiện phím chuột được tạo ra khi phím đó được nhấn. Còn các sự kiện "thả" chuột được tạo ra khi phím đó được nhả ra. Nếu bạn muốn phản ứng với các sự kiện nhấn chuột hay thả chuột ở một điểm tuỳ ý, hãy sử dụng chức năng "global mouse" ở thanh menu nhỏ.
Có hai sự kiện đặc biệt dành cho chuột. Một là sự kiện nhấn chuột xảy ra khi chuột được nhấp vào instance. Sự kiện thả chuột xảy ra khi chuột được thả khỏi instance. Những sự kiện này được áp dụng chủ yếu để thay đổi hình ảnh hoặc chơi nhạc. Các sự kiện di chuyển bánh xe chuột lên và xuống xảy ra khi người sử dụng quay bánh xe. Ngoài ra còn có rất nhiều sự kiện áp dụng cho bộ điều khiển (joystick) của máy chơi game chuyên dụng. Bạn có thể xác định các hành động cho 4 hướng hay 8 hướng của bộ điều khiển chính và phụ.
Các event khác
Ngoài ra có vô số event khác rất hữu dụng trong game và bạn có thể tìm thấy chúng trong menu này.
Outside: Sự kiện này xảy ra khi instance nằm hoàn toàn ngoài Room (không gian game - sẽ nói kỹ ở phần sau). Đây là thời điểm thích hợp để phá huỷ nó.
Boundary: Sự kiện này xảy ra khi instance cắt ranh giới của Room.
Game start: Điều này xảy ra với tất cả các instance ở Room đầu tiên khi trò chơi bắt đầu. Nó diễn ra trước khi sự kiện Room start (xem phần dưới). nhưng sau các sự kiên khởi tạo cho các instance trong Room. Sự kiện này thường được xác định trong một object "điều khiển" và được dùng để khởi động nhạc nền, tải dữ liệu...
Game end: Sự kiện này xảy ra đối với tất cả các instance khi game kết thúc. Thường thì chỉ một object xác định sự kiện này, ví dụ như để lưu trữ dữ liệu nào đó trong tậo tin.
Room Start: Sự kiện diễn ra đối với tất cả các instance khi Room khởi động và sau các sự kiện khởi tạo.
Room end: Xảy ra đối với tất cả các instance đang tồn tại khi Room kết thúc.
No more lives: Có một hành động để thiết lập và thay đổi số "lần sống" của đối tượng game. Bất cứ khi nào con số nào ít hơn hay bằng 0 thì sự kiện này xảy ra. Chức năng không thêm lần sống xảy ra khi muốn kết thúc hoặc khởi động lại game.
No more health: Bất cứ khi nào "máu" giảm xuống bằng hoặc nhỏ hơn 0 thì sự kiện này xảy ra. Dùng chức năng không thêm máu khi muốn giảm số lần sống và khởi động lại trò chơi.
End of animation: Kết thúc hình ảnh động. Như đã nhắc đến ở trên, một hình ảnh động bao gồm rất nhiều hình ảnh nối tiếp nhau. Sự kiện này sẽ xảy ra đúng lúc hình cuối cùng kết thúc và có thể áp dụng để thay đổi hình ảnh động hay huỷ instance.
End of path: Kết thúc path (đường đi của đối tượng - sẽ nói ở phần sau). Sự kiện này diễn ra khi instance đi theo một quãng đường và đến tận cùng quãng đường đó.
User defined (do người dùng xác định). Có 16 sự kiện thuộc loại này và thường do người dùng tự thêm vào bằng các dòng mã.
[Phần 3] Tự sáng tạo trò chơi với phần mềm Game Maker
Các hành động (action) chỉ ra những việc xảy ra trong một trò chơi mà Game Maker tạo nên. Những hành động này được đặt trong các “sự kiện” của object. Bất cứ khi nào sự kiện diễn ra, những hành động này được thực hiện và tạo ra “cách ứng xử” của các instance trong object. Có rất nhiều hành động khác nhau trong phần mềm này và điều quan trọng là chúng ta phải hiểu rõ về chức năng của chúng.
Bạn có thể tìm thấy tất cả các hành động ở bên tay phải bảng Object properties và có 6 loại action khác nhau. Cách chọn actions chúng ta đã thảo luận ở phần 2.
Khi bạn đã “kéo-thả” một action trong danh sách, một cửa sổ sẽ hiện lên và lúc này bạn có thể đưa vào các tham số cho hành động. Các tham số này sẽ được mô tả ở bên dưới các biểu tượng của actions; tuy nhiên có hai loại tham số phổ biến nhất mà chúng ta cần bàn luận kỹ hơn.
Ở phần đầu của bảng tham số bạn sẽ thấy mục Applies to và lúc này bạn phải chọn Self, Other hay Object. Phần mặc định Self sẽ quy định hành động thực hiện cho bản thân instance và phần lớn bạn sẽ chọn mục này. Trong trường hợp xảy ra sự kiện collision (đụng độ), bạn có thể xác định hành động cho instance khác tham gia vào vụ “đụng độ” đó, ví dụ như bạn có thể phá huỷ instance kia chẳng hạn. Cuối cùng, bạn có thể áp dụng hành động cho tất cả các instance của một object xác định.
Kiểu thứ hai là hộp trạng thái Relative. Nếu đánh dấu vào hộp này, giá trị mà bạn gõ vào sẽ tương ứng với những giá trị hiện thời. Ví dụ: bạn có thể thêm vào cho giá trị hiện tại chứ không thay đổi giá trị hiện tại thành một giá trị mới. Những tham số khác sẽ được mô tả dưới đây. Sau đó bạn có thể thay đổi các tham số bằng cách nhấn đúp vào biểu tượng hành động.
Bắt đầu di chuyểnBạn có thể sử dụng action này để bắt đầu di chuyển instance theo một hướng nhất định với nút có mũi tên 8 hướng này. Tốc độ di chuyển được tính bằng số pixel cho mỗi step. Bạn cũng có thể xác định nhiều hướng khác nhau cho đối tượng.
Thiết lập hướng và tốc độ di chuyển. Đây là cách thứ hai để xác định một chuyển động với góc từ 0 và 360 độ. 0 có nghĩa là di chuyển về bên phải và hướng di chuyển là theo chiều ngược kim đồng hồ. Như vậy 90 độ có nghĩa là di chuyển thẳng đứng lên. Nếu bạn muốn tạo ra một hướng bất kỳ thì có thể nhập vào số ngẫu nhiên từ 0 đến 360. Bạn sẽ để ý thấy là máy sẽ cho kết quả ngẫu nhiên thấp hơn con số mà bạn chỉ ra. Do đó, hãy chú ý đến hộp Relative. Nếu đánh dấu vào đây thì chuyển động mới sẽ được thêm vào chuyển động trước. Ví dụ: nếu instance đang chuyển động lên trên và bạn thêm chuyển động sang trái nào đó thì nõ sẽ chuyển động lên về phía bên trái.
Di chuyển đến một điểm xác định.Bạn có thể chỉ ra một vị trí, tốc độ xác định cho một instance di chuyển đến. Ví dụ: nếu muốn một viên đạn bay tới con tàu vũ trụ chẳng hạn, bạn có thể dùng tới vị trí như (tau.x,tau.y). Nếu đánh dấu vào hộp Relative, bạn sẽ xác định được tương đối cho vị trí hiện thời của instance.
Thiết lập tốc độ di chuyển theo phương nằm ngang. Tốc độ của instance bao gồm chuyển động theo phương nằm ngang và thẳng đứng. Với action này, bạn có thể thay đổi tốc độ theo phương nằm ngang (nghĩa là chuyển động sang phải, còn đặt giá trị âm instance sẽ chuyển động sang trái).
Thiết lập tốc độ di chuyển theo phương nằm ngang. Cũng tương tự như trên.
Thiết lập trọng lực. Với action này, bạn có thể tạo ra trọng lực cho một object nhất định. Bạn xác định một hướng (góc từ 0 đến 360 độ) và một tốc độ, và trong mỗi step tốc độ này được kèm vào chuyển động hiện tại của object. Thường thì bạn chỉ cần một số gia tốc độ rất nhỏ (ví dụ như 0,01) và hướng chuyển động đi xuống (270 độ chẳng hạn). Nếu đánh dấu vào hộp Relative, bạn có thể tăng được tốc độ trọng lực và hướng. Chú ý một điều là, không giống như trong thực tế, object khác nhau có các hướng trọng lực khác nhau.
Đảo ngược hướng theo phương nằm ngang. Với action này bạn có thể thay đổi chuyển động của instance theo phương ngang. Ví dụ: bạn có thể dùng khi object đụng vào bờ tường chẳng hạn.
Đảo ngược hướng theo phương thẳng đứng. Ví dụ, bạn có thể dùng khi object đụng vào nền cứng nằm ngang.
Thiết lập va chạm. Va chạm làm cho các instance di chuyển chậm lại. Bạn hãy xác định mức độ của va chạm. Trong mỗi step mức độ này bị trừ đi cho đến khi tốc độ bằng 0. Thường thì bạn muốn con số rất nhỏ, ví dụ như 0,01.
Nhảy đến một vị trí cho trước. Khi dùng action này, bạn có thể đặt instance vào một vị trí xác định. Bạn chỉ cần xác định toạ độ (x,y) cho instance đó là được. Nếu đánh dấu vào hộp Relative, vị trí này tương ứng với vị trí hiện tại của instance. Hành động này thường được áp dụng để di chuyển liên tục một instance.
Nhảy đến vị trí bắt đầu. Hành động này giúp bạn đặt instance quay trở lại vị trí ban đầu mà nó được tạo ra.
Nhảy đến vị trí ngẫu nhiên. Bạn có thể dùng hành động này để di chuyển instance đến một vị trí ngẫu nhiên trong room. Những vị trí được chọn là nơi instance không "giao" với các instance "dạng rắn" nào cả.
Xuất hiện lại khi ra ngoài room. Với hành động này, bạn có thể để một instance đi xoay
quanh room khi nó rời cạnh này của room rồi xuất hiện ở cạnh bên kia. Hành động này thường được dùng trong sự kiện Outside. Chú ý một điều là instance phải có tốc độ phù hợp để xuất hiện lại như vậy do hướng của nó dựa trên hướng của chuyển động (dọc, ngang hay cả hai).
Di chuyển đến vị trí tiếp xúc. Bạn có thể dùng action này để di chuyển instance theo một hướng cho trước cho tới khi tiến đến một vị trí tiếp xúc. Nếu đã có một sự kiện "đụng độ" tại vị trí hiện tại thì instance không di chuyển. Nói cách khác, instance được đặt ngay trước khi một "đụng độ" xảy ra. Bạn có thể xác định hướng với khoảng cách tối đa để di chuyển. Ví dụ: khi instance đang "rơi" bạn có thể di chuyển xuống dưới cho đến khi chạm vào một objưct nào đó. Bạn cũng có thể chỉ ra nó chỉ áp dụng cho những vật dạng "rắn" hay tất cả các đối tượng. Thường thì bạn dùng hành động này cho sự kiện "đụng độ" để đảm bảo rằng instance dừng lại khi va chạm với instance khác.
Bật vào các object khác.
Khi đặt hành động này vào sự kiện "đụng độ" với object khác, instance sẽ nảy ngược lại theo quy luật vật lý thông thường. Nếu đặt thông số là False thì hành động chỉ đúng với các "bức tường" nằm dọc và ngang. Khi đặt thông số bằng True thì hành động được áp dụng cho cả các "bức tường" dạng cong và "lởm chởm". Bạn cũng có thể xác định hành động cho các object dạng rắn hoặc với tất cả các object.
Tạo room
Sau khi đã hiểu sơ qua các khái niệm về object và các “ứng xử” của nó dưới hình thức “sự kiện” và “hành động”, bạn có thể bắt tay vào tạo room, hay còn gọi là các level cho game. Bất kỳ game nào cũng có ít nhất một room. Trong những room này, chúng ta hãy đặt vào các instance của các object. Khi game bắt đầu, room thứ nhất được thể hiện luôn và các instance trong đó được “thổi một luồng sinh khí” do các hành động được tiến hành.
Có rất nhiều khả năng lựa chọn khi tạo room. Ngoài việc đặt một loạt các thuộc tính và thêm instance của object, bạn còn có thể thêm vào các background, xác định các hình và thêm tiêu đề.
Trước hết, để tạo room, hãy chọn chức năng Add Room và bảng sau đây sẽ hiện ra:
Ở phần trên cùng là một thanh công cụ. Tại đây, bạn có thể xác định kích cỡ của bảng dùng để đặt vị trí các object. Bạn cũng có thể quyết định có để các đường kẻ ô hay không. Đôi khi bạn sẽ thấy rất hữu ích khi để ẩn một số thứ trong room; dù vậy khi các instance được thêm vào, chúng sẽ hiện ra và độc lập với phần thiết lập chế độ xem (view setting). Ở đây có các nút để xoá instance khỏi room và chuyển toàn bộ các instance lên số lượng pixel (điểm ảnh) khá lớn. Hãy dùng đến các số âm để dịch chuyển instance lên hoặc xuống. Điều này là rất hữu ích khi bạn muốn mở rộng room (thậm chí đặt các instance ra ngoài room). Nút Undo dùng để bỏ đi phần vừa chỉnh sửa, nút OK dùng để lưu chỉnh sửa.
Ở bên tay trái bạn sẽ thấy 3 mục chính là objects, settings và backgrounds. Với objects bạn có thể thêm instance vào room. Settings sẽ giúp bạn chỉ ra số thiết lập cho room. Trong mục backgrounds bạn có thể thiết lập các hình nền cho room.
Add instances (Thêm instance).
Khi bắt đầu room trống không với nền màu xám. Để thêm instance vào, đầu tiên chọn mục objects hoặc Add instance. Sau đó chọn object mà bạn muốn thêm vào và chú ý rằng khi bạn thay đổi nguồn của sprite thì sẽ có biểu tượng gạch chéo trên hình. Nhấn chuột trái vào màn hình room. Lúc này một instance sẽ hiện ra. Nếu bạn giữ phím Alt trong khi đặt instance này thì nó không được "sắp hàng" trên bảng. Nếu giữ phím chuột trong lúc kéo instance vào room thì bạn sẽ đặt nó được đúng chỗ. Còn khi giữ phím Shift trong khi nhấn và di chuyển chuột thì vô số instance tương tự sẽ được thêm vào.
Bạn sẽ để ý thấy một điều là nếu đặt một instance lên trên một instance khác thì instance ban đầu sẽ biến mất. Thường thì đây là điều mà bạn muốn, nhưng tất nhiên không phải lúc nào cũng thế. Bạn có thể tránh được điều này bằng cách không đánh dấu vào hộp Delete underlying.
Nếu muốn thay đổi vị trí của instance, hãy giữ phím Ctrl và nhấn chuột trái vào instance đó rồi giữ chuột để kéo vào vị trí mới. (Dùng phím Alt thì sẽ chính xác hơn). Nếu bạn giữ Ctrl trong khinhấn chuột phải vào một instance thì một menu xuất hiện. Tại đây, bạn có thể xoá object, nhập vào vị trí chính xác cho instance hay di chuyển instance ở tận cùng lên đầu và ngược lại.
Room setting (Thiết lập room).
Mỗi room có một số thiết lập riêng mà bạn có thể thay đổi bằng cách nhấn vào mục settings. Mỗi room đều có một tên riêng và tốt hơn hết hãy cho nó một cái tên có nghĩa. Bạn cũng có thể thiết lập chiều rộng và độ cao của room (bằng pixel), cũng như tốc độ của game (số step/giây). Nếu tốc độ càng cao thì hành động càng tỏ ra "êm ái". Tuy nhiên, bạn cần có máy tính cấu hình cao để chạy nó.
Thiết lập background
Dùng nút backgrounds bạn có thể tạo được hình nền cho room. Thực ra, bạn có thể xác định vô số backgrounds. Trang đó hiện ra như sau:
Ở phần đầu là màu của nền và bạn có thể nhấn vào đó để thay đổi. Màu nền chỉ hữu dụng nếu bạn không dùng hình nền che lấp toàn bộ room. Nói cách khác, tốt nhất là không đánh dấu vào ô có tên Draw background color.
Bạn sẽ thấy một danh sách gồm 8 background hiện ra và có thể xác định cho từng cái. Nhưng thường thì bạn chỉ cần từ một đến hai hình nền. Muốn xác định được background, trước hết hãy chọn trong danh sách. Sau đó đánh dấu vào hộp có tên Visible when room starts, nếu không bạn sẽ không nhìn thấy background mà bạn chọn. Tên của background sẽ được in đậm khi đã được xác định.
Lúc này bạn có thể chỉ ra hình nền trong menu và bạn có thể thay đổi rất nhiều setting. Trước hết, bạn cần xác định xem hình nền này đặt theo chiều dọc hay chiều ngang và có thể chọn vị trí của background trong room. Bạn còn có sự lựa chọn khác là trải rộng hình nền. Do đó background sẽ được tính tỷ lệ để "lấp đầy" room. Cuối cùng, bạn có thể "cuộn" background này bằng cách tạo cho nó tốc độ lên hoặc xuống (xác định bằng số pixel/step). Tốt hơn hết không sử dụng cách cuộn với nền bị trải rộng vì trông rất xấu.
Ngoài ra, bạn sẽ nhìn thấy một hộp có tên Foreground image. Khi đánh dấu vào đây, hình nền sẽ trở thành hình "phủ", nghĩa là "đè" lên các hình khác chứ không nằm sau nữa.
[Phần 4] Tự sáng tạo trò chơi với phần mềm Game Maker
Ở phần này, bạn sẽ làm quen với các chức năng cao cấp trong room, tạo ra vô số kiểu chữ xuất hiện trên hình nền và tự vẽ đường đi cho nhân vật game.
Trong room, bạn sẽ thấy có hai chức năng nữa là settings và view. Trong mục settings, bạn sẽ để ý thấy hộp trạng thái Persistent. Thường thì khi bạn rời khỏi room rồi sau đó quay trở lại, room sẽ được trở về trạng thái ban đầu. Điều này là tốt nếu bạn tạo rất nhiều level trong game nhưng thường thì đó là điều không mong muốn trong một game nhập vai chẳng hạn. Lúc này room cần giữ nguyên trạng thái như khi bạn thoát ra lần cuối cùng. Và muốn như vậy, hãy đánh dấu vào hộp Persistent. Như vậy, trạng thái của room sẽ được ghi nhớ và khi bạn trở lại room lần sau, nó sẽ y nguyên như khi bạn thoát ra lần cuối. Chỉ khi nào bạn restart trò chơi thì room mới được thiết lập lại. Thực ra, có một trường hợp ngoại lệ: Nếu bạn đánh dấu các object nào đó với trạng thái Persistent thì các instance của object này sẽ không "ở lại" trong room mà di chuyển sang room kế tiếp.
Thứ hai là nút Creation code. Tại đây, bạn có thể nhập vào một đoạn mã được kích hoạt khi room được tạo ra. Điều này rất hữu ích để bạn lấp đầy các tham số cho room, tạo ra các instance nào đó. Và việc hiểu cặn kẽ chính xác điều gì xảy ra khi bạn di chuyển đến một room nhất định trong game là rất quan trọng.
- Một là, trong room hiện thời tất cả các instance có một sự kiện ở cuối room. Sau đó các instance ở trạng thái không được đánh dấu Persistent đều bị di chuyển đi (không có sự kiện phá bỏ nào được tạo ra).
- Sau đó, đối với room mới, các instance có trạng thái persistent từ room trước đó được thêm vào.
- Tất cả các instance mới được tạo ra và các sự kiện khởi tạo này được thực hiện (nếu room ở trạng thái không persistent hoặc trước đó chưa được ghé vào).
- Khi đây là room đầu tiên, đối với tất cả các instance thì sự kiện khởi động game được tạo ra.
- Tiếp theo, mã tạo room sẽ hoạt động.
- Cuối cùng thì tất cả các instance đều tham gia vào sự kiện khởi động room.
Do đó, ví dụ như các sự kiện khởi động room có thể sử dụng các biến số do mã khởi tạo thiết lập nên cho room và trong mã này, bạn có thể chỉ dẫn đến các instance (cả những instance mới và cố định) trong room.
Trong menu hiện ra, khi bạn nhấn vào một instance bằng phím Ctrl, bạn có thể xác định một số mã khởi tạo cho một instance cụ thể. Mã này được thực hiện khi room được khởi động ngay trước sự kiện khởi tạo của instance. Điều này rất hữu ích, ví dụ như để thiết lập các biểu kế nào đó cụ thể đối với instance.
Chèn ô hình
Trong nhiều game, bạn sẽ muốn có được các nền "bắt mắt", ví dụ như trong mê cung thì phải có những bức tường kỳ bí chẳng hạn. Lúc này, bạn có thể xác định nhiều object khác nhau và tạo các room từ những object này. Dù vậy, vấn đề này đòi hỏi bạn mất rất nhiều công sức, dùng đến nguồn hình ảnh, âm thanh lớn nên làm cho game chạy chậm. Ví dụ: để tạo ra những bức tường đẹp trong trò chơi mê cung, bạn sẽ cần đến ít nhất 15 object hình tường khác nhau.
Cách tốt nhất được sử dụng trong nhiều game là các bức tường và object tĩnh được đưa vào background thực sự. Nhưng có thể bạn thắc mắc là làm sao mà trò chơi biết được một object nào đó đụng vào tường nếu như nó chỉ bị kéo vào background mà thôi? Bí quyết là như sau: Bạn chỉ tạo ra một object "tường" trong game. Nó phải có kích thước hợp lý, nhưng không cần quá đẹp. Khi tạo ra room, hãy đặt object này ở khắp mọi nơi có tường. Và tại đây, chúng ta hãy để object này trong trạng thái "Invisible" (ẩn). Do đó, khi chơi game, bạn sẽ không nhìn thấy các object dạng "tường" mà chỉ nhìn thấy một background mà thôi. Kỳ thực, các object dạng "tường" vẫn ở đó và những object khác trong game sẽ "phản ứng" lại được với nó.
Bạn có thể sử dụng kỹ thuật này cho bất kỳ object nào không thay đổi hình dạng hay vị trí. (Nhưng bạn không thể dùng nó cho những object "động đậy"). Đối với các game chơi trên một nền nào đó, có lẽ bạn chỉ cần một sàn và một object dạng "tường", nhưng người thiết kế game cũng có thể tạo ra những background đẹp như sóng cỏ mềm mại hay những cành cây sum suê.
Để thêm vào các ô "lát nền" cho room, trước hết bạn cần phải lấy một nguồn background cho trò chơi của mình có chứa các ô ca-rô. Nếu muốn các ô ca-rô này hiển thị một phần, hãy đảm bảo hình ảnh background "trong suốt" (dùng trạng thái transparent). Sau đó xác định kích cỡ của mỗi ô và quyết định xem có khoảng trống giữa các ô hay không. Lúc này, khi xác định room, nhấn vào nút Tiles, hình sau đây sẽ xuất hiện:
Ở góc bên trái phía trên có mộ loạt các ô đang sử dụng hiện thời. Để chọn tập hợp này, hãy nhấn vào menu phía dưới và hình ảnh background thích hợp.
Các ô nằm dưới sẽ bị bỏ đi, trừ khi bạn bỏ dấu ở hộp Delete underlying. Bạn cũng có thể dùng chuột phải để xoá ô này. Giữ phím Shift để nhân bội các ô lên tuỳ theo ý thích. Giữ phím Ctrl để di chuyển các ô hình đến vị trí mà bạn muốn.
Trong một số trường hợp, bạn có thể muốn thêm vào một phần của background trong room không cùng kích cỡ với một ô hay bao gồm nhiều ô. Điều này có thể thực hiện như sau: Tại hình ảnh trên cùng bên trái, nhấn chuột trái trong khi giữ phím Alt. Giờ đây, bạn có thể kéo một mảng để đặt vào room như cách bạn đặt các ô. Để "nhân" thêm nhiều ô, bạn có thể giữ phím Shift trong quá trình di chuyển. Chú ý rằng điều này chỉ có thể thực hiện được khi không có vạch ngăn cách giữa các ô. Nếu bạn muốn chọn chính xác vùng có nhiều cỡ ô trong room, giữ phím Ctrl, chứ không phải phím Shift. (Chú ý là bạn có thể thay đổi hai phím này trong quá trình kéo chuột và đôi khi việc này rất hữu ích).
Các ô có thể được xếp đặt theo nhiều lớp khác nhau với "độ dày" khác nhau. Ở dưới cùng là lớp hiện tại. Mặc định lớp này là 1000000 (con số thông thường sau tất cả các instance). Do đó, các instance sẽ di chuyển ở mặt trên của các ô. Bạn có thể sử dụng nút Add để thêm các lớp mới và mỗi lớp có "độ dày" khác nhau. "Độ dày" mang giá trị âm có thể được dùng để đặt các ô lên trước các instance. Nếu bạn cũng đặt các "độ dày" khác nhau cho object, bạn có thể đặt chúng ở giữa các lớp ảnh. Nếu nhấn vào Delete, bạn có thể xóa một lớp cùng các lớp con của nó. (Bạn phải có ít nhất một lớp ảnh). Nếu nhấn vào Change, bạn có thể thay đổi "độ dày" của lớp này, chú ý nếu các lớp có độ dày như nhau thì sẽ bị nhập vào nhau.
Sử dụng các ô là một tính năng mạnh mà bạn có thể tận dụng càng nhiều càng tốt. Việc này cũng nhanh hơn là dùng các object và các hình ảnh của ô được lưu trữ đúng một lần. Do đó, bạn có thể dùng các room có nhiều ô mà cần đến ít bộ nhớ.
Chức năng hiển thị game
Cuối cùng là nút Views. Đây là cơ chế để vẽ ra các phần khác nhau trong room với nhiều vị trí trên màn hình. Có nhiều cách để xem. Trước hết, trong nhiều trò chơi bạn muốn thể hiện thì chỉ một phần trong room hiển thị mà thôi. Ví dụ: trong phần lớn các game chơi trên nền 2 chiều (trong đó, các nhân vật đi từ trái sang phải, lên trên, xuống dưới như trò Mario chẳng hạn), việc xem diễn tiến của trò chơi phải đi theo nhân vật. Trong các game chơi đôi, bạn thường cần đến một chế độ màn hình "chia phần", trong đó bạn sẽ xem mỗi người chơi trên một phần màn hình. Cách thứ ba là một phần room có thể cuộn lên, cuộn xuống trong khi phần kia được giữ cố định.
Khi nhấn vào chức năng Views, bạn sẽ thấy hiện ra như sau:
Ở trên cùng bạn sẽ thấy hộp trạng thái Enable use of Views. Bạn phải đánh dấu vào hộp này để sử dụng. Phía dưới là danh sách 8 view mà bạn có thể xác định được. Phía dưới danh sách là những thồn tin dành cho các view. Trước hết, hãy xác định view này có "hiện hình" khi room khởi động hay không. Hãy đảm bảo có thể hiển thị ít nhất một view và view nào hiển thị sẽ được in đậm.
Một view được xác định bằng một hình chữ nhật trong room. Đây là khu vực phải được thể hiện trong view. Bạn sẽ chỉ ra vị trí của góc tận cùng bên trái, chiều rộng và chiều cao của vùng này. Thứ hai là bạn phải xác định vị trí hiển thị của vùng này trên cửa sổ màn hình (được gọi là "cổng nhìn"). Sau đó, bạn lại phải thiết lập tiếp vị trí của góc tận cùng bên trái và kích thước của cổng. Nếu bạn có một view đơn thì vị trí đó thường có tọa độ (0,0). Chú ý rằng kích thước của cổng có thể khác với view. Trong trường hợp này view sẽ được điều chỉnh để tương ứng với cổng.
Như đã nói ở trên, bạn thường muốn hiển thị game theo một object nào đó. Object này có thể xác định ở mục bên dưới cùng. Nếu có nhiều instance của object này thì chỉ instance đầu tiên được hiển thị trong view. Thường thì nhân vật có thể đi loanh quanh một chút mà không phải thay đổi view. Chỉ khi nhân vật tiến đến gần đường biên của view thì view này mới thay đổi. Bạn có thể xác định kích thước của đường biên này (nó vẫn hiển thị quanh object đó). Cuối cùng, bạn có thể hạn chế tốc độ thay đổi các view. Điều này có nghĩa là nhân vật có thể "bước ra" khỏi màn hình nhưng sự chuyển đổi sẽ diễn ra "êm ái" hơn.
Font chữ
Khi muốn thể hiện chữ trong game, bạn có thể dùng chức năng này của Game Maker với vô số kiểu dáng khác nhau. Nhưng để dùng các font khác nhau, bạn phải tạo ra nguồn font. Trong mỗi nguồn font, bạn hãy xác định một loại font xác định để có thể sử dụng trong trò chơi có dung action thiết lập font.
Khi nhấn vào Add Font, menu sau sẽ hiện ra:
Như bình thường, bạn hãy xác định một cái tên cho nguồn font. Sau đó, bạn có thể chọn cái tên đó. Cũng vậy, hãy chỉ ra kích cỡ chữ cũng như các dạng in nghiêng hay in đậm. Do các chữ lớn làm tốn bộ nhớ nên tốt hơn hết không nên để kích thước quá 32.
Một font thường bao gồm 256 ký tự được đánh số từ 0 đến 255. Nhưng nói chung, bạn chỉ dùng đến một phần nhỏ trong số này. Do đó, mặc định trong một font thường là các ký tự từ 32 đến 127. Tất nhiên, bạn có thể thay đổi dãy ký tự được sử dụng. Để xem danh sách này, có thể dùng sơ đồ ký tự trong menu Start của Windows trong thư mục Accessories/System Tools. Một số dãy tiêu chuẩn như: Normal từ 32 đến 127, All từ 0 đến 255, Digits bao gồm 10 chữ số và Letters bao gồm tất cả chữ viết hoa và chữ thường. Các dãy khác có thể được sử dụng bằng cách gõ vào trong chỉ mục ký tự đầu tiên và cuối cùng. Nếu một ký tự nào đó không nằm trong dãy, nó sẽ bị thay thế bằng một khoảng trống.
Thường thì bạn có rất nhiều font khác nhau đã được cài đặt trong máy hoặc có thể tải về từ trên mạng. Nhưng vấn đề là nếu bạn sử dụng chúng trong game rồi đưa game đó cho người khác không có font tương tự thì họ sẽ không đọc được. Để tránh điều này, hãy gửi kèm các tập tin font lạ.
Đường đi của object (Path)
Trong các trò chơi đẳng cấp cao hơn, bạn thường muốn các instance đi theo những con đường do bạn vẽ ra. Mặc dù bạn có thể chỉ ra con đường này bằng các sự kiện đặt giờ hay mã lệnh, việc này cũng khá phức tạp. Các nguồn path sẽ là biện pháp dễ dàng hơn. Ý tưởng này khá đơn giản. Bạn xác định một con đường bằng cách vẽ nó ra. Sau đó bạn có thể xác định một hành động trong sự kiện khởi tạo của object để cho object đó biết con đường xác định để đi.
Ở phía tận cùng bên trái, bạn có thể đặt tên đường như bình thường. Phía bên dưới là các tọa độ xác định con đường này. Mỗi điểm đều có vị trí và tốc độ (sp). Tùy thuộc vào cách bạn sử dụng con đường này, vị trí của nó hoặc là tuyệt đối (sẽ khiến instance đi theo tại một địa điểm xác định) hoặc tương đối (instance sẽ khởi động ở vị trí đầu tiên của con đường và từ đây sẽ đi theo nó). Tốc độ dược thể hiện như sau: Giá trị 100 có nghĩa là tốc độ ban đầu được áp dụng cho con đường ấn định đối với một instance nào đó; giá trị thấp hơn 100 sẽ làm giảm tốc độ; còn lớn hơn sẽ gia tăng tốc độ.
Để thêm một điểm nào đó, hãy nhấn nút Add. Một điểm tương tự sẽ được tạo ra. Giờ đây, bạn có thể thay đổi vị trí và tốc độ thật sự bằng cách đổi giá trị trong các hộp tương ứng. Bất cứ khi nào bạn chọn một điểm ở trong list, bạn có thể thay đổi các giá trị của nó. Nhấn vào Insert để chèn một điểm mới trước điểm hiện thời và Delete để xóa điểm hiện thời.
Ở phía bên tay phải bạn sẽ nhìn thấy con đường thật sự. Dấu màu đỏ xác định cho bạn thấy điểm được chọn hiện thời. Các dấu màu xanh là những điểm khác. Dấu ô vuông màu xanh chỉ ra vị trí bắt đầu của con đường. Bạn cũng có thể thay đổi bằng cách sử dụng chuột. Nhấn vào bất kỳ đâu trên hình ảnh để thêm một điểm nào đó. Nhấn vào một điểm sẵn có vào kéo nó đi để thay đổi vị trí. Khi giữ phím Shift trong lúc nhấn vào một điểm, bạn có thể chèn được một điểm nữa. Cuối cùng, bạn có thể nhấn chuột phải để bỏ các điểm này đi. Chú ý là bạn không thể thay đổi tốc độ theo cách này. Thường thì các điểm sẽ được chỉnh theo một bảng ô. Bạn có thể thay đổi thiết lập bảng ô ở trên mỗi thanh công cụ. Tại đây, bạn có thể xác định xem phần bảng ô đó có hiển thị hay không. Nếu muốn xác định chính xác vị trí của một điểm nào đó, hãy giữa phím Alt trong khi chèn thêm hoặc di chuyển nó.
Ngoài ra, bạn có thể thay đổi hình dạng đường đi theo hai cách. Một là dùng kiểu kết nối. Bạn có thể chọn các kết nối theo kiểu đường thẳng hoặc một đường đi "êm ái". Thứ hai là có thể chỉ ra đường đi đó có ở dạng "đóng" hay không.
Trên thanh công cụ có rất nhiều nút xử lý quan trọng. Nút đầu tiên từ trái sang thể hiện tình trạng người sử dụng muốn đóng form hay giữ lại các thay đổi. Nếu muốn bỏ các thay đổi này, nhấn nút dấu thập để đóng cửa sổ và không lưu lại thay đổi. Tiếp theo là nút Undo để bỏ đi thay đổi cuối cùng.
Tập hợp các nút công cụ sau đó sẽ cho phép bạn xóa đường đi, đảo lại trật tự, di chuyển, xoay tròn và xác định tỷ lệ của con đường. Sau đó là các nút để di chuyển view (không phải bản thân đường đi; khu vực view thực sự được chỉ ra trong thanh trạng thái ở dưới cùng) và đến trung tâm của view.
Như đã chỉ ra ở trên, bạn có thể thiết lập giá trị di chuyển (snap) và xác định xem có hiển thị grid hay không. Cuối cùng là nút để thể hiện rằng bạn muốn xem một room xác định, ví dụ như background cho path. Sử dụng nút này, bạn có thể để đường đi ở một vị trí trong room, ví dụ như một đường đua chẳng hạn, để sau đó các instance sẽ đi theo một con đường đúng. (Việc này chỉ có nghĩa khi bạn dùng các đường đi dạng tuyệt đối).
Căn chỉnh đường đi đối với các object
Để căn chỉnh đường đi tới một instance của object nào đó, bạn có thể thiết lập hành động đường đi trong một sự kiện nào đó, ví dụ như trong sự kiện khởi tạo. Trong hành động này, bạn phải xác định đường đi từ menu thả xuống và có thể đưa thêm một số giá trị.
Bạn phải chỉ ra đường đi cũng như tốc độ được xác định bằng số pixel cho mỗi step. Khi tốc độ mang giá trị dương thì instance khởi động ở đầu con đường. Nếu tốc độ mang giá trị âm thì nó sẽ khởi động ở cuối con đường. Hãy ghi nhớ rằng khi bạn xác định đường đi thì phải xác định luôn tốc độ tương đối thật sự cho tốc độ được chỉ ra. Cũng có một hành động thay đổi tốc độ trên đường đi này. Ví dụ như bạn có thể sử dụng nó để khiến cho một instance tăng tốc hay giảm tốc trên đường đi của mình. Chú ý rằng tốc độ bình thường của instance bị bỏ qua (để bằng 0) khi thực hiện đường đi. Những yếu tố như trọng lực, ma sát không làm ảnh hưởng đến chuyển động trên đường.
Tiếp theo, bạn hãy xác định “hành vi” ở cuối chặng đường đi. Bạn có thể chọn cách dừng chuyển động và kết thúc con đường này nhưng cũng có thể khởi động lại từ đầu (nghĩa là instance sẽ nhảy ngược lại vị trí bắt đầu của đường đi và thực hiện lại hành trình). Lựa chọn thứ 3 là khởi động lại từ vị trí hiện tại (nghĩa là instance tiếp tục đường đi đó nhưng từ vị trí khởi động mới, tương tự như khi đường đi bị đóng lại). Cuối cùng, bạn có thể chọn cách xoay chiều chuyển động, làm cho instance đi xuôi, đi ngược trên con đường này. Chú ý là vào cuối đoạn đường, có một sự kiện xảy ra.
Cuối cùng, bạn có thể chỉ ra xem đường đi này là tuyệt đối hay tương đối. Một đường đi tuyệt đối được thực hiện tại điểm được xác định. Instance được đặt ở vị trí khởi động và từ đó di chuyển đi. Điều này rất hữu ích, ví dụ như khi bạn có một đường đua chẳng hạn. Khi chọn lựa trạng thái tương đối, các instance bắt đầu thực hiện đường đi từ vị trí hiện tại. Điều này rất hữu ích khi một instance chuyển động trong khu vực cố định. Ví dụ: các con tàu không gian trong một trò chơi *** thiên hà nào đó có thể quay trở lại các hành tinh từ vị trí hiện tại.
Khi muốn đặt instance ở một điểm khác trên đường đi, bạn có thể sử dụng hành động thiết lập vị trí trên đường. Một vị trí trên đường đi nằm ở giữa số 0 và số 1; số 0 thể hiện vị trí khởi động và số 1 thể hiện vị trí kết thúc. Chú ý rằng trong mỗi bước đi, các hướng được tự động thiết lập đến hướng chính xác trên đường đi. Bạn có thể sử dụng tính biến thiên này để chọn định hướng chính xác cho các sprite.
Khi sử dụng các đoạn mã, bạn có nhiều khả năng hơn trong việc điều khiển cách thức mà đường đi đó được tiến hành. Có một chức năng để khởi động một đường đi đối với một instance. Biến số vị trí đường đi chỉ ra vị trí hiện tại trên đường (từ 0 đến 1 như đã nói ở trên). Biến số tốc độ trên đường đi thể hiện khả năng di chuyển nhanh, chậm trên đường. Biến số tỷ lệ đường đi có thể dùng để xác định tỷ lệ của con đường. Giá trị bằng 1 là kích thước ban đầu. Giá trị lớn hơn chỉ ra con đường được mở rộng hơn. Biến số định hướng đường đi cho thấy hướng của đường mà instance di chuyển theo các góc ngược chiều kim đồng hồ. Điều này cho phép bạn thực hiện đường đi theo một hướng khác (ví dụ như di chuyển lên, xuống chứ không phải sang trái, sang phải). Còn có một tham số khác để xác định hành vi “cuối đường”. Cuối cùng, bạn sẽ thấy có rất nhiều chức năng để xác định các đặc điểm của đường đi. Thậm chí còn có những chức năng tạo ra “đụng độ” giữa những đường đi tự do của một instance để tiến đến một mục tiêu nào đó.
Bạn có thể thắc mắc điều gì sẽ xảy ra khi một instance đụng độ với instance khác trong khi đi theo một con đường nào đó. Về cơ bản, điều tương tự sẽ xảy ra khi instance di chuyển. Khi có một instance ở dạng rắn, thì instance này được đặt trả lại vị trí trước đó. Khi cả hai instance đều không ở dạng rắn thì chúng sẽ được đặt ở vị trí trước đó. Tiếp đó, các sự kiện đụng độ được thực hiện và được kiểm tra lại xem đụng độ đó có được giải quyết hay không. Nếu không, và đồng thời instance kia thuộc dạng cứng, thì instance này sẽ dừng lại. Cũng vậy, tham số vị trí đường đi cùng không tăng lên. Khi instance gây cản biến mất thì instance đó sẽ tiếp tục theo con đường này. Để giải quyết các vụ “đụng độ”, bạn có thể dùng đến tham số vị trí đường đi. Nó sẽ duy trì vị trí trước cho đường đi và bạn có thể thiết lập vị trí đó cho tham số này để tránh tình trạng “trôi” về phía trước trong khi đi trên đường.
“Sự kiện” đường đi
Như đã mô tả ở trên, bạn có thể xác định điều gì phải diễn ra khi instance tiến đến phía cuối con đường. Vào thời điểm này sự kiện “cuối đường” xảy ra. Bạn có thể tìm thấy nó ở mục Others. Tại đây bạn có thể thiết lập các hành động. Ví dụ: bạn có thể phá hủy instance hoặc để nó khởi đầu một đường đi mới.
[Phần 5] Tự sáng tạo trò chơi với phần mềm Game Maker
Trong nhiều trò chơi, có những điều phải xảy ra đúng thời điểm nào đó. Bạn có thể làm điều này bằng cách dùng sự kiện “báo động”; nhưng khi mọi việc quá phức tạp thì cách này rất khó thực hiện. Chức năng “băng thời gian” sẽ giải quyết được vấn đề này. Trong một băng thời gian, bạn có thể xác định hành động nào phải diễn ra đúng lúc. Bạn cũng có thể dùng tất cả hành động đã có sẵn cho các sự kiện khác nhau. Khi đã tạo ra được một băng thời gian, bạn có thể áp dụng cho một instance của đối tượng.
Sau đó, instance này sẽ thực hiện các hành động trong các thời điểm đã chỉ ra. Có thể xét ví dụ sau đây. Giả sử rằng bạn muốn tạo ra một lính gác và nhân vật này phải di chuyển 20 bước về bên trái, tiến lên 10 bước, 20 bước về bên phải, lùi xuống 10 bước rồi dừng lại. Để làm được điều đó, trước hết hãy thiết kế một băng thời gian bắt đầu bằng chuyển động sang trái; tại bước thứ 20, thiết lập chuyển động tiến lên; tại bước 30, thiết lập chuyển động sang phải; tại bước 50 thiết lập chuyển động đi xuống và tại bước 60 dừng chuyển động. Bây giờ, bạn có thể áp dụng băng thời gian này cho tên lính gác và nó sẽ làm chính xác như vậy.
Ngoài ra, bạn còn dùng tính năng này để kiểm soát trò chơi của mình trên phạm vi rộng hơn. Ví dụ như tạo ra một đối tượng kiểm soát vô hình, một băng thời gian tạo kẻ thù trong một số thời điểm nào đó rồi áp dụng cho đối tượng kiểm soát này.
Để chèn một băng thời gian, chọn Add Time Line và cửa sổ sau đây sẽ hiện ra:
Trông cửa sổ này khá giống với cửa sổ các tính năng của object. Ở phía bên trái, bạn có thể đặt tên, chèn và chỉnh sửa các thời điểm trong băng thời gian. Bên cạnh đó là danh sách các thời điểm diễn ra sự kiện. Phía bên phải là danh sách các hành động để bạn lựa chọn.
Muốn chèn thời điểm diễn ra sự kiện, nhấn nút Add. Sau đó, xác định thời điểm bằng số bước đi tính từ lúc bắt đầu băng thời gian. Lúc này, bạn có thể “kéo – thả” các hành động vào danh sách. Bạn sẽ nhận thấy các nút để xóa, thay đổi hoặc nhân đôi hoạt động trong thời điểm đã chọn.
Có hai nút đặc biệt là Merge và Shift. Với Merge, bạn có thể “nhập” toàn bộ các hoạt động trong một khoảng thời gian vào một thời điểm nào đó. Với Shift, bạn có thể chuyển các hoạt động trong một khoảng thời gian lên hoặc xuống với biên độ thời gian nào đó. Nhưng nhớ rằng đừng lỡ để dấu âm vì chúng sẽ không bao giờ được thực hiện.
Còn có hai hành động liên quan đến băng thời gian:
Thiết lập một băng thời gian.
Với hành động này, bạn có thể tạo ra một băng thời gian xác định cho một instance của đối tượng. Hãy chỉ ra băng này và vị trí bắt đầu trong đó (0 thường là số bắt đầu). Bạn cũng có thể dùng hành động này để kết thúc một băng thời gian bằng cách chọn giá trị No Time Line.
Thiết lập vị trí băng thời gian.
Bạn có thể thay đổi vị trí của băng thời gian hiện tại (hoặc là tuyệt đối, hoặc là tương đối). Điều này có thể áp dụng để “nhảy” qua một số phần của băng thời gian hoặc để lặp lại một phần nào đó. Ví dụ: nếu muốn băng thời gian “quay vòng”, vào phút cuối hãy chèn hành động này vào để thiết lập vị trí về 0. Bạn còn dùng tính năng này để đợi một điều gì đó sẽ xảy ra. Hãy chèn vào để thử nghiệm, nếu không đúng thì thiết lập vị trí băng thời gian tương ứng với -1.
Mã lệnh (script)
Game Maker có một ngôn ngữ lập trình kèm theo. Nếu đã quen với phần mềm này rồi và muốn khai thác tối đa các tính năng của nó, bạn nên bắt tay vào học ngôn ngữ này. Có hai cách sử dụng. Trước hết, bạn hãy tạo ra các đoạn mã có tên. Chúng có thể được lưu lại hoặc tải về từ một tập tin nào đó. Cách thứ hai là bạn có thể chèn một hành động tạo mã (code action) vào một sự kiện bất kỳ và nhập mã vào đó. Việc chèn đoạn mã có thể tạo kết quả y như việc chèn hành động tạo mã, trừ hai điều sau: (1) Các hành động tạo mã không có tên và do đó (2) không thể sử dụng các thông số.
Các đoạn mã có thể dùng để thực hiện một công việc nhất định nào đó. Các đoạn mã này có thể nhận các biến số đầu vào (còn được gọi là thông số). Để thực hiện một đoạn mã từ bất kỳ sự kiện nào, bạn có thể sử dụng hành động tạo mã hoặc gọi mã trực tiếp. Trong hành động tạo mã, bạn hãy xác định đoạn mã cần dùng và khoảng 5 biến số. Nếu chèn một đoạn mã có sẵn, bạn có thể dùng đến 16 thông số. Mã này có thể trả lại một giá trị nào đó và việc này có thể sử dụng để thiết lập các phương pháp tính toán. Từ khóa return được sử dụng cho trường hợp này.
Để chèn một đoạn mã vào trong trò chơi, chọn Add Script, cửa sổ sau đây sẽ hiện ra với ví dụ là một đoạn mã nhỏ và hai thông số.
Thực ra đây là cửa sổ biên soạn mã đính kèm trong phần mềm. Ở ô phía góc phải trên cùng, bạn có thể xác định tên của mã. Chú ý rằng ở dưới cùng là một danh sách chỉ ra các chức năng, biến số và hằng số, giúp bạn tìm nhanh đoạn mã cần thiết. Bạn cũng có thể kích chuột 2 lần hoặc dùng tổ hợp phím Ctrl+P để thực hiện công việc tương tự. Cửa sổ soạn mã này có vô số tính năng, bạn có thể dùng các nút để gọi ra phần lớn các chức năng đó như kiểm tra lỗi cú pháp, tìm kiếm một dòng mã…
Như bạn thấy, mỗi phần trong đoạn mã đều được đánh dấu màu khác nhau. Cửa sổ soạn mã này có thể nhận biết các đối tượng đang có, biến số và các chức năng. Việc mã hóa bằng màu các đoạn của câu lệnh sẽ giúp bạn hạn chế được sai sót.
Mã lệnh là một chức năng rất đắc dụng trong Game Maker nhưng nó cũng đòi hỏi bạn phải thiết kế thật cẩn thận. Bạn có thể lưu trữ các đoạn mã trong thư viện của riêng mình để tiện gọi ra khi cần thiết với chức năng nhập mã (import script) từ thư viện vào game hoặc xuất mã (export script) từ game vào thư viện. Đây là những tập tin chữ đơn giản có đuôi .gml và tốt hơn hết là đừng chỉnh sửa chúng trực tiếp vì chúng đều có cấu trúc đặc biệt.
Khi tạo ra các đoạn mã lệnh, bạn rất dễ mắc sai sót nên luôn phải kiểm tra bằng nút tương ứng trên menu. Khi lỗi xảy ra trong quá trình thực hiện mã lệnh, phần mềm sẽ thông báo loại lỗi và vị trí của lỗi. Bạn sẽ hiếm khi gặp phải thông báo “Lỗi đột xuất xảy ra trong game” và nếu có thì đó là sự cố hệ điều hành hoặc phần cứng. Nguyên nhân thường là thiếu bộ nhớ.
Nếu muốn kiểm tra mọi thứ cẩn thận hơn bạn có thể chạy game trong chế độ gỡ lỗi (debug). Bạn có thể thấy cửa sổ như sau hiện ra:
Với chức năng Run, bạn có thể dừng game, chạy nó từng đoạn hoặc khởi động lại game. Với chức năng Watch, bạn có thể xem giá trị của các biểu thức. Sử dụng Add để nhập vào một biểu thức nào đó có giá trị được thể hiện trong mỗi bước của game. Theo cách này, bạn có thể kiểm tra trò chơi có hoạt động chính xác hay không. Với Tools, bạn sẽ tìm được thêm thông tin, ví dụ danh sách tất cả các instance trong game, các tham số của một instance, các tin nhắn mà bạn gửi đi từ mã có dùng đến chức năng thể hiện thông báo lỗi show_debug_message(str). Cuối cùng, bạn có thể ra các lệnh trong game và thay đổi tốc độ của trò chơi. Nếu thực sự muốn tạo ra game phức tạp, bạn nên học cách dùng các chức năng debug này.
[Phần 5] Tự sáng tạo trò chơi với phần mềm Game Maker
Trong nhiều trò chơi, có những điều phải xảy ra đúng thời điểm nào đó. Bạn có thể làm điều này bằng cách dùng sự kiện “báo động”; nhưng khi mọi việc quá phức tạp thì cách này rất khó thực hiện. Chức năng “băng thời gian” sẽ giải quyết được vấn đề này. Trong một băng thời gian, bạn có thể xác định hành động nào phải diễn ra đúng lúc. Bạn cũng có thể dùng tất cả hành động đã có sẵn cho các sự kiện khác nhau. Khi đã tạo ra được một băng thời gian, bạn có thể áp dụng cho một instance của đối tượng.
Sau đó, instance này sẽ thực hiện các hành động trong các thời điểm đã chỉ ra. Có thể xét ví dụ sau đây. Giả sử rằng bạn muốn tạo ra một lính gác và nhân vật này phải di chuyển 20 bước về bên trái, tiến lên 10 bước, 20 bước về bên phải, lùi xuống 10 bước rồi dừng lại. Để làm được điều đó, trước hết hãy thiết kế một băng thời gian bắt đầu bằng chuyển động sang trái; tại bước thứ 20, thiết lập chuyển động tiến lên; tại bước 30, thiết lập chuyển động sang phải; tại bước 50 thiết lập chuyển động đi xuống và tại bước 60 dừng chuyển động. Bây giờ, bạn có thể áp dụng băng thời gian này cho tên lính gác và nó sẽ làm chính xác như vậy.
Ngoài ra, bạn còn dùng tính năng này để kiểm soát trò chơi của mình trên phạm vi rộng hơn. Ví dụ như tạo ra một đối tượng kiểm soát vô hình, một băng thời gian tạo kẻ thù trong một số thời điểm nào đó rồi áp dụng cho đối tượng kiểm soát này.
Để chèn một băng thời gian, chọn Add Time Line và cửa sổ sau đây sẽ hiện ra:
Trông cửa sổ này khá giống với cửa sổ các tính năng của object. Ở phía bên trái, bạn có thể đặt tên, chèn và chỉnh sửa các thời điểm trong băng thời gian. Bên cạnh đó là danh sách các thời điểm diễn ra sự kiện. Phía bên phải là danh sách các hành động để bạn lựa chọn.
Muốn chèn thời điểm diễn ra sự kiện, nhấn nút Add. Sau đó, xác định thời điểm bằng số bước đi tính từ lúc bắt đầu băng thời gian. Lúc này, bạn có thể “kéo – thả” các hành động vào danh sách. Bạn sẽ nhận thấy các nút để xóa, thay đổi hoặc nhân đôi hoạt động trong thời điểm đã chọn.
Có hai nút đặc biệt là Merge và Shift. Với Merge, bạn có thể “nhập” toàn bộ các hoạt động trong một khoảng thời gian vào một thời điểm nào đó. Với Shift, bạn có thể chuyển các hoạt động trong một khoảng thời gian lên hoặc xuống với biên độ thời gian nào đó. Nhưng nhớ rằng đừng lỡ để dấu âm vì chúng sẽ không bao giờ được thực hiện.
Còn có hai hành động liên quan đến băng thời gian:
Thiết lập một băng thời gian.
Với hành động này, bạn có thể tạo ra một băng thời gian xác định cho một instance của đối tượng. Hãy chỉ ra băng này và vị trí bắt đầu trong đó (0 thường là số bắt đầu). Bạn cũng có thể dùng hành động này để kết thúc một băng thời gian bằng cách chọn giá trị No Time Line.
Thiết lập vị trí băng thời gian.
Bạn có thể thay đổi vị trí của băng thời gian hiện tại (hoặc là tuyệt đối, hoặc là tương đối). Điều này có thể áp dụng để “nhảy” qua một số phần của băng thời gian hoặc để lặp lại một phần nào đó. Ví dụ: nếu muốn băng thời gian “quay vòng”, vào phút cuối hãy chèn hành động này vào để thiết lập vị trí về 0. Bạn còn dùng tính năng này để đợi một điều gì đó sẽ xảy ra. Hãy chèn vào để thử nghiệm, nếu không đúng thì thiết lập vị trí băng thời gian tương ứng với -1.
Mã lệnh (script)
Game Maker có một ngôn ngữ lập trình kèm theo. Nếu đã quen với phần mềm này rồi và muốn khai thác tối đa các tính năng của nó, bạn nên bắt tay vào học ngôn ngữ này. Có hai cách sử dụng. Trước hết, bạn hãy tạo ra các đoạn mã có tên. Chúng có thể được lưu lại hoặc tải về từ một tập tin nào đó. Cách thứ hai là bạn có thể chèn một hành động tạo mã (code action) vào một sự kiện bất kỳ và nhập mã vào đó. Việc chèn đoạn mã có thể tạo kết quả y như việc chèn hành động tạo mã, trừ hai điều sau: (1) Các hành động tạo mã không có tên và do đó (2) không thể sử dụng các thông số.
Các đoạn mã có thể dùng để thực hiện một công việc nhất định nào đó. Các đoạn mã này có thể nhận các biến số đầu vào (còn được gọi là thông số). Để thực hiện một đoạn mã từ bất kỳ sự kiện nào, bạn có thể sử dụng hành động tạo mã hoặc gọi mã trực tiếp. Trong hành động tạo mã, bạn hãy xác định đoạn mã cần dùng và khoảng 5 biến số. Nếu chèn một đoạn mã có sẵn, bạn có thể dùng đến 16 thông số. Mã này có thể trả lại một giá trị nào đó và việc này có thể sử dụng để thiết lập các phương pháp tính toán. Từ khóa return được sử dụng cho trường hợp này.
Để chèn một đoạn mã vào trong trò chơi, chọn Add Script, cửa sổ sau đây sẽ hiện ra với ví dụ là một đoạn mã nhỏ và hai thông số.
Thực ra đây là cửa sổ biên soạn mã đính kèm trong phần mềm. Ở ô phía góc phải trên cùng, bạn có thể xác định tên của mã. Chú ý rằng ở dưới cùng là một danh sách chỉ ra các chức năng, biến số và hằng số, giúp bạn tìm nhanh đoạn mã cần thiết. Bạn cũng có thể kích chuột 2 lần hoặc dùng tổ hợp phím Ctrl+P để thực hiện công việc tương tự. Cửa sổ soạn mã này có vô số tính năng, bạn có thể dùng các nút để gọi ra phần lớn các chức năng đó như kiểm tra lỗi cú pháp, tìm kiếm một dòng mã…
Như bạn thấy, mỗi phần trong đoạn mã đều được đánh dấu màu khác nhau. Cửa sổ soạn mã này có thể nhận biết các đối tượng đang có, biến số và các chức năng. Việc mã hóa bằng màu các đoạn của câu lệnh sẽ giúp bạn hạn chế được sai sót.
Mã lệnh là một chức năng rất đắc dụng trong Game Maker nhưng nó cũng đòi hỏi bạn phải thiết kế thật cẩn thận. Bạn có thể lưu trữ các đoạn mã trong thư viện của riêng mình để tiện gọi ra khi cần thiết với chức năng nhập mã (import script) từ thư viện vào game hoặc xuất mã (export script) từ game vào thư viện. Đây là những tập tin chữ đơn giản có đuôi .gml và tốt hơn hết là đừng chỉnh sửa chúng trực tiếp vì chúng đều có cấu trúc đặc biệt.
Khi tạo ra các đoạn mã lệnh, bạn rất dễ mắc sai sót nên luôn phải kiểm tra bằng nút tương ứng trên menu. Khi lỗi xảy ra trong quá trình thực hiện mã lệnh, phần mềm sẽ thông báo loại lỗi và vị trí của lỗi. Bạn sẽ hiếm khi gặp phải thông báo “Lỗi đột xuất xảy ra trong game” và nếu có thì đó là sự cố hệ điều hành hoặc phần cứng. Nguyên nhân thường là thiếu bộ nhớ.
Nếu muốn kiểm tra mọi thứ cẩn thận hơn bạn có thể chạy game trong chế độ gỡ lỗi (debug). Bạn có thể thấy cửa sổ như sau hiện ra:
Với chức năng Run, bạn có thể dừng game, chạy nó từng đoạn hoặc khởi động lại game. Với chức năng Watch, bạn có thể xem giá trị của các biểu thức. Sử dụng Add để nhập vào một biểu thức nào đó có giá trị được thể hiện trong mỗi bước của game. Theo cách này, bạn có thể kiểm tra trò chơi có hoạt động chính xác hay không. Với Tools, bạn sẽ tìm được thêm thông tin, ví dụ danh sách tất cả các instance trong game, các tham số của một instance, các tin nhắn mà bạn gửi đi từ mã có dùng đến chức năng thể hiện thông báo lỗi show_debug_message(str). Cuối cùng, bạn có thể ra các lệnh trong game và thay đổi tốc độ của trò chơi. Nếu thực sự muốn tạo ra game phức tạp, bạn nên học cách dùng các chức năng debug này.
[Phần 7] Tạo đồ họa 3D 'giả cầy'
Các game 3D hiện đại đều thiết kế thế giới ảo bằng hình ảnh ba chiều và nhờ đến hỗ trợ phần cứng 3D để thể hiện các hình ảnh đó. Với một điểm nhìn cho trước, phần cứng này sẽ tạo ra hình ảnh chuẩn xác cùng với những yếu tố khác như ánh sáng, bỏ đi bề mặt ẩn (nghĩa là các đối tượng nằm khuất sau các đối tượng khác sẽ không được nhìn thấy, do đó không cần vẽ ra), cùng những hiệu ứng không gian. Việc thiết kế thế giới 3 chiều với các đối tượng 3 chiều là một việc khó và tốn thời gian. Đồng thời, việc tạo ra kết cấu logic của game như hành vi của các đối tượng, kiểm tra mức đụng độ và chuyển động của camera… cũng không đơn giản và ngốn rất nhiều nhân lực, tiền bạc.
Một câu hỏi mà bạn sẽ đặt ra là công việc này có nằm ngoài tầm với của mình không. Câu trả lời là cả “có” và “không”. Game Maker không hỗ trợ làm game loại này nhưng tạo ra được các trò chơi “có vẻ giống” 3D. Thực ra, nhiều trò chơi “giả 3D” trước và sau 1995 không dùng đến kỹ thuật 3D thật sự, ví dụ những game nổi tiếng như Đế Chế và Command and Conquer. Các nhà thiết kế đã dùng nhiều kỹ xảo để tạo cho người chơi cảm giác như hòa mình vào không gian 3 chiều vậy.
Một cảnh trong Đế chế. Các quy tắc căn bản:
Vật thể khuất sau vật thể khác là vô hình. Thường là bạn không thể nhìn xuyên qua các vật thể rắn. Vì vậy, bạn chỉ cần cho hiển thị những đối tượng có thể nhìn thấy thật sự. Quá trình này gọi là bỏ đi bề mặt ẩn. Phần cứng hỗ trợ đồ họa 3D cũng có cơ chế bỏ đi bề mặt ẩn một cách tự động, nhưng do Game Maker chỉ xử lý 2D, bạn sẽ dùng đến những kỹ thuật “giả cầy” là vẽ các sprite phản ứng với những đối tượng game (object) theo trật tự chính xác. Đối tượng nào nằm xa nhất thì vẽ trước rồi dẫn dần đến đối tượng gần nhất và các lớp nằm trước luôn “đè” lên một phần nào đó của các lớp nằm sau. Trong phần mềm này, bạn có thể làm được điều đó bằng cách thiết lập “độ dày” cho các instance khác nhau. Những instance có độ dày lớn hơn thì được vẽ trước và nằm về phía xa hơn.
Vật thể nằm xa hơn có vẻ như nhỏ hơn. Tận dụng đặc điểm thị giác này, bạn sẽ tạo ra cảm giác 3D thật hơn. Game Maker có thể làm được điều này bằng cách thay đổi kích cỡ của sprite, tùy thuộc vào khoảng cách. Hoặc bạn có thể tạo ra các sprite có kích thước khác nhau rồi dùng chức năng chỉnh tỷ lệ. Và tất nhiên, khi vật thể di chuyển càng gần đến người nhìn thì nó phải lớn hơn. Đây là một ấn tượng rất mạnh khi di chuyển trong thế giới 3D. Dù vậy, bạn vẫn nên cẩn thận. Nếu như tỷ lệ này bị tính sai thì sẽ tạo ra sự phản cảm rất lớn.
Vật thể nằm ở phía xa thì sẽ mờ nhạt hơn. Bạn có thể làm được điều này bằng cách sử dụng các sprite khác nhau cho một instance, tùy theo “độ dày” của chúng.
Vật thể nằm ở phía xa hơn có vẻ như di chuyển chậm hơn. Khi di chuyển sang phải, trái, bạn sẽ phải làm cho vật thể mất thời gian di chuyển nhiều hơn, còn khi vật thể chạy thẳng hướng về phía bạn thì có vẻ như nó không thay đổi vị trí trên màn hình. Nói chung, tốc độ di chuyển theo chiều dọc nên chậm hơn khi theo chiều ngang.
Vật thể luôn có bóng. Rất khó đổ bóng lên một vật thể khác nhưng bạn có thể đổ bóng dễ dàng lên sàn nhà. Và ngay cả khi không có bóng, bạn cũng nên để những điểm tối quanh chân vật thể để tạo ấn tượng nó đang đứng trên sàn nhà. Hãy đảm bảo những chiếc bóng này luôn luôn nối theo gót chân của vật thể. Ví dụ như ba hình dưới đây. Với hình đầu tiên, bạn không thể xác định được vị trí của đối tượng. Còn cái bóng của hình thứ 2 làm cho bạn biết chỗ mà nhân vật đang đứng. Hình thứ 3 nom giống như nhân vật đang nhảy lên.
ghj Các đường thẳng song song có vẻ như sẽ gặp nhau ở một điểm nào đó, ví dụ như hai lề đường. Nói một cách chính xác thì tầm nhìn đã tạo ra một góc chiếu và theo một mức độ nào đấy, thị giác đã “bóp méo” vật thể. Nhưng điều này cần được áp dụng để tạo ra không khí 3D. Xét hai hình dưới đây:
Hình bên dưới cho thấy mặt chiếu không có góc. Các dòng kẻ thẳng là những đường song song. Hình bên phải dùng đến sự chuyển đổi góc và do đó tạo ra cảm giác các đường thẳng sẽ gặp nhau tại một điểm nào đó. Hình chiếu góc là yếu tố rất quan trọng khi muốn làm game 3D nhưng không may là chẳng dễ gì khi làm được điều này bằng các sprite. Để hạn chế điều này, bạn có thể dùng đến các góc 45 độ. Nếu nhìn từ bên cạnh, các hình ảnh trông cũng chấp nhận được. Nói chung, hiệu quả của các đường song song không ấn tượng nhưng cũng làm cho người nhìn không bị rối mắt. Đây là điều cơ bản của những trò chơi giả 3D.
rg Nếu nhìn kỹ bạn sẽ thấy các đường thẳng vẫn song song (điều này là sai) nhưng tạo ra cảm giác 3D hơn. Tạo ra hình ảnh kiểu “giả cầy” mà vẫn ngon này là điều hoàn toàn có thể trong tầm tay của Game Maker và sau đây, chúng ta hãy bắt tay vào thực hiện.
Tạo hình thị sai
Như đã nói ở trên, vật thể nằm ở phía xa thì di chuyển chậm hơn và bạn có thể áp dụng điều này với các cảnh nền cuộn sang các bên và những đối tượng game dạng tĩnh.
Với Game Maker, bạn đã biết cách chèn hình nền (background) vào các room. Thường thì một room chỉ có một hình nền nhưng bạn có thể chèn nhiều hơn thế. Và để nhìn thấy các background, chúng cần phải “trong suốt” một phần nào đó hoặc phủ lên một phần của room. Bằng cách đặt tốc độ của nền thấp hơn với tốc độ thấp hơn, bạn sẽ tạo cho người chơi cảm giác chúng ở xa tít tắp. Hãy thử ví dụ sau đây với một chiếc xe đang chạy bên lề đường (đừng xét đến chất lượng đồ họa mà chỉ xét đến hiệu ứng của nó thôi).
Trước hết, ta sử dụng 2 nền. Nền đầu tiên tạo ra một vài đỉnh núi phía xa xa.
Nó sẽ được đặt lên phần trên của room và chạy sang trái với tốc độ chậm (1). Các đỉnh núi được “lát” theo chiều ngang chứ không theo chiều dọc. Còn nền thứ hai thể hiện một con đường rất nhỏ được đặt ở tận cùng của room và di chuyển nhanh hơn (4) và cũng chạy theo phương nằm ngang. Bây giờ chúng ta sẽ đặt một chiếc xe lên đường nhưng nó không nhất thiết phải di chuyển vì con đường đã di chuyển nên sẽ tạo ra ảo giác là chiếc xe này đang chạy. Vì con đường chuyển động nhanh hơn rặng núi nên bạn sẽ có cảm giác rặng núi này đang ở phía xa xa.
Để tạo thêm chiều sâu vào bức tranh này, chúng ta có thể đặt một vài cái cây với một số kích thước khác nhau. Với mỗi cái cây, chúng ta tạo ra một object. Hãy đảm bảo là cái cây nhỏ nằm phía sau cây trung bình và cây này phải nằm sau cây lớn. Cây lớn được đặt sát mép đường và có tốc độ như con đường này (4). Cây trung bình đặt xa hơn và có tốc độ là 3. Cuối cùng, cái cây nhỏ có tốc độ là 2. Hãy đặt hai cái cây cùng loại ở những vị trí thích hợp để làm sao khi chúng biến mất ở phía bên trái thì chúng sẽ xuất hiện lại ở phía tay phải (cùng với một chút ngẫu nhiên để tạo cảm giác đa dạng hơn). Kết quả đạt được như sau:
Bạn có thể tìm thấy phần demo này trong file parallax.gm6. Tất nhiên đây chưa phải là một trò chơi vì chúng ta chưa cho người chơi rồ ga để phóng đi hay thêm các chướng ngại vật trên đường…
Tạo hình thị sai là một phương pháp rất hữu dụng, ví dụ như game nền platform (trong đó nền game được cuộn sang trái, phải hoặc lên xuống theo đường đi của nhân vật). Trong trường hợp trên, bạn nên đặt tốc độ của các nền chuyển động giống như tốc độ của nhân vật mà người chơi điều khiển.
Tạo hình chiếu song song
Mặc dù các game ba chiều thực sự phải dùng đến các phép chiếu góc, trước hết chúng ta hãy bàn đến các hình chiếu song song. Trong một hình chiếu loại này, kích cỡ của đối tượng game vẫn không đổi và không phụ thuộc vào khoảng cách. Các đường thẳng song song vẫn giữ nguyên trong tình trạng song song. Điều này khiến bạn dùng sprite dễ dàng hơn vì các sprite đều có kích thước cố định. Nhưng một điều rõ ràng là cách này sẽ “bóp méo” cảnh. Để hạn chế tình trạng “méo mó” này, hãy đảm bảo người chơi không thể nhìn thấy các đối tượng nằm ở phía xa. Chúng ta có thể làm được điều đó bằng cách đặt góc nhìn từ trên xuống dưới (thường là góc 45 độ). Vì vậy, những hình vuông sẽ trông giống hình chữ nhật.Một hình nền sẽ trông như sau:
Bạn có thể dễ dàng tạo ra hình ảnh như vậy. Chúng ta đơn giản là xác định tỷ lệ theo chiều dọc.
Chúng ta sẽ thực hiện phương pháp này với một demo nhỏ, trong đó người chơi điều khiển một nhân vật có thể đi qua một khu vực đầy cây cối. Có ba thứ cần chú ý (1) thực hiện đúng yêu cầu bỏ đi bề mặt ẩn (vẽ nhân vật này trước khi vẽ cái cây để có thể bị lấp trong bóng cây đó); (2) đảm bảo tốc độ của nhân vật đúng như quy luật thông thường, ví dụ như sang phải sang trái phải nhanh hơn tiến hoặc lùi; (3) điều quan trọng nhất là tạo ra các vụ đụng độ thật chính xác.
Hãy bắt đầu bằng việc bỏ đi bề mặt ẩn.
Như bạn đã biết, mỗi sprite đều có một vị trí gốc và hãy mặc định nó ở góc tận cùng bên trái của hình sprite. Khi đặt instance của object tại một điểm xác định nào đó, chúng ta luôn đặt nó cùng với điểm gốc. Khi thực hiện công việc trong thế giới 3D, điều dễ nhất là xác định gốc của nó tại vị trí đang đứng. Như vậy, chúng ta đặt gốc của tất cả các sprite cho vị trí đó. Ví dụ như đối với một nhân vật đang đi trong rừng, bạn có thể xác định sprite như sau:
Chú ý rằng chúng ta có thể thiết lập một bounding box như dưới đây. Nhân vật được thể hiện bằng 4 sprite khác nhau với các hướng đi khác nhau. Một điều rõ ràng là chúng ta phải đặt cả 4 hình này với cùng vị trí gốc và chung một bounding box.
Và lúc này, hãy thực hiện “độ sâu” của hình ảnh. Trong nhiều trường hợp, thứ tự các đối tượng phải được vẽ giống như thứ tự mà chúng xuất hiện trên nền. Vì vậy, bằng cách xác lập vị trí gốc như trên, trục y của instance xác định vị trí đó. Instance có tọa độ y thấp (gần ở phía trên đỉnh của cửa sổ) cần phải vẽ trước instance có tọa độ cao (và do đó “độ sâu” thấp hơn). Bạn có thể làm điều này bằng cách để tọa độ đó mang giá trị âm.
Đối với các object tĩnh, ví dụ như cây cối, chúng ta chỉ cần làm việc này một lần trong sự kiện khởi tạo. Còn đối với các object động, ví dụ như nhân vật trong ví dụ này, chúng ta phải làm điều đó trông từng bước một. Tốt hơn hết là hãy dùng sự kiện End Step để đảm bảo tất cả các sự kiện khác đều được thực hiện trước khi “độ sâu” này được áp dụng.
Thứ hai là sự chuyển động của nhân vật. Chúng ta có thể làm được điều này bằng cách thông thường với các phím mũi tên. Trong mỗi sự kiện phím mũi tên, hãy đặt chuyển động theo hướng chính xác và đặt đúng sprite cho instance. Cũng vậy, để tạo hình ảnh động của sprite trong khi di chuyển và không tạo hình động trong khi nhân vật đứng yên, chúng ta có thể dùng đến biến số image_speed. Biến số này xác định tốc độ mà các hình ảnh đơn trong tập hợp ảnh làm thành hình động được thể hiện. Số 1 sẽ khiến ảnh động này di chuyển với tốc độ bình thường còn số 0 sẽ làm ngưng chuyển động. Bạn có thể dùng giá trị -1 cho các hình đơn để chúng không thay đổi trong khi đã di chuyển theo đúng 1 hướng nào đó.
Chúng ta thiết lập giá trị tốc độ bằng 0 cho thời điểm người chơi thả phím này ra. Và bạn cũng có thể làm điều này khi có sự kiện đụng độ xảy ra.
Nhưng chú ý điều quan trọng mà chúng ta phải quan tâm trong khía cạnh 3D là sự khác nhau về tốc độ. Đối với chuyển động theo phương nằm ngang, bạn có thể dùng tốc độ 3 còn theo chiều thẳng đứng là 2. Bạn phải thử nghiệm với các con số khác nhau để tạo ra hiệu ứng tốt nhất cho trò chơi của mình.
Điều cuối cùng và cũng là điều quan trọng nhất là các sự kiện đụng độ. Thường thì sự kiện này xảy ra khi các sprite “phủ” nhau một phần. Điều này rất dễ với game 2D nhưng không hề đơn giản với game 3D. Vì vậy, chúng ta cần một cách khác để xác định việc này. Ví dụ: chỉ khi chân của nhân vật chạm vào gốc cây thì mới diễn ra sự kiện đụng độ thật sự. Cách dễ dàng để làm được điều này là xác định một bounding box cho tất cả các sprite và không dùng chức năng kiểm tra đụng độ chính xác. Một đụng độ chỉ được thiết lập khi các bounding box “phủ” nhau một phần và đó mới chính là điều chúng ta cần.
Đối với các hình phức tạp hơn, bouding box này không thể chỉ ra chính xác được “vùng đụng độ”. Và trong trường hợp này, chúng ta có thể dùng đến một tính năng khác của Game Maker.
Một object có thể có “vỏ ngoài” khác so với sprite để thể hiện các instance. Do đó, bạn hãy tạo một sprite thứ hai có hình của “vùng đụng độ” như yêu cầu và dùng làm “vỏ ngoài” cho vụ đụng độ này. Đó chính là các nguyên liệu cần thiết để làm game 3D. Để mọi thứ trông có vẻ xinh xắn hơn, bạn hãy dùng đến các hình lát làm nền, ví dụ như kích cỡ 48x24 chẳng hạn, hay thêm vào những bức tường gồ ghề cho nền này. Sau đó, bạn có thể dùng đến một kỹ thuật tiêu chuẩn mà theo đó hãy xác định một object dạng tường “vô hình” rồi đặt những instance này lên mặt trên của tường. Như vậy, nhân vật sẽ dừng lại vì nó sẽ đụng vào những instance vô hình trong khi người chơi chỉ nhìn thấy hình nền tuyệt đẹp ở phía sau.
Công đoạn cuối cùng là tạo room. Chúng ta sẽ dùng đến một cảnh và tạo ra chiều sâu với kích cỡ 400x200. Chú ý bảng thông tin nên đặt ngang ở dưới màn hình để không gian game trông có vẻ rộng.
Xác định tỷ lệ hình ảnh
Khi dùng đến hình chiếu song song, nếu giữ cảnh có độ cao ở mức nào đó từ mặt đất lên theo một hướng xác định và chỉ thể hiện một phần nhỏ trong thế giới đó thì phương pháp này là ổn. Nhưng nếu muốn tạo ra góc nhìn của người thứ nhất hoặc nhìn sát hơn xuống mặt đất thì chúng ta phải cần đến phép chiếu góc. Kích cỡ của vật thể phải nhỏ hơn khi ở phía xa. Nhưng làm thế nào để có được điều đó? Trong phần tạo hình thị sai, chúng ta đã xét đến ví dụ về ba cái cây có kích cỡ khác nhau. Chúng sẽ thể hiện tốt khi những cái cây này giữ khoảng cách cố định. Nhưng trong thế giới 3D, người chơi có thể tiến đến gần chúng và do đó, kích thước này cần phải thay đổi liên tục.
Chúng ta có thể tạo ra vô số sprite khác nhau, mỗi sprite một kích thước. Tuy nhiên, việc này sẽ làm tốn bộ nhớ. Bạn có thể nghĩ rằng sẽ làm việc này cho các vật thể quan trọng để tạo ra ấn tượng tốt nhất. Nhưng chúng ta phải làm việc này với vô số sprite khác nữa.
Trước hết, chúng ta cần có một sprite cho cái cây và chỉ dùng một sprite. Nếu thích đụng độ với cái cây, bạn có thể đặt vị trí gốc tạo gốc cây. Các đặc điểm của sprite này được thể hiện như dưới đây:
Sau đó, bạn tiếp tục dùng đến hình rặng núi để làm nền nhưng lần này là không cuộn và dùng đến room lớn với độ rộng 2000. Đặt nhân vật chính ở giữa phần dưới của room và dùng kích thước cảnh nhìn (view) là 480x320 để giữ nhân vật này ở giữa bằng cách thiết lập biên giới của view để “đi theo” nhân vật như sau:
Nhân vật sẽ di chuyển từ trái sang phải khi người chơi nhấn phím mũi tên trái, phải. Chúng ta phải tránh để họ di chuyển quá xa về hai bên. Khi ghi điểm, chúng ta dùng thời gian mà nhân vật “sống”. Vì vậy, trong sự kiện Step của người chơi, chúng ta thiết lập giá trị 1 cho điểm số. Khi người chơi đụng với gốc cây là chúng ta hiển thị danh sách những người ghi điểm cao nhất và khởi động lại game. Điều còn lại phải giải quyết là cái cây. Có 3 yếu tố cần phải xử lý là kích thước, vị trí của màn hình và độ sâu. Những cái cây sẽ xuất hiện tại tung độ 180. Trong sự kiện End Step, chúng ta chỉnh tỷ lệ sprite dựa trên tung độ và có thể thay đổi biến số image_xscale và image_yscale, như dưới đây:
Bạn có thể áp dụng điều này để xoay hoặc chiếu hình sprite nhưng chúng ta không cần đến chức năng đó. Điều thứ hai là độ sâu. Trong sự kiện Step, hãy đặt độ sâu này với giá trị âm. Điều này có nghĩa là cái cây tiến gần đến phần dưới của màn hình (với tọa độ y tăng dần và gần người chơi hơn) hoặc ra xa màn hình tùy theo ý của bạn. Nhưng lưu ý đặt “độ sâu” thích hợp cho nhân vật để có vị trí chính xác giữa các lùm cây.
Điều cuối cùng là phải kiểm soát sự di chuyển của nhân vật và sẽ khó khăn hơn bạn tưởng tượng. Chúng ta có thể để các vòm lá này di chuyển xuống liên tục và do đó tăng tốc độ theo chiều dọc. Cũng vậy, các vật thể di chuyển về các cạnh bên nếu tiến đến gần hơn (do các đường thẳng song song có vẻ như sẽ gặp nhau ở một điểm nào đó). Vì vậy, dựa trên vị trí của cái cây so với điểm giữa của cảnh nhìn, chúng ta phải điều chỉnh tốc độ theo chiều ngang. Bạn có thể thực hiện được bằng đoạn mã sau với các con số thử nghiệm.
Để hoàn thiện trò chơi, chũng ta cần phải thêm một số thứ khác như hủy nó đi khi nó biến mất ở dưới màn hình và thêm object điều khiển để xử lý sự xuất hiện của những cái cây này.
Bạn có thể dùng cơ chế tương tự để tạo ra một trò chơi bắn súng với góc nhìn người thứ nhất. Điều này sẽ được nói kỹ hơn ở kỳ sau.
[Phần 8]Tạo đồ họa 3D 'giả cầy'
Làm tương tự đối với hình nền, chúng ta có được kết quả sau:
Những hình nền như vậy có thể tạo ra dễ dàng với Game Maker. Trước hết, hãy tạo ra một nền có các ô lát rồi chỉnh sửa nền này, phóng to các bức vẽ và quay nó theo một góc 45 độ và cuối cùng co lại theo chiều dọc 50%. Nếu không, bạn có thể dùng một tập hợp các ô lát nền đã được tạo theo hình chiếu song song. Trong phần chỉnh sửa room, hãy dùng một mạng lưới hình chiếu song song sẵn có.
Ưu điểm của góc nhìn giả 3D so với góc nhìn thông thường là bộ não của chúng ta ngay lập tức chuyển đổi các hình thoi đó thành hình vuông dưới một góc nhìn nào đó và điều này sẽ tạo ra hình ảnh 3 chiều. Rõ ràng là bạn vẫn phải bóp méo góc nhìn do kích cỡ của vật thể không đổi theo khoảng cách. Do đó, bạn có thể dùng kỹ thuật hạn chế tầm nhìn để tránh các sai sót quá lộ.
Khi đã có một hình nền đẹp, bạn sẽ đặt được các vật thể lên đó. Những vật thể này cũng cần có dáng vẻ 3D từ góc nhìn 45 độ. Việc tạo ra các vật thể kiểu này không hề đơn giản và thường là công đoạn tốn thời gian nhất.
Mỗi vật thể đều có bóng đổ trên sàn và chú ý rằng cái bóng này rất quan trọng. Bóng sẽ dùng để phát hiện các “đụng độ” hay nói một cách khác là được dùng làm “mặt nạ” đụng độ. Vì vậy, đối với mỗi vật thể, bạn cần phải làm hai sprite: hình của vật thể thật sự và “mặt nạ” của cái bóng. Tốt nhất nên tạo vị trí gốc của sprite và đặt “mặt nạ” này ở chính giữa cái bóng. Ví dụ như ở dưới đây là hình chi tiết dạng “tường” có thể dùng làm một mê cung giả 3D và “mặt nạ” bóng tương ứng. Dấu gạch chéo là vị trí gốc. “Mặt nạ” trong trường hợp này có độ lớn chính xác bằng một mặt trong hình.
Bằng cách xác định đụng độ trên cái bóng, các sprite được chồng lên nhau, miễn là các bóng đổ không đè lên nhau và đây chính là điều mà chúng ta cần. Ví dụ, khi một quả bóng di chuyển trên các khối đá, các sprite có thể chồng lên nhau; nhưng cuộc “đụng độ” với một bức tường diễn ra khi bóng của quả bóng đụng vào bóng của bức tường.
Như trong trường hợp tạo hình chiếu song song, chúng ta đặt “độ sâu” của mỗi instance là –y. Theo cách này, các instance được vẽ theo một trật tự chính xác.
Dù vậy, vẫn có một khó khăn là khi tạo room, các sprite không được vẽ theo trật tự này. Điều này khiến cho việc tạo cảnh chính xác trở nên khó khăn. Tốt nhất là nên bắt đầu theo nguyên tắc từ trên xuống và dùng chức năng phân loại instance bằng tọa độ y.
Cuối cùng là phần chuyển động. Do góc nhìn, hướng chuyển động theo chiều ngang nên tăng gấp đôi so với chiều dọc. Cũng vậy, khi sử dụng các phím mũi tên để định hướng chuyển động, bạn nên để các vật thể di chuyển chéo hơn là chiều dọc hay ngang.
Một ví dụ về làm game giả 3D
Chúng ta có thể xem ví dụ isometric.gmd. Bạn có thể tìm thấy tập tin này tại thư mục threed/example trong file nén 3D.zip, có thể download tại diễn đàn của Game Maker. (Bạn chỉ cần nhấn chuột vào Download rồi lưu tập tin, giải nén và sử dụng). Nhưng chú ý là tập tin này chạy trên phiên bản cũ gmaker.exe trong tập tin nén gmaker52.zip (download bản cũ tại đây).
Đầu tiên, tốt hơn hết là bạn thiết kế mê cung trên giấy và điều này là rất khó trong khi tạo room. Sau đó, tạo một nền phủ lên toàn bộ khu vực mê cung.
Tiếp theo là công đoạn tạo các sprite. Như đã nói ở trên, chúng ta cần hai sprite cho mỗi vật thể: hình thật sự và “mặt nạ” để kiểm tra “đụng độ”. (Thực ra, chúng ta có thể dùng một “mặt nạ” chung cho rất nhiều vật thể). Hãy đảm bảo mỗi sprite được vẽ gọn gàng trên sàn và vị trí gốc được đặt chính giữa mặt nạ bóng.
Để làm cho mọi thứ đẹp hơn, chúng ta nên thêm vào một cánh cổng. Cổng này gồm 3 phần: trụ trái, phải cao hơn tường và có màu khác. Chúng cũng dùng đến mặt nạ giống như những bức tường khác. Phần cánh cổng thì khác, nó bao gồm một khối cao hơn nhưng không cần đến mặt nạ vì quả bóng có thể di chuyển ở bên dưới. Nhưng chúng ta vẫn cần đặt vị trí gốc ở trung tâm của cái bóng (nếu không, chiều sâu của nó sẽ bị sai).
Đối với mỗi chi tiết cố định, chúng ta đặt độ sâu trong sự kiện khởi tạo. Đối với quả bóng, hãy đặt các chỉ số trong sự kiện End Step. Phần còn lại của game là một trò chơi mê cung đơn giản. Khi nhấn một phím mũi tên, chúng ta có thể di chuyển quả bóng đi theo chiều chéo góc, giả định là vị trí mới đến không xảy ra đụng độ. Khi quả bóng và cái bóng của nó đụng vào một lá cờ (chính là cái bóng của lá cờ) thì cuộc chơi mê cung này kết thúc.
Các tham số chung. Danh sách các sprite. Việc tạo ra các room lúc này đòi hỏi nhiều công sức hơn. Bạn phải đặt tất cả các chi tiết dạng tường một cách chính xác và thực hiện từ trên xuống dưới. Hãy dùng chức năng sắp xếp các instance theo tọa độ y nếu như bị sai và dùng một mạng carô 16x8 giả 3D để chỉnh các instance một cách chính xác. Trong quá trình làm, bạn cũng có thể xóa những instance nằm ở lớp dưới vì như thế sẽ dễ sắp đặt các instance hơn.
Có một xảo thuật cho bản demo này là khi giữ phím cách (Space), bạn có thể nhìn thấy quả bóng lăn xuyên qua tường. Điều này hết sức hữu dụng khi một vật thể di chuyển có thể biến mất hoàn toàn đằng sau các vật thể khác và bạn có thể thực hiện theo cách sau:
Tạo ra một vật thể khác, gọi là “quả bóng trong suốt” và có độ sâu là -100000 (nằm trên tất cả các vật thể khác). Khi nhấn phím cách, một instance của vật thể này được tạo ra và khi thả phím, vật thể này sẽ bị hủy đi. Hãy đảm bảo vật thể này có cùng vị trí như quả bóng thật sự kia với cùng sprite, nhưng đặt giá trị alpha là 0,2. Kết quả là chúng ta có được một hình “trong suốt” của quả bóng ngay trước bức tường.
Bạn hãy thử chạy chương trình gmaker.exe phiên bản 5 rồi mở đường dẫn đến tập tin isometric.gmd. Dùng công cụ Run để chạy trò chơi này và 4 phím mũi tên để di chuyển quả bóng.
Các chú ý thêm
Bạn có thể tận dụng các Resource ngay trên trang Game Maker hoặc nhiều trang khác để làm phong phú thêm thế giới trò chơi của mình.
Nói chung, các trò chơi giả 3D rất thích hợp đối với nhiều trò chơi. Ứng dụng lớn nhất của kỹ thuật này là tạo ra vẻ ngoài hấp dẫn cho game với “giá rẻ”. Có rất nhiều nguồn hình ảnh ở trên mạng, bạn chỉ cần gõ từ khóa “isometric tiles” vào trang tìm kiếm như Google hay Yahoo là có thể tìm được. Dưới đây là một số kết luận để quá trình tạo không gian giả 3D được tốt đẹp:
- Khi không thể “đi” sau những vật thể nào đó (như núi non hay rừng rậm), tốt hơn hết là bạn nên vẽ chúng trên nền rồi dùng một số vật thể “vô hình” để tránh việc các vật thể di chuyển có thể đè lên chúng.
- Khi một vật thể trải dài trên nhiều ô lát (tile), hãy chia nó ra thành nhiều phần nhỏ để tránh các rắc rối với độ sâu.
- Luôn phải đặt vị trí gốc ở mặt chiếu đứng của vật thể. Nhưng ví dụ như một con chim đang bay có vị trí gốc cách khá xa nó thì không nhất thiết phải làm.
- Trong một số ít trường hợp, mối quan hệ về độ sâu giữa hai vật thể còn phức tạp hơn nữa và có thể dùng một vài dòng lệnh.
[Phần 9] Làm game bắn súng góc nhìn người thứ nhất
hực ra môi trường của game là 2D, nhưng với kiến thức làm đồ họa 3D “giả cầy” như đã trình bày trong các kỳ trước, bạn có thể tạo không gian có chiều sâu. Do trong giai đoạn đầu này, phần đồ họa không quan trọng nên chưa cần đến các sprite đẹp. Tất cả các đối tượng như người chơi, kẻ thù, đạn… đều được thể hiện bằng bảng màu đơn giản. Khi đã đăng ký thành viên, bạn có thể xem ví dụ fps0.gm6 trong tập tin examples được giải nén sau khi tải tại đây.
Chúng ta sẽ tạo ra 2 object dạng tường, 1 theo chiều dọc, 1 theo chiều ngang, đồng thời tạo một object dạng tường cơ sở obj_wall_basic. Đây chính là object “mẹ” của các object dạng tường khác mà sau này chúng ta sẽ tạo mới. Việc này sẽ khiến cho các công đoạn phát hiện đụng độ và vẽ hình trở nên dễ dàng hơn. Các object dạng tường không có hành vi và tất cả các object loại này đều thuộc dạng rắn. Do đó, object dạng tường nằm ngang được xác định như dưới đây
Đối tượng tiếp theo mà chúng ta phải tạo ra là object mô tả người chơi. Ở đây, chúng ta thể hiện bằng một hình tròn nhỏ màu xanh (đánh dấu bằng một chấm đỏ ở một phía để có thể nhìn ra hướng di chuyển). Đây là yếu tố quan trọng duy nhất trong bản 2 chiều và không thích hợp trong bản 3D. Trong sự kiện End Step, đặt image_angle cho direction để điểm màu đỏ chỉ đúng hướng. Lúc này cần xác định chuyển động: để tạo chuyển động êm ái, chúng ta không cho bắt đầu và kết thúc đột ngột. Trong sự kiện Keyboard của phím Up (mũi tên đi lên), nhập vào mã lệnh sau:
Như vậy, tốc độ sẽ tăng dần dần cho đến khi đạt mức tối đa là 2. Trong sự kiện khởi tạo, đặt va chạm bằng 0,2 để khi người chơi thả phím Up, tốc độ của đối tượng sẽ giảm xuống lần nữa. (Nhưng bạn có thể chơi nhanh hơn, gần đến tốc độ tối đa và đặt va chạm đến hiệu ứng mà mình thích). Trong sự kiện phím Down ta cũng làm tương tự nhưng với hướng ngược lại. Còn phím Left hay Right, chúng ta cũng đơn giản tăng hoặc giảm hướng chuyển động. Cuối cùng, trong sự kiện đụng độ với đối tượng obj_wall_basic, ta cho ngừng chuyển động (điều này khá hạn chế nhưng chúng ta sẽ giải quyết trong bước sau). Do các bức tường khác đều có obj_wall_basic là gốc và chúng ta chỉ cần xác định một sự kiện đụng độ.
Cuối cùng, bạn sẽ tạo một level với các vùng khác nhau. Chú ý rằng thiết kế level càng cẩn trọng bao nhiêu thì gameplay sẽ càng thú vị bấy nhiêu. Còn trong ví dụ này, room được giới hạn như sau:
Bước 2: Chuyển sang game 3D
Có lẽ đây là phần quan trọng nhất. Chúng ta sẽ chuyển trò chơi 2D ở trên sang đồ họa 3D hấp dẫn hơn. Trong đó, object mô tả người chơi trở thành đối tượng quan trọng nhất. Trong sự kiện khởi tạo, chúng ta khởi động chế độ 3D bằng các dòng lệnh sau:
Dòng lệnh đầu tiên có chức năng khởi động chế độ 3D. Dòng thứ 2 xác định tình trạng bỏ đi bề mặt ẩn, điều này có nghĩa là object nằm sau các đối tượng khác đều không hiển thị và đây chính là điều bạn cần trong trò chơi 3D. Dòng thứ 3 thể hiện rằng chúng ta không dùng đến các nguồn ánh sáng. Dòng thứ 4 xác định không có tình trạng cắt xẻ xảy ra. Điều này hơi khó hiểu. Trước hết, bạn cứ hình dung vẽ một hình đa giác trong không gian thì nó có hai mặt và tình trạng cắt xẻ chỉ xảy ra trên một mặt (được xác định bằng thứ tự của các điểm ***p). Nếu thực hiện cẩn thận thì điều này sẽ giúp tiết kiệm thời gian vẽ, nhưng khi các bức tường được nhìn từ cả hai phía thì đây không phải là điều mà chúng ta muốn. Thực ra, 3 dòng này không cần thiết vì đã được mặc định. Cuối cùng, chúng ta thiết lập phần điều chỉnh kết cấu để khi tiến đến gần bề mặt nào đó, chúng ta vẫn thấy bề mặt đó mịn. (Bạn cũng có thể thực hiện điều này trong phần thiết lập tổng quát).
Để đảm bảo các sự kiện của đối tượng người chơi được thực hiện trước các sự kiện của đối tượng khác, chúng ta đặt độ sâu là 100 (vì các object được thực hiện theo thứ tự độ sâu giảm dần). Đồng thời, chúng ta bỏ đi sự kiện End Step đã từng tạo dựng trong bản 2D như đã nói trên vì sau này có thể nó sẽ gây trục trặc.
Việc tiếp theo là tân trang, tô điểm cho các bức tường và lúc này bạn cần tận dụng một số kết cấu và đưa về kích thước 128x128. Tốt hơn hết là đặt các kích cỡ là bội và ước của con số này (như 64, 128, 256) để chúng có thể chỉnh vừa với nhau. Dưới đây là tường, trần và nền nhà.
Chúng ta thêm các bức tường này để làm nguồn hình nền cho game và cần xác định tọa độ của chúng. Bạn thiết lập được các thông số này trong sự kiện khởi tạo của mỗi object tường riêng lẻ. Ví dụ, để tạo một bức tường ngang, có thể đưa đoạn mã sau vào sự kiện khởi tạo:
Dòng cuối cùng cần một chút giải thích để dễ hiểu. Chức năng background_get_texture () trở lại chỉ mục bề mặt tương ứng với nguồn hình nền đã chỉ ra. Chúng ta sẽ sử dụng nền này sau khi chỉ ra sprite được dùng để vẽ tường và đặt đoạn mã tương tự vào sự kiện khởi tạo cho tất cả các object dạng tường.
Để vẽ một bức tường, trong sự kiện khởi tạo của đối tượng obj_wall_basic, ta đưa vào đoạn mã sau:
Các mã lệnh này sẽ vẽ một bức tường và sử dụng những giá trị mà chúng ta đã thiết lập trong các sự kiện khởi tạo. Hai thông số cuối xác định bề mặt được lặp lại chỉ một lần trong cả hai hướng. Chúng ta sẽ thêm sàn nhà và trần nhà của room trong sự kiện Draw của đối tượng Camera và chèn vào đoạn mã sau:
Tại đây có 3 phần. Trong phần một, chúng ta đặt theo góc để có thể nhìn xuyên suốt room, từ vị trí (x,y,10). Điểm mà chúng ta nhìn theo khá phức tạp nhưng nó đơn giản là một điểm nằm trước một bước theo hướng camera. Cuối cùng, ta xác định hướng di chuyển lên của camera là trục z (0,0,1). Phần thứ hai, ta đặt alpha bằng 1 để tất cả các object đều ở dạng rắn. Đồng thời, đặt màu theo sắc độ trắng vì điều này rất quan trọng. Các kết cấu thực sự bị trộn lẫn với màu hiện tại. Đây là một tính năng rất quan trọng (ví dụ như bạn có thể tô màu đỏ cho trần nhà chẳng hạn). Nhưng thường thì bạn muốn đó là màu trắng. (Màu mặc định là đen, do đó, nếu không thay màu thì toàn bộ thế giới game sẽ là màu đen).
Trong phần thứ 3 chúng ta vẽ sàn và trần (với độ cao 32), có sử dụng đến các kết cấu chính xác. Kết cấu này phải được lặp lại nhiều lần trên trần nhà chứ không phải bị kéo giãn ra khắp bề mặt.
Bước 3: Tạo cảm giác ấn tượng hơn
Trong phần này, chúng ta sẽ tiến hành cải thiện “trò chơi” đã sáng tạo ra trong phần trước. Đầu tiên, chúng ta thêm vào một vài biến số bằng cách dùng nhiều loại tường khác nhau, sau đó biến đổi các thiết kế về level.
Tạo các bức tường khác nhau
Thế giới game mà chúng ta vừa thiết kế trông khá tẻ nhạt vì các bức tường trông y sì nhau và điều này khiến cho game thủ khó xác định mình đang ở đâu. Giải pháp cho rắc rối này lại khá đơn giản – bạn chỉ cần thêm một số kết cấu khác cho trò chơi và các object dạng tường nữa.
Thiết kế level tốt hơn
Level hiện tại có một số rắc rối: các bức tường trông khá phẳng vì bạn có thể nhìn thấy cả hai cạnh của chúng và điều này nên tránh; những khu vực game trông đơn điệu cần phải thay bằng những góc khuất và hành lang hẹp để tạo cảm giác sợ hãi.
Do đó, chúng ta cần thêm không gian bằng cách tăng thêm kích cỡ của room. Để kích cỡ cửa sổ không tăng theo, bạn có thể dùng cách nhìn cửa sổ theo một kích cỡ duy nhất mà mình muốn. Bạn có thể tìm thấy kết quả biến đổi trong tập tin fps2.gm6.
Thêm hiệu ứng sương khói
Để tạo hiệu ứng gây cảm giác “đau tim”, bạn có thể thêm vào game một ít sương mù để các object ở phía xa trông tối hơn (hoặc sáng hơn, tùy theo màu của sương). Khi một object nằm ở quá xa thì người chơi sẽ không nhìn thấy nó và do đó, sương sẽ tạo không khí mờ ảo và rờn rợn, đồng thời khiến ta không phải vẽ những đối tượng nằm quá xa và điều này khiến cho mọi thứ chuyển động nhanh hơn. Muốn tạo sương mù, hãy nhập vào những dòng sau trong sự kiện khởi tạo của object người chơi (sau khi khởi động chế độ 3D).
Nếu khởi động chế độ sương mù với màu đen, hãy bắt đầu với khoảng cách bằng 10 và để cho mọi thứ tối thui tại khoảng cách 300. Chú ý rằng một số card đồ họa không hỗ trợ hiệu ứng tạo sương.
Tạo chuyển động tốt hơn
Điều còn lại là cải thiện phần điều khiển chuyển động. Khi đụng vào một object bạn sẽ ngừng chuyển động tại thời điểm hiện thời. Nhưng việc này khiến cho việc di chuyển giữa các hành lang trở nên khó khăn. Do đó, khi đụng vào vật cản, bạn sẽ thực hiện việc đụng độ dưới một góc nào đó để trượt theo bờ tường hơn là dừng lại. Muốn làm được điều đó, ta cần phải thay đổi một chút. Trước hết, không cần để các bức tường ở dạng rắn nữa. Trong sự kiện đụng độ, ta thêm vào đoạn mã sau:
Trong hai dòng đầu tiên, chúng ta đặt người chơi trở lại vị trí trước đó (để gỡ bỏ tình trạng đụng độ). Sau đó kiểm tra xem có thể di chuyển người chơi theo phương nằm ngang hay không (trượt theo bờ tường nằm ngang). Chúng ta chỉ có thể làm điều này khi tốc độ theo phương ngang lớn hơn theo phương đứng. Nếu vị trí trượt nằm ngang không xảy ra đụng độ với bờ tường thì đặt nó ở đó. Tiếp theo, bạn thử với phương chuyển động thẳng đứng. Nếu cả hai cùng không được, bạn có thể đặt tốc độ bằng 0 để ngừng chuyển động.
Sự thay đổi thứ hai là cho phép đi bộ và chạy. Khi người chơi ấn phím Shift thì sẽ di chuyển nhanh hơn. Muốn làm được, bạn chỉ cần kiểm tra sự kiện bàn phím với mũi tên lên và xuống để xem các phím đó có được nhấn hay không. Nếu như vậy, hãy cho phép tốc độ cao hơn như sau:
Vấn đề cuối cùng là trong phần lớn các game FPS, người chơi có thể bắn phá, di chuyển sang trái, phải. Để làm được điều đó, chúng ta dùng đến phím x và z. Chuyển động nên vuông góc với hướng hiện thời mà người chơi đang quay mặt về. Đối với phím z thì đoạn mã như sau:
Bước 4: Thêm các đối tượng vào game
Lúc này thế giới game vẫn còn thưa thớt vì chỉ có một vài bức tường. Trong phần này, chúng ta sẽ tiếp tục làm cho không gian đó đầy lên. Dù chỉ giữ chức năng trang trí nhưng đó cũng là nơi người chơi và cả đối thủ của họ ẩn nấp. Nói chung là có 2 cách thêm object vào. Cách thứ nhất là tạo ra một đối tượng 3D bao gồm kết cấu tam giác có thể
mang lại hiệu ứng cao nhất nhưng khá tốn thời gian; thay vì đó ta dùng các sprite để thể hiện những đối tượng này. Chúng ta sẽ dùng kỹ thuật đó cho tất cả các vật thể như đạn, cây cối, vũ khí, các vụ nổ… Nhưng mọi thứ có vẻ như khó hơn nhiều vì các sprite đều phẳng và nếu chúng ta nhìn lệch hướng, chúng sẽ trở nên “vô hình”. Chúng ta sẽ giải quyết tình trạng này bằng cách giữ cho các sprite đối diện với người chơi.
Các sprite nhìn trực diện.
Chúng ta sẽ tạo ra một đối tượng hình cây để cho không gian game sinh động hơn. Cũng giống như người chơi và các bức tường, bạn có thể dùng một sprite rất đơn giản để thể hiện cái cây trong phòng này. Điều này rất dễ dàng khi thiết kế phòng và sẽ dùng kiểm tra đụng độ để người chơi không thể đi qua được cái cây. Chúng ta cũng đặt đối tượng cây này làm object gốc, giống như object tường cơ sở. Do đó, đối với người chơi (sau này là đạn), cái cây sẽ đóng vai trò như một bức tường. Dù vậy, chúng ta sẽ viết đè lên sự kiện Draw (vẽ) vì phải vẽ ra một cái khác. Để vẽ cái cây, chúng ta cần một sprite đẹp và nó cần phải “trong suốt” một phần và để làm cho các gờ tường trông đẹp hơn, chúng ta đổi sang lựa chọn “làm mượt” chúng. Trong sự kiện Draw, bạn dùng sprite này để vẽ cái cây trên một bờ tường dựng đứng. Do sprite này “trong suốt” một phần nên bạn chỉ nhìn thấy một phần nhất định của bức tường.
Dù vậy vẫn có một vấn đề quan trọng cần giải quyết là xử lý tình trạng “phẳng lỳ” của sprite. Nếu nhìn vào từ mặt bên thì sprite này rất mỏng và thậm chí biến mất. Chúng ta sẽ dùng đến xảo thuật hay áp dụng trong nhiều trò chơi là để sprite này đối diện với camera. Dù trông không tự nhiên lắm, các hiệu ứng vẫn tỏ ra khá tốt. Tuy vậy, bạn vẫn cần đến một thuật toán. Đồ thị dưới đây thể hiện tình huống này. Mũi tên thể hiện hướng mà người chơi nhìn (ký hiệu là D). Hình chữ nhật màu đen thể hiện sprite. Giả định sprite có độ dài là 2L thì các vị trí góc là:
Đoạn mã sau có thể đặt trong sự kiện Draw của đối tượng cây.
Chúng ta xác định bề mặt chính xác của sprite, tính toán đến hai giá trị trên và vẽ sprite trên một bức tường có kích thước 14x20 và đặt đứng trên mặt sàn, xoay theo một hướng chuẩn. Một điều rõ ràng là kích cỡ và vị trí đúng phụ thuộc vào object thực sự được vẽ ra.
Nếu có nhiều sprite được vẽ theo cách này thì thực ra bạn rất dễ chứa giá trị sin và cos làm biến số chung và giá trị này biến đổi theo đối tượng người chơi chứ không phải tính toán lại cho mỗi sprite cần vẽ. Trong mỗi sự kiện End Step của người chơi, chúng ta chứa sin và cos trong biến camsin và camcos.
Một điều cần chú ý nữa là do viền của sprite trong suốt một phần (do đã “làm mượt” chúng) nên phải cẩn thận với thứ tự vẽ object. Các sprite trong suốt một phần này chỉ được “trộn lẫn” với các object được vẽ trước đó. Để đạt đến hiệu ứng như yêu cầu, các sprite alpha được “trộn lẫn” này phải được vẽ sau tất cả các object khác. Điều này có thể làm được bằng cách đặt cho các object dạng cây một độ sâu có giá trị âm. Kết quả như sau:
Các object động
Chúng ta có thể tạo đối tượng động theo cách tương tự như trên. Có hai vấn đề chính. Một là chúng ta cần một sprite bao gồm một vài hình ảnh phụ cho chuyển động. Cần phải đảm bảo sprite thật sự mà chúng ta dùng để thể hiện object có số hình ảnh phụ giống như vậy để có thể dùng được biến image_index kèm theo. Thứ hai, trong sự kiện Draw, chúng ta phải chọn được bề mặt tương ứng với hình ảnh phụ có sử dụng biến image_index. Dưới đây là một đoạn mã có thể được sử dụng trong sự kiện Draw của một đối tượng “phát nổ” nào đó.
Bạn có thể tham khảo tập tin fps3.gm6.
Bước 5: Thực hiện phần bắn súng
Do đây là phần hướng dẫn làm game bắn súng nên chúng ta sẽ tiếp tục cách bắn đạn và cách đưa quái vật vào để làm bia đỡ đạn.
Đưa đạn vào game
Trước hết cần hình ảnh về một viên đạn. Thực ra, chúng ta cần hai viên đạn, một để khi nó đứng yên, một là để khi nó phát nổ. Để có được hình ảnh động chính xác, một điều quan trọng cần lưu ý là những sprite thể hiện cũng có cùng số hình ảnh phụ giống như các hình ảnh động thực sự. Chúng ta đặt cả viên đạn thường và viên đạn nổ làm cơ sở để không thể đi xuyên qua chúng. Bạn có thể đặt viên đạn thường ở các điểm khác nhau trong room. Do chỉ có hai hình ảnh phụ, chúng ta đặt biến số image_speed bắt đầu từ 0,1 trong sự kiện khởi tạo. Trong sự kiện Draw, chúng ta vẽ hình ảnh phụ chuẩn trên một bức tường đối diện như trên.
Khi viên đạn này bị phá hủy (như trong sự kiện phá hủy), ta tạo một viên đạn nổ ở cùng một vị trí. Đối với object này, ta chỉ đặt tốc độ chuyển động chậm. Do viên đạn thường không phát nổ ngay lập tức nên ta đặt một đồng hồ báo động để cho nó nổ vào một thời điểm nào đó.
Chúng ta vẫn vẽ với cách thức như trên nhưng có một xảo thuật như sau: giảm giá trị alpha dần dần để các vụ nổ “mờ dần” theo thời gian. Trong sự kiện Draw chúng ta đặt dòng mã sau đây:
Trong sự kiện cuối cùng, ta phá hủy viên đạn nổ và kết quả có thể thấy trong tập tin fps4.gm6.
Bạn cũng có thể dễ dàng thêm vào một số thứ linh tinh khác nữa để những gì gần viên đạn cũng bị bắn tung lên và vụ nổ gây ảnh hưởng hay thương tổn đến chính nhân vật người chơi.
Tạo súng
Đối với khẩu súng, chúng ta sẽ dùng một sprite động. Sprite này có các hình ảnh cho một khẩu súng tĩnh (subimage 0) và dành để bắn và tải lại. Thường thì chúng ta chỉ vẽ subimage 0 (vì vậy ta đặt image_speed bằng 0) nhưng khi một viên đạn được bắn đi, chúng ta phải dùng đến toàn bộ các hình động. Hãy để khẩu súng làm một lớp phủ (overlay) trên game. Trước hết, đảm bảo object phủ này được vẽ cuối cùng. Điều này có thể làm được bằng cách đặt độ sâu bằng -100. Thứ hai, chúng ta không dùng đến hình chiếu góc nữa mà thay bằng hình chiếu trực giao. Và cuối cùng, chúng ta phải tạm thời tắt chức năng bỏ đi bề mặt ẩn. Mã cho sự kiện Draw như sau:
Bạn có thể dùng một kỹ thuật tương tự cho tất cả các lớp phủ mà mình cần. Dưới đây chúng ta sẽ dùng đến nó để thể hiện “máu’ của người chơi nhưng bạn có thể dùng nó để ra hướng dẫn, thể hiện thông số… Bạn cũng có thể làm cho lớp phủ trong suốt một phần bằng cách thay đổi giá trị alpha.
Bắn súng
Lúc này chúng ta đã có đối tượng để bắn và súng nữa, nhưng màn bắn súng thì chưa có. Do đây là một khẩu súng ngắn nên đạn bay rất nhanh. Vì vậy, vào lúc người chơi nhấn phím Space, chúng ta phải xác định object bị đụng độ và nếu đó là đạn thường thì để nó nổ.
Trước hết, lập một biến số can_shoot để xác định người chơi có thể bắn đạn hay không. Chúng ta đặt giá trị tham số này bằng true trong sự kiện khởi tạo của đối tượng overlay. Nếu người chơi có thể bắn thì ta đặt giá trị đó bằng false và bắt đầu chuyển động của khẩu súng bằng cách thay đổi tốc độ hình ảnh. Vào đoạn cuối của chuyển động, ta đặt can_shoot trở lại giá trị true. Điều này có nghĩa là người chơi không thể bắn liên tiếp được. Để xác định viên đạn nào bắn trúng, chúng ta tiến hành như sau: Thiết lập từng bước nhỏ từ vị trí hiện tại của người chơi theo hướng hiện thời. Đối với mỗi vị trí, chúng ta kiểm tra xem object đó có bị bắn trúng không. Do tất cả các object này là “hậu duệ” của object dạng tường cơ sở nên chúng ta chỉ cần kiểm tra xem có instance nào ở vị trí đó không. Nếu vậy, chúng ta kiểm tra xem đó có phải là đạn thường không và nếu là đạn thường thì hủy bỏ chúng. Bất cứ khi nào bắn trúng một object dạng tường cơ sở, chúng ta cho ngừng vòng lặp vì đây sẽ là kết thúc đường đi của viên đạn. Mã lệnh như sau:
Bạn có thể tham khảo tập tin fps4.gm6.
Thêm địch thủ
Tất nhiên, bắn được đạn đã là thú vui, nhưng kẻ thù càng “ngầu” sẽ càng tăng thêm niềm hứng khởi. Ở đây, chúng ta sẽ tạo ra một con quái vật để làm ví dụ. Để làm được điều này, chúng ta cần 2 sprite động, một để khi nó sống và một để khi nó chết.
Đối với cả hai, chúng ta đặt tốc độ chuyển động này một cách chính xác. Khi nó chết, chúng ta tạo ra một con quái vật đang giẫy giụa ở cùng vị trí đó. Việc này diễn ra giống như đối với viên đạn thường. Chỉ có một sự khác biệt như sau: Vào đoạn cuối của chuyển động, chúng ta không phá hủy con quái vật đã chết mà để nó nằm vất vưởng trên sàn và như vậy chỉ cần hiển thị hình ảnh phụ cuối cùng của tập hợp ảnh động về nó.
Để có thể bắn những con quái vật, chúng ta tiến hành như đối với các viên đạn. Nhưng chúng ta phải thay đổi một chút. Trước hết, không đặt bọn quái vật này là “hậu duệ” của các object dạng tường nữa. Điều này sẽ gây khó khăn khi chúng bước đi loanh quanh. Vì vậy chúng ta thiết lập một đối tượng khác là obj_monster_basic và đây chính là object cơ sở của tất cả các loại quái vật. Sự thay đổi thứ hai là chúng ta cần thiết lập khả năng bắn xuyên qua những lùm cây. Như vậy, chúng ta tạo ra một đối tượng dạng cây cơ sở obj_plant_basic. Đối tượng dạng cây cơ bản này sẽ có gốc là đối tượng dạng tường cơ bản vì chúng ta không muốn đi xuyên qua các lùm cây. Mã bắn đạn được áp dụng như sau:
Phần lớn công việc diễn ra như đối với các viên đạn. Trước hết, chúng ta kiểm tra xem bức tường có bị trúng đạn không. Nếu không, chúng ta kiểm tra xem một con quái vật nào đó có trúng đạn không; nếu trúng thì hủy bỏ nó. Nếu bức tường bị trúng đạn thì tiếp tục kiểm tra xem instance có là một loại cây hay không, và nếu đúng thì tiếp tục (do đó viên đạn sẽ bay xuyên qua cái cây). Cuối cùng, nếu chúng ta bắn đạn trúng thì để nó nổ. Bạn có thể tham khảo tập tin fps5.gm6.
Điều cuối cùng là để con quái vật tấn công người chơi. Địch thủ này không bắn đạn mà đơn giản là đi về phía người chơi. Nếu nó chạm phải người chơi thì sẽ làm mất một ít “máu”. Cơ chế về máu cũng được xây dựng trong Game Maker. Trong sự kiện khởi tạo của nhân vật người chơi, chúng ta đặt lượng máu bằng 100. Trong đối tượng overlay, vẽ thanh máu như sau:
Trong sự kiện No more health, chúng ta sẽ khởi động lại game (dù cho có vẻ hơi nhàm chán).
Muốn để quái vật tấn công lại người chơi, chúng ta đặt đoạn mã sau trong sự kiện Begin Step.
Nếu khoảng cách từ quái vật đến người chơi khá xa thì chúng ta sẽ không làm gì và đơn giản là để tốc độ bằng 0. Nếu quái vật không nhìn thấy người chơi, chúng ta cũng không làm gì cả. Chỉ khi nào nó nhìn thấy người chơi thì nó bắt đầu di chuyển tới. Nếu khoảng cách nhỏ hơn 12, chúng ta giả định nó sẽ đụng vào người chơi và do đó ta để nó dừng lại và bắt đầu lấy đi một ít “máu”, đồng thời cho phát ra một tiếng động đáng sợ. Nếu không, ta di chuyển người chơi đến một vị trí nào đó với tốc độ nhất định. Để tránh cho quái vật đụng vào tường, bạn có thể áp dụng cơ chế trượt tương tự đối với nhân vật người chơi.
Giờ đây, chúng ta đặt một số quái vật trong những nơi “hiểm yếu” và bạn có thể thử tác dụng của nó trong tập tin fps5.gm6. Một điều rõ ràng là để làm mọi thứ trở nên sinh động hơn, bạn nên tạo ra một lối thoát vào room kế tiếp và quanh đó có nhiều quái vật canh giữ rồi tiếp tục lập ra các room khác. Bạn cũng nên tạo thêm các loại quái vật khác nhau và để bình máu rải rác trong room. Cũng vậy, bạn đặt cho quái vật một lượng máu nào đó và có thể xác định xem sau mấy phát đạn trúng thì nó sẽ lăn ra chết.
Những điều cần lưu ý
Tiết kiệm khi thiết kế
Khi đi trong thế giới 3D này, bạn sẽ chỉ nhìn thấy một phần nhỏ của nó mà thôi. Không may là hệ thống đó không nhận biết được bạn nhìn thấy phần nào. Do đó, tất cả các đối tượng (ít nhất là ở đằng trước bạn) đều phải vẽ ra. Điều này khá tốn thời gian và ngay cả trên các card đồ họa thuộc loại nhanh, việc này cũng khiến tốc độ của game bị giảm đi. Tất cả các trò chơi 3D đều phải tính đến vấn đề này và tránh vẽ quá nhiều những đối tượng không cần thiết.
Một phương án để đối phó với tình trạng này là tạo ra những level nhỏ. Sau đó, bạn có thể dùng các điểm đặc biệt như cổng thần (teleporter) để di chuyển từ level này sang level khác.
Bạn có thể khéo léo làm việc này để người chơi không nhận ra, ví dụ như đặt nó trong một hành lang ngoằn ngoèo chẳng hạn.
Một cách nữa là chỉ vẽ các object gần với người chơi. Bất cứ khi nào vẽ một cái gì đó, chúng ta kiểm tra xem object đó có khoảng cách đủ gần không. Muốn làm nhanh ***ng việc này, chúng ta có thể lưu vị trí hiện tại của người chơi (camera) trong hai biến chúng là camx và camy. Sau đó, trong sự kiện Draw của mọi bức tường, cây, quái vật… chúng ta thêm vào mã kiểm tra sau
Do đó, nếu khoảng cách đến camera lớn thì chúng ta sẽ không làm gì cả. Giá trị 240 là tùy thuộc vào cách thiết kế room của bạn. Tốt hơn hết, hãy đảm bảo rằng không có chỗ nào để người chơi có thể nhìn xuyên suốt cả một hành lang dài. Đồng thời, bạn hãy đặt nền màu đen để nếu có chỗ nào mà bạn nhìn xa được thì cũng bị chìm vào trong màn sương mờ ảo. Bạn có thể nhận thấy điều này trong tập tin fps6.gm6. Nếu bạn chỉ có card đồ họa chậm thì phần game mới này chạy tốt hơn phần trước.
Khi các room trở lên lớn hơn và có nhiều object hơn thì các hiệu ứng cũng tốt hơn. Bạn có thể xác định cần phải vẽ object nào. Những trò chơi có tính thương mại có sử dụng kỹ thuật cổng dịch chuyển tức thời để đẩy nhanh tốc độ di chuyển.
Thiết kế các cánh cửa bí hiểm
Các cánh cửa là một tính năng thú vị kết nối các căn phòng và dải hành lang. Chính yếu tố này sẽ tạo ra sự căng thẳng trong lúc chơi game vì ẩn sau đó là những điều bất ngờ thú vị.
Tại đây, chúng ta thêm vào những cánh cửa đơn giản nằm trên hành lang và có thể dùng đạn để bắn bật ra. Còn việc xoay nắm đấm để mở cửa có thể gây phức tạp hơn vì bạn có thể đối diện với một con quái vật hoặc tự khóa mình.
Để thêm một cánh cửa, trước hết bạn cần thêm vào một kết cấu cho nó. Chúng ta thêm vào như một hình nền, giống như một bức tường vậy và cũng cần một sprite để thể hiện nó trong thiết kế room và phát hiện đụng độ như các bức tường khác. Hãy tạo 2 đối tượng, một là cánh cửa đóng, hai là cánh cửa mở. Cánh cửa đóng trông giống như một object dạng tường, trừ phi trong sự kiện hủy bỏ nó tạo ra một instance của object dạng tường trượt. Một lần nữa, chúng ta để nó làm đối tượng dạng tường cơ sở để người chơi và quái vật không thể đi xuyên qua được.
Cánh cửa động cũng giống như cánh cửa đóng nhưng trong sự kiện khởi tạo, chúng ta đặt tốc độ theo phương nằm ngang của nó bằng 1. Cũng vậy, hãy đặt một đồng hồ báo động đến 32 và trong sự kiện báo động này, đặt tốc độ bằng 0 (thực ra chúng ta có thể hủy bỏ object này). Cuối cùng, trong sự kiện Step, chúng ta áp dụng các vị trí x1 và x2 để đảm bảo bề mặt này được vẽ ở vị trí chuẩn và việc này kết thúc bức tường động.
Chúng ta có thể đảm bảo cho cánh cửa này có thể mở được. Chúng ta sẽ quyết định cho mở cánh cửa này khi người chơi bắn vào. Đến lúc này, trong sự kiện Space của đối tượng overlay (nơi xử lý việc bắn súng), chúng ta thay đoạn mã như sau:
Hãy đặt một vài cánh cửa “chiến lược” trong room và đảm bảo rằng chúng có thể đẩy vào trong tường, vì vậy không nên đặt cửa ở tận cuối của bức tường. Bạn có thể xem tập tin fps6.gm6. Tất nhiên, để tạo ra những thứ thú vị hơn, bạn có thể thêm vào cửa trượt lên xuống hoặc mở sang trái, phải.
Sàn và trần
Dù đã tạo một sàn và trần khá lớn, hai khu vực này hơi tẻ nhạt. Bạn có thể tạo nhiều bề mặt khác nhau và mỗi chỗ một độ cao khác nhau. Theo cách này, bạn sẽ tạo ra nhiều địa hình phức tạp
Bạn cũng có thể tạo ra một số vùng "cấm địa" nguy hiểm như vũng nham thạch đang sối sùng sục để tạo cảm giác rờn rợn. Một giải pháp đơn giản để người chơi không thể đi vào đó là đặt các bờ tường dạng vô hình xung quanh nó.
Trên đây là những hướng dẫn cơ bản và một ví dụ cụ thể cho trò chơi FPS trong môi trường 3D. Với các nguồn hình ảnh có thể tìm kiếm trên mạng, một số kiến thức lập trình và sự mày mò của bản thân, bạn có thể tự tạo một trò chơi cho mình và bè bạn.
0 nhận xét:
Post a Comment