import tkinter as tk
import random
import time
class AirplaneGame:
def __init__(self, master):
self.master = master
self.master.title("飞机大战")
self.master.resizable(False, False)
# 游戏参数
self.width = 400 # 画布宽度
self.height = 325 # 画布高度
self.plane_size = 30 # 飞机大小
self.bullet_size = 5 # 子弹大小
self.enemy_size = 25 # 敌机大小
self.speed = 15 # 游戏速度(毫秒)
# 创建画布
self.canvas = tk.Canvas(
self.master,
width=self.width,
height=self.height,
bg="black",
highlightthickness=0
)
self.canvas.pack()
# 游戏标题
self.title_label = tk.Label(
self.master,
text="飞机大战",
font=("SimHei", 14, "bold")
)
self.title_label.pack(pady=5)
# 分数显示
self.score_label = tk.Label(
self.master,
text="分数: 0",
font=("SimHei", 12)
)
self.score_label.pack(pady=5)
# 生命值显示
self.lives_label = tk.Label(
self.master,
text="生命值: 3",
font=("SimHei", 12)
)
self.lives_label.pack(pady=5)
# 游戏说明
self.instruction_label = tk.Label(
self.master,
text="尚省独家赞助:方向键移动,空格键发射,按R重新开始",
font=("SimHei", 10)
)
self.instruction_label.pack(pady=5)
# 初始化游戏元素
self.reset_game()
# 绑定键盘事件
self.master.bind("<KeyPress>", self.on_key_press)
self.master.bind("<KeyRelease>", self.on_key_release)
# 开始游戏循环
self.game_loop()
def reset_game(self):
"""重置游戏"""
self.canvas.delete("all")
self.score = 0
self.lives = 3
self.game_over = False
self.score_label.config(text=f"分数: {self.score}")
self.lives_label.config(text=f"生命值: {self.lives}")
# 玩家飞机
self.player_x = self.width // 2
self.player_y = self.height - self.plane_size * 2
self.player_speed = 5
self.player_moving_up = False
self.player_moving_down = False
self.player_moving_left = False
self.player_moving_right = False
self.player_can_shoot = True
# 玩家飞机图形
self.player_id = self.canvas.create_polygon(
self.player_x, self.player_y - self.plane_size,
self.player_x - self.plane_size // 2, self.player_y + self.plane_size // 2,
self.player_x + self.plane_size // 2, self.player_y + self.plane_size // 2,
fill="blue"
)
# 子弹列表
self.bullets = []
# 敌机列表
self.enemies = []
# 敌机生成计时器
self.enemy_timer = 0
# 按键状态
self.keys = {"space": False, "r": False}
def on_key_press(self, event):
"""处理按键按下事件"""
key = event.keysym.lower()
if key == "up":
self.player_moving_up = True
elif key == "down":
self.player_moving_down = True
elif key == "left":
self.player_moving_left = True
elif key == "right":
self.player_moving_right = True
elif key == "space":
self.keys["space"] = True
elif key == "r" and self.game_over:
self.reset_game()
def on_key_release(self, event):
"""处理按键释放事件"""
key = event.keysym.lower()
if key == "up":
self.player_moving_up = False
elif key == "down":
self.player_moving_down = False
elif key == "left":
self.player_moving_left = False
elif key == "right":
self.player_moving_right = False
elif key == "space":
self.keys["space"] = False
def move_player(self):
"""移动玩家飞机"""
if self.player_moving_up and self.player_y > self.plane_size:
self.player_y -= self.player_speed
if self.player_moving_down and self.player_y < self.height - self.plane_size:
self.player_y += self.player_speed
if self.player_moving_left and self.player_x > self.plane_size:
self.player_x -= self.player_speed
if self.player_moving_right and self.player_x < self.width - self.plane_size:
self.player_x += self.player_speed
# 更新玩家飞机位置
self.canvas.coords(
self.player_id,
self.player_x, self.player_y - self.plane_size,
self.player_x - self.plane_size // 2, self.player_y + self.plane_size // 2,
self.player_x + self.plane_size // 2, self.player_y + self.plane_size // 2
)
# 发射子弹
if self.keys["space"] and self.player_can_shoot:
self.shoot()
self.player_can_shoot = False
self.master.after(200, self.enable_shooting)
def enable_shooting(self):
"""允许玩家再次射击"""
self.player_can_shoot = True
def shoot(self):
"""发射子弹"""
bullet_speed = 8
bullet_x = self.player_x
bullet_y = self.player_y - self.plane_size
bullet_id = self.canvas.create_oval(
bullet_x - self.bullet_size // 2,
bullet_y - self.bullet_size // 2,
bullet_x + self.bullet_size // 2,
bullet_y + self.bullet_size // 2,
fill="white"
)
self.bullets.append({
"id": bullet_id,
"x": bullet_x,
"y": bullet_y,
"speed": bullet_speed
})
def create_enemy(self):
"""创建敌机"""
enemy_speed = random.randint(2, 4)
enemy_x = random.randint(self.enemy_size, self.width - self.enemy_size)
enemy_y = -self.enemy_size
enemy_id = self.canvas.create_polygon(
enemy_x, enemy_y + self.enemy_size,
enemy_x - self.enemy_size // 2, enemy_y - self.enemy_size // 2,
enemy_x + self.enemy_size // 2, enemy_y - self.enemy_size // 2,
fill="red"
)
self.enemies.append({
"id": enemy_id,
"x": enemy_x,
"y": enemy_y,
"speed": enemy_speed
})
def move_enemies(self):
"""移动敌机"""
# 增加敌机生成计时器
self.enemy_timer += 1
if self.enemy_timer >= 50: # 每50帧生成一个敌机
self.create_enemy()
self.enemy_timer = 0
# 移动现有敌机
for enemy in self.enemies[:]:
enemy["y"] += enemy["speed"]
# 更新敌机位置
self.canvas.coords(
enemy["id"],
enemy["x"], enemy["y"] + self.enemy_size,
enemy["x"] - self.enemy_size // 2, enemy["y"] - self.enemy_size // 2,
enemy["x"] + self.enemy_size // 2, enemy["y"] - self.enemy_size // 2
)
# 检查敌机是否超出屏幕
if enemy["y"] > self.height:
self.canvas.delete(enemy["id"])
self.enemies.remove(enemy)
self.lives -= 1
self.lives_label.config(text=f"生命值: {self.lives}")
if self.lives <= 0:
self.game_over = True
self.show_game_over()
def move_bullets(self):
"""移动子弹"""
for bullet in self.bullets[:]:
bullet["y"] -= bullet["speed"]
# 更新子弹位置
self.canvas.coords(
bullet["id"],
bullet["x"] - self.bullet_size // 2,
bullet["y"] - self.bullet_size // 2,
bullet["x"] + self.bullet_size // 2,
bullet["y"] + self.bullet_size // 2
)
# 检查子弹是否超出屏幕
if bullet["y"] < 0:
self.canvas.delete(bullet["id"])
self.bullets.remove(bullet)
else:
# 检查子弹是否击中敌机
hit_enemy = False
for enemy in self.enemies[:]:
if (bullet["x"] > enemy["x"] - self.enemy_size and
bullet["x"] < enemy["x"] + self.enemy_size and
bullet["y"] > enemy["y"] - self.enemy_size and
bullet["y"] < enemy["y"] + self.enemy_size):
# 移除子弹和敌机
self.canvas.delete(bullet["id"])
self.bullets.remove(bullet)
self.canvas.delete(enemy["id"])
self.enemies.remove(enemy)
# 增加分数
self.score += 10
self.score_label.config(text=f"分数: {self.score}")
hit_enemy = True
break
if hit_enemy:
continue
def check_collisions(self):
"""检查碰撞"""
if self.game_over:
return
# 检查玩家与敌机的碰撞
for enemy in self.enemies[:]:
if (abs(self.player_x - enemy["x"]) < self.plane_size and
abs(self.player_y - enemy["y"]) < self.plane_size):
# 移除敌机
self.canvas.delete(enemy["id"])
self.enemies.remove(enemy)
# 减少生命值
self.lives -= 1
self.lives_label.config(text=f"生命值: {self.lives}")
if self.lives <= 0:
self.game_over = True
self.show_game_over()
break
def show_game_over(self):
"""显示游戏结束信息"""
self.canvas.create_text(
self.width // 2,
self.height // 2,
text="游戏结束!按R重新开始",
fill="red",
font=("SimHei", 16, "bold")
)
def game_loop(self):
"""游戏主循环"""
if not self.game_over:
self.move_player()
self.move_enemies()
self.move_bullets()
self.check_collisions()
self.master.after(self.speed, self.game_loop)
if __name__ == "__main__":
root = tk.Tk()
game = AirplaneGame(root)
root.mainloop()