Đẳng Cấp Học Sinh

Đẳng Cấp Học Sinh

Đại Ân 2
 
Trang ChínhPortalCalendarTrợ giúpTìm kiếmThành viênNhómĐăng kýĐăng Nhập

Share | 
 

 Game Maker (phần 9): Làm game bắn súng góc nhìn người thứ nhất

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down 
Tác giảThông điệp
zavasaki11
Thành Viên Cấp 2
Thành Viên Cấp 2


Tổng số bài gửi : 21
Join date : 03/05/2012
Age : 23
Đến từ : Đại Ân 2

Bài gửiTiêu đề: Game Maker (phần 9): Làm game bắn súng góc nhìn người thứ nhất   Mon May 21, 2012 5:25 pm

Phần hướng dẫn làm game loại này dành cho “nhà thiết kế” cao cấp vì trong quá trình xây dựng trò chơi, bạn cần biết viết mã lệnh. Hơn thế nữa, các chức năng đồ họa 3D rất cần thiết cho thể loại FPS chỉ có trong bản Game Maker đăng ký. Bạn có thể tiếp cận nguồn này với lệ phí 20 USD/năm [You must be registered and logged in to see this link.]

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 [You must be registered and logged in to see this link.].

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à.



Chúng ta thêm các bức tường này để làm nguồn hình nền cho game và cần xác định tọa độ của chúng. Bạn thiết lập được các thông số này trong sự kiện khởi tạo của mỗi object tường riêng lẻ. Ví dụ, để tạo một bức tường ngang, có thể đưa đoạn mã sau vào sự kiện khởi tạo:



Dòng cuối cùng cần một chút giải thích để dễ hiểu. Chức năng background_get_texture () trở lại chỉ mục bề mặt tương ứng với nguồn hình nền đã chỉ ra. Chúng ta sẽ sử dụng nền này sau khi chỉ ra sprite được dùng để vẽ tường và đặt đoạn mã tương tự vào sự kiện khởi tạo cho tất cả các object dạng tường.

Để vẽ một bức tường, trong sự kiện khởi tạo của đối tượng obj_wall_basic, ta đưa vào đoạn mã sau:



Các mã lệnh này sẽ vẽ một bức tường và sử dụng những giá trị mà chúng ta đã thiết lập trong các sự kiện khởi tạo. Hai thông số cuối xác định bề mặt được lặp lại chỉ một lần trong cả hai hướng. Chúng ta sẽ thêm sàn nhà và trần nhà của room trong sự kiện Draw của đối tượng Camera và chèn vào đoạn mã sau:



Tại đây có 3 phần. Trong phần một, chúng ta đặt theo góc để có thể nhìn xuyên suốt room, từ vị trí (x,y,10). Điểm mà chúng ta nhìn theo khá phức tạp nhưng nó đơn giản là một điểm nằm trước một bước theo hướng camera. Cuối cùng, ta xác định hướng di chuyển lên của camera là trục z (0,0,1). Phần thứ hai, ta đặt alpha bằng 1 để tất cả các object đều ở dạng rắn. Đồng thời, đặt màu theo sắc độ trắng vì điều này rất quan trọng. Các kết cấu thực sự bị trộn lẫn với màu hiện tại. Đây là một tính năng rất quan trọng (ví dụ như bạn có thể tô màu đỏ cho trần nhà chẳng hạn). Nhưng thường thì bạn muốn đó là màu trắng. (Màu mặc định là đen, do đó, nếu không thay màu thì toàn bộ thế giới game sẽ là màu đen).

Trong phần thứ 3 chúng ta vẽ sàn và trần (với độ cao 32), có sử dụng đến các kết cấu chính xác. Kết cấu này phải được lặp lại nhiều lần trên trần nhà chứ không phải bị kéo giãn ra khắp bề mặt.



Bước 3: Tạo cảm giác ấn tượng hơn


Trong phần này, chúng ta sẽ tiến hành cải thiện “trò chơi” đã sáng tạo ra trong phần trước. Đầu tiên, chúng ta thêm vào một vài biến số bằng cách dùng nhiều loại tường khác nhau, sau đó biến đổi các thiết kế về level.

Tạo các bức tường khác nhau

