如何在保持比例的同时使我的播放器图像在碰撞时变大?

How do I make my player image bigger on collision while keeping its proportions?

我正在 pygame 制作一款游戏,您现在可以在其中游来游去并吃掉小方块,并为水母制作动画。我已经这样做了,所以你在吃东西的时候会变大,但是当在比例尺上添加一个 1-9 之间的数字时,图像会变得比我想要的更宽。当我吃东西的时候体重增加了 10 或更多时,这个问题就没有那么严重了。

这是 jellyfish/player 的代码:

import pygame, math, time

pt = time.time()
speed = 40
pygame.display.set_mode((800, 500))
img0 = pygame.transform.scale(pygame.image.load("assets/glow0.png"), (30,30)).convert_alpha()
img1 = pygame.transform.scale(pygame.image.load("assets/glow1.png"), (30,30)).convert_alpha()
img2 = pygame.transform.scale(pygame.image.load("assets/glow2.png"), (30,30)).convert_alpha()
img3 = pygame.transform.scale(pygame.image.load("assets/glow3.png"), (30,30)).convert_alpha()
img4 = pygame.transform.scale(pygame.image.load("assets/glow4.png"), (30,30)).convert_alpha()
img5 = pygame.transform.scale(pygame.image.load("assets/glow5.png"), (30,30)).convert_alpha()
img6 = pygame.transform.scale(pygame.image.load("assets/glow6.png"), (30,30)).convert_alpha()
img7 = pygame.transform.scale(pygame.image.load("assets/glow7.png"), (30,30)).convert_alpha()
img8 = pygame.transform.scale(pygame.image.load("assets/glow8.png"), (30,30)).convert_alpha()

class Glow():
    rot = 0
    rotp = 1
    xsp = 0
    ysp = 0
    
    def __init__(self, x, y, scale):
        self.x, self.y = x, y
        self.scale = scale
        self.list = [img0, img1, img2, img3, img4, img5, img6, img7, img8]
        self.current = 0
        self.image = self.list[int(self.current)]
        self.rect = self.image.get_rect(center = (x, y))
        self.colRect = pygame.rect.Rect((0, 0), (self.rect.width/3, self.rect.height/3))
        self.colRect.center = self.rect.center

    def update(self, x, y, accex):
        global pt, speed
        now = time.time()
        dt = now - pt
        pt = now
        
        self.rect = self.image.get_rect(center = (x, y))
        if pygame.key.get_pressed()[pygame.K_UP] or accex:
            # animation
            self.current += dt*5
            if self.current >= len(self.list):
                self.current = 0
            self.image = pygame.transform.rotate(self.list[int(self.current)], self.rot)
            self.rect = self.image.get_rect(center = (x, y))
            self.colRect.center = self.rect.center

            # go in direction of rotation
            self.rotr = math.radians(self.rot) 
            self.ysp = math.cos(self.rotr)
            self.xsp = math.sin(self.rotr)
            self.x -= self.xsp*dt*speed
            self.y -= self.ysp*dt*speed
            if not accex:
                if pygame.key.get_pressed()[pygame.K_LEFT]:
                    self.rot += math.pi*dt*7

                if pygame.key.get_pressed()[pygame.K_RIGHT]:
                    self.rot -= math.pi*dt*7

        if accex:
            speed += dt*10

    def scaleup(self):
        self.scale += 2
        i = 0
        for img in self.list:
            self.list.remove(img)
            img = pygame.transform.scale(img, (self.scale, self.scale))
            self.list.insert(i, img)
            i += 1

这是游戏循环中与此相关的主要代码:

W, H = 800, 500
sc = pygame.display.set_mode((W, H))
score = 0
score_x, score_y = 10, 10
font = pygame.font.SysFont("calibri", 30)
score_text = font.render("0", True, (255,255,255))
score _rect = score_text.get_rect(topleft = (score_x, score_y))
if lvl0:
        glow.update(glow.x, glow.y, accex)
        sc.fill((0,0,0))
        for food in Food.food_list:
            sc.blit(food.image, (food.x, food.y))
            if pygame.Rect.colliderect(glow.colRect, food.rect):
                Food.food_list.remove(food)
                glow.scaleup()
                score += 3
                score_text = font.render(str(score), True, (255,255,255))
                score_rect = score_text.get_rect(topleft = (score_x, score_y))

        sc.blit(glow.image, glow.rect)
        sc.blit(label, label_rect)
        pygame.display.update()

Pygame 在旋转的情况下重复使用转换后的图像时表现得很奇怪...

我什至因此遇到过崩溃

因此请尝试使用最初加载为 img0、img1 等的相同图像。并将其缩放到所需的大小。截至目前,您一次又一次地使用相同的缩放图像。 这可能有帮助

我知道有一个已经被接受的答案,但我是这样做的:

class Wabbit:
    # this store the main, unaltered image loaded from disk
    _main_image = None
    def __init__(self, pos, scale=1):
        # if the class._main_image variable is not set
        # we do this so we only have to load the image once
        # when the first instance is created
        if not self._main_image:
            # load the image from disk
            self._main_image = pygame.image.load('wabbit_alpha.png')
        
        self.pos = Vector2(pos)
        self.vel = Vector2()
        self.scale = scale
        
        # some variables to store the "previous" values
        self._scale = None
        self._image = None
    
    @property
    def size(self):
        # returns the size of our image, as a Vector2
        return Vector2(self.image.get_size())
    
    @property
    def image(self):
        # this is where we look at our current scale
        # compare it to our previous _scale
        # and update our _image if the two arent the same
        if self.scale != self._scale:
            # update the previous _scale value
            self._scale = self.scale
            # get the size of the original image and scale it
            # according to our scale value
            size = Vector2(self._main_image.get_size()).elementwise() * self.scale
            # set our _image to be the scaled version of the main, original image
            self._image = pygame.transform.scale(self._main_image, size)
        # return our scaled image
        return self._image
    
    def update(self, dt):
        self.pos += self.vel * dt

    def draw(self, surface):
        surface.blit(self.image, self.pos-self.size/2)