Cách làm game bắn gà Space Invaders bằng Python

  • 1 Đánh giá

Space Invaders là tựa game arcade kinh điển đã gắn bó với tuổi thơ của nhiều game thủ 8x . Hiện bạn có thể tự xây dựng phiên bản Space Invaders của riêng mình bằng Python.

Tạo game Space Invaders bằng Python

Gameplay chính của Space Invaders

Trong game bắn súng Space Invaders, người chơi điều khiển một vũ khí laser di chuyển theo chiều ngang ở cuối màn hình để bắn vào các sinh vật ngoài hành tinh ở phía trên. Các sinh vật này di chuyển theo nhóm sang trái và phải, đồng thời hạ thấp dần vị trí khi tiến gần đến mép màn hình.

Mục tiêu chính của Space Invaders là tiêu diệt toàn bộ sinh vật ngoài hành tinh bằng hỏa lực. Nói cách khác, người chơi cần tránh bị tiêu diệt để có thể phản công lại những kẻ xâm lược.

Nếu kẻ xâm lược (sinh vật ngoài hành tinh) chạm tới cuối màn hình, trò chơi sẽ kết thúc ngay lập tức, ngay cả khi người chơi vẫn còn mạng.

Sử dụng Python và Pygame, bạn có thể xây dựng một phiên bản đơn giản nhưng đầy đủ chức năng của trò chơi nổi tiếng Space Invaders.

Python là một trong những ngôn ngữ lập trình phổ biến nhất; khi kết hợp với Pygame, người dùng có thể nhanh chóng phát triển nhiều loại ứng dụng trò chơi khác nhau.

Cách tạo game Space Invaders bằng Python

  1. Cài đặt ứng dụng Pygame.
  2. Xây dựng nhân vật người chơi và kẻ địch (Space Invaders).
  3. Sử dụng bàn phím để điều khiển chuyển động của người chơi và tự động hóa chuyển động của kẻ địch.
  4. Tự động hóa việc kẻ địch bắn ngẫu nhiên trong khi người chơi điều khiển việc bắn bằng bàn phím.
  5. Nhận diện va chạm giữa các đối tượng và thực hiện hành động xử lý phù hợp.

Chi tiết code lập trình game Space Invaders bằng Python

import math
import random
import pygame
from pygame import mixer

Dòng 1: Để sử dụng các hàm toán học được quy định bởi chuẩn C, cần phải nhập thư viện `math` trong Python.

Dòng 2: Thư viện `random` của Python cung cấp nhiều hàm để tạo hoặc thay đổi các số ngẫu nhiên. Các hàm trong thư viện này sử dụng hàm tạo số giả ngẫu nhiên `random()` để tạo ra các số thực (kiểu float) ngẫu nhiên trong khoảng từ 0.0 đến 1.0.

Dòng 3: Lệnh này nhập tất cả thành phần có thể truy cập được của `pygame` vào gói `pygame`.

Dòng 4: Các lớp dùng để tải đối tượng âm thanh (Sound objects) và quản lý việc phát âm thanh đều nằm trong thư viện `mixer`.

#Khởi tạo pygame
pygame.init()

Dòng 2: Tất cả mô-đun pygame đã được nhập đều được khởi tạo thông qua hàm `pygame.init()`.

Nếu một mô-đun khởi tạo thất bại, sẽ không có ngoại lệ nào được sinh ra; thay vào đó, hàm sẽ trả về một bộ (tuple) chứa tổng số lần khởi tạo thành công và thất bại.

Mặc dù `pygame.init()` là cách khởi tạo nhanh chóng tất cả mô-đun pygame đã nhập và bắt đầu làm việc, bạn hoàn toàn có thể khởi tạo từng mô-đun riêng lẻ. Khi phương thức `init()` của một mô-đun gặp lỗi, nó sẽ sinh ra một ngoại lệ.

# tạo màn hình
screen = pygame.display.set_mode((800, 500))

Dòng 2: Lệnh này sẽ tạo ra màn hình. Một cửa sổ hiển thị hình ảnh sẽ được tạo ra trên màn hình khi chế độ hiển thị trong PyGame được thay đổi.

Trên các nền tảng có trình quản lý cửa sổ, bề mặt này có thể ở chế độ toàn màn hình hoặc chế độ cửa sổ.

Một đối tượng bề mặt (surface object) PyGame thông thường sẽ đóng vai trò là bề mặt hiển thị.

# Background
background = pygame.image.load('background.png')

