Từ những kiến thức đã được học và tiếp thu từ ngôn ngữ Python thì việc tạo ra đượ ứng dụng hay lập trình ra game là điều mà nhà phát triển chuyên nghiệp phải hướng đến. Bài viết sau sẽ giúp bạn lập trình game rắn săn mồi với Python.
Giới thiệu về game rắn săn mồi với Python
Game rắn săn mồi là trò chơi không còn xa lạ với mỗi chúng ta khi còn bé. Trò chơi này được ra mắt từ năm 1970 và được ưa chuộng cho đến năm 1990. Nội dung của game là người chơi sẽ điều khiển một con rắn, rồi truy tìm những con mồi để trở nên dài hơn. Không những vậy, con rắn phải tránh những vật cản hay va chạm vào tường.
Cách lập trình game rắn săn mồi với Python
Sau khi đã nắm được game rắn săn mồi, bước tiếp theo chúng tôi sẽ hướng dẫn bạn cách tạo ra game rắn săn mồi với Python. Trước tiên, hãy dùng thư viện pygame cũng như định nghĩa những đối tượng liên quan trong game bao gồm: rắn, mồi và vật cản. Hãy nhớ chúng ta sẽ được phép điều khiển con rắn thông qua bốn phím mũi tên.
Dưới đây là các bước cơ bản để giúp các bạn làm ra game này. Hãy theo chúng tôi để tìm hiểu nhé.
Cài đặt module Pygame
Trước tiên, bạn phải cài đặt module Pygame. Nói cách khác, phải nhập câu lệnh bên dưới để cài đặt module này.
pip install pygame
Khi quá trình cài đặt kết thúc, nhập Pygame và triển khai việc viết mã cho dự án của bạn.
Khởi tạo màn hình game
Hãy dùng hàm ‘display.set_mode()’ để tạo màn hình game rắn săn mồi. Sau đó, các bạn phải dùng phương thức init() hay quit() để tạo mới cũng như loại bỏ tất cả những thứ không cần thiết còn sót lại trong chương trình.
Tiếp điến, dùng phương thức update() để cập nhật những thay đổi mà thực thi trên màn hình trò chơi. Ngoài ra, các bạn có thể dùng phương thức flip() để thay thế phương thức update(). Tính năng và công dụng của phương thức flip() cũng không quá khác biệt so với hàm update(). Tuy nhiên, hàm update() chỉ cập nhật thay đổi được thực thi (trong trường hợp không truyền vào tham số). Ngược lại, hàm flip() sẽ cập nhật lại cho màn hình với những thay đổi bất kỳ liên tục.
import pygame pygame.init() #Tạo một màn hình hiển thị trò chơi với kích thước chiều rộng là 400 và chiều cao là 300 dis = pygame.display.set_mode((400,300)) #Cho phép thực hiện cập nhật một số thành phần của màn hình pygame.display.update() pygame.quit() quit()
Khi chúng ta chạy đoạn code này, màn hình sẽ chạy liên tục và sẽ hiển thị các tác vụ diễn ra trên đó. Đơn giản là vì chúng ta dùng phương thức event.get(). Bên cạnh đó, các bạn sẽ dùng hàm display.set_caption() để đặt tên màn hình là “Snake game”.
Như vậy, màn hình game rắn săn mồi đã xong. Tuy nhiên, một vấn đề là khi bấm vào nút đóng thì màn hình không đóng được. Lý do là các bạn đã không ra lệnh cho màn hình sẽ thoát ra khi thực hiện thao tác đóng. Để khắc phục điều này, nên dùng sự kiện “Quit” từ Pygame.
import pygame pygame.init() dis=pygame.display.set_mode((400,300)) pygame.display.update() pygame.display.set_caption('Snake game') game_end=False while not game_end: for event in pygame.event.get(): #Phát hiện thao tác thoát khỏi trò chơi của người dùng if event.type==pygame.QUIT: game_end=True pygame.quit() quit()
Như vậy vấn đề đã giải quyết xong và quá trình khởi tạo màn hình của trò chơi đã thành công.
1. Tạo và hiển thị con rắn lên màn hình
Kế đến là tạo hình con rắn và hiển thị nó lên trên màn hình. Việc đầu tiên là tạo một số biếu màu để tô màu cho rắn, hay những thứ liên quan. Thông thường, hãy dùng bảng màu RGB. Nếu các bạn chỉnh cho những trường này là 0 thì những màu sẽ hiển thị chủ yếu là màu trắng và đen.
Trên thực tế, con rắn tạo ra chỉ là một hình chữ nhật. Hãy dùng hàm draw.rect() để vẽ hình chữ nhật với yêu cầu về màu lẫn kích thước từ phía bạn.
import pygame pygame.init() dis=pygame.display.set_mode((400,300)) pygame.display.set_caption('Snake game') #Tạo màu cho con rắn blue=(0,0,255) red=(255,0,0) game_end=False while not game_end: for event in pygame.event.get(): if event.type==pygame.QUIT: game_end=True #Thực hiện vẽ một ô hình vuông màu xanh nước biển(đại diện cho đầu con rắn) lên trên màn hình với vị trí #trên màn hình máy tính (x, y) là (200, 150) và có chiều rộng, chiều cao là 10 pygame.draw.rect(dis,blue,[200,150,10,10]) pygame.display.update() pygame.quit() quit()
Khi chạy đoạn code trên, đầu con rắn sẽ có màu xanh lam. Sau đó, hãy thao tác di chuyển con rắn lên trên màn hình.
Để di chuyển con rắn trong game, hãy tận dụng những sự kiện có ở lớp KEYDOWN trong Pygame. Những sự kiện này bao gồm: K_UP, K_DOWN, K_LEFT, K_RIGHT có chức năng làm cho rắn có thể di chuyển lên, xuống, qua trái hay phải.
Không những vậy, màn hình lúc này sẽ biến đổi từ đen sang trắng thông qua việc dùng hàm fill(). Hãy nhớ tạo những biến mới x1_change và y1_change để giữ những giá trị cập nhật theo tọa độ mong muốn.
import pygame pygame.init() white = (255, 255, 255) black = (0, 0, 0) red = (255, 0, 0) dis = pygame.display.set_mode((800, 600)) pygame.display.set_caption('Snake game') game_end = False x1 = 300 y1 = 300 x1_change = 0 y1_change = 0 clock = pygame.time.Clock() while not game_end: for event in pygame.event.get(): #Nếu kiểu sự kiện là QUIT, thực hiện kết thúc trò chơi if event.type == pygame.QUIT: game_end = True #Nếu kiểu sự kiện là KEYDOWN (nhấn phím mũi tên xuống) if event.type == pygame.KEYDOWN: #Nếu phím nhấn xuống là phím mũi tên bên trái, thực hiện cập nhật đầu con rắn sang trái if event.key == pygame.K_LEFT: x1_change = -10 y1_change = 0 #Nếu phím nhấn xuống là phím mũi tên bên phải, thực hiện cập nhật đầu con rắn sang phải elif event.key == pygame.K_RIGHT: x1_change = 10 y1_change = 0 #Nếu phím nhấn xuống là phím mũi tên lên trên, thực hiện cập nhật đầu con rắn tiến lên trên elif event.key == pygame.K_UP: y1_change = -10 x1_change = 0 #Nếu phím nhấn xuống là phím mũi tên xuống dưới, thực hiện cập nhật đầu con rắn tiến đi xuống elif event.key == pygame.K_DOWN: y1_change = 10 x1_change = 0 #Thực hiện cập nhật tọa độ cho đầu con rắn x1 += x1_change y1 += y1_change #Tô lại toàn bộ màn hình là màu trắng dis.fill(white) #Thực hiện vẽ lại con rắn lên trên màn hình với vị trí mới pygame.draw.rect(dis, black, [x1, y1, 10, 10]) pygame.display.update() #Điều chỉnh tốc độ của trò chơi clock.tick(30) pygame.quit() quit()
Lúc này, game rắn săn mồi sẽ kết thúc khi nó va vào vùng ranh giới hiển thị trên màn hình. Trong game này, một quy tắc được đặt ra là khi người chơi chạm vào ranh giới của màn hình thì trò chơi sẽ kết thúc và người đó sẽ bị xử thua.
Chính vì vậy, hãy dùng lệnh “IF” để xác định những giới hạn cho tọa độ x và y của con rắn so với tọa độ màn hình. Không những vậy, những biến được dùng để thay thế những giá trị khi bạn muốn thay đổi trong trò chơi.
import pygame import time pygame.init() white = (255, 255, 255) black = (0, 0, 0) red = (255, 0, 0) dis_width = 800 dis_height = 600 dis = pygame.display.set_mode((dis_width, dis_width)) pygame.display.set_caption('Snake game') game_end = False x1 = dis_width/2 y1 = dis_height/2 snake_block=10 x1_change = 0 y1_change = 0 clock = pygame.time.Clock() snake_speed=30 font_style = pygame.font.SysFont(None, 50) def message_func(msg,color): mesg = font_style.render(msg, True, color) dis.blit(mesg, [dis_width/2, dis_height/2]) while not game_end: for event in pygame.event.get(): if event.type == pygame.QUIT: game_end = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x1_change = -snake_block y1_change = 0 elif event.key == pygame.K_RIGHT: x1_change = snake_block y1_change = 0 elif event.key == pygame.K_UP: y1_change = -snake_block x1_change = 0 elif event.key == pygame.K_DOWN: y1_change = snake_block x1_change = 0 #Kiểm tra xem vị trí (x, y) của đầu con rắn đã chạm vào ranh giới hiển thị màn hình trò chơi hay chưa if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0: game_end = True x1 += x1_change y1 += y1_change dis.fill(white) pygame.draw.rect(dis, black, [x1, y1, snake_block, snake_block]) pygame.display.update() clock.tick(snake_speed) #Hiển thị thông báo rằng người chơi đã thua lên trên màn hình message_func("You lost",red) pygame.display.update() time.sleep(2) pygame.quit() quit()
2. Cung cấp đồ ăn cho con rắn
Có thể cung cấp thức ăn cho con rắn để khi nó di chuyển qua thì hiển thị thông báo “Yummy” nhằm cho người chơi biết nó đã ăn được thức ăn đó rồi. Tiếp đến, hãy thay đổi xíu trong phần này chính là thêm những tùy chọn để thoát khỏi game hay cho phép chơi lại khi người chơi bị xử thua. Để làm được điều đó, cần dùng vòng lặp While nữa nằm ở trong để hỗ trợ chơi lại khi bị xử thua.
import pygame import time import random pygame.init() white = (255, 255, 255) black = (0, 0, 0) red = (255, 0, 0) blue = (0, 0, 255) dis_width = 800 dis_height = 600 dis = pygame.display.set_mode((dis_width, dis_height)) pygame.display.set_caption('Snake game') clock = pygame.time.Clock() snake_block = 10 snake_speed = 30 font_style = pygame.font.SysFont(None, 30) def message_func(msg, color): mesg = font_style.render(msg, True, color) dis.blit(mesg, [dis_width/3, dis_height/3]) def gameLooping_func(): game_end = False game_close = False x1 = dis_width / 2 y1 = dis_height / 2 x1_change = 0 y1_change = 0 #Vị trí tọa độ (x, y) của đồ ăn trong trò chơi foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 while not game_end: while game_close == True: dis.fill(white) message_func("You Lost! Press Q-Quit or C-Play Again", red) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.KEYDOWN: #Nếu phím người dùng nhấn là phím chữ 'q', thực hiện thoát khỏi trò chơi if event.key == pygame.K_q: game_end = True game_close = False #Nếu phím người dùng nhấn là phím chữ 'c', thực hiện cho phép người chơi chơi lại if event.key == pygame.K_c: gameLooping_func() for event in pygame.event.get(): if event.type == pygame.QUIT: game_end = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x1_change = -snake_block y1_change = 0 elif event.key == pygame.K_RIGHT: x1_change = snake_block y1_change = 0 elif event.key == pygame.K_UP: y1_change = -snake_block x1_change = 0 elif event.key == pygame.K_DOWN: y1_change = snake_block x1_change = 0 if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0: game_close = True x1 += x1_change y1 += y1_change dis.fill(white) pygame.draw.rect(dis, blue, [foodx, foody, snake_block, snake_block]) pygame.draw.rect(dis, black, [x1, y1, snake_block, snake_block]) pygame.display.update() #Nếu vị trí đầu của con rắn trùng với vị trí của đồ ăn trên màn hình, tức là con rắn đã ăn đồ ăn #Thực hiện thông báo cho người dùng if x1 == foodx and y1 == foody: print("Yummy!!") clock.tick(snake_speed) pygame.quit() quit() gameLooping_func()
3. Tùy chỉnh kích thước con rắn
Dưới đây là đoạn code sẽ giúp con rắn được tăng kích thước khi nó ăn thức ăn. Tuy nhiên, nếu rắn chạm vào chính bộ phận cơ thể của nó thì game sẽ kết thúc và thông báo xuất hiện “You Lost! Press Q-Quit or C-Play Again”.
Lưu ý chiều dài con rắn sẽ được lưu trữ trong danh sách và kích thước lúc khởi tạo sẽ được mặc định là một khối.
import pygame import time import random pygame.init() white = (255, 255, 255) yellow = (255, 255, 102) black = (0, 0, 0) red = (213, 50, 80) green = (0, 255, 0) blue = (50, 153, 213) dis_width = 600 dis_height = 400 dis = pygame.display.set_mode((dis_width, dis_height)) pygame.display.set_caption('Snake game') clock = pygame.time.Clock() snake_block = 10 snake_speed = 15 font_style = pygame.font.SysFont("bahnschrift", 25) score_font = pygame.font.SysFont("comicsansms", 35) def snake_func(snake_block, snake_list): for x in snake_list: pygame.draw.rect(dis, black, [x[0], x[1], snake_block, snake_block]) def message_func(msg, color): mesg = font_style.render(msg, True, color) dis.blit(mesg, [dis_width / 6, dis_height / 3]) def gameLooping_func(): game_end = False game_close = False x1 = dis_width / 2 y1 = dis_height / 2 x1_change = 0 y1_change = 0 #Tạo một tập hợp kiểu List chứa các thành phần của con rắn snake_List = [] #Độ dài ban đầu của con rắn là 1 Length_of_snake = 1 foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0 while not game_end: while game_close == True: dis.fill(blue) message_func("You Lost! Press C-Play Again or Q-Quit", red) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_q: game_end = True game_close = False if event.key == pygame.K_c: gameLooping_func() for event in pygame.event.get(): if event.type == pygame.QUIT: game_end = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x1_change = -snake_block y1_change = 0 elif event.key == pygame.K_RIGHT: x1_change = snake_block y1_change = 0 elif event.key == pygame.K_UP: y1_change = -snake_block x1_change = 0 elif event.key == pygame.K_DOWN: y1_change = snake_block x1_change = 0 if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0: game_close = True x1 += x1_change y1 += y1_change dis.fill(blue) #Thực hiện vẽ đồ ăn màu xanh lá lên trên màn hình với kích thước bằng kích thước của một ô vuông #biểu diễn cho 1 phần thân của con rắn. pygame.draw.rect(dis, green, [foodx, foody, snake_block, snake_block]) #Thực hiện thêm phần thân của con rắn vào danh sách snake_Head = [] snake_Head.append(x1) snake_Head.append(y1) snake_List.append(snake_Head) #Thực hiện cập nhật danh sách chứa các thành phần của con rắn để cập nhật vị trí của từng thành #phần (ô vuông) của con rắn. Nếu số ô vuông (biểu diễn cho con rắn), lớn hơn kích thước hiện tại #của con rắn (độ dài của con rắn), Length_of_snake, thực hiện xóa vị trí cũ của phần đầu con rắn. if len(snake_List) > Length_of_snake: del snake_List[0] #Kiểm tra từng bộ phận của con rắn có chạm vào phần đầu của con rắn hay không, nếu có, tức là #người chơi thua, thực hiện kết thúc trò chơi bằng cách đặt biến game_close = True. for x in snake_List[:-1]: if x == snake_Head: game_close = True snake_func(snake_block, snake_List) pygame.display.update() if x1 == foodx and y1 == foody: foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0 Length_of_snake += 1 clock.tick(snake_speed) pygame.quit() quit() gameLooping_func()
4. Hiển thị kết quả qua điểm số
Để hiển thị điểm số của người chơi trong game, chúng ta cần khởi tạo một phương thức mới “score_func”. Chức năng của phương thức này sẽ xuất ra chiều dài con rắn bị trừ đi một ví đó là kích thước ban đầu của nó.
import pygame import time import random pygame.init() white = (255, 255, 255) yellow = (255, 255, 102) black = (0, 0, 0) red = (213, 50, 80) green = (0, 255, 0) blue = (50, 153, 213) dis_width = 600 dis_height = 400 dis = pygame.display.set_mode((dis_width, dis_height)) pygame.display.set_caption('Snake game') clock = pygame.time.Clock() snake_block = 10 snake_speed = 15 font_style = pygame.font.SysFont("bahnschrift", 25) score_font = pygame.font.SysFont("comicsansms", 35) def score_func(score): value = score_font.render("Scoring: " + str(score), True, yellow) dis.blit(value, [0, 0]) def snake_func(snake_block, snake_list): for x in snake_list: pygame.draw.rect(dis, black, [x[0], x[1], snake_block, snake_block]) def message_func(msg, color): mesg = font_style.render(msg, True, color) dis.blit(mesg, [dis_width / 6, dis_height / 3]) def gameLooping_func(): game_end = False game_close = False x1 = dis_width / 2 y1 = dis_height / 2 x1_change = 0 y1_change = 0 snake_List = [] Length_of_snake = 1 foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0 while not game_end: while game_close == True: dis.fill(blue) message_func("Lose", red) #Thực hiện điểm số của trò chơi tương đương với chiều dài của con rắn - 1 (không tính phần đầu #của con rắn) score_func(Length_of_snake - 1) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_q: game_end = True game_close = False if event.key == pygame.K_c: gameLooping_func() for event in pygame.event.get(): if event.type == pygame.QUIT: game_end = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x1_change = -snake_block y1_change = 0 elif event.key == pygame.K_RIGHT: x1_change = snake_block y1_change = 0 elif event.key == pygame.K_UP: y1_change = -snake_block x1_change = 0 elif event.key == pygame.K_DOWN: y1_change = snake_block x1_change = 0 if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0: game_close = True x1 += x1_change y1 += y1_change dis.fill(blue) pygame.draw.rect(dis, green, [foodx, foody, snake_block, snake_block]) snake_Head = [] snake_Head.append(x1) snake_Head.append(y1) snake_List.append(snake_Head) if len(snake_List) > Length_of_snake: del snake_List[0] for x in snake_List[:-1]: if x == snake_Head: game_close = True snake_func(snake_block, snake_List) score_func(Length_of_snake - 1) pygame.display.update() if x1 == foodx and y1 == foody: foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0 Length_of_snake += 1 clock.tick(snake_speed) pygame.quit() quit() gameLooping_func()
Như vậy chúng tôi đã hướng dẫn và trình bày cụ thể cách để lập trình game rắn săn mồi với Python.
Lời kết
Bài viết đã trình bày một cách chi tiết nhất để các bạn làm quen với cách lập trình game rắn săn mồi với Python. Cuối cùng, hy vọng sẽ nhận được ý kiến đóng góp từ quý đọc giả để chúng tôi hoàn thiện nội dung hơn trong tương lai.