首页 > 解决方案 > 在这种情况下如何滚动带有背景的元素?

问题描述

我不知道是哪一个,它可能是一个将项目类与背景一起滚动的命令。所以你能帮我找到一个命令来移动一个以上的班级吗

class item(object):


    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.end = end
        self.path = [self.x, self.end]
        self.walkCount = 0
        self.vel = 3
        self.hitbox = (self.x + 17, self.y + 2, 31, 57)


    def draw(self,win):
        win.blit(d, (self.x,self.y))
        self.hitbox = (self.x + 17, self.y + 2, 31, 57)
        pygame.draw.rect(win, (255,0,0), self.hitbox,2)


if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            man.x += man.vel
            man.left = False
            man.right = True
            man.up = False
            man.down = False

            if man.x > 1750:
                background.scroll(-5,0)
                man.x = 1750

标签: pythonpygame

解决方案


一次滚动背景和其他元素没有特殊的命令。您必须编写记住玩家移动的代码(即offset_x,offset_y)

player.move(speed_x, speed_y)

offset_x -= speed_x
offset_y -= speed_y

或始终让玩家居中的版本

player.move(speed_x, speed_y)

offset_x = screen_rect.centerx - player.rect.centerx
offset_y = screen_rect.centery - player.rect.centery

然后在绘制所有对象时使用它

screen.fill(BLACK)

background.draw(screen, offset_x, offset_y)

object1.draw(screen, offset_x, offset_y)
object2.draw(screen, offset_x, offset_y)

player.draw(screen, offset_x, offset_y)

它仅使用偏移量来计算要绘制的位置,但不会改变原始位置

def draw(self, surface, offset_x=0, offset_y=0):
    # don't change original `self.rect`

    rect = self.rect.move(offset_x, offset_y)

    surface.blit(self.image, rect)

最小工作示例。用于WASD移动对象和SPACE打开/关闭滚动。

代码总是滚动 - 它不检查玩家是否在地图边界附近,因为它需要额外的代码来停止滚动或使用if在更改偏移或跳过偏移之前检查玩家位置。

pygame.display.flip()

import pygame
import random

# --- constants --- (UPPER_CASE_NAMES)

SCREEN_WIDTH  = 800
SCREEN_HEIGHT = 600

FPS = 25

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

GRAY  = (128, 128, 128)

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

# --- classes --- (CamelCaseNames)

class Item(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height, color):
        super().__init__()
        
        self.image = pygame.surface.Surface((width, height)).convert()
        self.image.fill(color)
        self.rect = self.image.get_rect(centerx=x, centery=y)
        
    def update(self):
        pass
    
    def move(self, speed_x=0, speed_y=0):
        self.rect.move_ip(speed_x, speed_y)

    def draw(self, surface, offset_x=0, offset_y=0):
        # don't change original `self.rect`
        rect = self.rect.move(offset_x, offset_y)
        surface.blit(self.image, rect)

# --- functions --- (lower_case_names)

# --- main ---

pygame.init()

screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
screen_rect = screen.get_rect()

background = Item(screen_rect.centerx, screen_rect.centery, 600, 400, GREEN)

player = Item(screen_rect.centerx, screen_rect.centery, 50, 50, GRAY)

object1 = Item(200 , 200, 50, 50, RED)
object2 = Item(600 , 400, 50, 50, BLUE)
# --- mainloop ---

clock = pygame.time.Clock()

use_offset = False

offset_x = 0
offset_y = 0

speed_x = 0
speed_y = 0

running = True
while running:

    # --- events ---
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_ESCAPE:
                running = False
            # turn on/off scrolling
            elif event.key == pygame.K_SPACE:
                use_offset = not use_offset

    # A = move left, D = move right
    if pygame.key.get_pressed()[pygame.K_a]:
        speed_x = -5
    elif pygame.key.get_pressed()[pygame.K_d]:
        speed_x = 5
    else:
        speed_x = 0

    # W = move up, S = move down
    if pygame.key.get_pressed()[pygame.K_w]:
        speed_y = -5
    elif pygame.key.get_pressed()[pygame.K_s]:
        speed_y = 5
    else:
        speed_y = 0

    # --- changes/moves/updates ---

    # first move, later get offset    
    player.move(speed_x, speed_y)

    if use_offset:           
        offset_x -= speed_x
        offset_y -= speed_y
    
    #if use_offset:           
    #    offset_x = screen_rect.centerx - player.rect.centerx
    #    offset_y = screen_rect.centery - player.rect.centery
    #else:
    #    offset_x = 0
    #    offset_y = 0

    # --- draws ---

    screen.fill(BLACK)
    
    background.draw(screen, offset_x, offset_y)
    
    object1.draw(screen, offset_x, offset_y)
    object2.draw(screen, offset_x, offset_y)
    
    player.draw(screen, offset_x, offset_y)
    
    pygame.display.flip()

    # --- FPS ---

    ms = clock.tick(FPS)
    #pygame.display.set_caption('{}ms'.format(ms)) # 40ms for 25FPS, 16ms for 60FPS
    
    #fps = clock.get_fps()
    #pygame.display.set_caption('FPS: {}'.format(fps))
    
