Bối cảnh và vấn đề nghiên cứu

Đề tài tốt nghiệp "Thiết kế và thi công hệ thống trò chơi bắn vịt trời" do sinh viên Lâm Trọng Nhân thực hiện dưới sự hướng dẫn của GVHD Huỳnh Hoàng Hà tại Khoa Đào tạo Chất lượng cao, Trường Đại học Sư phạm Kỹ thuật Thành phố Hồ Chí Minh (ngành Công nghệ Kỹ thuật Máy tính, khóa 2014 - 2018).

Sự phát triển của kỹ thuật điện tử và công nghệ thông tin đã thúc đẩy việc ứng dụng các bộ vi điều khiển hiện đại vào nhiều lĩnh vực đời sống, từ y tế, nông nghiệp, giao thông cho đến các hệ thống giải trí tự động. Trong lĩnh vực trò chơi điện tử, lịch sử phát triển đã ghi nhận bước tiến từ những trò chơi thử nghiệm tương tác người - máy đầu tiên như OXO (cờ ca-rô của Douglas) cho đến các hệ thống máy chơi game thùng (arcade/game xèng) thịnh hành tại Bắc Mỹ và Nhật Bản vào đầu thập niên 1980. Nhằm tiếp cận nguyên lý vận hành của một hệ thống giải trí tương tác thực tế kết hợp giữa phần cứng nhúng và phần mềm máy tính, tác giả đã lựa chọn nghiên cứu và triển khai đề tài này.

Mục tiêu và nhiệm vụ nghiên cứu của đề tài được xác định cụ thể:

  1. Xây dựng một hệ thống trò chơi giải trí hoàn chỉnh trên hệ điều hành Windows sử dụng ngôn ngữ lập trình Python theo mô hình hướng đối tượng.
  2. Thiết kế cơ chế điều khiển tương tác vật lý, cho phép người chơi thực hiện thao tác xoay trái, xoay phải khẩu súng trang bị cảm biến để dịch chuyển hồng tâm trên màn hình và ngắm bắn mục tiêu.
  3. Thiết kế mạch phần cứng thu thập dữ liệu chuyển động và phím bấm, truyền thông ổn định với máy tính qua cổng nối tiếp.

Đối tượng và phạm vi nghiên cứu:

  • Đối tượng nghiên cứu: Kỹ thuật lập trình hướng đối tượng (OOP), lập trình giao diện người dùng (GUI) bằng thư viện Tkinter, vi điều khiển ATmega328 trên bo mạch Arduino Uno R3, và cảm biến quán tính 6 bậc tự do MPU6050.
  • Phạm vi nghiên cứu: Xây dựng trò chơi 2D mức độ cơ bản trên máy tính cá nhân kết nối có dây với module điều khiển súng cầm tay qua giao thức UART và I2C.

Cơ sở lý thuyết và phương pháp

Đề tài sử dụng các nền tảng lý thuyết và công nghệ kỹ thuật sau:

  • Ngôn ngữ lập trình Python và Lập trình hướng đối tượng (OOP): Tác giả sử dụng Python nhờ cú pháp rõ ràng, hỗ trợ đa nền tảng và quản lý module phong phú. Bốn nguyên lý hướng đối tượng được áp dụng gồm:
    • Tính trừu tượng (Abstraction): Trừu tượng hóa các thực thể trò chơi thành các lớp và hàm thuần ảo.
    • Tính đóng gói (Encapsulation): Bảo toàn dữ liệu, kiểm soát truy cập thuộc tính thông qua đối tượng.
    • Tính kế thừa (Inheritance): Tái sử dụng mã nguồn bằng cách xây dựng lớp con kế thừa phương thức và thuộc tính từ lớp cha.
    • Tính đa hình (Polymorphism): Các đối tượng khác nhau kế thừa cùng lớp cha có thể thực thi cùng một phương thức theo các hành vi riêng biệt.
  • Thư viện giao diện đồ họa Tkinter: Gói phần mềm hỗ trợ module Tk chạy trên nền Python để xây dựng các khung nhìn (Frames), nút bấm, nhãn văn bản và đối tượng đồ họa Canvas.
  • Phần cứng vi điều khiển Arduino Uno R3: Sử dụng chip xử lý 8-bit ATmega328 chịu trách nhiệm cấu hình, đọc dữ liệu cảm biến và truyền dữ liệu lên máy tính.
  • Cảm biến MPU6050: Tích hợp cảm biến gia tốc 3 trục (Accelerometer) và con quay hồi chuyển 3 trục (Gyroscope) trong một vi mạch để đo góc quay và gia tốc hướng.
  • Chuẩn giao tiếp I2C và UART: Giao thức I2C 2 dây (SDA, SCL) với cơ chế Master-Slave dùng để giao tiếp giữa Arduino và MPU6050; giao thức UART (chân TX, RX) truyền dữ liệu nối tiếp từ Arduino lên máy tính qua cổng COM ảo.
