Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python For循环阻塞其他For循环_Python_Loops_Pygame_Collision Detection - Fatal编程技术网

Python For循环阻塞其他For循环

Python For循环阻塞其他For循环,python,loops,pygame,collision-detection,Python,Loops,Pygame,Collision Detection,我正在检查导弹群,看看是否有导弹与敌人群中的敌人发生碰撞。运行时,它为第一个循环打印“命中”,但忽略第二个循环。为什么呢 #### Imagine this is in a game loop #### for missile in missileGroup: if pygame.sprite.spritecollide(missile, enemyGroup, False) : print("Hit")

我正在检查导弹群,看看是否有导弹与敌人群中的敌人发生碰撞。运行时,它为第一个循环打印“命中”,但忽略第二个循环。为什么呢

 #### Imagine this is in a game loop ####
    for missile in missileGroup:
        if pygame.sprite.spritecollide(missile, enemyGroup, False) :
            print("Hit")

    
    for enemy in enemyGroup:
        if pygame.sprite.spritecollide(enemy, missileGroup, False):
            print("HI")

更新:@rabbi76表示,
spritecollide
不起作用,因为spriteGroup
enemyGroup
是一个组中的精灵列表(enemyGroup),根据提供的信息(a),没有明显的原因说明第二次冲突检查失败的原因。如果敌人7号和导弹3号,导弹3号和敌人7号之间也应该发生碰撞

您没有使用任何像提供您自己的(可能是非交换的)碰撞函数这样的边缘情况,因此它只会使用精灵矩形来检测这个

我很想看到当你颠倒代码中两个循环的顺序时的行为


此外,您还应该指定这些组变量的类型。如果
enemyGroup
类似于一个可耗尽的生成器,而不是一个列表,则第一个循环会将其“清空”,然后第二个循环将没有可迭代的项(b)(spritecollide调用将在组中迭代,以对照sprite检查每个项目)

这是除了spritecollide本身的bug之外,唯一能让你看到你描述的效果的方法


作为示例,这里有一段代码尝试在生成器上迭代两次:

gen3类(对象):
定义初始化(self):self.\u num=0
定义iter(自我):返回自我
定义下一个(自我):
如果self.\u num==3:raise StopIteration()
self._num+=1
返回自我。\u num-1
gen=gen3()
打印(“A:”)
对于gen中的i:打印(“,i)
打印(“B:”)
对于gen中的i:打印(“,i)
输出显示第二个循环不执行任何操作:

A:
0
1.
2.
B:

最后,检查组状态的确定方法是在每个循环之前简单地放置以下代码:

print(“循环X敌人”,len(enemyGroup),enemyGroup)
打印(“回路X导弹”,len(导弹组),导弹组)
使用适当的
X
值来区分这两个循环


当然,你所给出的信息总是不完全准确或完整的(没有恶意意图,但有时人们会不经意地跳过他们认为不重要的细节,结果非常重要)。 示例:这两个循环之间可能发生了一些事情,这导致了问题的出现。我更愿意让人们相信这一点,但如果是这样的话,您可能应该让我们知道



(b) 在第一个循环的第一次迭代中,它实际上会被清空,因此您会发现它可能只会与第一枚导弹匹配。

这里有一个简单的例子,表明(在PyGame 1.9.6中)这种报告的行为不会发生

该示例创建两个,然后以与OP示例代码完全相同的方式碰撞它们

除了打印,精灵会从大纲->填充更改,这取决于他们是否认为自己参与了碰撞。有一个1:1的敌人与导弹碰撞的地图,反之亦然

抱歉帧速率太低。。。

