You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的渲染是按代码执行顺序叠加的,先画的内容会被后画的内容覆盖。你当前的代码先绘制所有菱形(包括顶部的),再绘制小球;同时下方菱形的绘制顺序也在顶部菱形之后,导致顶部菱形被遮挡。

修改步骤

  1. 拆分菱形绘制逻辑:把顶部菱形和下方菱形的绘制分开,避免下方菱形覆盖顶部。
  2. 调整绘制顺序:将顶部菱形的绘制放在所有元素最后,确保它处于最上层。

修改后的代码片段

首先,修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:55:54