-
08-21-2008, 06:55 AM #1
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
Download và hướng dẫn Game Maker_Làm Game
đây là hướng dẫn khá tốt ai muốn học thì đọc cho hết nha nó hướng dẫn cả làm game online nữa tui kiếm được và đang học
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
Khái niệm object (đối tượng)
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ã.
Tạo action
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ển. Bạ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.
-
08-21-2008, 06:55 AM #2
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
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.
Các chức năng thiết lập room cao cấp
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.
-
08-21-2008, 06:57 AM #3
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
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 xâm lược 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.
Tạo băng thời gian (time line)
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.
Thông tin về game
Thường thì trong game đều có phần cung cấp thông tin về cách chơi và thường được hiển thị khi bạn ấn phím F1. Để tạo ra chức năng này, hãy nhấn vào Game Information trên thanh menu. Một cửa sổ biên soạn sẽ hiện ra để bạn nhập thông tin và trên đó có các kiểu font chữ, màu sắc chữ và màu nền khác nhau.
Trong menu File, “nhà thiết kế” có thể thiết lập rất nhiều lựa chọn với Options. Tại đây, bạn sẽ chỉ ra được cách mở hướng dẫn chơi game khi đang chạy trò chơi; vị trí và kích cỡ của cửa sổ thông tin, cũng như lựa chọn thay đổi kích cỡ cửa sổ của người chơi. Bạn có thể “bắt ép” cửa sổ đó hiện lên trên màn hình và xác định xem có để trò chơi tiếp tục trong khi hiện cửa sổ thông tin lên hay không.
Một lựa chọn thú vị nữa là khớp với cửa sổ chính của game. Khi nhấn vào lựa chọn này, cửa sổ trợ giúp được hiển thị chính xác như vị trí và kích thước cửa sổ chơi game. Bạn cũng có thể cho phép người chơi chọn Escape để thoát khỏi cửa sổ trợ giúp và tiếp tục game.
Thiết lập tổng quát
Bạn có thể thay đổi cách thiết lập cho game. Việc này có thể biến đổi hình dạng của cửa sổ chính, tạo nên một số lựa chọn về đồ họa, giải quyết một số vấn đề về tương tác, cho đến việc tải hình ảnh, thông số và thông tin về người sáng tạo ra trò chơi. Cũng vậy, bạn có thể xác định file nào có thể đưa vào trò chơi riêng lẻ và cách thức xử lý lỗi.
Phần thiết lập này có thể thay đổi bằng cách nhấp đúp vào mục Global Game Settings ở bên trái màn hình. Dưới đây là một số mục đáng chú ý:
Đồ họa
Trong mục này, bạn có thể thiết lập rất nhiều tính năng liên quan đến phần thể hiện đồ họa của trò chơi. Việc kiểm tra tác động của các lựa chọn này là rất hữu dụng vì chúng có ảnh hưởng rất quan trọng đến giao diện của game. Chú ý là máy tính của người dùng có thể khác nhau và hãy đảm bảo phần cài đặt của bạn cũng hoạt động tốt trên các máy khác.
Tại đây, bạn có thể quyết định nhiều lựa chọn như:
Khởi động chế độ toàn màn hình
Khi đánh dấu vào mục này, trò chơi sẽ chạy trên toàn bộ màn hình, nếu không, nó sẽ chạy trên một cửa sổ.
Xác định tỷ lệ cửa sổ chơi game
Bạn có thể quyết định một tỷ lệ cố định giữa room với trung tâm cửa sổ chơi game và màn hình, trong đó số 100 là không tỷ lệ. Thường thì bạn dùng tỷ lệ cố định khi các sprite và room rất nhỏ. Lựa chọn tiếp theo là tỷ lệ choán màn hình nhưng giữ cho chiều cao và độ rộng tương đương nhau. Lựa chọn thứ ba là để room choán toàn bộ màn hình. Việc này có thể làm cho hình ảnh bị “bóp méo”.
Lấp màu vào khoảng trống
Nếu đánh dấu vào ô này, màu của các điểm ảnh trong sprite, nền game và các hình “lát” (tile) không cân đối với các điểm ảnh trên màn hình sẽ được lấp thêm vào. Điều này được áp dụng khi chúng bị xoay, xác định lại tỷ lệ… Việc lấp màu sẽ làm cho chuyển động trong game mềm mại hơn nhưng có thể gây ra hiệu ứng mờ.
Lấp màu vào vùng ngoài room
Khi room không choán toàn bộ màn hình, bạn có thể xác định màu quanh vùng này.
Cho phép người chơi xác định lại kích cỡ cửa sổ
Khi mục này được đánh dấu, người sử dụng có thể thay đổi độ lớn của cửa sổ chơi game bằng cách kéo chuột ở bốn góc.
Để cửa sổ game luôn ở trên các cửa sổ khác
Đánh dấu vào mục này sẽ làm cho cửa sổ chơi game được “ưu ái” nằm trên mọi cửa sổ khác.
Không hiển thị đường viền cửa sổ
Khi chọn mục này, cửa sổ chơi game sẽ không có đường viền và thanh chỉ dẫn.
Không hiển thị các nút điều chỉnh cửa sổ
Nếu chọn mục này, bạn sẽ làm mất các nút thu nhỏ, phóng to và đóng cửa sổ
Hiển thị con trỏ
Ngoài việc có thể hiển thị con trỏ trong game, bạn còn dễ dàng thiết kế con trỏ riêng cho mình với Game Maker.
Ngừng chạy game khi có ứng dụng khác chen vào
Khi tính năng này được chọn, bất cứ khi nào có các ứng dụng khác xuất hiện “đè” lên cửa sổ thì trò chơi sẽ dừng lại cho đến khi lấy lại “vị thế” của mình.
Độ phân giải
Trong mục này bạn có thể thiết lập độ phân giải màn hình để chạy game. Nếu để mặc định thì độ phân giải sẽ không thay đổi. Nhưng đôi khi bạn có thể muốn chạy game với thông số thấp hơn hoặc thiết lập tần số của màn hình để việc xác định thời gian trong game diễn ra chính xác. Nếu muốn thay đổi thông số này, hãy nhấn vào mục Set the resolution of the screen để chọn lựa.
Ngoài ra, "nhà thiết kế" có thể kèm các file hình ảnh, âm thanh khác vào trò chơi, thiết lập các tùy chọn tải game, cách thức báo lỗi...
Vậy khi nói một trò chơi nào đó là 3D thì người ta ám chỉ điều gì? Hơi khó tìm ra câu trả lời ngay lập tức vì đây là sự kết hợp giữa cách tạo game với hình ảnh mà người chơi nhìn thấy và cách họ điều khiển trò chơi.
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.
-
08-21-2008, 06:57 AM #4
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
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 trá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.
-
08-21-2008, 06:58 AM #5
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
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.
Rất nhiều trò chơi điện tử nổi tiếng đã dùng đến kỹ thuật giả 3D như Đế Chế, Diablo, Command and Conquer, SimCity và nhiều game chiến thuật hoặc mô phỏng khác. Về nguyên tắc, phương pháp làm game như vậy là có thể với phần mềm Game Maker (nhưng chú ý rằng sản xuất một trò chơi mang tính thương mại cao đòi hỏi rất nhiều công sức của một đội ngũ giỏi).
Một cảnh trong Đế Chế.
Nguyên tắc làm game giả 3D là đặt thế giới ảo này dưới góc nhìn cố định 45 độ. Bạn cần sử dụng đến phương pháp tạo hình chiếu song song như đã nói ở phần trước. Thực ra, với cách này, các vật thể ở xa sẽ không nhỏ đi. Hãy giả định thế giới ảo bao gồm những ô vuông như hình bên trái. Khi chuyển sang góc nhìn giả 3D, mọi thứ sẽ trông như hình bên tay phải. Mỗi ô vuông sẽ biến thành hình thoi. Để thuận tiện, chúng ta dùng hình thoi với tỷ lệ 2x1 (ví dụ như 32x16 pixel).
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.
Bước 1: Xây dựng một game 2D
Thự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 chó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à.
-
08-21-2008, 06:59 AM #6
Junior Member
- Ngày tham gia
- Nov 2015
- Bài viết
- 0
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.
-
08-21-2008, 07:00 AM #7
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
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 chó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.
Đấu game với máy tính đã thú vị, thi thố giữa người với người trong môi trường game còn thú vị hơn. Việc thể hiện loại game này khá dễ dàng vì bạn không phải mất công thực hiện các phần việc phức tạp của đối thủ mà ta gọi là trí thông minh nhân tạo (Artificial Intelligence).
Cùng kết nối để chơi game nào. (WSC)
Tất nhiên là bạn có thể ngồi với một người nữa trên cùng một máy tính và mỗi người dùng một cụm phím khác nhau để điều khiển. Nhưng sẽ thú vị hơn khi dù xa đến nửa vòng trái đất, bạn vẫn có thể “đối đầu” trực tiếp với nhau. Phần mềm Game Maker có hỗ trợ cách làm này, nhưng bạn chỉ có thể dùng tính năng tạo game online khi đã đăng ký với chi phí 20 USD/năm tại đây.
Nhưng tất nhiên, tạo ra một trò chơi online hiệu quả không phải dễ dàng. Nó đòi hỏi bạn phải sử dụng Game Maker thật thành thạo và biết cách viết mã. Trong phần này, chúng ta sẽ bàn về các khía cạnh sau:
- Thiết lập kết nối đến một máy tính khác
- Tạo lập và tham gia vào một “phòng” game
- Giữ cho trò chơi diễn ra đồng thời đối với những người cùng tham gia
Kỳ 1: Thiết lập kết nối đến một máy tính khác
Cách chuẩn để chạy một game nhiều người chơi như sau: Mỗi người chạy một bản copy của trò chơi, mặc dù chúng có thể chạy trên nhiều chế độ (mode) khác nhau. Một người sẽ kích hoạt trò chơi của mình trên chế độ server (dùng máy chủ). Những người khác chạy game trên chế độ client (máy khách). Máy chủ sẽ khởi động trò chơi trước rồi tạo ra một “phòng” (session) để những người người này vào “phòng” và tham gia trò chơi. Người chơi phải quyết định cơ chế dùng để liên hệ giữa các máy tính. Trên một mạng nội bộ, cách dễ nhất là dùng kết nối IPX.
Nếu tất cả đều có kết nối với Internet thì cơ chế thường dùng là TCP/IP. Trong giao thức này, các máy khách phải biết được địa chỉ IP của máy chủ. Do đó, người chơi chạy game trên chế độ máy chủ phải đưa địa chỉ IP cho những người dùng máy khách.
Bạn cũng có thể tìm thấy địa chỉ IP của mình bằng cách sử dụng chương trình winipcfg.exe trong thư mục windows hoặc dùng chức năng mplay_ipaddress ( ). Một cách cổ điển hơn nữa là sử dụng modem (trong trường hợp đó, máy khách phải biết số điện thoại của máy chủ) hoặc sử dụng một dòng số. Nhưng cần chú ý một điều là hiện nay việc liên lạc giữa các máy trở nên khó khăn hơn do mọi người dùng “tưởng lửa” (firewall) và các cầu dẫn (router) để bảo vệ máy tính của mình. Do đó, các tin nhắn và địa chỉ IP cũng dễ bị chặn.
Để hai máy tính liên hệ được với nhau, chúng phải cần đến một giao thức kết nối nào đó. Giống như phần nhiều các trò chơi, Game Maker hỗ trợ 4 kiểu kết nối là IPX, TCP/IP, Modem và Serial.
Giao thức IPX hoạt động hoàn toàn dễ hiểu vì nó có thể dùng để chơi game với người khác trên cùng một mạng cục bộ và cần được cài đặt trên máy của bạn. Còn TCP/IP là giao thức kết nối Internet, được dùng để chơi game với người khác ở bất kỳ đâu thông qua mạng toàn cầu với giả định là bạn biết địa chỉ IP của họ. Trên mạng cục bộ, bạn có thể dùng nó mà không cần cung cấp địa chỉ. Kết nối Modem được thiết lập thông qua một modem. Bạn phải cài đặt modem bằng một dải mã số và một số điện thoại. Cuối cùng, khi dùng tới một dải số (serial line – dùng để kết nối trực tiếp giữa các máy tính), bạn cần cung cấp một số thiết lập cổng truyền dẫn.
4 chức năng GML (ngôn ngữ lập trình của Game Maker) có thể dùng để khởi động các kết nối này:
mplay_init_ipx ( ) khởi động giao thức IPX
mplay_init_tcpip (addr) khởi động giao thức TCO/IP
addr ở đây là một dải ký tự hoặc số có chứa địa chỉ trang web hoặc địa chỉ IP, ví dụ như 'www.gameplay.com' hoặc ‘123.123.123.12’, có thể được nối tiếp bằng số thứ tự cổng (ví dụ như (‘:12’). Chỉ khi tham gia vào một phòng game (xem phần sau), bạn cần cung cấp một địa chỉ. Người tạo phòng thì không cần đưa ra địa chỉ. Trên mạng cục bộ bạn không cần địa chỉ nào nhưng vẫn phải gọi điện.
mplay_init_modem (initstr, phonenr) tạo ra một kết nối modem.
initstr là dải ký tự khởi động modem (có thể bỏ trống)
phonenr là một dải số chứa số điện thoại để thực hiện cuộc gọi (ví dụ như ‘0201234567’) chẳng hạn.
mplay_init_serial (porno, baudrate,stopbits,parity,flow) khởi động kết nối dãy số
porno là số cổng (từ 1 đến 4)
baudrate là tốc độ kết nối (100 đến 256K)
stopbit thể hiện số bit khóa (0= 1bit, 1 = 1.5 bit, 2 = 2 bit)
parity thể hiện trạng thái (0= không, 1= lẻ, 2= chẵn, 3= đánh dấu)
flow thể hiện kiểu điều chỉnh luồng (0=không, 1=xbật/xtắt, 2=rts, 3=dtr, 4=rts và dtr)
(rts là tín hiểu RS-232 được gửi từ trạm truyền đến trạm tiếp nhận, yêu cầu được truyền tải; dtr cũng là một tín hiệu giao thức RS-232 được gửi từ máy tính hoặc thiết bị cuối đến modem để thể hiện rằng nó có thể chấp nhận dữ liệu)
Một cuộc gọi tiêu chuẩn là mplay_init_serial(1,57600,0,0,4).
Ta đặt 0 làm tham số đầu tiên để mở một hộp thoại cho người sử dụng thay đổi phần cài đặt.
Trò chơi của bạn cần sử dụng một trong 4 chức năng này một cách chính xác. Tất cả các chức năng đó đều thông báo chúng có hoạt động thành công hay không. Nguyên do thất bại có thể là giao thức đó chưa được cài đặt hoặc máy tính không hỗ trợ.
Do đó, room đầu tiên trong game cần thể hiện 4 khả năng đó để người chơi chọn lấy một (hoặc chỉ cho phép các giao thức mà bạn muốn. Hai giao thức cuối có thể quá chậm cho game của bạn). Chúng ta gọi chức năng khởi động này trong sự kiện Mouse và nếu thành công, hãy tới room kế tiếp. Nếu không, chúng ta cần gửi tin nhắn báo lỗi. Trong sự kiện Mouse của nút IPX, đặt đoạn mã sau:
{
if (mplay_init_ipx( ))
room_goto_next( )
else
show_message('Failed to initialize IPX connection.')
}
Khi trò chơi kết thúc hoặc khi người sử dụng không muốn chức năng chơi nhiều người nữa, bạn nên dùng thường trình (routine) sau để kết thúc
mplay_end ( ) ngắt kết nối hiện thời
Bạn nên gọi thường trình này trước khi muốn thiết lập một kết nối khác.
Kỳ 2: Thiết lập các phòng game
Điều duy nhất mà bạn cần biết là khi thay đổi ID của game trong phần thiết lập tổng quát thì đặc điểm này thay đổi. Theo cách này, bạn có thể tránh việc người dùng bản game cũ chơi được với người dùng bản game mới. Nếu muốn khởi động một trò chơi mạng mới, bạn cần phải tạo ra một phòng mới và lúc này bạn có thể dùng đến công thức sau:
mplay_session_create (sesname, playnumb, playername) có chức năng tạo phòng mới trên kết nối hiện thời.
sesname là một dải mã chỉ ra tên của phòng game
playnumb là một số xác định số người tối đa được phép tham gia vào trò chơi
playername là tên người chơi
Gửi tin báo xem có thành công hay không.
Trong nhiều trường hợp, tên người chơi không được sử dụng đến và có thể là một dải mã trống. Cũng vậy, tên của phòng chỉ quan trọng nếu bạn muốn người chơi được lựa chọn phòng nào để tham gia.
Trước hết, bạn cần xem các phòng nào đang có sẵn rồi chọn một. Ba công thức sau đây rất quan trọng đối với việc này:
mplay_session_find ( ) tìm kiếm tất cả các phòng còn chấp nhận người chơi và cho kết quả là số phòng tìm thấy.
mpaly_session_name (numb) cho kết quả là tên của phòng có đánh số (0 là phòng đầu tiên). Công thức này chỉ có thể được gọi ra sau khi bạn đã gọi công thức trên.
mplay_session_join (numb, playername) sẽ giúp bạn tham gia vào một phòng có đánh số (0 là phòng đầu tiên).
playername là tên người chơi.
Trả kết quả xem có thành công hay không.
Do đó, cách tiêu chuẩn cần làm là gọi lệnh mplay_session_find ( ) để tìm tất cả các phòng đang tồn tại. Sau đó, bạn có thể dùng lặp lại lệnh mpaly_session_name ( ) để hiện thị các tên cho người chơi biết và để họ lựa chọn, hoặc bạn có thể ngay lập thức tham gia vào phòng đầu tiên. (Chú ý rằng việc tìm kiếm phòng sẽ làm mất thời gian nên không gọi lệnh này cho mỗi bước).
Người chơi có thể thoát khỏi phòng khi bạn dùng lệnh sau:
mplay_session_end ( ) kết thúc phòng cho người chơi.
Câu lệnh này rất hữu dụng trong việc báo trước cho người chơi về việc này nhưng không nhất thiết cần đến.
Do đó, trong trò chơi của mình, phòng thứ hai cho người chơi 2 lựa chọn: hoặc là tạo ra một phòng mới, hoặc tham gia vào phòng hiện có. Đối với lựa chọn đầu tiên, bạn có thể thực hiện đoạn mã sau trong sự kiện đối với Mouse.
{
if (mplay_session_create('',2,''))
{
global.master = true;
room_goto_next( );
}
else
show_message('Failed to create a session.')
}
Chú ý rằng chúng ta thiết lập một tham số chung master có giá trị True. Lý do là trong trò chơi, ta cần phân biệt người chơi chính (gọi là master) và người thứ hai (gọi là slave). Master sẽ chịu trách nhiệm đối với phần lớn gameplay, trong khi slave chỉ đơn thuần là theo sau các hoạt động của master.
Lựa chọn thứ hai là tham gia vào một game sẵn có. Đoạn mã sau được sử dụng:
{
if (mplay_session_find() > 0)
{
if (mplay_session_join(0,''))
{
global.master = false;
room_goto_next( );
}
else
show_message('Failed to join a session.')
}
else
show_message('No session available to join.')
}
Do đó, trong ví dụ này, ta chỉ tham gia vào phòng đầu tiên đang có sẵn. Do ở trên ta đã chỉ ra số người tối đa là 2 nên không ai có thể tham gia thêm vào phòng này nữa.
Xử lý các hoạt động của người chơi
Khi master đã tạo ra một phòng, chúng ta phải đợi một người khác nữa cùng tham gia. Có 3 công thức để xử lý các hoạt động của người chơi.
mplay_player_find ( ) tìm kiếm tất cả những người tham gia trong phòng hienẹ thời và cho kết quả là số người chơi tìm thấy
mplay_player_name (numb) cho kết quả là tên của người chơi mang số nào đó (0 là người đầu tiên). Công thức này chỉ có thể được gọi ra sau khi đã gọi công thức đầu tiên.
mplay_player_id (numb) cho kết quả là id duy nhất của người chơi mang số nào đó ( 0 là người đầu tiên). Công thức này chỉ có thể được gọi ra sau khi đã gọi công thức đầut iên. ID này được dùng để gửi và nhận các tin nhắn giữa những người tham gia với nhau.
Trong room thứ 3, chúng ta đơn giản đợi người chơi thứ hai tham gia vào. Vì vậy, hãy đặt một object nào đó ở đấy và trong sự kiện Step, đưa vào đoạn mã sau:
{
if (mplay_player_find() > 1)
room_goto_next( );
}
(Nhưng thực ra chúng ta không cần vào room này đối với slave).
Sau khi đã thiết lập kết nối, tạo phòng game và có hai người, chúng ta sẽ bắt đầu trò chơi. Nhưng điều này cũng có nghĩa là bắt đầu một ý tưởng gọi là “liên lạc”. Khó khăn chính trong bất cứ trò chơi nhiều người nào cũng là các hành động diễn ra đồng thời.
Xét trong ví dụ trò chơi đánh bóng bàn pong1.gm6 trong file examples sau khi giải nén tập tin multiplayer, khi một người chơi nhìn thấy quả bóng trong game ở nơi khác so với người thứ hai thì chắc hẳn những diễn biến lạ lùng sẽ xảy ra. (Trong trường hợp xấu nhất, một người nhìn thấy vợt đập trúng bóng còn người kia sẽ thấy đập trượt). Trò chơi dễ dàng bị “lệch pha” và từ đó sẽ tạo ra nhiều rắc rối. Chúng ta phải hạn chế lượng liên lạc càng nhiều càng tốt. Rất có thể dữ liệu còn dễ bị truyền chậm ở phía đầu kết nối kia, thậm chí bị mất và không đến được. Chúng ta phải xử lý các vấn đề này dựa trên kiểu game, ví dụ như game chiến thuật theo lượt sẽ dùng đến cơ chế khác so với các trò chơi hành động nhanh.
Game Maker hỗ trợ hai cơ chế để liên lạc là chia sẻ dữ liệu và truyền message. Cách thứ nhất khá dễ dàng còn cơ chế thứ hai thì linh hoạt và phức tạp hơn nhưng cũng đòi hỏi bạn phải hiểu cách thức hoạt động của liên lạc.
-
08-21-2008, 07:01 AM #8
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
Kỳ 3: Chia sẻ dữ liệu
Theo cách này, tất cả các liên lạc đều bị bạn chặn. Giá trị 1000000 là thông số chung cho tất cả các thực thể của game (ví dụ như cả Master và Slave). Mỗi thực thể này có thể thiết lập và đọc các giá trị. Game Maker đảm bảo cho mỗi thực thể này đều nhận biết được cùng các giá trị đó. Một giá trị có thể là số thực, có thể là một string.
Có hai công thức sau:
mplay_data_write (ind,val) viết giá trị val (string hoặc số thực) vào vị trí ind (ind giữa 0 và 1000000)
mplay_data_read (ind) trả giá trị vào vị trí ind (ind có giá trị trong khoảng 0 đến 1000000)
Vào lúc ban đầu tất cả các giá trị đều bằng 0.
Để dùng cơ chế này, bạn phải xác định giá trị nào dùng cho thức thể nào và ai được phép thay đổi nó. Tốt hơn hết là một instance của game được viết giá trị này và chỉ dùng vài vị trí đầu tiên để lưu bộ nhớ.
Trong trường hợp này, có 4 giá trị quan trọng: tọa độ y cây vợt của Master, tọa độ y cây vợt của Slave, tọa độ x, y của quả bóng. Vì vậy, chúng ta dùng vị trí 1 để xác định tọa độ y cho cây vợt của Master, vị trí 2 để xác định tọa độ y cho cây vợt của Slave. Xác lập Master chịu trách nhiệm cho các giá trị của quả bóng. Slave chỉ đơn giản là vẽ quả bóng theo vị trí đúng cho mỗi bước.
Cách hoạt động như sau: Trước hết, cây vợt của Master (vợt bên trái) chỉ được Master điều khiển. Điều này có nghĩa là các sự kiện keyboard cho mũi tên lên, xuống dùng để điều khiển nó, bạn phải đảm bảo rằng vị trí chỉ thay đổi nếu bạn là Master. Mã cho phím mũi tên lên như sau:
{
if (!global.master) exit;
if (y > 104) y -= 6;
mplay_data_write(1,y);
}
Còn cây vợt của Slave cũng được viết với mã tương tự. Giờ đây, cả Master và Slave phải đảm bảo rằng họ đặt vợt của đối phương vào đúng vị trí và chúng ta thực hiện điều này trong sự kiện Step. Nếu là Slave, trong sự kiện Step cho cây vợt của Master, chúng ta thiết lập vị trí như sau:
{
if (global.master) exit;
y = mplay_data_read(1);
}
Thực hiện tương tự cho cây vợt của Slave.
Cuối cùng, đối với quả bóng, chúng ta phải làm cho nó nảy tưng tưng khi đụng vào bàn hoặc vợt. Thực ra, điều này chỉ thực hiện với Master. Để gửi dữ liệu về quả bóng cho Slave, bạn chènt hêm đoạn mã sau vào sự kiện Step.
{
if (global.master)
{
mplay_data_write(3,x);
mplay_data_write(4,y);
}
else
{
x = mplay_data_read(3);
y = mplay_data_read(4);
}
}
Với các mã trên, việc liên lạc cơ bản đã được thực hiện. Việc còn lại là xử lý phần khởi động của trò chơi, phần ghi điểm… Master sẽ quyết định khi nào người chơi thua và thay đổi điểm số, khởi động quả bóng mới.
Một điều cần chú ý là với cách thức liên lạc như trên, hai phần chơi có thể hơi “lệch pha” nhưng bạn có thể tránh rắc rối đó bằng cách đưa vào một object đồng thời. Object này sử dụng một số giá trị để đảm bảo cho hai bên đều sẵn sàng trước khi bất kỳ thứ gì được vẽ ra trên màn hình. Dù vậy, bạn vẫn phải cẩn trọng vì có thể xảy ra tình trạng ngưng để chờ phía bên kia.
Hơn thế nữa, khi một người tham gia vào trò chơi sau khi các giá trị chia sẻ này thay đổi thì chúng sẽ không được gửi tới người mới. Do vậy, chỉ những thay đổi mới sau thời điểm đó mới được gửi đến người mới tham gia.
Cơ chế liên lạc thứ hai mà Game Maker hỗ trợ là gửi và nhận tin nhắn. Người chơi có thể gửi các tin nhắn này đến một hoặc tất cả những người cũng tham gia khác. Các bên có thể nhìn thấy message đến và thực hiện các hoạt động liên quan liền sau đó.
Kỳ 4: Truyền tin nhắn
Những dữ liệu này được gửi theo chế độ đảm bảo, theo đó chắc chắn là chúng tới được nhưng với tốc độ chậm hoặc theo chế độ không đảm bảo nhưng có tốc độ nhanh hơn.
Chúng ta sẽ dùng các message để chèn vào một số hiệu ứng âm thanh mô tả lúc quả bóng đập vào mặt vợt, vào bờ tường… hay lúc một người thắng cuộc. Chỉ có Master mới có thể nhận biết được các sự kiện như thế. Do đó, Master phải quyết định âm thanh nào được phát ra. Việc này khá đơn giản vì Master chỉ cần bật âm thanh đó, nhưng nó phải “bảo” cho Slave cũng phát ra tiếng động này.
Ta có thể dùng cách chia sẻ dữ liệu cho việc này nhưng điều đó khá phức tạp, còn dùng message thì dễ dàng hơn. Master chỉ cần gửi một message đến cho Slave, báo là phải “bật đài”. Còn Slave thì nghe và thực hiện “mệnh lệnh”.
Dưới đây là các công thức truyền message:
mplay_message_send (player,id,val) có chức năng gửi message đến một người chơi xác định (dùng thông số định dạng hoặc một cái tên; dùng số 0 để gửi message cho tất cả những người chơi).
id là một thông số định dạng message có giá trị là số nguyên.
val là giá trị số thực hoặc chuỗi ký tự.
Message được gửi đi bằng chế độ không đảm bảo.
mplay_message_send_guaranteed (player,id,val) làm nhiệm vụ gửi message cho một người chơi xác định (dùng thông số định dạng hoặc một cái tên; dùng số 0 để gửi message cho tất cả những người chơi).
id là một thông số định dạng message có giá trị là số nguyên.
val là giá trị số thực hoặc chuỗi ký tự.
Message được gửi đi bằng chế độ đảm bảo.
mplay_message_receive (player) có chức năng nhận tin nhắn kế tiếp từ dãy message được gửi đến từ một người chơi xác định (một thông số hoặc một cái tên). Dùng số 0 dành cho các tin nhắn được gửi đến từ bất kỳ người chơi nào. Công thức này cho thông báo có message mới hay không. Nếu có, bạn dùng những công thức sau để nhận nội dung tin nhắn:
mplay_message_id ( ) cho thông số của message cuối cùng nhận được
mplay_message_value ( ) cho giá trị của message cuối cùng nhận được
mplay_message_player ( ) cho thông tin người chơi đã gửi tin nhắn cuối cùng thành công
mplay_message_name ( ) hiện tên người chơi đã gửi tin nhắn cuối cùng thành công
mplay_message_count (player) cho hiện ra số message còn lại trong hàng từ người chơi (dùng 0 để đếm toàn bộ các tin nhắn)
Có một số chú ý ở đây. Trước hết, nếu muốn gửi message đến một người chơi duy nhất, bạn cần biết ID của người đó. Như đã nói ở phần trước, bạn có thể có được ID này bằng cách dùng hàm mplay_player_id ( ). Thông số này cũng được sử dụng để khi nhận message từ một người chơi xác định. Hoặc bạn có thể đưa tên của người chơi dưới dạng một dãy ký tự. Nếu nhiều người tham gia lại trùng tên thì chỉ có người đầu tiên nhận được message.
Hai là, bạn có thể thắc mắc tại sao mỗi message lại có một thông số dạng số nguyên. Lý do là điều này sẽ giúp ứng dụng của bạn gửi được nhiều loại tin nhắn khác nhau. Người nhận có thể kiểm tra kiểu message này bằng cách dùng ID. (Nhưng do các message không được đảm bảo có đến được hay không nên việc gửi ID và giá trị trong các tin nhắn khác nhau có thể gây ra những rắc rối nghiêm trọng)
Để gửi âm thanh đi, chúng ta làm theo phương pháp sau đây: khi Master xác định quả bóng đập trúng cây vợt thì nó sẽ thực hiện đoạn mã sau:
{
if (!global.master) exit;
sound_play(sound_bat); // play the sound yourself
mplay_message_send(0,100,sound_bat); // send it to the slave
}
Còn object điều khiển trong sự kiện Step sẽ thực hiện đoạn mã:
{
while (mplay_message_receive(0))
{
if (mplay_message_id() == 100) sound_play(mplay_message_value());
}
}
Nó sẽ kiểm tra xem có message nào không và nếu có, nó sẽ kiểm tra ID là gì. Nếu ID là 100 thì nó sẽ phát ra âm thanh được chọn trong giá trị message.
Nói tổng quát hơn, thường thì trò chơi của bạn có một object điều khiển trong các room và trong sự kiện Step, nó thực hiện công việc sau:
{
var from, name, messid, val;
while (mplay_message_receive(0))
{
from = mplay_message_player();
name = mplay_message_name();
messid = mplay_message_id();
val = mplay_message_value();
if (messid == 1)
{
// do something
}
else if (messid == 2)
{
// do something else
}
// etc.
}
}
Trò chơi bóng bàn mà chúng ta đang thử nghiệm ở phần thực hiện chức năng chơi online này có một vấn đề nghiêm trọng như sau: Khi có sự ngắt quãng trong liên lạc, quả bóng của Slave sẽ tạm thời đứng im. Không có vị trí tọa độ nào được gửi tới và do đó, quả bóng không di chuyển.
Rắc rối này nảy sinh nhất là khi khoảng cách giữa các máy tính quá xa nhau và đường truyền chậm. Khi trò chơi trở nên phức tạp hơn, bạn sẽ cần thêm nhiều giá trị để mô tả tình trạng của nó. Nếu bạn thay đổi nhiều giá trị trong mỗi step thì sẽ có nhiều thông tin hơn cần được truyền đi. Việc này sẽ khiến bạn mất thời gian, làm chậm trò chơi hoặc có thể làm cho mọi hoạt động bị “lệch pha”.
Một cách để truyền tải dữ liệu chia sẻ nhanh hơn được một chút là không dùng chế độ đảm bảo. Bạn có thể dùng hàm sau:
mplay_data_mode (guar) xác định xem có dùng hay không dùng chế độ truyền tải đảm bảo.
guar có thể mang giá trị True (mặc định) hoặc False.
Một kỹ thuật hay hơn để xử lý tình trạng này là xác định điểm “chết”. Tại đây, chúng ta gửi thông tin từ thời điểm này đến thời điểm khác. Vào khoảng thời gian giữa, bản thân trò chơi phải “đoán” điều gì đang diễn ra tùy vào thông tin mà nó có.
Kỳ 5: Xác định điểm "chết"
Chúng ta sẽ áp dụng điều này cho trò chơi bóng bàn: Không chỉ gửi đi vị trí của quả bóng trong mỗi step, ta gửi cả thông tin về tốc độ và hướng đi của quả bóng. Lúc này, Slave có thể tự thực hiện phần lớn các phép tính. Miễn là không có thông tin mới đến từ Master, trò chơi đơn giản chỉ tính đường di chuyển của quả bóng.
Chúng ta sẽ không dùng dữ liệu chia sẻ trong trường hợp này mà dùng cách truyền tin nhắn, chỉ ra thay đổi về vị trí, tốc độ của quả bóng và vị trí của cây vợt. Master gửi những message đó bất cứ khi nào có sự thay đổi. Đối tượng điều khiển trong Slave sẽ “lắng nghe” các tin nhắn này và thiết lập các thông số đúng. Nhưng nếu Slave không nhận được gì, nó sẽ để cho quả bóng di chuyển. Nếu Slave gây ra “lỗi lầm” nhỏ nào thì message sau của Master sẽ sửa lại. Ví dụ, trong sự kiện Step của quả bóng, chúng ta đưa vào đoạn mã sau:
{
if (!global.master) exit;
mplay_message_send(0,11,x);
mplay_message_send(0,12,y);
mplay_message_send(0,13,speed);
mplay_message_send(0,14,direction);
}
Trong sự kiện của đối tượng điều khiển, ta đặt đoạn mã sau:
{
var messid, val;
while (mplay_message_receive(0))
{
messid = mplay_message_id();
val = mplay_message_value();
// Check for bat changes
if (messid == 1) bat_left.y = val;
if (messid == 2) bat_right.y = val;
// Check for ball changes
if (messid == 11) object_ball.x = val;
if (messid == 12) object_ball.y = val;
if (messid == 13) object_ball.speed = val;
if (messid == 14) object_ball.direction = val;
// Check for sounds
if (messid == 100) sound_play(val);
}
}
Chú ý rằng các message không cần phải gửi đi theo chế độ đảm bảo. Nếu lỡ mất một tin nhắn thì vẫn không gây ra vấn đề nào nghiêm trọng lắm. Bạn có thể tìm thấy trò chơi ứng dụng kỹ thuật này trong pong2.gm6. Giờ đây, bạn sẽ thất vọng khi chạy pong2 vì vẫn còn một số chỗ ngắt quãng. Nguyên nhân gây ra sự cố này là đường truyền chậm. Slave có thể nhận các tin nhắn bị gửi lại sau một thời gian, do đó, nó sẽ làm cho quả bóng quay lại một chút rồi sau đó, khi nhận được message mới, nó mới đẩy bóng về phía trước.
Do đó, hãy tiếp tục thử lần thứ ba và bạn có thể kiểm tra công việc với pong3.gm6. Trong trường hợp này, chúng ta chỉ thay đổi thông tin khi quả bóng đụng vào cây vợt. Tất cả phần còn lại của hành động được thực hiện bằng cách dùng đến chức năng xác định điểm “chết”. Master “lo” cho mọi hoạt động diễn ra ở phần vợt của mình và Slave thì chịu trách nhiệm cho hoạt động của vợt ở đầu bên kia. Trong khi quả bóng di chuyển từ đầu này đến đầu kia, không có message nào được truyền đi truyền lại nữa.
Lúc này bạn sẽ thấy quả bóng di chuyển khá mềm mại. Chỉ khi nó đập trúng một cây vợt thì mới có thể xảy ra sự “tắc nghẽn” hoặc quả bóng mới di chuyển trước khi nó đến được cây vợt phía bên kia. Lý do là cơ chế này giả định cả hai phần chơi diễn ra cùng một tốc độ. Nếu một trong các máy tính có tốc độ chậm thì có thể gây ra rắc rối. Nhưng sự tắc nghẽn xảy ra ở một cây vợt sẽ dễ dàng được chấp nhận hơn là trong quá trình chuyển động.
Nhằm tránh rắc rối kiểu này, bạn cần thêm một số cơ chế cải tiến nữa. Ví dụ: bạn có thể gửi thông tin để mỗi bên biết được trò chơi có tốc độ thế nào ở đầu bên kia và có thể sửa lỗi.
Trong chế độ chơi mạng, ắt hẳn người tham gia sẽ muốn nói chuyện với nhau và chúng ta đưa vào bản demo của game một phần “chat chit”. Ta sẽ thiết kế nhiều “phòng” khác nhau và cho người chơi chọn lựa phòng nào tùy ý.
Kỳ 6: "Chát chít" trong game
Ở đây, bạn sẽ dùng đến các message có dải ký tự để gửi đoạn văn bản đi.
Chúng ta sẽ dùng đến một cơ chế hơi phức tạp hơn để thiết lập kết nối. Phòng game đầu tiên giờ đây có 4 sự lựa chọn về kết nối nhưng nó không tạo ra kết nối. Thay vào đó, nó chỉ hiển thị các kiểu kết nối chung. Trong phòng thứ hai, người chơi lại có thể chọn cách tạo một game (hay thực ra là một phòng chat) để tham gia. Đến lúc này kết nối mới được khởi động.
Tùy người chơi có tạo hay tham gia vào game thì một số câu hỏi mới được đưa ra. Sau khi kết nối được thực hiện thành công, phòng game mới được tạo ra hoặc cho phép người chơi tham gia vào. Lần này, người chơi sẽ phải khai báo tên hay một thông tin gì đó để xác định bản thân.
Chúng ta xây dựng một menu tất cả các phòng game để họ chọn lấy một.
Thường thì khi trò chơi tạo ra các điểm dừng của phòng thì phòng game này cũng ngừng hoạt động. Nhưng đối với một chương trình chat thì đây là điều bạn không muốn chút nào vì những người chơi khác vẫn đang tiếp tục trò chuyện với nhau. Điều này có thể xử lý bằng hàm sau đây:
mplay_session_mode (move) xác định chuyển hay không chuyển chủ phòng game (host) sang máy tính khác khi bên này kết thúc hoạt động.
move có thể mang giá trị True hoặc False (mặc định).
Có thể bạn muốn sử dụng lại toàn bộ cơ chế của hai phòng đầu tiên cho trò chơi vì chúng thường như nhau. Sau đó, chúng ta sẽ tới phòng chat. Ở đây chỉ có một đối tượng điều khiển kiểm soát mọi công việc. Khi đã biết cách lập trình theo ngôn ngữ của Game Maker, bạn sẽ thấy phần hiển thị các dòng để gõ chữ khá đơn giản. Bất cứ khi nào người chơi nhấn phím Enter, dòng chữ đã được gõ sẽ được gửi đến tất cả những người cùng tham gia khác, bắt đầu bằng tên của mình. Cũng vậy, khi một người tham gia hoặc thoát khỏi phòng, anh ta cũng gửi message cho mọi người. Bạn có thể tham khảo tập tin chat.gm6 để hình dung ra công việc.
Tải Về Với Pass congtruongit.com
Link down bản GM 8 mới nhất
http://www.mediafire.com/?mmdyfyn5hwc
-
10-21-2008, 03:23 AM #9
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
bác này spam vui quá nhỉ ! Đã thế em theo lun :Khi (33)
-
11-19-2008, 12:39 AM #10
Junior Member
- Ngày tham gia
- Aug 2015
- Bài viết
- 0
huhu. Sao em ko thấy hình ảnh minh họa gì hết vậy nè????
Các Chủ đề tương tự
-
Kho Game [Miễn Phí] Download Tốc Độ Cao
Bởi huongduong30 trong diễn đàn Download Các Loại Game KhácTrả lời: 4Bài viết cuối: 01-11-2013, 05:08 AM -
[Request Game Ps2] Cần tìm link download hoặc địa chỉ bán/copy đĩa game busin 0 alternative neo
Bởi hungcong88 trong diễn đàn Thảo Luận, Yêu Cầu Game Giả LậpTrả lời: 0Bài viết cuối: 10-04-2012, 07:05 AM -
[Cần Game] Cho tôi xin link download game IGI 1
Bởi freedomf trong diễn đàn Thảo Luận, Yêu Cầu Game Hành ĐộngTrả lời: 2Bài viết cuối: 04-12-2012, 04:02 AM -
download game trên web (Game flash) ???
Bởi nguoiloantin trong diễn đàn Game OnlineTrả lời: 1Bài viết cuối: 07-12-2009, 09:55 PM -
Download game châu Á
Bởi phamthaovnn trong diễn đàn Download Game Nhập VaiTrả lời: 8Bài viết cuối: 07-12-2009, 12:26 AM
Review cắt môi bé và giá cắt môi bé tại Đà Nẵng. Ngoài ra, bài viết dưới đây từ đội ngũ bác sĩ của Viện Thẩm Mỹ Viola Eva, sẽ giúp bạn có được thật nhiều kiến thức về cắt môi bé. Mời bạn cùng đọc chi...
Giá Cắt Môi Bé Tại Đà Nẵng Bao...