STDIO
Tìm kiếm gần đây
    Nội dung
    0
    0
    Chia sẻ
    Nội dung
    0
    0
    Chia sẻ

    STML5 CF - Game Loop

    Một khi đã đặt chân vào lĩnh vực phát triển game, bạn chắc chắn sẽ gặp một thuật ngữ cho dù game bạn có nhỏ hay lớn thế nào đi chăng nữa. Đó là Game Loop. Trong bài viết này, tôi sẽ giới thiệu cho các bạn thuật ngữ này và cách hiện thực Game Loop sử dụng STML5 CF.
    27/08/2015 24/09/2020 4 phút đọc
    STML5 CF - Game Loop

    Khi đặt chân vào lĩnh vực phát triển game, dù game lớn hay nhỏ, bạn chắc chắn sẽ gặp một thuật ngữ đó là Game Loop. Trong bài viết này, tôi sẽ giới thiệu về Game Loop và cách hiện thực Game Loop bằng STML5 CF.

    Bài viết này dành cho những bạn đang muốn tìm hiểu HTML5, STML5 CF và những bạn muốn tự phát triển Framework HTML5 riêng cho những sản phẩm của mình.

    Game Loop là gì

    Game Loop (vòng lặp game) là trái tim của tất cả các game hiện nay. Tất cả những phần liên quan đến xử lý sự kiện, cập nhật trạng thái game (như vị trí của nhân vật, trí thông minh của các con quái, cảnh chơi ... ) đều nằm trong Game Loop. Game Loop gồm có 3 thành phần cơ bản là handleEvents (để xử lý những sự kiện do hệ thống sinh ra), update (cập nhật trạng thái game) và render (vẽ game).

    Tùy cách nhìn nhận khác nhau, tôi thường thêm 2 thành phần nữa vào Game Loop là init (khởi tạo trạng thái ban đầu của game) và release (giải phóng tài nguyên game đã sử dụng). Lúc này tôi gọi nó là Game Loop mở rộng.

    Game Loop của tôi trong game sẽ có dạng như sau:

    init();
    while(isGameRunning)
    {
        handleEvents();
        update();
        render();   
    }
    release();

    Hiện thực Game Loop sử dụng STML5 CF

    Chương trình chính của tôi đơn giản chỉ là file html nhúng thư viện STML5 CF và những file tôi viết để demo cho bài viết này. Tất cả những phần ma thuật tôi sẽ viết trong stml5Game.js.

    <!DOCTYPE html>
    <html>
    <head>
    <!-- Include STML5CF -->
    <script src="../stml5cf/Graphics.js"></script>
    <script src="../stml5cf/TextureCache.js"></script>
    
    <!-- Demo Sources -->
    <script src="./src/Resources.js"></script>
    <script src="./src/stml5Game.js"></script>
    </head>
    <body onload="startGameLoop()">
    </body>
    </html>

    Sau khi trang Web của tôi load xong, tôi sẽ gọi hàm startGameLoop để kích hoạt game của mình.

    Game Loop

    Game Loop của tôi bắt đầu ngay sau khi TextureCache của tôi load xong

    this.textureCache.startLoading(function() {
        game.init();
        gameLoop();
    }); 

    Với đoạn code trên, bạn đã thấy một phần trong Game Loop mở rộng là init rồi phải không. Ở phần dưới đây bạn sẽ thấy những phần còn lại.

    function gameLoop() {
        window.requestAnimationFrame(gameLoop);
    
        game.update();
        game.render();
    }

    Hai thành phần update và render xuất hiện không có gì lạ. Mấu chốt ở đâu là cách sử dụng hàm window.requestAnimationFrame. Hàm window.requestAnimationFrame thông báo cho browser biết hàm gameLoop của bạn chính là một vòng lặp. Khi gọi hàm này, browser của bạn sẽ gọi lại hàm gameLoop ở lần vẽ tiếp theo. Điều đó giúp bạn tạo một vòng lặp game hoàn chỉnh.

    Ví dụ minh họa

    Trong ví dụ minh họa, tôi sẽ vẽ logo của Stdio ở giữa màn hình và cho logo này di chuyển theo đường chéo. Khi gặp các cạnh của Canvas, logo sẽ đổi hướng theo góc phản xạ.

    Hiện thực hàm init

    this.init = function() {
        this.screenWidth = 800;
        this.screenHeight = 480;
    
        initSTML5CF(this.screenWidth, this.screenHeight);
    
        this.x = 400;
        this.y = 240;
    
        this.vx = 2;
        this.vy = 3;
    
        this.stdioImage = this.textureCache.getImage(s_stdioLogo);
    };

    Trong phần init này, tôi đã khởi tạo STML5CF thông qua hàm initSTML5CF và các trạng thái game như vị trí, vận tốc di chuyển của logo. Ngoài ra tôi khai báo thêm 1 biến thành viên stdioImage để sử dụng cho việc vẽ trong hàm render.

    Hiện thực hàm update

    this.update = function() {
        var dt = 1; //THIS IS A CHEAT
        this.x += this.vx*dt;
        this.y += this.vy*dt;
    
        if(this.x < 0 || this.x > this.screenWidth - getImageWidth(this.stdioImage)) {
            this.vx = -this.vx;
        }
    
        if(this.y < 0 || this.y > this.screenHeight - getImageHeight(this.stdioImage)) {
            this.vy = -this.vy;
        }
    }
    

    Logic phần update tương đối đơn giản. Vị trí của logo được tôi tăng tùy thuộc vào thời gian giữa 2 frame liên tiếp nhau dt. Trong ví dụ này, tôi cho dt có giá trị cố định nhưng trong thực tế, bạn phải tính toán con số này thật CHÍNH XÁC. Phần còn lại là phần tôi dùng để thay đổi chiều chuyển động của logo.

    Lưu ý: Hàm getImageWidthgetImageHeight là 2 hàm dùng để lấy chiều rộng và chiều cao của hình ảnh. Các hàm này nằm trong STML5 CF.

    Hiện thực hàm render

    this.render = function() {
        clearScreen();
    
        drawImage(this.stdioImage, this.x, this.y);
    }

    Trong game, hàm render luôn luôn bắt đầu bằng một phép gọi hàm để xóa sạch màn hình game. Trong ví dụ này cũng vậy, tôi gọi clearScreen() để xóa sạch Canvas. Sau đó tôi dùng hàm drawImage để vẽ logo tại vị trí tôi đã khai báo ở trên.

    Mã nguồn

    Bạn có thể tải toàn bộ mã nguồn của bài viết này tại STML5CF_GameLoop.

    Bài chung series

    0 Bình luận
    JavaScript

    JavaScript

    STDIO Training - Đào tạo lập trình Frontend - Backend.

    Khi bạn nhấn vào sản phẩm do chúng tôi đề xuất và mua hàng, chúng tôi sẽ nhận được hoa hồng. Điều này hỗ trợ chúng tôi có thêm kinh phí tạo nhiều nội dung hữu ích. Tìm hiểu thêm.
    STDIO

    Trang chính

    Công ty TNHH STDIO

    • 30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
      +84 28.36205514 - +84 942.111912
      developer@stdio.vn
    • 383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
      Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012
    ©STDIO, 2013 - 2021