Thông số Bo mạch Arduino Uno R3 Cảm biến MPU6050
Vi điều khiển / Chip ATmega328 (họ 8-bit) MPU-6050
Điện áp hoạt động 5V DC (cấp qua cổng USB) 3 ~ 5V DC
Tần số hoạt động 16 MHz Tần số bus I2C chuẩn 100kHz - 400kHz
Dòng tiêu thụ Khoảng 30 mA -
Cổng I/O 14 Digital I/O (6 chân PWM phần cứng), 6 Analog (10-bit) Chân giao tiếp I2C: SDA, SCL, chân địa chỉ AD0
Độ phân giải đo ADC 10-bit (0 - 1023) Tốc độ góc: ±250, ±500, ±1000, ±2000 °/s; Gia tốc: ±2, ±4, ±8, ±16g
Bộ nhớ tích hợp 32 KB Flash, 2 KB SRAM, 1 KB EEPROM Các thanh ghi cấu hình và lưu giá trị đo

Thiết kế và triển khai

Hệ thống được thiết kế tích hợp gồm 5 khối chức năng chính:

  1. Khối nguồn: Cung cấp năng lượng 5V DC trực tiếp từ cổng USB máy tính cho toàn bộ hệ thống phần cứng.
  2. Khối cảm biến MPU6050: Thu thập dữ liệu góc quay theo 3 trục của súng trong suốt thời gian trò chơi vận hành. Hai chân SDA và SCL được mắc điện trở kéo lên nguồn để đảm bảo mức logic chuẩn I2C.
  3. Khối phím nhấn: Ghi nhận sự kiện bóp cò súng của người chơi thông qua cơ chế ngắt ngoài (External Interrupt) trên vi điều khiển.
  4. Khối xử lý trung tâm (Arduino Uno R3): Khởi tạo cấu hình thanh ghi MPU6050, đọc dữ liệu góc quay theo chu kỳ, nhận tín hiệu ngắt khi có phím bấm và đóng gói dữ liệu truyền qua UART.
  5. Khối PC Game: Chương trình Python tiếp nhận dữ liệu từ cổng COM ảo, tính toán độ lệch tọa độ pixel để vẽ hồng tâm trên Canvas và xử lý logic tương tác mục tiêu.
# Cấu trúc kế thừa và định nghĩa đối tượng trong Python được tác giả áp dụng
class CBaseObject:
    def __init__(self, canvas, id_obj, pos_x, pos_y):
        self.m_Canvas = canvas
        self.m_nIDObject = id_obj
        self.m_nPosX = pos_x
        self.m_nPosY = pos_y

    def DrawObject(self):
        pass

    def SetPos(self, x, y):
        self.m_nPosX = x
        self.m_nPosY = y

    def GetPos(self):
        return self.m_nPosX, self.m_nPosY

