CmltcG9ydCBzeXMKaW1wb3J0IHRpbWUKaW1wb3J0IHJhbmRvbQoKIyDmuLjmiI/lj4LmlbAKU0NSRUVOX1dJRFRIID0gNDAgICMg5o6n5Yi25Y+w5a695bqm77yI5a2X56ym5pWw77yJClNDUkVFTl9IRUlHSFQgPSAyMCAgIyDmjqfliLblj7Dpq5jluqbvvIjlrZfnrKbmlbDvvIkKUExBWUVSX0NIQVIgPSAmcXVvdDvilrYmcXVvdDsgICAjIOeOqeWutumjnuacuu+8iOWQkeWPs+eureWktO+8iQpFTkVNWV9DSEFSID0gJnF1b3Q7WCZxdW90OyAgICAgIyDmlYzmnLoKQlVMTEVUX0NIQVIgPSAmcXVvdDt8JnF1b3Q7ICAgICMg5a2Q5by5CkRFTEFZID0gMC4xICAgICAgICAgICMg5Yi35paw6Ze06ZqU77yI56eS77yJCgpjbGFzcyBQbGF5ZXI6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi54ID0gU0NSRUVOX1dJRFRIIC8vIDIgICMg5Yid5aeL5L2N572u5bGF5LitCiAgICAgICAgc2VsZi55ID0gU0NSRUVOX0hFSUdIVCAtIDEgICMg5bqV6YOo5L2N572uCgogICAgZGVmIG1vdmVfbGVmdChzZWxmKToKICAgICAgICBpZiBzZWxmLnggJmd0OyAwOgogICAgICAgICAgICBzZWxmLnggLT0gMQoKICAgIGRlZiBtb3ZlX3JpZ2h0KHNlbGYpOgogICAgICAgIGlmIHNlbGYueCAmbHQ7IFNDUkVFTl9XSURUSCAtIDE6CiAgICAgICAgICAgIHNlbGYueCArPSAxCgogICAgZGVmIHNob290KHNlbGYpOgogICAgICAgIHJldHVybiBCdWxsZXQoc2VsZi54LCBzZWxmLnkgLSAxKSAgIyDlrZDlvLnku47po57mnLrkuIrmlrnlj5HlsIQKCmNsYXNzIEVuZW15OgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYueCA9IHJhbmRvbS5yYW5kaW50KDAsIFNDUkVFTl9XSURUSCAtIDEpICAjIOmaj+acuuaoquWQkeS9jee9rgogICAgICAgIHNlbGYueSA9IDAgICMg5LuO6aG26YOo55Sf5oiQCgogICAgZGVmIHVwZGF0ZShzZWxmKToKICAgICAgICBzZWxmLnkgKz0gMSAgIyDmlYzmnLrkuIvokL0KCmNsYXNzIEJ1bGxldDoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB4LCB5KToKICAgICAgICBzZWxmLnggPSB4CiAgICAgICAgc2VsZi55ID0geQoKICAgIGRlZiB1cGRhdGUoc2VsZik6CiAgICAgICAgc2VsZi55IC09IDEgICMg5a2Q5by55LiK6aOeCgpkZWYgY2xlYXJfc2NyZWVuKCk6CiAgICAmcXVvdDsmcXVvdDsmcXVvdDvmuIXlsY/vvIjpgILnlKjkuo7mjqfliLblj7DvvIkmcXVvdDsmcXVvdDsmcXVvdDsKICAgIHN5cy5zdGRvdXQud3JpdGUoJnF1b3Q7XDAzM1tIXDAzM1tKJnF1b3Q7KSAgIyBBTlNJIOa4heWxj+espgoKZGVmIHJlbmRlcihwbGF5ZXIsIGVuZW1pZXMsIGJ1bGxldHMpOgogICAgJnF1b3Q7JnF1b3Q7JnF1b3Q75riy5p+T55S76Z2iJnF1b3Q7JnF1b3Q7JnF1b3Q7CiAgICBjbGVhcl9zY3JlZW4oKQogICAgIyDnu5jliLblrZDlvLkKICAgIGZvciBidWxsZXQgaW4gYnVsbGV0czoKICAgICAgICBpZiAwICZsdDs9IGJ1bGxldC55ICZsdDsgU0NSRUVOX0hFSUdIVDoKICAgICAgICAgICAgcHJpbnQoZiZxdW90O1wwMzNbe2J1bGxldC55KzF9O3tidWxsZXQueCsxfUh7QlVMTEVUX0NIQVJ9JnF1b3Q7KSAgIyDlrprkvY3lrZfnrKbkvY3nva4KICAgICMg57uY5Yi25pWM5py6CiAgICBmb3IgZW5lbXkgaW4gZW5lbWllczoKICAgICAgICBpZiAwICZsdDs9IGVuZW15LnkgJmx0OyBTQ1JFRU5fSEVJR0hUOgogICAgICAgICAgICBwcmludChmJnF1b3Q7XDAzM1t7ZW5lbXkueSsxfTt7ZW5lbXkueCsxfUh7RU5FTVlfQ0hBUn0mcXVvdDspCiAgICAjIOe7mOWItueOqeWutgogICAgcHJpbnQoZiZxdW90O1wwMzNbe3BsYXllci55KzF9O3twbGF5ZXIueCsxfUh7UExBWUVSX0NIQVJ9JnF1b3Q7KQogICAgc3lzLnN0ZG91dC5mbHVzaCgpICAjIOWIt+aWsOi+k+WHugoKZGVmIG1haW4oKToKICAgIHBsYXllciA9IFBsYXllcigpCiAgICBlbmVtaWVzID0gW10KICAgIGJ1bGxldHMgPSBbXQogICAgc2NvcmUgPSAwCiAgICBsYXN0X2VuZW15X3RpbWUgPSB0aW1lLnRpbWUoKQoKICAgIHdoaWxlIFRydWU6CiAgICAgICAgIyDlpITnkIbovpPlhaXvvIjpnIDmiYvliqjovpPlhaXmjIfku6TvvIzmjInlm57ovabnoa7orqTvvIkKICAgICAgICBjbWQgPSBpbnB1dCgmcXVvdDvmk43kvZzvvIhh5bem56e7L2Tlj7Pnp7sv56m65qC85bCE5Ye7L3HpgIDlh7rvvIk6ICZxdW90Oykuc3RyaXAoKS5sb3dlcigpCiAgICAgICAgaWYgY21kID09ICdxJzoKICAgICAgICAgICAgYnJlYWsKICAgICAgICBpZiBjbWQgPT0gJ2EnOgogICAgICAgICAgICBwbGF5ZXIubW92ZV9sZWZ0KCkKICAgICAgICBlbGlmIGNtZCA9PSAnZCc6CiAgICAgICAgICAgIHBsYXllci5tb3ZlX3JpZ2h0KCkKICAgICAgICBlbGlmIGNtZCA9PSAnICc6CiAgICAgICAgICAgIGJ1bGxldCA9IHBsYXllci5zaG9vdCgpCiAgICAgICAgICAgIGJ1bGxldHMuYXBwZW5kKGJ1bGxldCkKICAgICAgICAKICAgICAgICAjIOeUn+aIkOaVjOacuu+8iOavjzLnp5LnlJ/miJDkuIDkuKrvvIkKICAgICAgICBpZiB0aW1lLnRpbWUoKSAtIGxhc3RfZW5lbXlfdGltZSAmZ3Q7IDI6CiAgICAgICAgICAgIGVuZW1pZXMuYXBwZW5kKEVuZW15KCkpCiAgICAgICAgICAgIGxhc3RfZW5lbXlfdGltZSA9IHRpbWUudGltZSgpCiAgICAgICAgCiAgICAgICAgIyDmm7TmlrDlrZDlvLnnirbmgIEKICAgICAgICBsaXZlX2J1bGxldHMgPSBbXQogICAgICAgIGZvciBidWxsZXQgaW4gYnVsbGV0czoKICAgICAgICAgICAgYnVsbGV0LnVwZGF0ZSgpCiAgICAgICAgICAgIGlmIGJ1bGxldC55ICZndDs9IDA6CiAgICAgICAgICAgICAgICBsaXZlX2J1bGxldHMuYXBwZW5kKGJ1bGxldCkKICAgICAgICBidWxsZXRzID0gbGl2ZV9idWxsZXRzCiAgICAgICAgCiAgICAgICAgIyDmm7TmlrDmlYzmnLrnirbmgIHlubbmo4DmtYvnorDmkp4KICAgICAgICBsaXZlX2VuZW1pZXMgPSBbXQogICAgICAgIGZvciBlbmVteSBpbiBlbmVtaWVzOgogICAgICAgICAgICBlbmVteS51cGRhdGUoKQogICAgICAgICAgICBpZiBlbmVteS55ICZsdDsgU0NSRUVOX0hFSUdIVDoKICAgICAgICAgICAgICAgICMg5qOA5rWL5a2Q5by55Ye75Lit5pWM5py6CiAgICAgICAgICAgICAgICBmb3IgYnVsbGV0IGluIGJ1bGxldHM6CiAgICAgICAgICAgICAgICAgICAgaWYgYWJzKGVuZW15LnggLSBidWxsZXQueCkgJmx0Oz0gMSBhbmQgZW5lbXkueSA9PSBidWxsZXQueToKICAgICAgICAgICAgICAgICAgICAgICAgc2NvcmUgKz0gMQogICAgICAgICAgICAgICAgICAgICAgICBwcmludChmJnF1b3Q75Ye75Lit77yB5b6X5YiG77yae3Njb3JlfSZxdW90OykKICAgICAgICAgICAgICAgICAgICAgICAgIyDnp7vpmaTooqvlh7vkuK3nmoTlrZDlvLnlkozmlYzmnLoKICAgICAgICAgICAgICAgICAgICAgICAgYnVsbGV0cy5yZW1vdmUoYnVsbGV0KQogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBsaXZlX2VuZW1pZXMuYXBwZW5kKGVuZW15KQogICAgICAgIGVuZW1pZXMgPSBsaXZlX2VuZW1pZXMKICAgICAgICAKICAgICAgICAjIOa4suafk+eUu+mdogogICAgICAgIHJlbmRlcihwbGF5ZXIsIGVuZW1pZXMsIGJ1bGxldHMpCiAgICAgICAgdGltZS5zbGVlcChERUxBWSkKCmlmIF9fbmFtZV9fID09ICZxdW90O19fbWFpbl9fJnF1b3Q7OgogICAgbWFpbigpCiZuYnNwOw==
import sys
import time
import random
# 游戏参数
SCREEN_WIDTH = 40 # 控制台宽度(字符数)
SCREEN_HEIGHT = 20 # 控制台高度(字符数)
PLAYER_CHAR = "▶" # 玩家飞机(向右箭头)
ENEMY_CHAR = "X" # 敌机
BULLET_CHAR = "|" # 子弹
DELAY = 0.1 # 刷新间隔(秒)
class Player:
def __init__(self):
self.x = SCREEN_WIDTH // 2 # 初始位置居中
self.y = SCREEN_HEIGHT - 1 # 底部位置
def move_left(self):
if self.x > 0:
self.x -= 1
def move_right(self):
if self.x < SCREEN_WIDTH - 1:
self.x += 1
def shoot(self):
return Bullet(self.x, self.y - 1) # 子弹从飞机上方发射
class Enemy:
def __init__(self):
self.x = random.randint(0, SCREEN_WIDTH - 1) # 随机横向位置
self.y = 0 # 从顶部生成
def update(self):
self.y += 1 # 敌机下落
class Bullet:
def __init__(self, x, y):
self.x = x
self.y = y
def update(self):
self.y -= 1 # 子弹上飞
def clear_screen():
"""清屏(适用于控制台)"""
sys.stdout.write("\033[H\033[J") # ANSI 清屏符
def render(player, enemies, bullets):
"""渲染画面"""
clear_screen()
# 绘制子弹
for bullet in bullets:
if 0 <= bullet.y < SCREEN_HEIGHT:
print(f"\033[{bullet.y+1};{bullet.x+1}H{BULLET_CHAR}") # 定位字符位置
# 绘制敌机
for enemy in enemies:
if 0 <= enemy.y < SCREEN_HEIGHT:
print(f"\033[{enemy.y+1};{enemy.x+1}H{ENEMY_CHAR}")
# 绘制玩家
print(f"\033[{player.y+1};{player.x+1}H{PLAYER_CHAR}")
sys.stdout.flush() # 刷新输出
def main():
player = Player()
enemies = []
bullets = []
score = 0
last_enemy_time = time.time()
while True:
# 处理输入(需手动输入指令,按回车确认)
cmd = input("操作(a左移/d右移/空格射击/q退出): ").strip().lower()
if cmd == 'q':
break
if cmd == 'a':
player.move_left()
elif cmd == 'd':
player.move_right()
elif cmd == ' ':
bullet = player.shoot()
bullets.append(bullet)
# 生成敌机(每2秒生成一个)
if time.time() - last_enemy_time > 2:
enemies.append(Enemy())
last_enemy_time = time.time()
# 更新子弹状态
live_bullets = []
for bullet in bullets:
bullet.update()
if bullet.y >= 0:
live_bullets.append(bullet)
bullets = live_bullets
# 更新敌机状态并检测碰撞
live_enemies = []
for enemy in enemies:
enemy.update()
if enemy.y < SCREEN_HEIGHT:
# 检测子弹击中敌机
for bullet in bullets:
if abs(enemy.x - bullet.x) <= 1 and enemy.y == bullet.y:
score += 1
print(f"击中!得分:{score}")
# 移除被击中的子弹和敌机
bullets.remove(bullet)
break
else:
live_enemies.append(enemy)
enemies = live_enemies
# 渲染画面
render(player, enemies, bullets)
time.sleep(DELAY)
if __name__ == "__main__":
main()