首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >创建具有指定最小距离和随机方向的图像对象的随机模式

创建具有指定最小距离和随机方向的图像对象的随机模式
EN

Stack Overflow用户
提问于 2014-09-17 06:35:44
回答 2查看 1.3K关注 0票数 0

这是我第一次使用堆栈溢出,我希望你们中的一些人能帮助我解决这个问题。

我正在设计一个心理物理学实验,它需要随机显示模式,如下所示:

https://www.dropbox.com/s/n09vkvbqxagt8hd/dot%20pairs.png?dl=0

但是,我仍然需要指定几个剩余的参数,但我不知道如何实现:

  1. 每个对象(导入的点对图像)需要随机分布,但要保持与任何其他对象和背景矩形边缘的最小、不重叠的距离。
  2. 每个物体(点对图像)必须有一个随机的方向。

我希望有人能尽快帮助我在1和2下添加这两个参数!

谢谢你!

我找到、修改并用于生成这里给出的插图的代码是(有9幅图像,每个图像由点对组成,命名为"stim"*.png):

代码语言:javascript
复制
import random
import pygame

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

class Player():

def __init__(self, image, x=0, y=0):

    self.image = pygame.image.load(image) #.convert()
    #self.image.set_colorkey(WHITE)
    self.rect = self.image.get_rect()

    self.rect.centerx = x
    self.rect.centery = y

#------------

def draw(self, screen):
    screen.blit(self.image, self.rect)

#------------

def update(self):
    # here change randomly positon
    self.rect.topleft = random.randint(60,220+1), random.randint( 0, 475+1)

class Game():

def __init__(self):

    pygame.init()

    self.screen = pygame.display.set_mode((800,600))

    self.background = pygame.image.load("background.jpg").convert()
    self.multi_players = []

    # create stimuli

    for i in range(1,10):
        player = Player("stim"+str(i)+".png")
        player.update() # set random position on start
        self.multi_players.append(player)

#------------

def run(self):

    clock = pygame.time.Clock()
    RUNNING = True

    while RUNNING:

        # --- events ---

        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                RUNNING = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    RUNNING = False

                # changes position when key is pressed

                for player in self.multi_players:
                    player.update()

        # --- updates ---- 

        # place for updates

        # --- draws ---

        self.screen.fill(BLACK)

        self.screen.blit(self.background, self.background.get_rect())

        for player in self.multi_players:
            player.draw(self.screen)

        pygame.display.flip()

        # --- FPS ---

        clock.tick(20)

    # --- quit ---

    pygame.quit()

Game().run()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-17 13:04:35

由于这是我第一次接触到游戏库,这可能是有一个更好的解决方案,但经过一项小的研究后,我认为最好的方法是使用检测像素完美碰撞在.png masks.That is,吡咯烷酮允许检查按颜色重叠的玩家通过定义面具。我修改了您的代码,现在它似乎运行得很好:

代码语言:javascript
复制
import random
import pygame

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

PLAYERS = []

class Player():

    def __init__(self, image, x=0, y=0):

        self.image = pygame.image.load(image).convert_alpha() #.convert()
        #self.image.set_colorkey(WHITE)
        self.rect = self.image.get_rect()

        self.rect.centerx = x
        self.rect.centery = y


        #self.image.set_colorkey(BLACK)


    #------------

    def draw(self, screen):
        screen.blit(self.image, self.rect)

    #------------

    def update(self):
        #randomly rotate
        angle = random.randint(0,360)
        #self.image = pygame.transform.rotate(self.image, angle)
        self.image = pygame.transform.rotozoom(self.image, angle, 1)

        # here change randomly positon
        self.rect.topleft = random.randint(60,220+1), random.randint( 0, 475+1)
        searchAgain = 0
        while (searchAgain < 1):
            self.rect.topleft = random.randint(60,220+1), random.randint( 0, 475+1)
            searchAgain = 1

            for p in PLAYERS:
                # creating masks for the images
                myImage_mask = pygame.mask.from_surface(self.image)
                myOtherImage_mask = pygame.mask.from_surface(p.image)

                # this is where the images are
                myImage_rect = self.rect
                myOtherImage_rect = p.rect

                # this is where we check for pixel perfect collision
                # observe the order mask variables are used in calculating offset and in overlap method
                offset_x, offset_y = (myOtherImage_rect.left - myImage_rect.left), (myOtherImage_rect.top - myImage_rect.top)
                print (offset_x, offset_y )
                if (myImage_mask.overlap(myOtherImage_mask, (offset_x, offset_y)) != None):
                    print 'Collision Detected!'

                    #if we detect collision of players stay in the loop so that we get another pair of coordinates for the new player
                    searchAgain = 0
                else:
                    print 'None'