Thế giới game mà chúng ta vừa thiết kế trông khá tẻ nhạt vì các bức tường trông y sì nhau và điều này khiến cho game thủ khó xác định mình đang ở đâu. Giải pháp cho rắc rối này lại khá đơn giản – bạn chỉ cần thêm một số kết cấu khác cho trò chơi và các object dạng tường nữa.

Thiết kế level tốt hơn

Level hiện tại có một số rắc rối: các bức tường trông khá phẳng vì bạn có thể nhìn thấy cả hai cạnh của chúng và điều này nên tránh; những khu vực game trông đơn điệu cần phải thay bằng những góc khuất và hành lang hẹp để tạo cảm giác sợ hãi.

Do đó, chúng ta cần thêm không gian bằng cách tăng thêm kích cỡ của room. Để kích cỡ cửa sổ không tăng theo, bạn có thể dùng cách nhìn cửa sổ theo một kích cỡ duy nhất mà mình muốn. Bạn có thể tìm thấy kết quả biến đổi trong tập tin fps2.gm6.



Thêm hiệu ứng sương khói

Để tạo hiệu ứng gây cảm giác “đau tim”, bạn có thể thêm vào game một ít sương mù để các object ở phía xa trông tối hơn (hoặc sáng hơn, tùy theo màu của sương). Khi một object nằm ở quá xa thì người chơi sẽ không nhìn thấy nó và do đó, sương sẽ tạo không khí mờ ảo và rờn rợn, đồng thời khiến ta không phải vẽ những đối tượng nằm quá xa và điều này khiến cho mọi thứ chuyển động nhanh hơn. Muốn tạo sương mù, hãy nhập vào những dòng sau trong sự kiện khởi tạo của object người chơi (sau khi khởi động chế độ 3D).



Nếu khởi động chế độ sương mù với màu đen, hãy bắt đầu với khoảng cách bằng 10 và để cho mọi thứ tối thui tại khoảng cách 300. Chú ý rằng một số card đồ họa không hỗ trợ hiệu ứng tạo sương.

Tạo chuyển động tốt hơn

Điều còn lại là cải thiện phần điều khiển chuyển động. Khi đụng vào một object bạn sẽ ngừng chuyển động tại thời điểm hiện thời. Nhưng việc này khiến cho việc di chuyển giữa các hành lang trở nên khó khăn. Do đó, khi đụng vào vật cản, bạn sẽ thực hiện việc đụng độ dưới một góc nào đó để trượt theo bờ tường hơn là dừng lại. Muốn làm được điều đó, ta cần phải thay đổi một chút. Trước hết, không cần để các bức tường ở dạng rắn nữa. Trong sự kiện đụng độ, ta thêm vào đoạn mã sau:



Trong hai dòng đầu tiên, chúng ta đặt người chơi trở lại vị trí trước đó (để gỡ bỏ tình trạng đụng độ). Sau đó kiểm tra xem có thể di chuyển người chơi theo phương nằm ngang hay không (trượt theo bờ tường nằm ngang). Chúng ta chỉ có thể làm điều này khi tốc độ theo phương ngang lớn hơn theo phương đứng. Nếu vị trí trượt nằm ngang không xảy ra đụng độ với bờ tường thì đặt nó ở đó. Tiếp theo, bạn thử với phương chuyển động thẳng đứng. Nếu cả hai cùng không được, bạn có thể đặt tốc độ bằng 0 để ngừng chuyển động.

Sự thay đổi thứ hai là cho phép đi bộ và chạy. Khi người chơi ấn phím Shift thì sẽ di chuyển nhanh hơn. Muốn làm được, bạn chỉ cần kiểm tra sự kiện bàn phím với mũi tên lên và xuống để xem các phím đó có được nhấn hay không. Nếu như vậy, hãy cho phép tốc độ cao hơn như sau:



Vấn đề cuối cùng là trong phần lớn các game FPS, người chơi có thể bắn phá, di chuyển sang trái, phải. Để làm được điều đó, chúng ta dùng đến phím x và z. Chuyển động nên vuông góc với hướng hiện thời mà người chơi đang quay mặt về. Đối với phím z thì đoạn mã như sau:



Bước 4: Thêm các đối tượng vào game

