Chương 6. Tạo space - shooter game
Chúc mừng
bạn đã tiến tới chương này. Bây giờ, bạn đã học được rất nhièu
điều về C2 và cách sử dụng nó. Bạn biết về các hành vi và cách
sử dụng nó qua các sự kiện. Bạn cũng đã học về các biểu thức và
sự kiện phụ, thứ vô cùng hữu ích khi tạo game phức tạp. Tuy nhiên,
vẫn còn một thứ mà nếu bạn muốn tạo ra sự hấp dẫn cho trò chơi,
đó là sự cạnh tranh.
Làm
cho người chơi cạnh tranh với bạn bè của họ là một cách hay để cải
thiện kinh nghiệm. Có một cách để làm điều này là thêm một bảng
thành tích vào game của bạn để người chơi chiến đấu cho vị trí cao
nhất. Chúng ta sẽ thêm phần tử này vào space shooter game (game bắn
máy bay giống như chiến cơ huyền thoại). Trong việc tạo ra game bắn
máy bay này, bạn sẽ học cách cuộn background và sinh ra một đối tượng
mới liên quan đến một đối tượng đã có.
Trong
chương này, bạn sẽ học:
- Cách để tạo ra một cuộn background (chả biết gọi thế nào :’))), scrolling background).
- Cách lưu các biến vào C2 và so sánh chúng với những biến được lưu khác.
- C2 lưu dữ liệu trên máy tính hoặc thiết bị của người chơi như thế nào.
Bài 1. Thiết lập trò chơi
Giống
như những chương trước, ta sẽ bắt đầu thiết kế layout của chúng ta.
Các sprite sử dụng trong chương này có thể tìm thấy ở tệp Space shooter. Tuy nhiên, ta cần phải
thay đổi độ phân giải mặc định đầu tiên, bởi vì game bắn máy bay này
sử dụng màn hình dọc. Chúng ta sẽ bắt đầu với một new empty project, theo mặc định,
bạn sẽ có màn hình phân giải 854 x 480. Để thay đổi điều này, chúng
ta chỉ cần thay đổi kích cỡ màn hình trong Project Properties. Để mở Project
Properties hoặc kích vào tên project, nhìn vào thanh Properties bên tay trái:
Kích
vào cái này sẽ hiển thị thuộc tính của project với rất nhiều hình
dạng bạn có thể áp dụng cho project của mình, chẳng hạn như thay đổi
tên hay miêu tả của trò chơi, chọn trình duyệt xem trước để sử dụng,
và lựa chọn engine vật lí cho các hành vi vật lí, cùng nhiều thứ
khác. Bây giờ hãy thay đổi kích thước 480 x 854. Đây là độ phân giải
WFVGA và là tỉ lệ hiển thị 16:9 của màn hình rộng. Đây là độ phân
giải an toàn mà ko cần bất cứ cắt hình ảnh nào. Tôi sẽ thay đổi chiều
rộng và chiều cao của nó thành chế độ chân dung thay vì cảnh quan.
Như bạn có thể thấy ở layout, thay đổi này cũng làm thay đổi các đường gạch đứt thành hình dạng thẳng đứng. Sau đó, thêm background mới và playerShip object. Để cho người chơi di chuyển, thêm hành vi 8 Direction và ngăn ko cho nó di chuyển ra khỏi màn hình bằng hành vi Bound to Layout. Đừng quên thiết lập thuộc tính Set angle của hành vi 8 Direction thành No vì ta muốn nó hướng mặt lên trên mọi lúc.
1. Cuộn các cửa ải
Bây
giờ, giống như tất cả các trò chơi bắn súng khác, chúng ta sẽ khiến
người chơi đi đến trụ sở của kẻ địch và tiêu diệt tất cả tàu địch
trên đường đi của họ. Tuy nhiên, thật sự là màn hình ko hề di chuyển
đi bất cứ chỗ nào. Con tàu của người chơi tiến lên phía trước chỉ
là ảo giác; thật sự là cái bản đồ đang di chuyển ngược về phía con
tàu, khiến cho người chơi tưởng là con tàu đang tiến lên. Đây là mẹo
trong lập trình game để khiến người chơi tiến về phía trước. Bạn
cũng có thể lập trình cho tàu bay tiến về phía trước cũng được.
Bây giờ, tạo
một layer mới gọi là Star và
thêm nó dưới Main layer trên Background layer. Chúng tôi tạo ra
con tàu của mình ở Main layer, và cũng sẽ tạo tàu địch ở đó. Stars layer là nơi ta sẽ tạo ra
những ngôi sao di chuyển ngược trở lại, hoặc giảm đi trong trường hợp
này, để tạo cho người chơi ảo giác tiến về phía trước. Để làm điều
này, trước tiên hãy tạo một star sprite object và thêm nó vào Stars layer và sau đó thêm hành vi Bullet để nó có thể di chuyển.
Bạn có thể sử dụng star sprite trong tệp Sprites/ Space shooter / Effect. Sau đó, chuyển tới event sheet
vì ta sẽ làm các ngôi sao di chuyển xuống bằng cách dùng code.
Logic
của game là như thế này: mỗi 0.5 giây, ta sẽ tạo ra một ngôi sao ở
một vị trí ngẫu nhiên trên màn hình, và sau đó, ta sẽ thay đổi góc
chuyển động để nó di chuyển xuống. Chúng ta cũng sẽ thay đổi tốc độ
của nó để những ngôi sao ko di chuyển qá nhanh. Dịch nó sang code và
bạn sẽ nhận được kết qả như sau:
Nếu bạn test
game bây giờ, bạn sẽ thấy ngôi sao đi xuống dưới màn hình, tạo ra ảo
giác người chơi tiến về phía trước. Nếu trong khi test, bạn di chuyển
quá xa về phía tay phải hoặc phía dưới màn hình, bạn sẽ nhận ra rằng
con tàu bay ra khỏi cửa sổ màn hình, trong khi bên trái và phía trên
thì ko bị.
Cái
gì gây ra điều này? Có phải chúng ta đã ko thêm hành vi Bound to Layout? Đó là do ta buộc
nó vào layout (bound to layout), chứ ko phải là cửa sổ màn hình. Để
trói buộc con tàu vào cửa sổ màn hình, chúng ta sẽ phải thay đổi
kích thước của layout để phù hợp với cửa sổ trò chơi. Chúng ta có
thể dễ dàng thiết lập cái này từ thuộc tính của layout:
Bây
giờ thì con tàu đã hoàn toàn bound
to window.
WAITING FOR LUV
Bạn có muốn cải thiện khả năng thiết kế đồ họa của mình? Chắc hẳn các bạn cũng biết, nếu các dòng code là linh hồn của một trò chơi, thì đồ họa chính là bộ mặt của trò chơi đó. Đồ họa đẹp, dễ nhìn sẽ khiến trò chơi của bạn tăng tỉ lệ hấp dẫn người xem đến 90%. Hiện tại có hai công cụ hỗ trợ thiết kế đồ họa game tiện nhất mà mình biết, đó là Photoshop và Illustrator. Mình sẽ cố gắng tìm kiếm và chia sẻ các đồ họa game miễn phí cho các bạn tại blog này; tuy nhiên,
một trò chơi mà 100% do chính mình tạo ra vẫn hơn là đi cóp nhặt hình ảnh từ nơi khác đúng không nào. Tiện đây, mình có chia sẻ một khóa học thiết kế đồ họa Game 2D cho Mobile. Các bạn có thể tham khảo dưới đây để được giảm 40% học phí nhé.
2. Tạo kẻ thù
Tiếp theo
chúng ta sẽ tạo ra kẻ địch, bởi vì ko thể có trò bắn máy bay nào
mà lại ko có cái để bắn. Thêm một sprite object được gọi là enemy và đặt nó ở Main layer. Kẻ địch sẽ làm 2 điều:
di chuyển và bắn. Di chuyển đối tượng kẻ địch thì rất dễ, nó giống
với di chuyển những ngôi sao. Vì vậy, chỉ cần làm lại những bước
đó. Bây giờ, tôi sẽ giải thích cách tạo ra kẻ địch một cách ngẫu
nhiên.
Chúng
ta sẽ tạo ra kẻ địch ở một vị trí bất kì mỗi 2 giây, và sau đó,
kẻ địch sẽ di chuyển chậm dần xuống bên dưới. Vì vậy, hãy thêm
hành vi Bullet cho đối tượng kẻ địch của chúng ta và thiết lập
giá trị góc thành No. Sau đó ta
sẽ thay đổi tốc độ thành 100 để nó di chuyển chậm hơn. Tiếp theo ta
sẽ tạo kẻ địch ở tọa độ x
ngẫu nhiên trên màn hình và thiết lập góc của nó là 90 như sau:
Test game bây
giờ, và bạn sẽ thấy ta đã tạo ngẫu nhiên được kẻ địch. Tiếp theo là
thiết lập cho chúng bắn.
Từ bắn có nghĩa là kẻ địch sẽ tạo
ra một đối tượng mới thuộc về chính nó, và đối tượng mới đó sẽ
tự di chuyển. Trong trường hợp này ta sẽ tạo ra một viên đạn mới và
bắn nó xuống. Để làm điều này, ta cần 2 điều:
- Đối tượng viên đạn.
- Hình ảnh kể thù.
Chính
vì vậy, hãy thêm một sprite object mới như một viên đạn. Ta sẽ đặt tên
viên đạn này là enemyBullet để
phân biệt nó với viên đạn của người chơi. Trước khi kết thúc việc
này, chúng ta sẽ xoay hình ảnh này 90o theo chiều kim đồng
hồ. Lí do mà ta làm điều này là đối tượng này sẽ sử dụng hành vi Bullet cho sự di chuyển, và ta muốn
thay đổi góc chuyển động của hành vi Bullet.
Góc 0 độ của sự di động sẽ nhắm vào phía bên phải màn hình, xoay
vòng sprite nếu bạn muốn kẻ địch bắn về nhiều phía hơn là một.
Đóng cửa sổ chỉnh sửa hình ảnh để thêm viên đạn vào layout và đặt nó ở đâu đó bên ngoài màn hình. Một điều nữa là ta cần tự động phá hủy viên đạn khi nó bắn ra khỏi màn hình, bời vì ta ko cần một viên đạn hết hạn sử dụng. Chúng ta có thể dùng code, nhưng cũng có một hành vi dành cho điều này, đó là Destroy Outside Layout; nó sẽ phá hủy đối tượng ra khỏi layout. Thêm hành vi này vào enemyBullet.
Tiếp theo, ta
sẽ thêm điểm ảnh cho đối tượng kẻ địch. Điểm ảnh này sẽ là nơi viên
đạn được tạo ra bởi kẻ thù. Vị trí điểm ảnh ở phàn dưới nửa giữa
của sprite. Chúng ta cần kẻ địch bắn viên đạn tại một khoảng thời
gian thay vì mỗi lần tích. Vì vậy hãy thêm hành vi Timer cho đối tượng kẻ địch.
Logic
là khi kẻ địch được tạo, chúng ta sẽ bắt đầu hẹn giờ để thiết lập
khoảng thời gian cho mỗi lần bắn và khiến bộ hẹn giờ này lặp lại.
Mỗi lần hẹn giờ được kích hoạt, chúng ta sẽ sinh ra một viên đạn mới
tại điểm ảnh mà chúng ta tạo. Sau đó, ta sẽ chuyển đổi góc của viên
đạn để khiến nó đi xuống. Code dành cho sự kiện enemy On created như sau:
Và
đây là code dành cho enemy On timer “
shoots “ như sau:
Điều
này sẽ khiến kẻ địch bắn đạn mỗi giây. Nếu bạn nghĩ khoảng thời
gian quá ngắn, bạn có thể thay đổi nó. Test game bây giờ, và bạn sẽ
thấy thành quả của mình.
3. Xóa những đối tượng bên ngoài màn hình
Bây giờ, ta
có 2 đối tượng bên ngoài màn hình và ko sử dụng nữa, đó là: kẻ
thù và ngôi sao. Phá hủy những đối tượng bên ngoài màn hình sẽ là
một thói quen tốt, nó sẽ tối ưu hóa dung lượng cho game, vì vậy hãy
phá hủy chúng.
Chúng
ta sẽ phá hủy đối tượng kẻ địch khi chúng di chuyển vượt quá 100
pixel phía dưới màn hình và với ngôi sao là 50 pixel. Có một biểu
thức của System được gọi là LayoutHeight sẽ nói cho ta biết chiều
cao của layout hiện tại, và ta sẽ sử dụng nó để so sánh với tọa độ
y của cả 2 đối tượng. Nhìn vào
sự kiện sau:
4. Thiết lập tàu của ta có thể bắn kẻ địch
Thật tuyệt
khi ta đã làm kẻ địch bắn được chúng ta, nhưng ko vui chút nào nếu
chỉ mình bị ăn hành, vì vậy hãy làm cho tàu của mình có thể bắn
được kẻ địch. Chúng ta sẽ làm một chút khác biệt với đối phương
bắn; chúng ta sẽ làm tàu của người chơi bắn khi họ ấn nút nào đó, ví
dụ phím Z.
Để làm điều
này, chúng ta chắc chắn phải thêm đối tượng Keyboard vào project của mình. Sau đó ta sẽ thêm hành vi Timer cho đối tượng playerShip. Sau đó ta sẽ thêm đối
tượng viên đạn của người chơi tới layout và thêm hành vi Bullet cho nó. Giống như đối tượng enemyBullet, chúng ta sẽ xoay vật
này 900 theo chiều kim đồng hồ. Cuối cùng ta sẽ thêm một
điểm ảnh cho playerShip, đó là
nơi viên đạn được sinh ra.
Bây
giờ, hãy thiết kế logic cho việc bắn đạn. Chúng ta sẽ bắt đầu hẹn
giờ khi người chơi bấm nút Z, bởi vì chúng ta ko muốn bắt đầu hẹn
giờ sau mỗi lần tích mà nút Z được nhấn. Chúng ta sẽ dừng hẹn giờ
khi người chơi ngừng bấm nút Z; đó là lúc mày bay ngừng bắn. Việc
bắn diễn ra khi hẹn giờ chạy, chúng ta sẽ thiết lập hẹn giờ để
kích hoạt mỗi nửa giây. Nếu ta dùng code, thì nó sẽ như này:
Test game bây giờ, và bạn có thể thấy người chơi có thể bắn sau khi nút Z đước nhấn và ngừng bắn khi nút Z được nhả ra. Có lẽ bạn sẽ tự hỏi “Tại sao chúng ta không sử dụng sự kiện is key down của đối tượng Keyboard để kiểm tra khi nút Z được bấm và sinh ra một viên đạn mới nếu giá trị là true? Nó không giống nhau sao?”. Chính xác, nó ko giống nhau. Nếu chúng ta sử dụng sự kiện is key down, sự kiện này sẽ đúng với mỗi lần tích, và con tàu của người chơi sẽ bắn vào mỗi lần tích. Đây là điều chúng ta ko muốn vì nó khó kiểm soát. Sử dụng một sự kết hợp của hành vi Timer và On key pressed sẽ khiến nó dễ dàng hơn để thay đổi khoảng thời gian của phát bắn.
5. Thêm các hiệu ứng
Bây
giờ cả người chơi và kẻ địch đều có thể bắn, hãy làm cho viên đạn
đập vào họ thay vì đi xuyên qua họ. Để làm nó trông giống như một
phát nổ, chúng ta sẽ phá hủy viên đạn khi chúng va chạm. Chính vì
vậy, chúng ta sẽ phá huye viện đạn của kẻ địch khi nó va chạm với
người chơi và ngược lại. Tuy nhiên, khiến chúng biến mất như thế sẽ
khiến người chơi cảm thấy ko thật, chính vì vậy hãy thêm 2 sprite
object để xuất hiện khi viên đạn va chạm và đặt tên chúng là playerBlast và enemyBlast. Sau đó, hãy thêm dòng code để nó xuất hiện:
Dòng
code cho sự kiện On colission with enemy như sau:
Test
thử trò chơi và bạn sẽ thấy hiệu ứng nổ khi va chạm với kẻ thù.
Có vẻ
tốt hơn rồi đấy, nhưng hiệu ứng nổ ko biến mất sau khi được xuất hiện.
Hãy thêm hành vi Fade cho cả hai
đối tượng playerBlast và enemyBlast để khiến chúng biến mất
dần, thời gian có thể thay đổi từ thuộc tính của nó. Sau đó, hành
vi này sẽ phá hủy đối tượng khi nó biến mất hẳn.
Bản dịch do construct2vn.ga thực hiện
Ai sao chép hay chia sẻ hãy ghi nguồn và đưa link www.construct2vn.ga vào đầu bài chia sẻ nhé
Ai sao chép hay chia sẻ hãy ghi nguồn và đưa link www.construct2vn.ga vào đầu bài chia sẻ nhé