Kiến trúc phần mềm được phân tách thành các lớp giao diện và lớp quản lý dữ liệu riêng biệt:

  • Cửa sổ Menu (CFrmMenu) gắn liền với lớp logic CMyTrailerGame.
  • Cửa sổ Chơi game (CFrmGame) gắn liền với lớp logic CMyGame.
  • Lớp tạo đối tượng chim CFactoryBird quản lý việc khởi tạo định kỳ các đối tượng: CMainBird, CGunBird, và CBulletBird.
  • Lớp thuần ảo CBaseObject và CBaseBird cung cấp thuộc tính cơ bản (tọa độ, ID, mảng hình ảnh, tốc độ bay, hướng di chuyển) và các phương thức Fly(), Move(), DrawObject().
  • Lớp người chơi CPlayer quản lý số lượng đạn (m_nBullet), số chim hạ gục (m_nMainBird) và sở hữu một đối tượng súng CGun (có các thuộc tính đường kính m_nDiameter, dấu chữ thập m_nLenOfLine, màu sắc m_strColor).
Lớp (Class) Thuộc tính chính Phương thức chức năng
CFactoryBird m_arrSpeedMove, m_arrTimeCreateBird, m_arrNumOfBird, các mảng ảnh (m_arrImageGun, m_arrImageBullet, m_arrImageMain) CreateMainBird(), CreateGunBird(), CreateBulletBird(), CheckPosBird(), CancelCreate(), RemoveBird()
CBaseObject m_nIDObject, m_nPosX, m_nPosY, m_Canvas DrawObject(), SetPos(), GetPos()
CBaseBird m_arrPicBirdFlying, m_nSpeedFlying, m_nSpeedMove, m_arrDirection Fly(), Move(), DrawObject()
CPlayer m_nBullet, m_nMainBird, đối tượng CGun Cập nhật điểm số, quản lý trạng thái thắng/thua
CGun m_nDiameter, m_nLenOfLine, m_strColor Thay đổi kích thước hồng tâm theo cấp độ súng

Nội dung chính theo từng chương

Chương 1: Tổng quan

Chương này giới thiệu lược sử phát triển của các hệ thống trò chơi điện tử từ tựa game sơ khai OXO đến các dòng game xèng thùng thập niên 1980. Tác giả trình bày lý do lựa chọn đề tài xuất phát từ mong muốn nắm bắt quy trình xây dựng một trò chơi tương tác thực tế. Chương 1 xác định rõ mục tiêu chế tạo hệ thống bắn vịt điều khiển bằng cử chỉ xoay súng, phạm vi nghiên cứu giới hạn ở tương tác cơ bản giữa Arduino Uno R3, MPU6050 và ứng dụng Python trên máy tính, đồng thời nêu bố cục tổng thể của đồ án gồm 6 chương.

Chương 2: Cơ sở lý thuyết

Chương 2 phân tích cơ sở lý thuyết về ngôn ngữ Python và lập trình hướng đối tượng, so sánh sự khác biệt giữa lập trình thủ tục và lập trình hướng đối tượng thông qua 4 tính chất (trừu tượng, đóng gói, kế thừa, đa hình). Tác giả cung cấp cú pháp khai báo class, constructor __init__, con trỏ self và các ví dụ minh họa. Tiếp theo, chương trình bày chi tiết thông số phần cứng bo mạch nhúng Arduino Uno R3 (vi điều khiển ATmega328, cấu hình chân Digital/Analog/PWM/UART), cấu tạo cảm biến chuyển động MPU6050, và nguyên lý truyền thông I2C (cấu tạo dây SDA/SCL, điều kiện Start/Stop, cơ chế phản hồi bit ACK).

Chương 3: Phần cứng