Lúc này thế giới game vẫn còn thưa thớt vì chỉ có một vài bức tường. Trong phần này, chúng ta sẽ tiếp tục làm cho không gian đó đầy lên. Dù chỉ giữ chức năng trang trí nhưng đó cũng là nơi người chơi và cả đối thủ của họ ẩn nấp. Nói chung là có 2 cách thêm object vào. Cách thứ nhất là tạo ra một đối tượng 3D bao gồm kết cấu tam giác có thể mang lại hiệu ứng cao nhất nhưng khá tốn thời gian; thay vì đó ta dùng các sprite để thể hiện những đối tượng này. Chúng ta sẽ dùng kỹ thuật đó cho tất cả các vật thể như đạn, cây cối, vũ khí, các vụ nổ… Nhưng mọi thứ có vẻ như khó hơn nhiều vì các sprite đều phẳng và nếu chúng ta nhìn lệch hướng, chúng sẽ trở nên “vô hình”. Chúng ta sẽ giải quyết tình trạng này bằng cách giữ cho các sprite đối diện với người chơi.

Các sprite nhìn trực diện.

Chúng ta sẽ tạo ra một đối tượng hình cây để cho không gian game sinh động hơn. Cũng giống như người chơi và các bức tường, bạn có thể dùng một sprite rất đơn giản để thể hiện cái cây trong phòng này. Điều này rất dễ dàng khi thiết kế phòng và sẽ dùng kiểm tra đụng độ để người chơi không thể đi qua được cái cây. Chúng ta cũng đặt đối tượng cây này làm object gốc, giống như object tường cơ sở. Do đó, đối với người chơi (sau này là đạn), cái cây sẽ đóng vai trò như một bức tường. Dù vậy, chúng ta sẽ viết đè lên sự kiện Draw (vẽ) vì phải vẽ ra một cái khác. Để vẽ cái cây, chúng ta cần một sprite đẹp và nó cần phải “trong suốt” một phần và để làm cho các gờ tường trông đẹp hơn, chúng ta đổi sang lựa chọn “làm mượt” chúng. Trong sự kiện Draw, bạn dùng sprite này để vẽ cái cây trên một bờ tường dựng đứng. Do sprite này “trong suốt” một phần nên bạn chỉ nhìn thấy một phần nhất định của bức tường.

Dù vậy vẫn có một vấn đề quan trọng cần giải quyết là xử lý tình trạng “phẳng lỳ” của sprite. Nếu nhìn vào từ mặt bên thì sprite này rất mỏng và thậm chí biến mất. Chúng ta sẽ dùng đến xảo thuật hay áp dụng trong nhiều trò chơi là để sprite này đối diện với camera. Dù trông không tự nhiên lắm, các hiệu ứng vẫn tỏ ra khá tốt. Tuy vậy, bạn vẫn cần đến một thuật toán. Đồ thị dưới đây thể hiện tình huống này. Mũi tên thể hiện hướng mà người chơi nhìn (ký hiệu là D). Hình chữ nhật màu đen thể hiện sprite. Giả định sprite có độ dài là 2L thì các vị trí góc là:



Đoạn mã sau có thể đặt trong sự kiện Draw của đối tượng cây.

Chúng ta xác định bề mặt chính xác của sprite, tính toán đến hai giá trị trên và vẽ sprite trên một bức tường có kích thước 14x20 và đặt đứng trên mặt sàn, xoay theo một hướng chuẩn. Một điều rõ ràng là kích cỡ và vị trí đúng phụ thuộc vào object thực sự được vẽ ra.

Nếu có nhiều sprite được vẽ theo cách này thì thực ra bạn rất dễ chứa giá trị sin và cos làm biến số chung và giá trị này biến đổi theo đối tượng người chơi chứ không phải tính toán lại cho mỗi sprite cần vẽ. Trong mỗi sự kiện End Step của người chơi, chúng ta chứa sin và cos trong biến camsin và camcos.

Một điều cần chú ý nữa là do viền của sprite trong suốt một phần (do đã “làm mượt” chúng) nên phải cẩn thận với thứ tự vẽ object. Các sprite trong suốt một phần này chỉ được “trộn lẫn” với các object được vẽ trước đó. Để đạt đến hiệu ứng như yêu cầu, các sprite alpha được “trộn lẫn” này phải được vẽ sau tất cả các object khác. Điều này có thể làm được bằng cách đặt cho các object dạng cây một độ sâu có giá trị âm. Kết quả như sau:



