拖动多个具有不同“update()"的精灵来自 Pygame 中同一个 Sprite 类的方法 [英] Drag multiple sprites with different "update ()" methods from the same Sprite class in Pygame

查看:50
本文介绍了拖动多个具有不同“update()"的精灵来自 Pygame 中同一个 Sprite 类的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作来自同一个 pygame 精灵类的多个精灵.

class AnimatedSprites(pygame.sprite.Sprite):def __init__(self, spriteName):pygame.sprite.Sprite.__init__(self)self.image = pygame.Surface((width,height))self.images = []self.images.append(spriteName[0])self.rect = self.image.get_rect() #设置精灵大小和位置self.rect.center = (POSITIONx1[4], POSITIONy1[4])self.animation_frames = 12self.current_frame = 0self.previous_positiony = self.rect.yself.previous_positionx = self.rect.x定义更新(自我):全球鼠标按下如果(鼠标按下 == 1):self.rect = self.image.get_rect()self.rect.y = POSITIONy1[get_square_under_mousey()] - 25self.rect.x = POSITIONx1[get_square_under_mousex()] - 25如果(鼠标按下 == 2):如果碰撞(植物,购买2):self.rect.y = self.previous_positionyself.rect.x = self.previous_positionx别的:self.rect = self.image.get_rect()self.rect.y = POSITIONy1[get_square_under_mousey()] + 35#从 func 中拉出 x 和 y 位置self.rect.x = POSITIONx1[get_square_under_mousex()] - 25self.previous_positiony = self.rect.yself.previous_positionx = self.rect.x鼠标按下 = 0

我使用这个类在屏幕上创建一个精灵,然后使用 def update() 来控制精灵.控制精灵的方式是,当用户点击精灵时,他们可以用鼠标拖动它,并将其移动到屏幕上他们想要的任何位置.问题是,如果我使用这个类来创建第二个精灵并同时在屏幕上有两个精灵,当用户拿起"一个精灵,他们都移动到鼠标位置.我只想根据被点击的动作做出一个动作.

我假设他们都移动到同一个位置,因为他们都使用相同的 def update() 来决定他们的移动,所以我的问题是,无论如何在 pygame 或 python 中是否有让被点击的那个移动而不是两者,不创造第二个class animationSprites(pygame.sprite.Sprite): 来制作它.我想同时在屏幕上显示多个精灵,但不想制作数十个单独的类和 update() defs 来分别控制每个.

对不起,如果这没有意义,我是 python 和 pygame 的初学者.

解决方案

我建议创建一个 DragOperator 类,它可以拖动