Chương 3 trình bày sơ đồ khối hệ thống gồm 5 khối chức năng (Nguồn, Cảm biến MPU6050, Phím nhấn, Xử lý trung tâm, PC Game). Tác giả cung cấp sơ đồ nguyên lý đấu nối chi tiết giữa Arduino Uno R3 và MPU6050 qua chuẩn I2C, kết nối phím bấm vào chân nhận tín hiệu ngắt. Chương cũng phân tích lưu đồ thuật toán chương trình chính (khởi tạo thanh ghi cảm biến, lặp vòng đọc dữ liệu gia tốc góc, xử lý quy đổi góc quay thành tọa độ và truyền UART lên PC) cùng lưu đồ ngắt ngoài nhằm tối ưu hóa thời gian đáp ứng khi người chơi nhấn nút bắn.

Chương 4: Phần mềm

Chương 4 tập trung vào cấu trúc phần mềm trò chơi xây dựng bằng Tkinter. Tác giả phân tích cơ chế chuyển đổi giao diện giữa hai cửa sổ Menu Game (hiển thị thông tin, nút Start Game) và Play Game (vùng chơi, hiển thị điểm số, nút End Game) thông qua gửi nhận thông điệp ẩn/hiện Frame. Chương này mô tả chi tiết biểu đồ lớp (Class Diagram), luồng khởi tạo đối tượng chim từ CFactoryBird (tải 3 trạng thái bitmap bay, luân phiên thay đổi ảnh theo timer, tính toán tọa độ di chuyển), luồng hoạt động của Frame Game và quy trình mở rộng thêm một đối tượng trò chơi mới kế thừa từ CBaseBird.

Chương 5: Kết quả

Chương 5 báo cáo kết quả thi công thực tế của hệ thống. Ứng dụng chạy trên nền Python 3.6 giao tiếp mượt mà với cảm biến, hồng tâm di chuyển chính xác theo góc quay súng mà không gặp hiện tượng giật hình. Tác giả đánh giá điểm hạn chế trong việc thay đổi các giá trị hằng số (constants) sau khi đóng gói mã nguồn thành tệp thực thi .exe, từ đó đưa ra giải pháp xây dựng bảng mẫu (template) thiết lập trên Excel, dùng mã Visual Basic (VBA với thư viện Microsoft XML) để xuất ra tệp cấu hình .xml giúp phần mềm nạp lại thông số linh hoạt mà không cần biên dịch lại mã nguồn.

Chương 6: Kết luận và hướng phát triển

Chương 6 tổng kết các kết quả đạt được về mặt học thuật và kỹ năng thực hành thiết kế hệ thống nhúng kết hợp phần mềm. Tác giả đề xuất hướng phát triển mở rộng hỗ trợ nhiều người chơi cùng lúc:

  • Thiết kế cho 2 người chơi: Bổ sung cảm biến MPU6050 thứ hai nối chân AD0 lên nguồn để đổi địa chỉ I2C thành 0x69, ghép phím bấm qua cổng logic AND để chia sẻ ngắt.
  • Thiết kế cho 3 người chơi trở lên: Kết nối chân AD0 của từng cảm biến vào các chân Digital I/O riêng biệt trên Arduino để điều khiển mức logic, chuyển đổi tuần tự địa chỉ về 0x68 khi cần đọc dữ liệu.

Kết quả và đóng góp