Các object động

Chúng ta có thể tạo đối tượng động theo cách tương tự như trên. Có hai vấn đề chính. Một là chúng ta cần một sprite bao gồm một vài hình ảnh phụ cho chuyển động. Cần phải đảm bảo sprite thật sự mà chúng ta dùng để thể hiện object có số hình ảnh phụ giống như vậy để có thể dùng được biến image_index kèm theo. Thứ hai, trong sự kiện Draw, chúng ta phải chọn được bề mặt tương ứng với hình ảnh phụ có sử dụng biến image_index. Dưới đây là một đoạn mã có thể được sử dụng trong sự kiện Draw của một đối tượng “phát nổ” nào đó.



Bạn có thể tham khảo tập tin fps3.gm6.

Bước 5: Thực hiện phần bắn súng

Do đây là phần hướng dẫn làm game bắn súng nên chúng ta sẽ tiếp tục cách bắn đạn và cách đưa quái vật vào để làm bia đỡ đạn.

Đưa đạn vào game

Trước hết cần hình ảnh về một viên đạn. Thực ra, chúng ta cần hai viên đạn, một để khi nó đứng yên, một là để khi nó phát nổ. Để có được hình ảnh động chính xác, một điều quan trọng cần lưu ý là những sprite thể hiện cũng có cùng số hình ảnh phụ giống như các hình ảnh động thực sự. Chúng ta đặt cả viên đạn thường và viên đạn nổ làm cơ sở để không thể đi xuyên qua chúng. Bạn có thể đặt viên đạn thường ở các điểm khác nhau trong room. Do chỉ có hai hình ảnh phụ, chúng ta đặt biến số image_speed bắt đầu từ 0,1 trong sự kiện khởi tạo. Trong sự kiện Draw, chúng ta vẽ hình ảnh phụ chuẩn trên một bức tường đối diện như trên.

Khi viên đạn này bị phá hủy (như trong sự kiện phá hủy), ta tạo một viên đạn nổ ở cùng một vị trí. Đối với object này, ta chỉ đặt tốc độ chuyển động chậm. Do viên đạn thường không phát nổ ngay lập tức nên ta đặt một đồng hồ báo động để cho nó nổ vào một thời điểm nào đó.

Chúng ta vẫn vẽ với cách thức như trên nhưng có một xảo thuật như sau: giảm giá trị alpha dần dần để các vụ nổ “mờ dần” theo thời gian. Trong sự kiện Draw chúng ta đặt dòng mã sau đây:



Trong sự kiện cuối cùng, ta phá hủy viên đạn nổ và kết quả có thể thấy trong tập tin fps4.gm6.

Bạn cũng có thể dễ dàng thêm vào một số thứ linh tinh khác nữa để những gì gần viên đạn cũng bị bắn tung lên và vụ nổ gây ảnh hưởng hay thương tổn đến chính nhân vật người chơi.

Tạo súng

Đối với khẩu súng, chúng ta sẽ dùng một sprite động. Sprite này có các hình ảnh cho một khẩu súng tĩnh (subimage 0) và dành để bắn và tải lại. Thường thì chúng ta chỉ vẽ subimage 0 (vì vậy ta đặt image_speed bằng 0) nhưng khi một viên đạn được bắn đi, chúng ta phải dùng đến toàn bộ các hình động. Hãy để khẩu súng làm một lớp phủ (overlay) trên game. Trước hết, đảm bảo object phủ này được vẽ cuối cùng. Điều này có thể làm được bằng cách đặt độ sâu bằng -100. Thứ hai, chúng ta không dùng đến hình chiếu góc nữa mà thay bằng hình chiếu trực giao. Và cuối cùng, chúng ta phải tạm thời tắt chức năng bỏ đi bề mặt ẩn. Mã cho sự kiện Draw như sau:



Bạn có thể dùng một kỹ thuật tương tự cho tất cả các lớp phủ mà mình cần. Dưới đây chúng ta sẽ dùng đến nó để thể hiện “máu’ của người chơi nhưng bạn có thể dùng nó để ra hướng dẫn, thể hiện thông số… Bạn cũng có thể làm cho lớp phủ trong suốt một phần bằng cách thay đổi giá trị alpha.

