pygame 1.9.4-Python 2.7.15-Kali Linux 2018.2
我整理了一些旧的“平方根”益智游戏的游戏脚本。 我确定可以将它们更好地组合在一起(使用列表),但是我想知道是否以及如何将矩形锁定在网格上,以及使它们在发生任何碰撞时“停止”。感谢您的任何帮助,初学者可以肯定。目的是使红色方块到达底部中心...
import pygame
# --- constants --- (UPPER_CASE names)
SCREEN_WIDTH = 490
SCREEN_HEIGHT = 600
LINE_WIDTH = 10
#BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
LIGHT_BROWN = (153, 102, 51)
FPS = 30
# --- classses --- (CamelCase names)
# empty
# --- functions --- (lower_case names)
# empty
# --- main ---
# - init -
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH+LINE_WIDTH, SCREEN_HEIGHT+LINE_WIDTH))
#screen_rect = screen.get_rect()
pygame.display.set_caption("Game Of Squares")
# - objects -
square = pygame.rect.Rect(150, 50, 200, 200)
square_draging = False
r1 = pygame.rect.Rect(40, 50, 100, 200)
r1_draging = False
r2 = pygame.rect.Rect(40, 260, 100, 200)
r2_draging = False
r3 = pygame.rect.Rect(360, 50, 100, 200)
r3_draging = False
r4 = pygame.rect.Rect(360, 260, 100, 200)
r4_draging = False
r5 = pygame.rect.Rect(150, 260, 200, 100)
r5_draging = False
s1 = pygame.rect.Rect(150, 370, 95, 95)
s1_draging = False
s2 = pygame.rect.Rect(255, 370, 95, 95)
s2_draging = False
s3 = pygame.rect.Rect(45, 470, 95, 95)
s3_draging = False
s4 = pygame.rect.Rect(360, 470, 95, 95)
s4_draging = False
# - mainloop -
clock = pygame.time.Clock()
running = True
while running:
# -square
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if square.collidepoint(event.pos):
square_draging = True
mouse_x, mouse_y = event.pos
offset_x = square.x - mouse_x
offset_y = square.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
square_draging = False
elif event.type == pygame.MOUSEMOTION:
if square_draging:
mouse_x, mouse_y = event.pos
square.x = mouse_x + offset_x
square.y = mouse_y + offset_y
if square.x > 290:
square.x = 290
if square.x < 10:
square.x = 10
if square.y > 400:
square.y = 400
if square.y < 10:
square.y = 10
#r1
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if r1.collidepoint(event.pos):
r1_draging = True
mouse_x, mouse_y = event.pos
offset_x = r1.x - mouse_x
offset_y = r1.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
r1_draging = False
elif event.type == pygame.MOUSEMOTION:
if r1_draging:
mouse_x, mouse_y = event.pos
r1.x = mouse_x + offset_x
r1.y = mouse_y + offset_y
if r1.x > 390:
r1.x = 390
if r1.x < 10:
r1.x = 10
if r1.y > 400:
r1.y = 400
if r1.y < 10:
r1.y = 10
#r2
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if r2.collidepoint(event.pos):
r2_draging = True
mouse_x, mouse_y = event.pos
offset_x = r2.x - mouse_x
offset_y = r2.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
r2_draging = False
elif event.type == pygame.MOUSEMOTION:
if r2_draging:
mouse_x, mouse_y = event.pos
r2.x = mouse_x + offset_x
r2.y = mouse_y + offset_y
if r2.x > 390:
r2.x = 390
if r2.x < 10:
r2.x = 10
if r2.y > 395:
r2.y = 395
if r2.y < 10:
r2.y = 10
#r3
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if r3.collidepoint(event.pos):
r3_draging = True
mouse_x, mouse_y = event.pos
offset_x = r3.x - mouse_x
offset_y = r3.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
r3_draging = False
elif event.type == pygame.MOUSEMOTION:
if r3_draging:
mouse_x, mouse_y = event.pos
r3.x = mouse_x + offset_x
r3.y = mouse_y + offset_y
if r3.x > 390:
r3.x = 390
if r3.x < 10:
r3.x = 10
if r3.y > 400:
r3.y = 400
if r3.y < 10:
r3.y = 10
#r4
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if r4.collidepoint(event.pos):
r4_draging = True
mouse_x, mouse_y = event.pos
offset_x = r4.x - mouse_x
offset_y = r4.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
r4_draging = False
elif event.type == pygame.MOUSEMOTION:
if r4_draging:
mouse_x, mouse_y = event.pos
r4.x = mouse_x + offset_x
r4.y = mouse_y + offset_y
if r4.x > 390:
r4.x = 390
if r4.x < 10:
r4.x = 10
if r4.y > 395:
r4.y = 395
if r4.y < 10:
r4.y = 10
#r5
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if r5.collidepoint(event.pos):
r5_draging = True
mouse_x, mouse_y = event.pos
offset_x = r5.x - mouse_x
offset_y = r5.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
r5_draging = False
elif event.type == pygame.MOUSEMOTION:
if r5_draging:
mouse_x, mouse_y = event.pos
r5.x = mouse_x + offset_x
r5.y = mouse_y + offset_y
if r5.x > 290:
r5.x = 290
if r5.x < 10:
r5.x = 10
if r5.y > 500:
r5.y = 500
if r5.y < 10:
r5.y = 10
#s1
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if s1.collidepoint(event.pos):
s1_draging = True
mouse_x, mouse_y = event.pos
offset_x = s1.x - mouse_x
offset_y = s1.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
s1_draging = False
elif event.type == pygame.MOUSEMOTION:
if s1_draging:
mouse_x, mouse_y = event.pos
s1.x = mouse_x + offset_x
s1.y = mouse_y + offset_y
if s1.x > 395:
s1.x = 395
if s1.x < 10:
s1.x = 10
if s1.y > 505:
s1.y = 505
if s1.y < 10:
s1.y = 10
#s2
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if s2.collidepoint(event.pos):
s2_draging = True
mouse_x, mouse_y = event.pos
offset_x = s2.x - mouse_x
offset_y = s2.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
s2_draging = False
elif event.type == pygame.MOUSEMOTION:
if s2_draging:
mouse_x, mouse_y = event.pos
s2.x = mouse_x + offset_x
s2.y = mouse_y + offset_y
if s2.x > 395:
s2.x = 395
if s2.x < 10:
s2.x = 10
if s2.y > 505:
s2.y = 505
if s2.y < 10:
s2.y = 10
#s3
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if s3.collidepoint(event.pos):
s3_draging = True
mouse_x, mouse_y = event.pos
offset_x = s3.x - mouse_x
offset_y = s3.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
s3_draging = False
elif event.type == pygame.MOUSEMOTION:
if s3_draging:
mouse_x, mouse_y = event.pos
s3.x = mouse_x + offset_x
s3.y = mouse_y + offset_y
if s3.x > 395:
s3.x = 395
if s3.x < 10:
s3.x = 10
if s3.y > 505:
s3.y = 505
if s3.y < 10:
s3.y = 10
#s4
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if s4.collidepoint(event.pos):
s4_draging = True
mouse_x, mouse_y = event.pos
offset_x = s4.x - mouse_x
offset_y = s4.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
s4_draging = False
elif event.type == pygame.MOUSEMOTION:
if s4_draging:
mouse_x, mouse_y = event.pos
s4.x = mouse_x + offset_x
s4.y = mouse_y + offset_y
if s4.x > 395:
s4.x = 395
if s4.x < 10:
s4.x = 10
if s4.y > 505:
s4.y = 505
if s4.y < 10:
s4.y = 10
# - updates (without draws) -
# empty
# - draws (without updates) -
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, [0,0,SCREEN_WIDTH,LINE_WIDTH])
# bottom line
pygame.draw.rect(screen, WHITE, [0,SCREEN_HEIGHT,SCREEN_WIDTH,LINE_WIDTH])
# left line
pygame.draw.rect(screen, WHITE, [0,0,LINE_WIDTH, SCREEN_HEIGHT])
# right line
pygame.draw.rect(screen, WHITE, [SCREEN_WIDTH,0,LINE_WIDTH, SCREEN_HEIGHT+LINE_WIDTH])
#Draw Stuffs
pygame.draw.rect(screen, RED, square)
pygame.draw.rect(screen, LIGHT_BROWN, r1)
pygame.draw.rect(screen, LIGHT_BROWN, r2)
pygame.draw.rect(screen, LIGHT_BROWN, r3)
pygame.draw.rect(screen, LIGHT_BROWN, r4)
pygame.draw.rect(screen, LIGHT_BROWN, r5)
pygame.draw.rect(screen, LIGHT_BROWN, s1)
pygame.draw.rect(screen, LIGHT_BROWN, s2)
pygame.draw.rect(screen, LIGHT_BROWN, s3)
pygame.draw.rect(screen, LIGHT_BROWN, s4)
pygame.display.flip()
# - constant game speed / FPS -
clock.tick(FPS)
# - end -
pygame.quit()
答案 0 :(得分:2)
程序中有很多重复,并且事件不应在while
中处理,而应在事件循环中处理。我将所有矩形放入列表,并在for
循环中绘制和更新它们。
要选择一个rect,只需在这些rect上循环并将冲突的rect分配给一个变量(在下面的示例中为selected
)。当发生pygame.MOUSEMOTION
事件时,您只需将event.rel
(鼠标相对移动)添加到所选矩形的x
和y
属性中即可。
我们需要分别沿x和y轴移动,以便能够处理与其他矩形的碰撞。如果所选矩形沿x轴移动并且与另一个矩形发生碰撞,我们可以将其right
或left
的坐标设置为碰撞的left
或right
的坐标直肠然后,我们可以对y轴执行相同的操作,并设置top
或bottom
坐标。
对于边界,我将使用与屏幕大小相同的矩形,并将其缩小一点(使用pygame.Rect.inflate
),以得到较小的矩形用于边界检查。
import pygame
LINE_WIDTH = 10
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
LIGHT_BROWN = (153, 102, 51)
FPS = 30
pygame.init()
screen = pygame.display.set_mode((490+LINE_WIDTH, 600+LINE_WIDTH))
clock = pygame.time.Clock()
screen_rect = screen.get_rect()
boundary = screen_rect.inflate((-21, -21))
boundary.move_ip(1, 1)
# Keep the square as a separate variable, so that we can
# draw it with a different color.
square = pygame.rect.Rect(150, 50, 200, 200)
# Put all rects (the square as well) into a list.
rects = [
pygame.rect.Rect(40, 50, 100, 200),
pygame.rect.Rect(40, 260, 100, 200),
pygame.rect.Rect(360, 50, 100, 200),
pygame.rect.Rect(360, 260, 100, 200),
pygame.rect.Rect(150, 260, 200, 100),
pygame.rect.Rect(150, 370, 95, 95),
pygame.rect.Rect(255, 370, 95, 95),
pygame.rect.Rect(45, 470, 95, 95),
pygame.rect.Rect(360, 470, 95, 95),
square,
]
selected = None # The currently selected rect.
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
for rect in rects:
if rect.collidepoint(event.pos):
selected = rect # Select the colliding rect.
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
selected = None # Deselect the rect.
elif event.type == pygame.MOUSEMOTION:
if selected: # Move the selected rect.
# Move along the x-axis first.
selected.x += event.rel[0]
selected.clamp_ip(boundary)
for rect in rects:
# Skip the selected rect.
if rect is not selected and selected.colliderect(rect):
# Set the selected rect's position if it collides
# with another rect.
if event.rel[0] > 0:
selected.right = rect.left
elif event.rel[0] < 0:
selected.left = rect.right
# Do the same as above for the y-axis.
selected.y += event.rel[1]
selected.clamp_ip(boundary)
for rect in rects:
if rect is not selected and selected.colliderect(rect):
if event.rel[1] < 0:
selected.top = rect.bottom
elif event.rel[1] > 0:
selected.bottom = rect.top
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, screen_rect, 20) # Boundary.
# Draw the rects.
for rect in rects:
pygame.draw.rect(screen, LIGHT_BROWN, rect)
pygame.draw.rect(screen, RED, square) # Draw the red square separately.
pygame.display.flip()
clock.tick(FPS)
pygame.quit()