|
|
# 第5关【最终炼狱】
{
"platforms": [
{"rect":[0, 440, 70, 60], "move":False},
{"rect":[90, 340, 50, 22], "move":True,"mr":45,"msp":1.7},
{"rect":[180, 250, 50, 22], "move":False},
{"rect":[270, 330, 50, 22], "move":True,"mr":40,"msp":1.8},
{"rect":[360, 250, 50, 22], "move":False},
{"rect":[450, 170, 50, 22], "move":True,"mr":38,"msp":1.9},
{"rect":[540, 250, 50, 22], "move":False},
{"rect":[630, 170, 50, 22], "move":True,"mr":35,"msp":2.0},
{"rect":[715, 80, 55, 22], "move":False},
],
"spikes": [
[65, 418, 36, 22],
[110, 318, 36, 22],
[200, 228, 36, 22],
[290, 308, 36, 22],
[380, 228, 36, 22],
[470, 148, 36, 22],
[560, 228, 36, 22],
[650, 148, 36, 22],
],
"monsters": [
{"type":"patrol","x":185,"y":208,"range":32,"speed":2.7},
{"type":"patrol","x":365,"y":208,"range":30,"speed":2.8},
{"type":"patrol","x":635,"y":128,"range":28,"speed":2.8},
],
"chase_monsters":[
{"x":275,"y":288,"speed":2.2,"detect_range":270},
{"x":455,"y":128,"speed":2.3,"detect_range":260},
{"x":545,"y":208,"speed":2.1,"detect_range":250}
],
"finish": [720, 36, 48, 44],
"start_x": 8,
"start_y": 350
}
]
# 全局状态
current_level = 0
px = 0
py = 0
vx = 0
vy = 0
on_ground = False
game_over = False
win_level = False
game_complete = False
platform_list = []
patrol_monster_list = []
chase_monster_list = []
def load_level(lv_idx):
global px,py,vx,vy,on_ground,game_over,win_level
global platform_list, patrol_monster_list, chase_monster_list
lv = levels[lv_idx]
px = lv["start_x"]
py = lv["start_y"]
vx = 0
vy = 0
on_ground = False
game_over = False
win_level = False
# 加载平台(保存原始坐标用于移动)
platform_list = []
for p_data in lv["platforms"]:
x,y,w,h = p_data["rect"]
plat = {
"x":x,"y":y,"w":w,"h":h,
"origin_x":x,
"move":p_data["move"],
"mr":p_data.get("mr",0),
"msp":p_data.get("msp",0),
"dir":1
}
platform_list.append(plat)
# 巡逻怪
patrol_monster_list = []
for m in lv["monsters"]:
patrol_monster_list.append({
"x":m["x"],"y":m["y"],
"origin_x":m["x"],
"range":m["range"],
"speed":m["speed"],
"dir":1,
"w":28,"h":28
})
# 追踪怪
chase_monster_list = []
for cm in lv["chase_monsters"]:
chase_monster_list.append({
"x":cm["x"],"y":cm["y"],
"origin_x":cm["x"],
"speed":cm["speed"],
"detect":cm["detect_range"],
"w":28,"h":28
})
load_level(current_level)
clock = pygame.time.Clock()
running = True
while running:
screen.fill(SKY)
clock.tick(60)
keys = pygame.key.get_pressed()
lv_data = levels[current_level]
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
if game_complete:
current_level = 0
game_complete = False
load_level(current_level)
else:
load_level(current_level)
if not game_over and not win_level and not game_complete:
if event.key == pygame.K_UP and on_ground:
vy = jump_power
on_ground = False
if not game_over and not win_level and not game_complete:
# 玩家移动
vx = 0
if keys[pygame.K_LEFT]:
vx = -speed
if keys[pygame.K_RIGHT]:
vx = speed
vy += gravity
px += vx
py += vy
player_rect = pygame.Rect(px, py, pw, ph)
on_ground = False
# 更新移动平台位置
for plat in platform_list:
if plat["move"]:
plat["x"] += plat["msp"] * plat["dir"]
if plat["x"] > plat["origin_x"] + plat["mr"]:
plat["dir"] = -1
if plat["x"] < plat["origin_x"] - plat["mr"]:
plat["dir"] = 1
# 平台碰撞
for plat in platform_list:
pr = pygame.Rect(plat["x"], plat["y"], plat["w"], plat["h"])
if player_rect.colliderect(pr):
if vy > 0 and player_rect.bottom - vy <= pr.top + 3:
py = pr.top - ph
vy = 0
on_ground = True
# 边界限制
if px < 0:
px = 0
if px > WIDTH - pw:
px = WIDTH - pw
if py > HEIGHT:
game_over = True
# 尖刺碰撞
for s in lv_data["spikes"]:
sr = pygame.Rect(*s)
if player_rect.colliderect(sr):
game_over = True
# ===== 巡逻怪物【碰到边界立刻折返,无缓冲】 =====
for m in patrol_monster_list:
m["x"] += m["speed"] * m["dir"]
if m["x"] >= m["origin_x"] + m["range"]:
m["dir"] = -1
if m["x"] <= m["origin_x"] - m["range"]:
m["dir"] = 1
mr = pygame.Rect(m["x"], m["y"], m["w"], m["h"])
if player_rect.colliderect(mr):
game_over = True
# ===== 追踪怪物逻辑(水平追踪玩家) =====
for cm in chase_monster_list:
dist_x = (px + pw/2) - (cm["x"] + cm["w"]/2)
if abs(dist_x) < cm["detect"]:
if dist_x > 2:
cm["x"] += cm["speed"]
elif dist_x < -2:
cm["x"] -= cm["speed"]
cmr = pygame.Rect(cm["x"], cm["y"], cm["w"], cm["h"])
if player_rect.colliderect(cmr):
game_over = True
# 终点判定
finish_rect = pygame.Rect(*lv_data["finish"])
if player_rect.colliderect(finish_rect):
win_level = True
# 关卡切换
if win_level and not game_complete:
current_level += 1
if current_level >= len(levels):
game_complete = True
else:
pygame.time.delay(400)
load_level(current_level)
# 绘制平台
for plat in platform_list:
x,y,w,h = plat["x"],plat["y"],plat["w"],plat["h"]
pygame.draw.rect(screen, GROUND_BOTTOM, (x,y+4,w,h-4), border_radius=3)
pygame.draw.rect(screen, GROUND_TOP, (x,y,w,6), border_radius=3)
# 绘制尖刺
for s in lv_data["spikes"]:
x,y,w,h = s
p1=(x,y+h)
p2=(x+w//2,y)
p3=(x+w,y+h)
pygame.draw.polygon(screen, SPIKE_COLOR, [p1,p2,p3])
# 巡逻怪绘制(红色)
for m in patrol_monster_list:
mx,my = m["x"],m["y"]
mw,mh = m["w"],m["h"]
pygame.draw.rect(screen, MONSTER_COLOR, (mx,my,mw,mh), border_radius=5)
pygame.draw.rect(screen, MONSTER_OUTLINE, (mx,my,mw,mh),2,border_radius=5)
pygame.draw.circle(screen,WHITE,(mx+7,my+9),3)
pygame.draw.circle(screen,WHITE,(mx+21,my+9),3)
# 追踪怪绘制(紫色区分)
for cm in chase_monster_list:
mx,my = cm["x"],cm["y"]
mw,mh = cm["w"],cm["h"]
pygame.draw.rect(screen, CHASE_MONSTER_COLOR, (mx,my,mw,mh), border_radius=5)
pygame.draw.rect(screen, CHASE_MONSTER_OUTLINE, (mx,my,mw,mh),2,border_radius=5)
pygame.draw.circle(screen,YELLOW,(mx+7,my+9),3)
pygame.draw.circle(screen,YELLOW,(mx+21,my+9),3)
# 绘制缩小玩家
pygame.draw.rect(screen, PLAYER_MAIN, (px, py, pw, ph), border_radius=6)
pygame.draw.rect(screen, PLAYER_OUTLINE, (px, py, pw, ph), 2, border_radius=6)
ey = py + 8
pygame.draw.circle(screen, WHITE, (px+7, ey), 3)
pygame.draw.circle(screen, WHITE, (px+19, ey), 3)
pygame.draw.circle(screen, BLACK, (px+8, ey), 1.5)
pygame.draw.circle(screen, BLACK, (px+20, ey), 1.5)
# UI
panel_rect = pygame.Rect(8, 8, 170, 36)
pygame.draw.rect(screen, (0,0,0,120), panel_rect, border_radius=6)
pygame.draw.rect(screen, WHITE, panel_rect, 1, border_radius=6)
level_text = small_font.render(f"关卡 {current_level+1}/{len(levels)}", True, WHITE)
screen.blit(level_text, (15, 12))
# 弹窗
if game_complete:
overlay = pygame.Surface((WIDTH, HEIGHT))
overlay.set_alpha(140)
overlay.fill(BLACK)
screen.blit(overlay, (0,0))
txt = font.render("炼狱通关!按R重来", True, YELLOW)
screen.blit(txt, txt.get_rect(center=(WIDTH//2, HEIGHT//2)))
elif win_level:
overlay = pygame.Surface((WIDTH, HEIGHT))
overlay.set_alpha(100)
overlay.fill(BLACK)
screen.blit(overlay, (0,0))
txt = font.render("过关!准备下一关", True, WHITE)
screen.blit(txt, txt.get_rect(center=(WIDTH//2, HEIGHT//2)))
elif game_over:
overlay = pygame.Surface((WIDTH, HEIGHT))
overlay.set_alpha(100)
overlay.fill(BLACK)
screen.blit(overlay, (0,0))
txt = font.render("阵亡!按R重试", True, RED)
screen.blit(txt, txt.get_rect(center=(WIDTH//2, HEIGHT//2)))
pygame.display.update()
pygame.quit()
sys.exit() |
|