# --- end ---

pygame.quit()
     

编辑:

不带Rect(), rect.move(), rect.move_ip(), rect.centerx, 的版本rect.centery

import pygame
import random

# --- constants --- (UPPER_CASE_NAMES)

SCREEN_WIDTH  = 800
SCREEN_HEIGHT = 600

FPS = 25

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

GRAY  = (128, 128, 128)

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

# --- classes --- (CamelCaseNames)

class Item:

    def __init__(self, centerx, centery, width, height, color):
        self.x = centerx - width//2
        self.y = centery - height//2
        self.width = width
        self.height = height

        self.image = pygame.surface.Surface((width, height)).convert()
        self.image.fill(color)

        #self.rect = self.image.get_rect(centerx=centerx, centery=centery)

    def update(self):
        pass

    def move(self, speed_x=0, speed_y=0):
        self.x += speed_x
        self.y += speed_y
        #self.rect.move_ip(speed_x, speed_y)

    def draw(self, surface, offset_x=0, offset_y=0):
        # don't change original `self.x, self.y`
        x = self.x + offset_x
        y = self.y + offset_y
        surface.blit(self.image, (x,y))

        # don't change original `self.rect`
        #rect = self.rect.move(offset_x, offset_y)
        #surface.blit(self.image, rect)

# --- functions --- (lower_case_names)

# --- main ---

pygame.init()

screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT) )
screen_rect = screen.get_rect()

background = Item(screen_rect.centerx, screen_rect.centery, 600, 400, GREEN)

player = Item(screen_rect.centerx, screen_rect.centery, 50, 50, GRAY)

object1 = Item(200 , 200, 50, 50, RED)
object2 = Item(600 , 400, 50, 50, BLUE)
# --- mainloop ---

clock = pygame.time.Clock()

use_offset = True

offset_x = 0
offset_y = 0

speed_x = 0
speed_y = 0

running = True
while running:

    # --- events ---

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_ESCAPE:
                running = False
            # turn on/off scrolling
            elif event.key == pygame.K_SPACE:
                use_offset = not use_offset

    # A = move left, D = move right
    if pygame.key.get_pressed()[pygame.K_a]:
        speed_x = -5
    elif pygame.key.get_pressed()[pygame.K_d]:
        speed_x = 5
    else:
        speed_x = 0

    # W = move up, S = move down
    if pygame.key.get_pressed()[pygame.K_w]:
        speed_y = -5
    elif pygame.key.get_pressed()[pygame.K_s]:
        speed_y = 5
    else:
        speed_y = 0

    # --- changes/moves/updates ---

    # first move, later get offset
    player.move(speed_x, speed_y)

    #if use_offset:
    #    offset_x -= speed_x
    #    offset_y -= speed_y

    if use_offset:
    #    #offset_x = screen_rect.centerx - player.rect.centerx
    #    #offset_y = screen_rect.centery - player.rect.centery
        offset_x = screen_rect.centerx - (player.x + player.width//2)
        offset_y = screen_rect.centery - (player.y + player.height//2)
    else:
        offset_x = 0
        offset_y = 0

    # --- draws ---

    screen.fill(BLACK)

    background.draw(screen, offset_x, offset_y)

    object1.draw(screen, offset_x, offset_y)
    object2.draw(screen, offset_x, offset_y)

    player.draw(screen, offset_x, offset_y)

    pygame.display.flip()

    # --- FPS ---

    ms = clock.tick(FPS)
    #pygame.display.set_caption('{}ms'.format(ms)) # 40ms for 25FPS, 16ms for 60FPS

    #fps = clock.get_fps()
    #pygame.display.set_caption('FPS: {}'.format(fps))

# --- end ---

pygame.quit()

推荐阅读