Advertisement
  1. Code
  2. Coding Fundamentals
  3. Game Development

Làm quen với Crafty: Vòng lặp của Game

Scroll to top
Read Time: 8 min

() translation by (you can also view the original English article)

Đến thời điểm này trong loạt bài, bạn đã học được cách làm thế nào để thao tác các thực thể khác nhau và sử dụng bàn phím để di chuyển chúng xung quanh. Trong phần này, bạn sẽ tìm hiểu cách làm thế nào để sử dụng vòng lặp game trong Crafty để liên tục kiểm tra các sự kiện khác nhau và hoạt hình các thực thể khác nhau.

Vòng lặp game trong Crafty được cài đặt trong Crafty.timer.step, sử dụng các sự kiện toàn cục để liên lạc với phần còn lại của cơ chế. Vòng lặp được điều khiển bởi requestAnimationFrame khi có sẵn. Mỗi vòng lặp gồm một hoặc nhiều lần gọi sự kiện EnterFrame và gọi RenderScene mà cho ra kết quả bằng việc vẽ lại mỗi lớp.

Giá trị cuối cùng của tất cả các thuộc tính và các biến được phân giải trước khi một cảnh được kết xuất. Ví dụ, nếu bạn di chuyển nhân vật 5 px về bên phải mười lần bên trong một sự kiện EnterFrame, nó sẽ trực tiếp vẽ ra 50 px bên phải bằng cách bỏ qua tất cả các bản vẽ trung gian.

EnterFrame và RenderScene

Tất cả mọi thứ trong game của bạn mà cần thay đổi theo thời gian cuối cùng được liên kết đến sự kiện EnterFrame. Bạn có thể sử dụng phương thức .bind() liên kết các thực thể khác nhau với sự kiện này. Các hàm ràng buộc với sự kiện này đồng thời được truyền vào một đối tượng với các thuộc tính như dt xác định số mili giây đã trôi qua kể từ sự kiện EnterFrame cuối cùng.

Bạn có thể sử dụng thuộc tính dt để cung cấp một trải nghiệm chơi Game trơn tru bằng cách xác định khung hình game sẽ tiến lên bao xa.

Sự kiện RenderScene được sử dụng để đảm bảo rằng tất cả mọi thứ có thể nhìn thấy trên màn hình phù hợp với khung hình hiện tại của game ở sự kiện EnterFrame gần nhất. Thông thường, bạn sẽ không cần phải tự mình ràng buộc sự kiện này trừ khi bạn quyết định cài đặt các lớp kết xuất tuỳ biến của riêng bạn.

Sử dụng Tween để hoạt hình các thuộc tính 2D

Bạn có thể sử dụng thành phần Tween khi bạn chỉ muốn hoạt hình các thuộc tính 2D của một thực thể trong một khoảng thời gian cụ thể. Bạn có thể hoạt hình các thuộc tính x, y, w, h, rotationalpha bằng cách sử dụng thành phần này. Chúng ta hãy hoạt hình giá trị x và chiều cao của các hộp màu cam và đen mà bạn đã tạo ở hai hướng dẫn trước.

Dưới đây là đoạn code mà bạn cần:

1
blackBox.tween({x: 500}, 3000);
2
3
orangeBox.tween({x: 50, h: 100, rotation: 360}, 3000);

Bạn có thể thấy rằng hộp màu da cam không quay quanh tâm của nó mà xoay quanh góc trên bên trái của nó. Bạn có thể chuyển sang quay quanh tâm bằng cách sử dụng phương thức .origin(). Nó có thể chấp nhận hai đối số số nguyên xác định khoản cách tâm trên trục x và y.

Nó cũng chấp nhận một giá trị chuỗi như là đối số của nó. Giá trị của chuỗi có thể là một sự kết hợp của center, top, bottom, midle, left và right. Ví dụ, .origin("center") sẽ xoay thực thể xung quanh tâm của nó, và .origin ("bottom right") sẽ xoay thực thể xung quanh góc dưới bên phải của nó.

Bạn có thể tạm dừng hoặc tiếp tục tất cả các tween liên kết với một thực thể nhất định bằng cách sử dụng các phương thức .pauseTweens().resumeTweens(). Tương tự, bạn cũng có thể sử dụng .cancelTween() để hủy bỏ một tween cụ thể.

Tìm hiểu về Crafty Timer

Đối tượng Crafty.timer xử lý tất cả các khoảnh khắc của game trong Crafty. Bạn có thể sử dụng phương thức .FPS() với đối tượng này để có được tỷ lệ khung hình của mục tiêu. Hãy nhớ rằng nó không phải là tỷ lệ khung hình thực tế.

Bạn cũng có thể sử dụng phương thức .simulateFrames(số khung [, số timestep]) để nhích khung hình game lên một số khung nhất định. timestep là khoảng thời gian để truyền mỗi khung hình. Nếu nó không được chỉ định, giá trị mặc định 20ms được sử dụng.

Một phương thức hữu ích khác là .step() mà sẽ nhích game lên bằng cách thực hiện một bước. Một bước có thể gồm một hoặc nhiều khung hình theo sau bởi một kết xuất. Số lượng khung hình sẽ phụ thuộc vào steptype của timer. Phương thức này kích hoạt một loạt các sự kiện như EnterFrameExitFrame cho mỗi khung hình và các sự kiện PreRender, RenderScene, và PostRender cho mỗi kết xuất.