Dòng 2: Để thêm hình nền, tất cả những gì bạn cần làm là sử dụng hàm `image.load` và truyền đường dẫn của hình ảnh vào làm tham số.

# Âm thanh
mixer.music.load("background.wav")
mixer.music.play(-1)

Dòng 2: Tệp nhạc (dưới dạng tên tệp hoặc đối tượng tệp) sẽ được tải và sẵn sàng để phát. Luồng nhạc sẽ bị dừng nếu đang phát. Thao tác này không bắt đầu phát nhạc.

Dòng 3: Luồng nhạc đã tải sẽ được phát. Bài hát sẽ phát lại từ đầu nếu đang phát.

# Chú thích và icon
pygame.display.set_caption("Space Invader")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)

Dòng 2: Thiết lập tiêu đề cho cửa sổ hiện tại.

Dòng 3: Một đối tượng Surface chứa hình ảnh đã tải sẽ được trả về thông qua phương thức `pygame.image.load()`. Đối tượng Surface hiển thị (display Surface) và đối tượng Surface này sẽ là hai đối tượng khác nhau.

Dòng 4: Dùng để thay đổi biểu tượng.

# Người chơi
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 380
playerX_change = 0

Dòng 2: Phương thức `pygame.image.load()` sẽ trả về một đối tượng Surface có chứa hình ảnh đã được tải. Đối tượng Surface hiển thị (display Surface) và đối tượng Surface này sẽ là hai đối tượng khác nhau.

Dòng 3: Thiết lập tọa độ X của người chơi

Dòng 4: Thiết lập tọa độ Y của người chơi

Dòng 5: Thiết lập giá trị thay đổi tọa độ X của người chơi

# Kẻ thù
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6

Dòng 2: Thiết lập danh sách dành cho kẻ địch.

Dòng 3: Khởi tạo danh sách tọa độ X của kẻ địch.

Dòng 4: Khởi tạo danh sách tọa độ X của kẻ địch.

Dòng 5: Khởi tạo danh sách mức thay đổi tọa độ X của kẻ địch.

Dòng 6: Khởi tạo danh sách mức thay đổi tọa độ Y của kẻ địch.

Dòng 7: Khởi tạo biến num_of_enemies để lưu trữ số lượng kẻ địch.

for i in range(num_of_enemies):
    enemyImg.append(pygame.image.load('enemy.png'))
    enemyX.append(random.randint(0, 736))
    enemyY.append(random.randint(50, 150))
    enemyX_change.append(4)
    enemyY_change.append(40)

Dòng 1: Sử dụng vòng lặp dựa trên biến `num_of_enemies` để thêm và thay đổi tọa độ X, Y của kẻ địch.

Dòng 2: Thêm hình ảnh kẻ địch (`enemyImg`) bằng phương thức `image.load()`.

Dòng 3: Để thiết lập ngẫu nhiên tọa độ X của kẻ địch trong ví dụ này, sử dụng hàm `random` từ thư viện `random`.

Dòng 4: Để thiết lập ngẫu nhiên tọa độ Y của kẻ địch trong ví dụ này, sử dụng hàm `random` từ thư viện `random`.

Dòng 5: Thêm giá trị thay đổi tọa độ X của kẻ địch.

Dòng 6: Thêm giá trị thay đổi tọa độ Y của kẻ địch.

# Bullet
# Ready - Bạn không thể thấy đạn trên màn hình
# Fire - Đạn hiện đang di chuyển
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 380
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"

Dòng 4: Thiết lập bulletImg bằng cách sử dụng image.load()

Dòng 5: Khởi tạo tọa độ X của viên đạn.

Dòng 6: Khởi tạo tọa độ Y của viên đạn.

Dòng 7: Khởi tạo mức thay đổi tọa độ X của viên đạn.

Dòng 8: Khởi tạo mức thay đổi tọa độ Y của viên đạn.

Dòng 9: Khởi tạo trạng thái của viên đạn là “ready” (sẵn sàng).

# Ghi điểm
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
testY = 10

Dòng 2: Khởi tạo biến score_value.

Dòng 3: Thiết lập phông chữ là ‘freesansbold.ttf’ bằng cách sử dụng pygame.font.Font().

Dòng 4: Khởi tạo tọa độ X của văn bản.

Dòng 5: Khởi tạo tọa độ X của văn bản.

# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)

Dòng 2: Thiết lập phông chữ là ‘freesansbold.ttf’ bằng cách sử dụng pygame.font.Font().

def show_score(x, y):
    score = font.render("Score : " + str(score_value), True, (255, 255, 255))
    screen.blit(score, (x, y))