class Game():

    def __init__(self):

        pygame.init()

        self.screen = pygame.display.set_mode((800,600))

        self.background = pygame.image.load("background.jpg").convert()
        self.multi_players = []

        # create stimuli

        for i in range(1,10):
            player = Player("stim"+str(i)+".png")
            #player = Player("stim6.gif")
            player.update() # set random position on start
            PLAYERS.append(player)

            self.multi_players.append(player)

    #------------

    def run(self):

        clock = pygame.time.Clock()
        RUNNING = True

        while RUNNING:

            # --- events ---

            for event in pygame.event.get():

                if event.type == pygame.QUIT:
                    RUNNING = False

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        RUNNING = False

                    # changes position when key is pressed

                    for player in self.multi_players:
                        player.update()

            # --- updates ---- 

            # place for updates

            # --- draws ---

            self.screen.fill(WHITE)

            self.screen.blit(self.background, self.background.get_rect())

            for player in self.multi_players:
                player.draw(self.screen)

            pygame.display.flip()

            # --- FPS ---

            clock.tick(20)

        # --- quit ---

        pygame.quit()

Game().run()

大多数更改都是在Player类中的update()函数中完成的,但总的来说,我所做的是:

  1. 我定义了一个全局玩家列表,并将每个新创建的播放器添加到其中。
  2. 在每次更新中,我首先将播放器旋转成一个随机角度。
  3. 然后我给它一个随机的x,y位置
  4. 之后,我检查新创建的播放器是否与播放机中的现有播放器重叠,我通过掩码比较进行检查。
  5. 如果没有碰撞-我添加玩家,如果有碰撞-我要求另一组随机坐标。

至于对,我不太明白你是否需要创建对相反的点,但无论如何,我希望你将有足够的继续我在这里张贴的东西。您可以在这里获得完整的示例:关于我的dropbox链接

希望它能帮上忙,向你问好,加森。

另外,当使用透明的PNG文件以避免在旋转非平方png图像后出现黑色背景的问题时,只需对代码中的self.image.set_colorkey(黑色)行进行注释。我是这样说的,出于个人的理由,在使用PNG时,您似乎不需要通过定义颜色键来注意透明度。

票数 2
EN

Stack Overflow用户

发布于 2014-09-17 07:36:31

我现在不能用pygame测试这段代码,因为它不是安装在这台计算机上,而是为了提供理论上的建议:

1)避免对象重叠。您应该维护已经放置的项的列表,并在生成随机位置时验证它们的边界框是否重叠。

一个例子就是

__init__方法中添加一个self.surfaces = []

然后在绘制对象时,将它们添加到self.surfaces中。每次生成新的随机对象时,请如下所示:

代码语言:javascript
复制
def test_overlapping_with_other_surfaces(self, myRandomlyPlacedImage):
    """ Tests if the randomly placed image overlap with an already existing image. """
    for surface in self.surface:
        if surface.get_rect.colliderect(myRandomlyPlacedImage.get_rect):
            return False
    return True

如果对此函数的调用返回false,则将图像随机移动到另一个位置并再次测试。

2)方向的随机性似乎很简单。事实上,请参阅正式文档http://www.pygame.org/docs/ref/transform.html#pygame.transform.rotate

代码语言:javascript
复制
def randomly_rotate_image(self, image):
    """ Returns the image randomly rotated. """
    angle = randint(0,360)
    return pygame.transform.rotate(image, angle)

利用self.randomly_rotate_image(image).clip()而不是image.clip()

希望能帮上忙。

亚瑟。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25883818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档