Pygame菱形坐标问题:如何让顶部菱形显示在前景
问题描述
我正在用Pygame开发一款小游戏(目前处于面向对象编程OOP学习阶段,暂未考虑Kivy)。游戏里有小球和堆叠成长方体视觉效果的菱形组,顶部的菱形可以通过方向键沿X轴移动。我已经手动调整了它的Y坐标让它位于顶部,但它看起来像在背景里,没法呈现前景效果。
以下是顶部菱形移动时的坐标输出:
This is are a points of firts rhombus[(170, 364), (350, 364), (300, 414), (120, 414)] ...[省略重复坐标内容]
完整代码如下:
import pygame as pg import random import time pg.init() BG_COLOR = pg.Color('black') WHITE = pg.Color('white') ORANGE = pg.Color('orange') BLUE = pg.Color('blue') RED = pg.Color('red') PURPLE = pg.Color('purple') BALL_COOR_X = 240 screen = pg.display.set_mode((500, 800)) clock = pg.time.Clock() bg = pg.image.load("bg.png") def rhombus(screen, color, space): point1 = (170, 760 - space) point2 = (350, 760 - space) point3 = (300, 810 - space) point4 = (120, 810 - space) points = [point1, point2, point3, point4] #print(points) return pg.draw.polygon(screen, color, points) def first_rhombus(screen, color, x_coor): point1 = (170-x_coor, 364 ) point2 = (350-x_coor, 364 ) point3 = (300-x_coor, 414 ) point4 = (120-x_coor, 414 ) points = [point1, point2, point3, point4] print(f"This is are a points of firts rhombus{points}") return pg.draw.polygon(screen, color, points) def colors(): collist = [] old_col = None for trash in range(0, 43): col = random.choice([RED, ORANGE, RED, BLUE, WHITE]) if col != old_col: collist.append(col) old_col = col else: collist.append(PURPLE) old_col = col return collist def cube(collist, space,x_coor): positions = [] for x in range(0, 43): if x == 0: position = first_rhombus(screen, collist[x], x_coor) else: position = rhombus(screen, collist[x], space) positions.append(position) space += 8 return positions def move_rhumbus(x_coor, keys): if keys[pg.K_LEFT]: if x_coor > -500: x_coor -= 5 if keys[pg.K_RIGHT]: if x_coor < 500: x_coor += 5 return x_coor #Ball functions def ball(color, x, y): pg.draw.circle(screen, color, (x, y), 15) def plus(y): y = y + 1 return y def minus(y): y = y - 1 return y def check_collision(space, index): end = False #print(f"This is a plus in check_collision: {space}") #print(f"This is a index in check_collision: {index} ") if space > 0 and space< 500: if colorlist[ballcol] != colorlist[index]: end = True return end def ball_color(colorlist): li = [0, 1, 2, 3, 4] ballcol = random.choice(li) return ballcol # Main game loop done = False colorlist = colors() ballcol = ball_color(colorlist) ball_coor_y = 300 constant_of_px = 440 end = False restart = False x_coor = 0 space = 0 while not done: for event in pg.event.get(): if event.type == pg.QUIT: done = True keys = pg.key.get_pressed() x_coor = move_rhumbus(x_coor, keys) screen.fill(BG_COLOR) # Draw rhombus and store their positions rhombus_positions = cube(colorlist, space,x_coor) # Check for collisions for i, position in enumerate(rhombus_positions): end = check_collision(space, i) if end: break ball(colorlist[ballcol], BALL_COOR_X, ball_coor_y) # Ball movement if ball_coor_y < constant_of_px: ball_coor_y = plus(ball_coor_y) else: ball_coor_y = minus(ball_coor_y) constant_of_px = 0 if colorlist[ballcol] != colorlist[i]: end = True if ball_coor_y == 300: constant_of_px = 440 #This is a bg after game over but in dev it is banned so please remove """ """ if end: screen.blit(bg, (0, 0)) """ pg.display.flip() clock.tick(30)
解决方案
问题核心是绘制顺序:Pygame的渲染是按代码执行顺序叠加的,先画的内容会被后画的内容覆盖。你当前的代码先绘制所有菱形(包括顶部的),再绘制小球;同时下方菱形的绘制顺序也在顶部菱形之后,导致顶部菱形被遮挡。
修改步骤
- 拆分菱形绘制逻辑:把顶部菱形和下方菱形的绘制分开,避免下方菱形覆盖顶部。
- 调整绘制顺序:将顶部菱形的绘制放在所有元素最后,确保它处于最上层。
修改后的代码片段
首先,修改cube()函数,只处理下方菱形的绘制:
def cube(collist, space): positions = [] for x in range(1, 43): # 跳过顶部的x=0,只画下方菱形 position = rhombus(screen, collist[x], space) positions.append(position) space += 8 return positions
然后调整主循环的绘制顺序:
while not done: # ... 事件处理、按键逻辑保持不变 ... screen.fill(BG_COLOR) # 1. 先绘制下方菱形组(背景层) rhombus_positions = cube(colorlist, space) # 2. 绘制小球(中间层) ball(colorlist[ballcol], BALL_COOR_X, ball_coor_y) # 3. 最后绘制顶部可移动菱形(最上层,前景) first_rhombus(screen, colorlist[0], x_coor) # ... 碰撞检测、小球移动逻辑保持不变 ... pg.display.flip() clock.tick(30)
原理说明
Pygame的坐标系以左上角为原点,Y值越大越靠下。顶部菱形的Y坐标在364-414区间(屏幕上半部分),下方菱形的Y坐标从760开始逐步减小到424(屏幕下半部分),原本的绘制顺序会让下方菱形先占满下半区,再画顶部菱形,但后续的小球绘制会覆盖顶部菱形的重叠区域。调整后,顶部菱形最后绘制,会覆盖所有之前的元素,自然呈现前景效果。
内容的提问来源于stack exchange,提问作者Alan Wales
相关产品推荐
相关产品推荐