Dòng 1: Định nghĩa hàm `show_score(x, y)` với `x` và `y` là các tham số.

Dòng 2: Sử dụng hàm `render()` của đối tượng font trong PyGame để tạo một đối tượng bề mặt văn bản (Text surface) – tức là một đối tượng bề mặt có chứa nội dung văn bản được vẽ lên đó.

Dòng 3: Phương thức `screen.blit(x, y)` thực hiện việc vẽ bề mặt văn bản lên màn hình tại vị trí tọa độ `(x, y)`.

def game_over_text():
    over_text = over_font.render("GAME OVER", True, (255, 255, 255))
    screen.blit(over_text, (200, 250))

Dòng 1: Định nghĩa hàm game_over_text()

Dòng 2: Sử dụng hàm render() của đối tượng font trong PyGame để tạo một đối tượng bề mặt văn bản (Text surface object) – tức là một đối tượng bề mặt có chứa nội dung văn bản được vẽ lên đó.

Dòng 3: Phương thức screen.blit(x,y) thực hiện việc vẽ bề mặt nền lên màn hình và đặt nó tại vị trí (x,y).

def player(x, y):
screen.blit(playerImg, (x, y))

Dòng 1: Định nghĩa hàm `player(x, y)` với `x` và `y` là các tham số.

Dòng 2: Phương thức `screen.blit(x, y)` thực hiện việc vẽ bề mặt nền lên màn hình và đặt nó tại vị trí `(x, y)`.

def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))

Dòng 1: Định nghĩa hàm `def enemy(x, y, i)` với các tham số là `x`, `y` và `i`.

Dòng 2: Phương thức `screen.blit(x, y)` thực hiện việc vẽ bề mặt (hình ảnh) lên màn hình tại vị trí tọa độ `(x, y)`.

def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 16, y + 10))

Dòng 1: Định nghĩa hàm `def fire_bullet(x, y)` với các tham số là `x` và `y`.

Dòng 2: Khai báo biến trạng thái đạn (`bullet_state`) là biến toàn cục và khởi tạo giá trị ban đầu là "fire" (bắn).

Dòng 3: Phương thức `screen.blit(x, y)` thực hiện việc vẽ bề mặt (hình ảnh) lên màn hình tại vị trí tọa độ `(x, y)`.