导入pygame
随机输入
#窗口大小
窗宽=800
窗户高度=800
深蓝色=(3,5,54)
红色=(200,0,0)
黄色=(240250,0)
黑色=(0,0,0)
灰色=(200200200200)
绿色=(250,0,0)
透明=(0,0,0,0)
类形状(pygame.sprite.sprite):
def uuu init uuuu(自,宽=48,高=48):
pygame.sprite.sprite.\uuuuu init\uuuuuuu(自我)
self.image=pygame.Surface((宽度、高度),pygame.SRCALPHA)
self.rect=self.image.get_rect()
#开始位置在屏幕上是随机的,稍微偏离顶部
self.rect.center=(random.randrange(0,窗口宽度),random.randrange(0,窗口高度))
#运动
self.dx=random.randrange(-2,2)
self.dy=random.randrange(-2,2)
#看起来像
自填=2
self.last_fill=-1
self.render()
def setFilled(自身,值):
如果(值==True):
自填充=0
其他:
自填=2
def更新(自我):
如果(自上次填充!=自填充):
自上次填充=自填充
self.render()
self.rect.move_ip(self.dx,self.dy)
如果(self.rect.left>窗口宽度):
self.rect.x=-self.rect.width
elif(自校正右<0):
self.rect.left=窗口宽度
如果(自校正y>窗口高度):
自校正y=0
elif(自校正y<0):
自校正y=窗高
类方形(形状):
def渲染(自):
#要画的东西
如果(自填==0):
self.image.fill(红色)
其他:
边框=3
x、 y=边框,边框
宽度=self.rect.width-边框-1
高度=self.rect.height-边框-1
self.image.fill(透明)
pygame.draw.rect(self.image,红色,(x,y,宽度,高度),self.filled)
类圆(形状):
def渲染(自):
self.image.fill(透明)
pygame.draw.circle(self.image,黄色,(self.rect.width//2,self.rect.height//2),self.rect.width//2,self.filled)
###初始化
pygame.init()
window=pygame.display.set_模式((窗口宽度、窗口高度))
###一些精灵团体
missileGroup=pygame.sprite.Group()
对于范围(3)中的i:
新_导弹=圆()
新的_飞弹(render)
missileGroup.add(圆())
enemyGroup=pygame.sprite.Group()
对于范围(12)内的i:
新敌人=Square()
for missile in missileGroup:
    if pygame.sprite.spritecollide(missile, enemyGroup, False) :
        missile.reset()

for eachEnemy in enemyGroup: 
        if pygame.sprite.spritecollide(eachEnemy, missileGroup, False):
            eachEnemy.reset()
import pygame
import random

# Window size
WINDOW_WIDTH    = 800
WINDOW_HEIGHT   = 800

DARK_BLUE = (   3,   5,  54 )
RED       = ( 200,   0,   0 )
YELLOW    = ( 240, 250,   0 )
BLACK     = (   0,   0,   0 )
GREY      = ( 200, 200, 200 )
GREEN     = ( 250,   0,   0 )
TRANSPARENT=( 0,0,0,0 )


class Shape(pygame.sprite.Sprite):
    def __init__(self, width=48, height=48):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface( ( width, height ), pygame.SRCALPHA)
        self.rect  = self.image.get_rect()
        # Start position is randomly across the screen, and a little off the top
        self.rect.center = ( random.randrange( 0, WINDOW_WIDTH ), random.randrange( 0, WINDOW_HEIGHT ) )
        # Movement
        self.dx = random.randrange( -2, 2 )
        self.dy = random.randrange( -2, 2 )
        # Looks like
        self.filled = 2
        self.last_fill = -1
        self.render()

    def setFilled( self, value ):
        if ( value == True ):
            self.filled = 0
        else:
            self.filled = 2

    def update( self ):
        if ( self.last_fill != self.filled ):
            self.last_fill = self.filled
            self.render()

        self.rect.move_ip( self.dx, self.dy )

        if ( self.rect.left > WINDOW_WIDTH ):
            self.rect.x = -self.rect.width
        elif ( self.rect.right < 0 ):
            self.rect.left = WINDOW_WIDTH
        if ( self.rect.y > WINDOW_HEIGHT ):
            self.rect.y = 0
        elif ( self.rect.y < 0 ):
            self.rect.y = WINDOW_HEIGHT


class Square( Shape ):
    def render( self ):
        # Something to draw

        if ( self.filled == 0 ):
            self.image.fill( RED )
        else:
            border=3
            x, y = border, border
            width = self.rect.width - border -1
            height = self.rect.height - border -1
            self.image.fill( TRANSPARENT )
            pygame.draw.rect( self.image, RED, (x,y,width,height), self.filled )

class Circle( Shape ):
    def render( self ):
        self.image.fill( TRANSPARENT )
        pygame.draw.circle( self.image, YELLOW, (self.rect.width//2, self.rect.height//2), self.rect.width//2, self.filled )




### initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )

### Some sprite groups
missileGroup = pygame.sprite.Group()
for i in range( 3 ):
    new_missile = Circle()
    new_missile.render()
    missileGroup.add( Circle() )

enemyGroup = pygame.sprite.Group()
for i in range( 12 ):
    new_enemy = Square()
    new_enemy.render()
    enemyGroup.add( Square() )


### Main Loop
clock = pygame.time.Clock()
done = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.MOUSEBUTTONUP ):
            # On mouse-click
            pass
    # Move * collide the sprites
    missileGroup.update()
    enemyGroup.update()

    # Test Collisions
    for missile in missileGroup:
        if pygame.sprite.spritecollide(missile, enemyGroup, False) :
            print("Missile " + str(missile) + " Hits Enemy")
            missile.setFilled( True )
        else:
            missile.setFilled( False )

    for enemy in enemyGroup:
        if pygame.sprite.spritecollide(enemy, missileGroup, False):
            print("Enemy  " + str(enemy) + " Hits Missile")
            enemy.setFilled( True )
        else:
            enemy.setFilled( False )


    # Paint the window, but not more than 60fps
    window.fill( DARK_BLUE )
    enemyGroup.draw( window )
    missileGroup.draw( window )
    pygame.display.flip()


    # Clamp FPS
    clock.tick(60)


pygame.quit()
for missile in missileGroup:
    if pygame.sprite.spritecollide(missile, enemyGroup, False):
        print("Hit")

for enemy in enemyGroup:
    if pygame.sprite.spritecollide(enemy, missileGroup, False):
        print("HI")