导入pygame类 DragOperator:def __init__(self, sprite):self.sprite = 精灵self.dragging = 假self.rel_pos = (0, 0)定义更新(自我,事件列表):对于 event_list 中的事件:如果 event.type == pygame.MOUSEBUTTONDOWN:self.dragging = self.sprite.rect.collidepoint(event.pos)self.rel_pos = event.pos[0] - self.sprite.rect.x, event.pos[1] - self.sprite.rect.y如果 event.type == pygame.MOUSEBUTTONUP:self.dragging = 假如果 event.type == pygame.MOUSEMOTION 和 self.dragging:self.sprite.rect.topleft = event.pos[0] - self.rel_pos[0], event.pos[1] - self.rel_pos[1]类精灵对象(pygame.sprite.Sprite):def __init__(self, x, y, 颜色):super().__init__()self.original_image = pygame.Surface((50, 50), pygame.SRCALPHA)pygame.draw.circle(self.original_image, color, (25, 25), 25)self.drag_image = pygame.Surface((50, 50), pygame.SRCALPHA)pygame.draw.circle(self.drag_image, color, (25, 25), 25)pygame.draw.circle(self.drag_image, (255, 255, 255), (25, 25), 25, 4)self.image = self.original_imageself.rect = self.image.get_rect(center = (x, y))self.drag = DragOperator(self)定义更新(自我,事件列表):self.drag.update(event_list)self.image = self.drag_image if self.drag.dragging else self.original_imagepygame.init()窗口 = pygame.display.set_mode((300, 300))时钟 = pygame.time.Clock()sprite_object = SpriteObject(*window.get_rect().center, (255, 255, 0))group = pygame.sprite.Group([SpriteObject(window.get_width()//3, window.get_height()//3, (255, 0, 0)),SpriteObject(window.get_width() * 2//3, window.get_height()//3, (0, 255, 0)),SpriteObject(window.get_width()//3, window.get_height() * 2//3, (0, 0, 255)),SpriteObject(window.get_width() * 2//3, window.get_height() * 2//3, (255, 255, 0)),])运行 = 真运行时:时钟滴答(60)event_list = pygame.event.get()对于 event_list 中的事件:如果 event.type == pygame.QUIT:运行 = 错误group.update(event_list)window.fill(0)group.draw(窗口)pygame.display.flip()pygame.quit()出口()

I'm trying to make multiple sprites that all come from the same pygame sprite class.

class animatedSprites(pygame.sprite.Sprite):
    def __init__(self, spriteName):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((width,height))
        self.images = []
        self.images.append(spriteName[0])
        self.rect = self.image.get_rect() #sets sprites size and pos
        self.rect.center = (POSITIONx1[4], POSITIONy1[4])
        self.animation_frames = 12
        self.current_frame = 0
        self.previous_positiony = self.rect.y
        self.previous_positionx = self.rect.x

    def update(self):
        global MOUSEPRESSED
        if (MOUSEPRESSED == 1):
            self.rect = self.image.get_rect()
            self.rect.y = POSITIONy1[get_square_under_mousey()] - 25
            self.rect.x = POSITIONx1[get_square_under_mousex()] - 25
        if (MOUSEPRESSED == 2):
            if collide(plant, bought2):
                self.rect.y = self.previous_positiony
                self.rect.x = self.previous_positionx
            else:
                self.rect = self.image.get_rect()
                self.rect.y = POSITIONy1[get_square_under_mousey()] + 35#pulled x and y pos from func
                self.rect.x = POSITIONx1[get_square_under_mousex()] - 25
                self.previous_positiony = self.rect.y
                self.previous_positionx = self.rect.x
            MOUSEPRESSED = 0

I use this class to create a sprite on the screen, then use the def update() to control the sprite. The way the sprite is controlled is that when the user clicks on the sprite they can drag it around with their mouse and move it where ever they'd like on the screen. The problem is, if I use this class to create a second sprite and have two simultaneously on the screen, when the user "picks up" one sprite, they both move to the mouse position. I would like to make only one move depending on which is being clicked.

I'm assuming they're both moving to the same position because they both use the same def update() to decide their movement, so my question is, is there anyway in pygame or python to make the one being clicked on to move and not both, without creating a second class animatedSprites(pygame.sprite.Sprite): to make it. I would like to have multiple sprites on the screen at once but don't want to make dozens of individual classes and update() defs to control each one separately.

Sorry if this doesn't make sense, I'm a beginner to both python and pygame.

解决方案

I recommend to create a class DragOperator which can drag an pygame.Rect object:

class DragOperator:
    def __init__(self, sprite):
        self.sprite = sprite
        self.dragging = False
        self.rel_pos = (0, 0)
    def update(self, event_list):
        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                self.dragging = self.sprite.rect.collidepoint(event.pos)
                self.rel_pos = event.pos[0] - self.sprite.rect.x, event.pos[1] - self.sprite.rect.y
            if event.type == pygame.MOUSEBUTTONUP:
                self.dragging = False
            if event.type == pygame.MOUSEMOTION and self.dragging:
                self.sprite.rect.topleft = event.pos[0] - self.rel_pos[0], event.pos[1] - self.rel_pos[1]

The dragging of the rectangle is implemented in the update method. Use this class in a pygame.sprite.Sprite object. Pass the list of events to the update method of the Sprite and delegate it to the drag operator:

class animatedSprites(pygame.sprite.Sprite):
    def __init__(self, spriteName):
        # [...]

        self.drag = DragOperator(self)

    def update(self, event_list):
        self.drag.update(event_list) 

Pass the list of event form the main application loop to the pygame.sprite.Group:

all_sprites = pygame.sprite.Group()
all_sprites.add(animatedSprites("my_sprite"))

run = True
while run:
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False

    all_sprites.update(event_list)

    # [...]


Minmal example:

import pygame

class DragOperator:
    def __init__(self, sprite):
        self.sprite = sprite
        self.dragging = False
        self.rel_pos = (0, 0)
    def update(self, event_list):
        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                self.dragging = self.sprite.rect.collidepoint(event.pos)
                self.rel_pos = event.pos[0] - self.sprite.rect.x, event.pos[1] - self.sprite.rect.y
            if event.type == pygame.MOUSEBUTTONUP:
                self.dragging = False
            if event.type == pygame.MOUSEMOTION and self.dragging:
                self.sprite.rect.topleft = event.pos[0] - self.rel_pos[0], event.pos[1] - self.rel_pos[1]

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, color):
        super().__init__() 
        self.original_image = pygame.Surface((50, 50), pygame.SRCALPHA)
        pygame.draw.circle(self.original_image, color, (25, 25), 25)
        self.drag_image = pygame.Surface((50, 50), pygame.SRCALPHA)
        pygame.draw.circle(self.drag_image, color, (25, 25), 25)
        pygame.draw.circle(self.drag_image, (255, 255, 255), (25, 25), 25, 4)
        self.image = self.original_image 
        self.rect = self.image.get_rect(center = (x, y))
        self.drag = DragOperator(self)
    def update(self, event_list):
        self.drag.update(event_list) 
        self.image = self.drag_image if self.drag.dragging else self.original_image

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

sprite_object = SpriteObject(*window.get_rect().center, (255, 255, 0))
group = pygame.sprite.Group([
    SpriteObject(window.get_width() // 3, window.get_height() // 3, (255, 0, 0)),
    SpriteObject(window.get_width() * 2 // 3, window.get_height() // 3, (0, 255, 0)),
    SpriteObject(window.get_width() // 3, window.get_height() * 2 // 3, (0, 0, 255)),
    SpriteObject(window.get_width() * 2// 3, window.get_height() * 2 // 3, (255, 255, 0)),
])

run = True
while run:
    clock.tick(60)
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False

    group.update(event_list)

    window.fill(0)
    group.draw(window)
    pygame.display.flip()

pygame.quit()
exit()

这篇关于拖动多个具有不同“update()"的精灵来自 Pygame 中同一个 Sprite 类的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