def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt(math.pow(enemyX - bulletX, 2) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False

Dòng 1: Định nghĩa hàm `def isCollision(enemyX, enemyY, bulletX, bulletY)` với các tham số là `enemyX`, `enemyY`, `bulletX` và `bulletY`.

Dòng 2: Tính toán khoảng cách bằng cách áp dụng công thức tính khoảng cách.

Dòng 3, 4, 5 & 6: Sử dụng câu lệnh điều kiện `if` đối với giá trị khoảng cách để kiểm tra và trả về kết quả `True` (đúng) hoặc `False` (sai).

# Game Loop
running = True
while running:

Dòng 2: Khởi tạo biến `running` với giá trị `True`.

Dòng 3: Sử dụng vòng lặp `while` dựa trên biến `running`.

# RGB = Red, Green, Blue
screen.fill((0, 0, 0))

Dòng 2: Phương thức này được sử dụng để tô màu cho màn hình hiển thị bằng màu sắc được chỉ định. 

 # Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

Dòng 2: Phương thức screen.blit(x, y) thực hiện việc vẽ bề mặt hình nền lên màn hình và đặt nó tại vị trí (x, y).

Dòng 3: Sử dụng vòng lặp `for` để duyệt qua các sự kiện trong `pygame.event.get()`.

Dòng 4 & 5: Sử dụng câu lệnh điều kiện `if` với giá trị `event.type` để kiểm tra xem `event.type` có bằng `pygame.QUIT` hay không; nếu đúng, biến `running` sẽ được gán giá trị `False`.

# Kiểm tra xem phím được nhấn là phím sang trái hay sang phải
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5

Dòng 2: Sử dụng câu lệnh điều kiện `if` với `event.type` để kiểm tra xem `event.type` có bằng `pygame.KEYDOWN` hay không.

Dòng 3 & 4: tiếp tục sử dụng câu lệnh điều kiện `if` với `event.key` để kiểm tra xem `event.key` có bằng `pygame.K_LEFT` hay không; nếu đúng, ta sẽ thay đổi tọa độ X của người chơi một lượng là -5.

Dòng 5 & 6: Sử dụng câu lệnh điều kiện `if` với `event.key` để kiểm tra xem `event.key` có bằng `pygame.K_RIGHT` hay không; nếu đúng, ta sẽ thay đổi tọa độ X của người chơi thêm 5 đơn vị.

if event.key == pygame.K_SPACE:
if bullet_state == "ready":
bulletSound = mixer.Sound("laser.wav")
bulletSound.play()

Dòng 1: Sử dụng câu lệnh điều kiện `if` với `event.key` để kiểm tra xem `event.key` có bằng `pygame.K_SPACE` hay không.

Dòng 2, 3 & 4: Sử dụng câu lệnh điều kiện `if` với `bullet_state` để kiểm tra xem `bullet_state` có bằng "ready" hay không; nếu đúng, ta sẽ phát âm thanh "laser.wav".

# Lấy tọa độ x hiện tại của tàu vũ trụ
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0

Dòng 2: Gán vị trí của người chơi cho viên đạn.

Dòng 3: Gọi hàm `fire_bullet(bulletX, bulletY)` với `bulletX` và `bulletY` là các tham số.

Dòng 4: Sử dụng câu lệnh điều kiện `if` cho `event.type` để kiểm tra xem `event.type` có bằng `pygame.KEYUP` hay không.

Dòng 5 & 6: Tiếp tục sử dụng câu lệnh điều kiện `if` cho `event.key` để kiểm tra xem `event.key` có bằng `pygame.K_LEFT` hoặc `pygame.K_RIGHT` hay không; nếu đúng thì ta sẽ đặt lại tọa độ của người chơi về 0.

# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736

Dòng 3: Toán tử `+=` trong Python cộng hai giá trị và lưu kết quả vào một biến. Tên gọi của toán tử này là toán tử gán cộng (addition assignment operator).

Toán tử này thường được sử dụng khi cộng thêm giá trị vào một biến đếm (biến dùng để đếm số lần một sự kiện xảy ra).

Trong trường hợp này, nó tương đương với `playerX = playerX + playerX_change`.

Dòng 4 & 5: Sử dụng câu lệnh điều kiện `if` cho `playerX` để kiểm tra xem `playerX <= 0` hay không; nếu đúng thì ta sẽ gán `playerX = 0`.

Dòng 6 & 7: Tiếp tục sử dụng câu lệnh điều kiện `elif` (else if) cho `playerX` để kiểm tra xem `playerX >= 736` hay không; nếu đúng thì sẽ gán `playerX = 736`.

# Di chuyển của kẻ địch
for i in range(num_of_enemies):

Dòng 2: Sử dụng vòng lặp `for` với `num_of_enemies` để xử lý việc di chuyển của kẻ địch. # Kết thúc trò chơi
if enemyY[i] > 340:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break

Dòng 2, 3 & 4: Sử dụng câu lệnh điều kiện `if` để kiểm tra xem `enemyY[i]` có lớn hơn 340 hay không; nếu điều kiện này đúng, ta thực hiện vòng lặp qua `num_of_enemies` để gán giá trị `enemyY[j] = 2000`.

Dòng 5 & 6: Gọi hàm `game_over_text()` và sau đó thoát khỏi vòng lặp.

enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 4
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -4
enemyY[i] += enemyY_change[i]

Dòng 1: Toán tử gán cộng được sử dụng cho `enemyX[i] += enemyX_change[i]`.

Dòng 2 & 3: Sử dụng câu lệnh điều kiện `if` cho `enemyX[i]` để kiểm tra xem `enemyX[i] <= 0` hay không; nếu đúng, ta gán `enemyX_change[i] = 4` và sử dụng toán tử gán cộng cho `enemyY[i] += enemyY_change[i]`.

Dòng 4, 5 & 6: Tiếp tục sử dụng câu lệnh điều kiện `elif` cho `enemyX[i]` để kiểm tra xem `enemyX[i] >= 736` hay không; nếu đúng, ta gán `enemyX_change[i] = -4` và sử dụng toán tử gán cộng cho `enemyY[i] += enemyY_change[i]`.

# Va chạm
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
explosionSound = mixer.Sound("explosion.wav")
explosionSound.play()
bulletY = 380
bullet_state = "ready"
score_value += 1
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)

Dòng 2, 3, 4 & 5: Phần này xử lý va chạm, kiểm tra xem có xảy ra va chạm hay không. Nếu có, trước tiên ta phát âm thanh "explosion.wav" và sau đó...

Dòng 6: Thiết lập lại `bulletY` thành 380 và `bullet_state` thành "ready".

Dòng 7: Tăng biến `score_value` thêm 1 bằng cách sử dụng toán tử gán cộng.

