If you're seeing this message, it means we're having trouble loading external resources on our website.

Nếu bạn đang sử dụng bộ lọc web, vui lòng kiểm tra lại xem bộ lọc có chặn hai tên miền *.kastatic.org*.kasandbox.org hay không.

Nội dung chính

Giao diện cho phép tương tác

Trong bài đọc trước, chúng ta đã biết cách tạo những giao diện có hiệu ứng hoạt hình. Trong bài đọc này, chúng ta sẽ tiếp tục tìm hiểu cách xử lý một loại giao diện không tĩnh khác, đó là loại giao diện có thể phản hồi lại tương tác của người dùng. Ta sẽ cùng lập trình giao diện Winston bên cạnh con mình và cho phép người dùng nhấn chuột vào để giúp Winston có thêm em bé.
Sau đây là giao diện trên khi được lập trình trong một chương trình riêng biệt. Chương trình sẽ vẽ trước phần tĩnh của giao diện. Sau đó trong hàm mouseClicked, ta bổ sung câu lệnh vẽ hình ảnh em bé Winston tại vị trí nhấn chuột, chèn lên các hình đã vẽ trước đó:
Làm thế nào để chúng ta tích hợp giao diện này vào chương trình vẽ nhiều giao diện đã có? Ta sẽ bắt đầu bằng cách gộp tất cả các lệnh vẽ hình tĩnh vào hàm vẽ giao diện drawScene5(), đồng thời thêm điều kiện chuyển giao diện vào hàm mouseClicked:
var drawScene5 = function() {
    currentScene = 5;
    background(173, 239, 255);
    fill(7, 14, 145);
    textSize(39);
    text("Winston has babies!", 10, 47);
    ...
};

mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        drawScene1();
    }
};
Ta được chương trình như sau:
Nhưng làm cách nào để tích hợp chức năng của hàm mouseClicked? Chúng ta đã định nghĩa hàm mouseClicked trong chương trình và không thể định nghĩa lần thứ hai. Trong JavaScript, định nghĩa hàm cuối cùng sẽ ghi đè mọi định nghĩa trước đó. Như vậy nghĩa là chúng ta cần tìm một vị trí tốt để đặt dòng lệnh vẽ em bé bên trong hàm mouseClicked hiện có. Hãy cùng tham khảo một số phương án:
1. Đặt dòng lệnh ở đầu hàm:
mouseClicked = function() {
    image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    ...
};
Như vậy, dòng lệnh này sẽ được gọi trong TẤT CẢ các lần người dùng nhấn chuột, ngay cả khi đó không phải là giao diện đang xét. Vì thế, chúng ta không nên chọn phương án này.
2. Đặt dòng lệnh bên trong khối lệnh "if" với điều kiện currentScene === 4:
mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    } else if (currentScene === 5) {
        drawScene1();
    }
};
Đây cũng là vị trí ta gọi hàm drawScene5() và hình vẽ em bé sẽ được thêm vào giao diện thứ 5. Điều này có nghĩa là chương trình sẽ luôn vẽ thêm một em bé trong mỗi lần vẽ giao diện. Tuy nhiên, ta sẽ không thể vẽ thêm bất kỳ em bé nào nữa, bởi vì biến currentScene đã nhận giá trị 5 và các mã lập trình trong khối lệnh "if" đó sẽ không tiếp tục được thực thi.
3. Đặt dòng lệnh bên trong khối lệnh "if" với điều kiện currentScene === 5:
mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
        drawScene1();
    }
};
Lựa chọn này đồng nghĩa với việc chúng ta sẽ không vẽ em bé cho đến khi vẽ xong giao diện thứ 5 và nhấn chuột. Tuy nhiên, như bạn có thể thấy từ dòng lệnh tiếp theo, em bé sẽ ngay lập tức được thay thế bằng giao diện thứ 1.
Đến đây, bạn có thể đã nhận ra một lỗ hổng nghiêm trọng trong ý tưởng tích hợp giao diện có tương tác nhấn chuột này vào chương trình đã có: Chúng ta đang sử dụng cùng một kiểu tương tác (nhấn chuột vào bất kỳ vị trí nào trên khung kết quả) để chuyển giao diện cũng như thực hiện các tương tác bên trong. Để giải quyết vấn đề hóc búa này, chúng ta cần có một giải pháp triệt để hơn.
4. Không vẽ lại giao diện thứ 1 ở cuối chương trình và đề nghị người dùng khởi động lại: Chắc chắn lựa chọn này sẽ có hiệu quả, nhưng phụ thuộc vào việc giao diện tương tác bằng cách nhấn chuột phải là giao diện cuối cùng. Điều gì sẽ xảy ra nếu chúng ta muốn có một giao diện tương tác bằng cách nhấn chuột trước đó? Câu trả lời là, phương án này sẽ không khả thi.
5. Sử dụng một kiểu tương tác khác, chẳng hạn như mouseDragged: Lựa chọn này sẽ có hiệu quả vì thao tác kéo chuột khác với thao tác nhấn chuột. Tuy nhiên, ta vẫn cần kiểm tra điều kiện currentScene === 5 để đảm bảo thao tác kéo chuột không khiến hình vẽ em bé xuất hiện trong bất kỳ giao diện nào khác:
mouseDragged = function() {
    if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    }
};
Hãy thử nghiệm ở chương trình hoàn chỉnh dưới đây, đừng quên kéo chuột khi đến giao diện cuối cùng:
Về cơ bản thì phương án trên đã mang lại hiệu quả. Tuy nhiên, đây chưa phải là một phương án tối ưu vì nó cũng có nghĩa là chúng ta đã tự hạn chế bản thân với những giao diện không phản hồi khi người dùng nhấn chuột. Để vượt qua được giới hạn, ta cần tìm phương án tốt hơn.
Điều gì sẽ xảy ra nếu chúng ta phân biệt các thao tác nhấn chuột theo vị trí để khi nhấn chuột vào một vị trí đồng nghĩa với việc chuyển giao diện và khi nhấn chuột vào các vị trí khác đồng nghĩa với việc tương tác trong giao diện đó? Về cơ bản thì đây chính là các nút bấm trong chương trình và cũng là phương án mà hầu hết các chương trình nhiều giao diện sử dụng trên thực tế. Chúng ta sẽ tìm hiểu về phương án này trong bài đọc tiếp theo.

Tham gia cuộc thảo luận?

Chưa có bài đăng nào.
Bạn có hiểu Tiếng Anh không? Bấm vào đây để thấy thêm các thảo luận trên trang Khan Academy Tiếng Anh.