Hệ thống đã được chế tạo và thử nghiệm với các kết quả cụ thể:

  • Ứng dụng trò chơi chạy trên nền tảng Python 3.6 và môi trường Windows, nhận dữ liệu ổn định từ bo mạch Arduino Uno R3.
  • Cơ chế đọc dữ liệu góc quay từ cảm biến MPU6050 qua bus I2C và truyền nối tiếp qua UART đáp ứng thời gian thực, hồng tâm di chuyển bám sát chuyển động tay cầm, không xảy ra hiện tượng trễ giật.
  • Toàn bộ mạch phần cứng cầm tay sử dụng nguồn cấp trực tiếp từ cổng USB 5V DC của máy tính mà không cần nguồn phụ ngoài.
  • Thiết lập quy tắc trò chơi rõ ràng với 3 loại thực thể:
    • Main Bird: Xuất hiện cố định 3 đối tượng; người chơi bắn hạ được 2 con đầu tiên sẽ giành chiến thắng.
    • Bullet Bird: Xuất hiện ngẫu nhiên; bắn trúng giúp hồi phục chỉ số đạn (m_nBullet). Mỗi phát bắn (trúng hoặc trượt) đều tiêu hao 1 viên đạn; nếu đạn giảm xuống dưới 0 thì người chơi bị xử thua.
    • Gun Bird: Xuất hiện ngẫu nhiên; bắn trúng giúp tăng cấp độ súng (Level Gun), làm tăng đường kính hồng tâm (m_nDiameter) giúp việc ngắm bắn thuận lợi hơn.
  • Giải pháp kỹ thuật đóng góp: Tác giả xây dựng quy trình cấu hình trò chơi thông qua bảng mẫu Excel và xuất dữ liệu sang tệp XML bằng Visual Basic. Nhờ đó, người vận hành có thể thay đổi các hằng số logic (như xác suất sinh chim Gun Bird) mà không cần can thiệp mã nguồn hay biên dịch lại tệp .exe.

Hạn chế và hướng nghiên cứu tiếp

Hạn chế của đề tài:

  • Đồ án mới dừng lại ở việc thiết kế và thi công phần cứng phục vụ cho một người chơi đơn lẻ.
  • Giao diện đồ họa Canvas 2D và hiệu ứng chuyển động ở mức độ cơ bản.
  • Việc thay đổi cấu hình trò chơi ban đầu gặp trở ngại khi đóng gói thành tệp .exe, đòi hỏi phải bổ sung giải pháp trung gian qua tệp XML.

Hướng phát triển mở rộng được đề xuất trong văn bản:

  1. Mở rộng cho 2 người chơi: Bổ sung thêm 1 cảm biến MPU6050 và 1 phím nhấn. Cảm biến thứ hai được kích hoạt chân AD0 lên mức cao để nhận địa chỉ I2C 0x69 (song song với cảm biến thứ nhất ở địa chỉ 0x68). Tín hiệu 2 phím nhấn được đưa qua cổng logic AND trước khi đưa vào chân ngắt của vi điều khiển.
  2. Mở rộng cho 3 người chơi trở lên: Đấu nối chân AD0 của các cảm biến MPU6050 vào từng chân Digital I/O của Arduino Uno R3. Vi điều khiển sẽ lần lượt kéo chân I/O tương ứng xuống mức thấp để gán địa chỉ 0x68 cho cảm biến cần đọc và giữ các cảm biến còn lại ở địa chỉ 0x69, từ đó đọc tuần tự nhiều cảm biến trên cùng một đường bus I2C.

Giá trị tham khảo

Tài liệu đồ án mang lại giá trị tham khảo thiết thực cho sinh viên các ngành Công nghệ Kỹ thuật Máy tính, Kỹ thuật Điện - Điện tử, Cơ điện tử và Kỹ thuật Phần mềm:

  • Cung cấp hướng dẫn chi tiết về việc kết nối và đọc cảm biến quán tính 6 trục MPU6050 bằng giao thức I2C trên vi điều khiển AVR ATmega328.
  • Cung cấp mô hình tham khảo về lập trình hướng đối tượng (OOP) ứng dụng trong game 2D sử dụng Python và Tkinter Canvas, đặc biệt là cấu trúc phân tầng giữa lớp điều khiển giao diện (Frame) và lớp logic nghiệp vụ.
  • Tài liệu hóa phương pháp kết nối dữ liệu giữa phần cứng nhúng và ứng dụng máy tính qua giao tiếp nối tiếp UART.
  • Đưa ra giải pháp thực tế về quản lý và nạp động các tham số cấu hình phần mềm thông qua định dạng XML kết hợp công cụ bảng tính Excel VBA.

Câu hỏi thường gặp

