There are several problems here. First, the immediate problem.
In update
, where do you think b
is coming from in this line?
if b.powered==True:
It's not coming from one of these parts:
if any(b.rect.collidepoint(self.rect.left,self.rect.top-5) for b in [b for b in blocks if b is not self]):
^ ^
It's coming from the last iteration of this list comprehension:
[b for b in blocks if b is not self]
The last not-self block in the block list is used for all if b.powered == True
tests. The loop variable of a generator expression isn't available outside the generator expression, and the loop variable of a list comprehension is only available outside the list comprehension due to a design decision made for performance reasons and undone in Python 3.
Instead of trying to use b
outside the any
call, put the test inside:
if any(b.powered and b is not self and b.rect.collidepoint(self.rect.left,self.rect.top-5) for b in blocks):
or since this is a pretty huge line, split this into an explicit loop instead of an any
call. While you're at it, you can merge the 4 any
calls into one pass over the list:
for b in blocks:
if not b.powered:
continue
if b is self:
# You don't actually need this test.
continue
adjacent = False
if b.rect.collidepoint(self.rect.left,self.rect.top-5):
adjacent = True
if b.rect.collidepoint(...):
adjacent = True
# and the other two adjacency checks
...
if adjacent:
self.powered = True
break
Now, the other problems. Your power-up logic only checks adjacent blocks. That means if a block is placed apart from the power source and then connected, it may take many updates for the block to realize it's receiving power. Also, if a block is disconnected from power or the power supply is removed, the block may never turn off, since whenever it looks, all its neighbors are powered. This will require a change to your algorithm. I recommend using a flood fill from the power sources to determine which blocks are powered.