Bắn súng

Lúc này chúng ta đã có đối tượng để bắn và súng nữa, nhưng màn bắn súng thì chưa có. Do đây là một khẩu súng ngắn nên đạn bay rất nhanh. Vì vậy, vào lúc người chơi nhấn phím Space, chúng ta phải xác định object bị đụng độ và nếu đó là đạn thường thì để nó nổ.

Trước hết, lập một biến số can_shoot để xác định người chơi có thể bắn đạn hay không. Chúng ta đặt giá trị tham số này bằng true trong sự kiện khởi tạo của đối tượng overlay. Nếu người chơi có thể bắn thì ta đặt giá trị đó bằng false và bắt đầu chuyển động của khẩu súng bằng cách thay đổi tốc độ hình ảnh. Vào đoạn cuối của chuyển động, ta đặt can_shoot trở lại giá trị true. Điều này có nghĩa là người chơi không thể bắn liên tiếp được. Để xác định viên đạn nào bắn trúng, chúng ta tiến hành như sau: Thiết lập từng bước nhỏ từ vị trí hiện tại của người chơi theo hướng hiện thời. Đối với mỗi vị trí, chúng ta kiểm tra xem object đó có bị bắn trúng không. Do tất cả các object này là “hậu duệ” của object dạng tường cơ sở nên chúng ta chỉ cần kiểm tra xem có instance nào ở vị trí đó không. Nếu vậy, chúng ta kiểm tra xem đó có phải là đạn thường không và nếu là đạn thường thì hủy bỏ chúng. Bất cứ khi nào bắn trúng một object dạng tường cơ sở, chúng ta cho ngừng vòng lặp vì đây sẽ là kết thúc đường đi của viên đạn. Mã lệnh như sau:



Bạn có thể tham khảo tập tin fps4.gm6.

Thêm địch thủ

Tất nhiên, bắn được đạn đã là thú vui, nhưng kẻ thù càng “ngầu” sẽ càng tăng thêm niềm hứng khởi. Ở đây, chúng ta sẽ tạo ra một con quái vật để làm ví dụ. Để làm được điều này, chúng ta cần 2 sprite động, một để khi nó sống và một để khi nó chết.

Đối với cả hai, chúng ta đặt tốc độ chuyển động này một cách chính xác. Khi nó chết, chúng ta tạo ra một con quái vật đang giẫy giụa ở cùng vị trí đó. Việc này diễn ra giống như đối với viên đạn thường. Chỉ có một sự khác biệt như sau: Vào đoạn cuối của chuyển động, chúng ta không phá hủy con quái vật đã chết mà để nó nằm vất vưởng trên sàn và như vậy chỉ cần hiển thị hình ảnh phụ cuối cùng của tập hợp ảnh động về nó.

Để có thể bắn những con quái vật, chúng ta tiến hành như đối với các viên đạn. Nhưng chúng ta phải thay đổi một chút. Trước hết, không đặt bọn quái vật này là “hậu duệ” của các object dạng tường nữa. Điều này sẽ gây khó khăn khi chúng bước đi loanh quanh. Vì vậy chúng ta thiết lập một đối tượng khác là obj_monster_basic và đây chính là object cơ sở của tất cả các loại quái vật. Sự thay đổi thứ hai là chúng ta cần thiết lập khả năng bắn xuyên qua những lùm cây. Như vậy, chúng ta tạo ra một đối tượng dạng cây cơ sở obj_plant_basic. Đối tượng dạng cây cơ bản này sẽ có gốc là đối tượng dạng tường cơ bản vì chúng ta không muốn đi xuyên qua các lùm cây. Mã bắn đạn được áp dụng như sau:



Phần lớn công việc diễn ra như đối với các viên đạn. Trước hết, chúng ta kiểm tra xem bức tường có bị trúng đạn không. Nếu không, chúng ta kiểm tra xem một con quái vật nào đó có trúng đạn không; nếu trúng thì hủy bỏ nó. Nếu bức tường bị trúng đạn thì tiếp tục kiểm tra xem instance có là một loại cây hay không, và nếu đúng thì tiếp tục (do đó viên đạn sẽ bay xuyên qua cái cây). Cuối cùng, nếu chúng ta bắn đạn trúng thì để nó nổ. Bạn có thể tham khảo tập tin fps5.gm6.