Dòng 8: Sử dụng hàm randint() để gán ngẫu nhiên một giá trị số nguyên cho enemyX[i] trong khoảng từ 0 đến 736.

Dòng 9: Sử dụng hàm randint() để gán ngẫu nhiên một giá trị số nguyên cho enemyY[i] trong khoảng từ 50 đến 150.

Dòng 10: Gọi hàm enemy(enemyX[i], enemyY[i], i) với các tham số enemyX[i], enemyY[i] và i.

# Di chuyển của đạn
if bulletY <= 0:
bulletY = 380
bullet_state = "ready"

Dòng 2, 3 & 4: Sử dụng câu lệnh điều kiện `if` với biến bulletY để kiểm tra xem bulletY có nhỏ hơn hoặc bằng 0 hay không; nếu đúng, ta sẽ gán bulletY = 380 và bullet_state = "ready".

if bullet_state == "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change

Dòng 1, 2 & 3: Sử dụng câu lệnh điều kiện `if` với biến bullet_state để kiểm tra xem bullet_state có bằng "fire" hay không; nếu đúng, ta sẽ gọi hàm fire_bullet(bulletX, bulletY) với các tham số bulletX và bulletY, đồng thời thực hiện phép gán giảm bulletY -= bulletY_change.

Việc này được thực hiện để xử lý chuyển động của viên đạn.

player(playerX, playerY)
show_score(textX, testY)
pygame.display.update()

Dòng 1 & 2: Gọi hàm player(playerX, playerY) với các tham số playerX và playerY, và hàm show_score(textX, testY) với các tham số textX và testY.

Dòng 3: Cuối cùng, cập nhật và hiển thị điểm số lên màn hình.

Kết quả đầu ra

pygame 2.1.0 (SDL 2.0.16, Python 3.8.12)

Hello from the pygame community. https://www.pygame.org/contribute.html

Chi tiết toàn bộ code game Space Invaders bằng Python

import math
import random
import pygame
from pygame import mixer

# Intialize the pygame
pygame.init()

# create the screen
screen = pygame.display.set_mode((800, 500))

# Background
background = pygame.image.load('background.png')

# Sound
mixer.music.load("background.wav")
mixer.music.play(-1)

# Caption and Icon
pygame.display.set_caption("Space Invader")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)

# Player
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 380
playerX_change = 0

# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6

for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(0, 736))
enemyY.append(random.randint(50, 150))
enemyX_change.append(4)
enemyY_change.append(40)

# Bullet
# Ready - You can't see the bullet on the screen
# Fire - The bullet is currently moving

bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 380
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"

# Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
testY = 10

# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)

def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))

def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (200, 250))

def player(x, y):
screen.blit(playerImg, (x, y))

def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))

def fire_bullet(x, y):
global bullet_state
bullet_state = "fire"
screen.blit(bulletImg, (x + 16, y + 10))

def isCollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt(math.pow(enemyX - bulletX, 2) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False

# Game Loop
running = True
while running:

# RGB = Red, Green, Blue
screen.fill((0, 0, 0))

# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

# if keystroke is pressed check whether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -5
if event.key == pygame.K_RIGHT:
playerX_change = 5
if event.key == pygame.K_SPACE:
if bullet_state == "ready":
bulletSound = mixer.Sound("laser.wav")
bulletSound.play()

# Get the current x cordinate of the spaceship
bulletX = playerX
fire_bullet(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0

# 5 = 5 + -0.1 -> 5 = 5 - 0.1
# 5 = 5 + 0.1
playerX += playerX_change
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736

# Enemy Movement
for i in range(num_of_enemies):

# Game Over
if enemyY[i] > 340:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break

enemyX[i] += enemyX_change[i]
if enemyX[i] <= 0:
enemyX_change[i] = 4
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 736:
enemyX_change[i] = -4
enemyY[i] += enemyY_change[i]

# Collision
collision = isCollision(enemyX[i], enemyY[i], bulletX, bulletY)
if collision:
explosionSound = mixer.Sound("explosion.wav")
explosionSound.play()
bulletY = 380
bullet_state = "ready"
score_value += 1
enemyX[i] = random.randint(0, 736)
enemyY[i] = random.randint(50, 150)
enemy(enemyX[i], enemyY[i], i)

# Bullet Movement
if bulletY <= 0:
bulletY = 380
bullet_state = "ready"
if bullet_state == "fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
player(playerX, playerY)
show_score(textX, testY)
pygame.display.update()
Cập nhật: 09/10/2026
  • lượt xem
Xem thêm: Space Invaders Python