Có ba chế độ khác nhau của steptype: fixed, variable, và semifixed. Trong chế độ fixed, mỗi khung trong Cratfy được gửi cùng một giá trị của dt. Tuy nhiên, steptype này có thể kích hoạt nhiều khung hình trước mỗi kết xuất để đạt được mục tiêu tốc độ của game.

Bạn cũng có thể kích hoạt một khung hình trước mỗi kết xuất bằng cách sử dụng chế độ variable. Trong trường hợp này, giá trị của dt là tương đương với thời gian trôi qua thực tế kể từ khung cuối.

Cuối cùng, chế độ semifixed kích hoạt nhiều khung hình mỗi kết xuất, và thời gian kể từ khi khung cuối được phân chia đều đặn giữa chúng.

Tạo một Game cơ bản

Nếu bạn đã đọc tất cả các hướng dẫn trong loạt bài này, bạn sẽ có đủ kiến thức để tạo ra một trò chơi rất cơ bản. Trong phần này, bạn sẽ tìm hiểu cách làm thế nào để gom tất cả những gì bạn đã học được để sử dụng và tạo ra một game mà nhân vật chính phải ăn một miếng thức ăn.

Thức ăn sẽ là một hình vuông màu đỏ đang xoay. Ngay sau khi thức ăn tiếp xúc với nhân vật, nó biến mất khỏi vị trí cũ và đẻ ra ở một vị trí mới ngẫu nhiên. Người chơi có thể di chuyển nhân vật bằng cách sử dụng các phím A, W, S, D hoặc các phím mũi tên.

Một điều nữa mà bạn cần phải quan tâm là vị trí của nhân vật. Nó được xem như phải ở trong giới hạn của khung hình game.

Hãy viết code cho thức ăn trước:

1
var foodBox = Crafty.e("2D, Canvas, Color, Food")
2
  .attr({x: 150, y: 250, w: 15, h: 15})
3
  .color("red")
4
  .origin("center")
5
  .bind("EnterFrame", function(eventData) {
6
    this.rotation += 4;
7
  });

Mặc định, Crafty sẽ sử dụng góc trên bên trái của thực thể thức ăn để xoay nó. Cài đặt origin thành center đảm bảo rằng các thực thể thực phẩm xoay quanh trung tâm của nó.

1
var playerBox = Crafty.e("2D, Canvas, Color, Fourway, Collision")
2
  .attr({x: 50, y: 360, w: 50, h: 50})
3
  .color("black")
4
  .fourway(200)
5
  .bind("EnterFrame", function(eventData) {
6
    if(this.x < 0) {
7
      this.x = 0;
8
    }
9
    if(this.y < 0) {
10
      this.y = 0;
11
    }
12
    if(this.x > (stageWidth - this.w)) {
13
      this.x = stageWidth - this.w;
14
    }
15
    if(this.y > (stageHeight - this.h)) {
16
      this.y = stageHeight - this.h;
17
    }
18
  });

Thực thể nhân vật kiểm tra vị trí hiện tại của nó trong mỗi khung và thiết lập lại vị trí nếu nhân vật cố gắng đi ra ngoài khung hình của game.

Bạn có thể sử dụng một thực thể Text để theo dõi các điểm số. Số điểm được hiển thị ở góc trên bên trái. Biến gameScore lưu trữ số lần nhân vật va chạm thực thể thực phẩm.

1
var scoreText = Crafty.e('2D, DOM, Text')
2
  .attr({ x: 10, y: 10 })
3
  .textFont({ size: '25px' });
4
5
scoreText.text(gameScore.toString());

Bây giờ, bạn chỉ cần viết code để di chuyển thức ăn đến một vị trí khác khi một va chạm xảy ra. Các code sau sẽ thực hiện chính xác điều đó.

1
playerBox.checkHits("Food").bind("HitOn", function(hitData) {
2
  foodBox.x = Math.random() * (stageWidth - foodBox.w);
3
  foodBox.y = Math.random() * (stageHeight - foodBox.h);
4
  gameScore += 1;
5
  scoreText.text(gameScore.toString());
6
});

Bạn cần phải ghi nhớ rằng bạn trừ chiều rộng và chiều cao của thực thể thức ăn của bạn khỏi các chiều rộng và chiều cao của khung hình tương ứng. Điều này đảm bảo rằng thức ăn luôn luôn hoàn toàn nằm bên trong khung hình game. Dưới đây là một bản demo của game:

Kết luận

Với sự giúp đỡ của Crafty, bạn đã tạo ra một game rất cơ bản bằng cách viết một vài dòng code. Ngay bây giờ, game thiếu một vài tính năng mà có thể làm cho nó thú vị hơn. Đầu tiên, là không có âm thanh. Thứ hai, không có cách nào để người chơi bị loại, và mức độ khó khăn vẫn giữ nguyên trong suốt trò chơi. Bạn sẽ tìm hiểu về âm thanh, sprite, sự kiện chuột và các tính năng khác của thư viện trong các bài tiếp theo.

Nếu bạn có bất kỳ vấn đề hoặc không biết trong khi xem qua tất cả các ví dụ trong loạt bài, hãy cho tôi biết trong phần bình luận nhé.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.