Điều cuối cùng là để con quái vật tấn công người chơi. Địch thủ này không bắn đạn mà đơn giản là đi về phía người chơi. Nếu nó chạm phải người chơi thì sẽ làm mất một ít “máu”. Cơ chế về máu cũng được xây dựng trong Game Maker. Trong sự kiện khởi tạo của nhân vật người chơi, chúng ta đặt lượng máu bằng 100. Trong đối tượng overlay, vẽ thanh máu như sau:



Trong sự kiện No more health, chúng ta sẽ khởi động lại game (dù cho có vẻ hơi nhàm chán).

Muốn để quái vật tấn công lại người chơi, chúng ta đặt đoạn mã sau trong sự kiện Begin Step.



Nếu khoảng cách từ quái vật đến người chơi khá xa thì chúng ta sẽ không làm gì và đơn giản là để tốc độ bằng 0. Nếu quái vật không nhìn thấy người chơi, chúng ta cũng không làm gì cả. Chỉ khi nào nó nhìn thấy người chơi thì nó bắt đầu di chuyển tới. Nếu khoảng cách nhỏ hơn 12, chúng ta giả định nó sẽ đụng vào người chơi và do đó ta để nó dừng lại và bắt đầu lấy đi một ít “máu”, đồng thời cho phát ra một tiếng động đáng sợ. Nếu không, ta di chuyển người chơi đến một vị trí nào đó với tốc độ nhất định. Để tránh cho quái vật đụng vào tường, bạn có thể áp dụng cơ chế trượt tương tự đối với nhân vật người chơi.



Giờ đây, chúng ta đặt một số quái vật trong những nơi “hiểm yếu” và bạn có thể thử tác dụng của nó trong tập tin fps5.gm6. Một điều rõ ràng là để làm mọi thứ trở nên sinh động hơn, bạn nên tạo ra một lối thoát vào room kế tiếp và quanh đó có nhiều quái vật canh giữ rồi tiếp tục lập ra các room khác. Bạn cũng nên tạo thêm các loại quái vật khác nhau và để bình máu rải rác trong room. Cũng vậy, bạn đặt cho quái vật một lượng máu nào đó và có thể xác định xem sau mấy phát đạn trúng thì nó sẽ lăn ra chết.

Những điều cần lưu ý


Tiết kiệm khi thiết kế

Khi đi trong thế giới 3D này, bạn sẽ chỉ nhìn thấy một phần nhỏ của nó mà thôi. Không may là hệ thống đó không nhận biết được bạn nhìn thấy phần nào. Do đó, tất cả các đối tượng (ít nhất là ở đằng trước bạn) đều phải vẽ ra. Điều này khá tốn thời gian và ngay cả trên các card đồ họa thuộc loại nhanh, việc này cũng khiến tốc độ của game bị giảm đi. Tất cả các trò chơi 3D đều phải tính đến vấn đề này và tránh vẽ quá nhiều những đối tượng không cần thiết.

Một phương án để đối phó với tình trạng này là tạo ra những level nhỏ. Sau đó, bạn có thể dùng các điểm đặc biệt như cổng thần (teleporter) để di chuyển từ level này sang level khác. Bạn có thể khéo léo làm việc này để người chơi không nhận ra, ví dụ như đặt nó trong một hành lang ngoằn ngoèo chẳng hạn.

Một cách nữa là chỉ vẽ các object gần với người chơi. Bất cứ khi nào vẽ một cái gì đó, chúng ta kiểm tra xem object đó có khoảng cách đủ gần không. Muốn làm nhanh 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.

Nguồn : [You must be registered and logged in to see this link.]
Về Đầu Trang Go down
Xem lý lịch thành viên
 

Game Maker (phần 9): Làm game bắn súng góc nhìn người thứ nhất

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang 
Trang 1 trong tổng số 1 trang

Permissions in this forum:Bạn không có quyền trả lời bài viết
Đẳng Cấp Học Sinh :: Lập Trình - Thiết Kế :: Phát Triển Game :: Game Maker-