使用pygame放大和缩小

问题描述 投票:0回答:3

我正在尝试这样做,以便您可以在我的 pygame 项目中放大和缩小。它工作正常,除了当我放大时,屏幕似乎向左上方放大,然后重新调整自身(使玩家位于屏幕的中心)。当我缩小时,它只是对对角做同样的事情,有人可以解释我为什么这样做吗?这是我的代码:

import pygame
import random 
import sys

from pygame.locals import *

WINDOW_SIZE = (600, 400)
FPS = 60


# Initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode(WINDOW_SIZE)
zoom = 2
display = pygame.Surface((int(WINDOW_SIZE[0] / zoom), int(WINDOW_SIZE[1] / zoom)))
pygame.display.set_caption('Game')
clock = pygame.time.Clock()

player_img = pygame.image.load('player.png').convert()
player_img.set_colorkey((255, 255, 255))
player_rect = pygame.Rect(0, 0, 5, 16)

grass_img = pygame.image.load('grass.png').convert()
dirt_img = pygame.image.load('dirt.png').convert()

# 0 = Air
# 1 = Grass
# 2 = Dirt

game_map =[['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
           ['0','0','0','0','0','0','1','1','1','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
           ['1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','1','0','0','0','0','0','0','0','0','0'],
           ['2','2','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','2','2','0','0','0','1','1','1','1','1','0'],
           ['2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','0','0','0','2','2','2','2','2','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2','2','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2','0','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','0','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
           ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0']]


def collision_test(rect,tiles):
    collisions = []
    for tile in tiles:
        if rect.colliderect(tile):
            collisions.append(tile)
    return collisions
 
def move(rect, movement, tiles):
    collision_direction = {'up': False, 'down': False, 'right': False, 'left' : False}
    
    rect.x += movement[0]
    collisions = collision_test(rect, tiles)
    for tile in collisions:
        if movement[0] > 0:
            rect.right = tile.left
            collision_direction['right'] = True
        if movement[0] < 0:
            rect.left = tile.right
            collision_direction['left'] = True
            
    rect.y += round(movement[1])
    collisions = collision_test(rect, tiles)
    for tile in collisions:
        if movement[1] > 0:
            rect.bottom = tile.top
            collision_direction['down'] = True
        if movement[1] < 0:
            rect.top = tile.bottom
            collision_direction['up'] = True
            
    return rect, collision_direction

mouvement_speed = 2
moving_right = False
moving_left = False
moving_up = False
moving_down = False

ctrl_pressed = False
equals_pressed = False
minus_pressed = False
zero_pressed = False

player_y_momentum = 0

air_timer = 0

scroll = [0, 0]


running = True
# Game loop
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        if event.type == KEYDOWN:
            if event.key == K_RIGHT or event.key == K_d:
                moving_right = True
            if event.key == K_LEFT or event.key == K_a:
                moving_left = True
                
            if event.key == K_UP or event.key == K_w:
                if air_timer < 3:
                    player_y_momentum = -4
                    
            if event.key == K_DOWN or event.key == K_s:
                moving_down = True

            if event.key == K_RCTRL or event.key == K_LCTRL:    
                ctrl_pressed = True

            if event.key == K_EQUALS:
                equals_pressed = True

            if event.key == K_MINUS:
                minus_pressed = True

            if event.key == K_0:
                zero_pressed = True
                
        if event.type == KEYUP:
            if event.key == K_RIGHT or event.key == K_d:
                moving_right = False
            if event.key == K_LEFT or event.key == K_a:
                moving_left = False
            if event.key == K_UP or event.key == K_w:
                moving_up = False
            if event.key == K_DOWN or event.key == K_s:
                moving_down = False
            if event.key == K_EQUALS:
                equals_pressed = False
            if event.key == K_MINUS:
                minus_pressed = False
            if event.key == K_0:
                zero_pressed = False
            if event.key == K_RCTRL or event.key == K_LCTRL:    
                ctrl_pressed = False

    if equals_pressed and ctrl_pressed:
        zoom += 0.2
        print('ZOOMING IN')

    if minus_pressed and ctrl_pressed:
        zoom -= 0.2
        print('ZOOMING OUT')

    if zero_pressed and ctrl_pressed:
        zoom = 2
        print('RESET')
        
    try:   
        display = pygame.Surface((int(WINDOW_SIZE[0] / zoom), int(WINDOW_SIZE[1] / zoom)))
    except:
        zoom = 0.4

    display.fill((5, 195, 225))

    tile_rect = []
    y = 0
    for layer in game_map:
        x = 0
        for tile in layer:
            if tile == '1':
                display.blit(grass_img, (x * 16 - scroll[0], y * 16 - scroll[1]))
            if tile == '2':
                display.blit(dirt_img, (x * 16 - scroll[0], y * 16 - scroll[1]))
            if tile != '0':
                tile_rect.append(pygame.Rect(x * 16, y * 16, 16, 16))  
            x += 1
        y += 1

    scroll[0] += ((player_rect.x - int(WINDOW_SIZE[0]/ (zoom * 2)) + 2) - scroll[0]) / 12
    scroll[1] += ((player_rect.y - int(WINDOW_SIZE[1]/ (zoom * 2)) + 5) - scroll[1]) / 12
    
    player_mouvement = [0, 0]
    
    if moving_right:
        player_mouvement[0] += mouvement_speed
    if moving_left:
        player_mouvement[0] -= mouvement_speed
    if moving_down:
        player_mouvement[1] += 5    
    player_y_momentum += 0.2
    if player_y_momentum > 5:
        player_y_momentum = 5
        
    player_mouvement[1] += player_y_momentum
    
    player_rect, collision_direction = move(player_rect, player_mouvement, tile_rect)

    if collision_direction['down']:
        air_timer = 0
        player_y_momentum = 0
    else:
        air_timer += 1
        
    if collision_direction['up']:
        player_y_momentum = 0
                     
    display.blit(player_img, (player_rect.x - scroll[0], player_rect.y - scroll[1]))
    #pygame.draw.rect(display,(255, 255, 255),player_rect)

    #print(air_timer)      
    screen.blit(pygame.transform.scale(display,WINDOW_SIZE),(0,0))
    pygame.display.update()
    clock.tick(FPS)
    

pygame.quit()
sys.exit()
python pygame
3个回答
1
投票

您需要做的就是使用

将滚动锁定到玩家
scroll[0] = player_rect.x - int(WINDOW_SIZE[0]/ (zoom * 2)) + 2
scroll[1] = player_rect.y - int(WINDOW_SIZE[1]/ (zoom * 2)) + 5

1
投票

您的

scroll
计算有点令人困惑,我不太确定计算到底在做什么(并且没有注释来解释它)。显然,其目的是滚动它来跟踪玩家,从而调整
game_map
被绘制到
display
上的位置以及玩家被绘制到其上的位置。然后您
scale()
screen
即可获得缩放效果

虽然我无法准确评论卷轴的问题是什么,但我可以建议一种不同的并且我相信更简单的方法来解决这个问题。绘制你的

display
而不做滚动的事情。然后使用
subsurface()
以所需的大小抓取以播放器为中心的
display
的一部分,以实现您想要的缩放效果。然后缩放该地下层并将其
blit()
screen
上。

虽然上面为了简单起见我只是说以您的播放器为中心,但如果播放器在所需的缩放级别太靠近

display
的边缘,您就必须进行调整。

这应该会简化

display
的所有创建,唯一的努力是确定
display
内地下的位置和大小,以获得您想要的位置和缩放系数。


0
投票

如果我也想能够向上行走,这里有人知道如何处理这段代码吗?我知道这段代码适用于 2D 游戏,但除了这个之外,我找不到一个好的代码可以实现我想要的缩放。

© www.soinside.com 2019 - 2024. All rights reserved.