1. Cảm biến MPU6050 trong đồ án truyền dữ liệu về vi điều khiển bằng giao thức nào và cần lưu ý gì về phần cứng?
Cảm biến MPU6050 giao tiếp với Arduino Uno R3 thông qua chuẩn giao tiếp nối tiếp 2 dây I2C (chân SDA và SCL). Về mặt phần cứng, do hai chân SDA và SCL thuộc dạng cực máng để hở (open-drain) nên bắt buộc phải mắc thêm điện trở kéo lên nguồn (pull-up resistor) để đảm bảo đường truyền nhận diện được mức điện áp logic cao.

2. Điều kiện thắng hoặc thua trong trò chơi bắn vịt trời được quy định như thế nào?
Trong màn chơi (Play Game) xuất hiện tối đa 3 đối tượng Main Bird, người chơi bắn hạ được 2 Main Bird đầu tiên sẽ giành chiến thắng. Mỗi lần bóp cò súng (bắn trúng hoặc trượt), người chơi bị trừ 1 điểm đạn (Bullet). Nếu chỉ số đạn giảm xuống dưới 0 (Bullet < 0), người chơi sẽ bị xử thua cuộc ngay lập tức.

3. Tác giả giải quyết bài toán thay đổi hằng số cài đặt trò chơi sau khi đóng gói mã nguồn .exe như thế nào?
Tác giả thiết kế một bảng mẫu cài đặt trên Microsoft Excel và sử dụng mã Visual Basic (thư viện Microsoft XML) để trích xuất các giá trị thiết lập ra một tệp .xml. Phía chương trình Python được bổ sung phương thức đọc tệp XML này khi khởi động để nạp giá trị vào các biến khởi tạo, giúp người dùng tùy chỉnh tham số mà không cần chỉnh sửa mã nguồn gốc hay biên dịch lại.

4. Bo mạch Arduino Uno R3 xử lý sự kiện bắn súng như thế nào để tránh trễ?
Arduino Uno R3 sử dụng chương trình ngắt ngoài (External Interrupt) để kiểm tra trạng thái phím nhấn trên súng. Khi người chơi bóp cò, chương trình chính tạm dừng để chương trình ngắt thực thi tức thời việc kiểm tra phím và gửi dữ liệu lên máy tính qua cổng UART, đảm bảo thao tác bắn được phản hồi tức thời.

5. Giải pháp kỹ thuật nào được tác giả đề xuất để mở rộng hệ thống cho từ 3 người chơi trở lên?
Tác giả đề xuất nối chân AD0 của từng cảm biến MPU6050 vào các chân Digital I/O riêng biệt trên bo mạch Arduino. Khi muốn đọc dữ liệu từ cảm biến nào, vi điều khiển sẽ xuất mức logic thấp (Low) ra chân I/O tương ứng để gán địa chỉ 0x68 cho cảm biến đó, đồng thời xuất mức cao (High) cho các chân còn lại (địa chỉ 0x69), cho phép đọc tuần tự nhiều cảm biến trên cùng một tuyến bus I2C.


Kết luận

Đồ án tốt nghiệp "Thiết kế và thi công hệ thống trò chơi bắn vịt trời" của sinh viên Lâm Trọng Nhân đã hoàn thiện việc tích hợp giữa phần cứng nhúng thu thập chuyển động và ứng dụng trò chơi hướng đối tượng trên máy tính. Hệ thống vận hành ổn định trên nền tảng Python 3.6 và vi điều khiển ATmega328, cho phép điều khiển hồng tâm súng theo thời gian thực thông qua cảm biến quán tính MPU6050 kết nối I2C và UART. Công trình thể hiện quy trình thiết kế kỹ thuật bài bản từ phân tích lý thuyết, thiết kế sơ đồ mạch, xây dựng kiến trúc lớp phần mềm cho đến việc đề xuất phương án mở rộng hệ thống đa người chơi trong thực tiễn.