本博客使用了Pygame库来创建游戏窗口和处理游戏逻辑。
一、代码的详细解释:
创建游戏窗口:
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Bee")
创建了一个名为"Bee"的游戏窗口,窗口的大小由WIDTH
和HEIGHT
变量决定。
蜜蜂的定义与循环出现:
class Enemy():
# 构造函数
def __init__(self):
self.img = pygame.image.load('bee.png')
self.x = random.randint(200, 600)
self.y = random.randint(50, 250)
self.step = random.randint(2, 6)
# 重置蜜蜂位置
def reset(self):
self.x = random.randint(200, 600)
self.y = random.randint(50, 200)
enemies = []
for i in range(number_of_bee):
enemies.append(Enemy())
定义了一个名为Enemy
的类,每个蜜蜂对象有图像、x坐标、y坐标和步长。蜜蜂的循环出现在enemies
列表中,初始位置随机。
显示蜜蜂和处理碰撞:
def show_bee():
for e in enemies:
screen.blit(e.img, (e.x, e.y))
e.x += e.step
if e.x > 736 or e.x < 0:
e.step *= -1
e.y += 40
if e.y >= 450:
over, over_rect = init_item('game over.jpg', 0, 0)
txt_restart, txt_restart_rect = show_text("Restart", 300, 300, 32)
screen.blit(over, over_rect) ##显示gameover图片
screen.blit(txt_restart, txt_restart_rect)
quit()
这个函数用于显示蜜蜂,并在蜜蜂到达窗口边缘时,让其改变方向并向下移动。如果蜜蜂的y坐标超过了450,则游戏结束,显示"game over"图片和"Restart"文字,然后退出游戏。
定义射击器:
play_x = 400
play_y = 500
shoot, shoot_rect = init_item('fighter.png', play_x, play_y)
playerstep = 0
定义了射击器的初始位置,并加载了射击器的图像。
子弹的定义与处理碰撞:
class bullet():
def __init__(self):
self.img = pygame.image.load('bullet1.png')
self.x = play_x
self.y = play_y + 10
self.step = 10 # 子弹移动的速度
def hit(self):
for e in enemies:
if distance(self.x, self.y, e.x, e.y) < 30:
bullets.remove(self)
e.reset()
bullets = []
def show_bullets():
for b in bullets:
screen.blit(b.img, (b.x, b.y))
b.hit()
b.y -= b.step
if b.y < 0:
bullets.remove(b)
这段代码定义了bullet
类,每个子弹对象有图像、x坐标、y坐标和速度。在子弹的hit()
方法中,检查子弹与蜜蜂是否碰撞,若是,则移除该子弹并重新生成蜜蜂。show_bullets()
函数用于显示子弹,并在子弹超出窗口时移除它们。
计算两点间距离的函数:
def distance(bx, by, ex, ey):
a = bx - ex
b = by - ey
return math.sqrt(a * a + b * b)
这个函数用于计算两点之间的距离,其中bx
和by
表示子弹的坐标,ex
和ey
表示蜜蜂的坐标。
播放背景音乐:
pygame.mixer.music.load('背景音乐.mp3') # 导入音乐
pygame.mixer.music.play(loops=-1) # 循环播放
这段代码加载名为"背景音乐.mp3"的音乐,并设置为循环播放。
主游戏循环:
clock = pygame.time.Clock() ##用来设定窗口的刷新频率
while True:
clock.tick(60) ##每秒执行60次
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
playerstep = 5
elif event.key == pygame.K_LEFT:
playerstep = -5
elif event.key == pygame.K_SPACE:
bullets.append(bullet())
if event.type == pygame.KEYUP:
playerstep = 0
screen.blit(shoot, (play_x, play_y))
play_x += playerstep
if play_x > 736:
play_x = 736
if play_x < 0:
play_x = 0
show_bee()
show_bullets()
pygame.display.flip()
这是游戏的主循环,游戏会在每次循环中执行以下步骤:
最后,游戏会在主循环中不断重复执行以上步骤,实现了蜜蜂的循环出现、射击器的控制以及子弹和蜜蜂之间的碰撞检测。
- 设置窗口刷新频率为60帧。
- 填充窗口背景为黑色。
- 处理事件,包括按键事件和退出事件。
- 根据按键事件移动射击器的位置,如果按下空格键,则添加一个新的子弹对象到
bullets
列表。 - 显示射击器的图像,根据按键事件移动射击器的位置,使其在窗口内左右移动,并限制其不超出窗口边界。
- 调用
show_bee()
函数,显示蜜蜂,并处理蜜蜂与窗口边界的碰撞,以及蜜蜂与子弹的碰撞。 - 调用
show_bullets()
函数,显示子弹,并处理子弹与窗口边界的碰撞,以及子弹与蜜蜂的碰撞。 - 使用
pygame.display.flip()
方法更新整个游戏窗口。二、完整代码展示:
import pygame import sys import random import math WIDTH = 800 HEIGHT = 600 def pygame_1(): global event, e pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Bee") ##蜜蜂: number_of_bee = 6 ##显示分数 txt_score, txt_score_rect = show_text("Score:0", 40, 20, 20) score = 0 ##蜜蜂的循环出现 class Enemy(): def __init__(self): self.img = pygame.image.load('bee.png') self.x = random.randint(200, 600) self.y = random.randint(50, 250) self.step = random.randint(2, 6) def reset(self): self.x = random.randint(200, 600) self.y = random.randint(50, 200) enemies = [] for i in range(number_of_bee): enemies.append(Enemy()) def show_bee(): for e in enemies: screen.blit(e.img, (e.x, e.y)) e.x += e.step if e.x > 736 or e.x < 0: e.step *= -1 e.y += 40 if e.y >= 450: over, over_rect = init_item('game over.jpg', 0, 0) txt_restart, txt_restart_rect = show_text("Restart", 300, 300, 32) screen.blit(over, over_rect) ##显示gameover图片 screen.blit(txt_restart, txt_restart_rect) quit() ##射击器 play_x = 400 play_y = 500 shoot, shoot_rect = init_item('fighter.png', play_x, play_y) playerstep = 0 ##子弹 class bullet(): def __init__(self): self.img = pygame.image.load('bullet1.png') self.x = play_x self.y = play_y + 10 self.step = 10 # 子弹移动的速度 def hit(self): for e in enemies: if distance(self.x, self.y, e.x, e.y) < 30: bullets.remove(self) e.reset() bullets = [] def show_bullets(): for b in bullets: screen.blit(b.img, (b.x, b.y)) b.hit() b.y -= b.step if b.y < 0: bullets.remove(b) def distance(bx, by, ex, ey): a = bx - ex b = by - ey return math.sqrt(a * a + b * b) pygame.mixer.music.load('背景音乐.mp3') # 导入音乐 pygame.mixer.music.play(loops=-1) # 循环播放 clock = pygame.time.Clock() ##用来设定窗口的刷新频率 while True: clock.tick(60) ##每秒执行60次 screen.fill((0, 0, 0)) for event in pygame.event.get(): if event.type == pygame.QUIT: exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT: playerstep = 5 elif event.key == pygame.K_LEFT: playerstep = -5 elif event.key == pygame.K_SPACE: bullets.append(bullet()) if event.type == pygame.KEYUP: playerstep = 0 screen.blit(shoot, (play_x, play_y)) play_x += playerstep if play_x > 736: play_x = 736 if play_x < 0: play_x = 0 show_bee() show_bullets() pygame.display.flip() def init_item(img_path, pos_x, pos_y): ##显示图片 item = pygame.image.load(img_path) item_rect = pygame.Rect((pos_x, pos_y, 0, 0)) item_rect.size = item.get_size() return item, item_rect def show_text(txt, pos_x, pos_y, fontsize=12): ##设定显示文本信息 font = pygame.font.Font(None, fontsize) text = font.render(txt, True, (255, 0, 0)) text_rect = text.get_rect() text_rect.centerx = pos_x text_rect.centery = pos_y return text, text_rect if __name__ == "__main__": pygame_1()
三、视频演示:
用python做小游戏——以射击游戏为例子