我一直在开发一个电路模拟器,类似于Minecraft的红石,但是是二维的。目前为止,我已经实现了电源和导线。电源会给导线供电,并在后面用于给其他组件供电。但是,我遇到的问题是,当导线与电源断开连接时,它仍然保持通电状态,因为它的所有相邻部分都通电。以下是图片表示这个问题:未连接电源的导线、已连接并通电的导线以及移除电源但导线仍处于活动状态。以下是导线的更新循环:
我希望能通过其他电线为电线提供电力,但前提是它们都连接到一个电源。所以我想,如果每个电线段可以递归地检查它连接到的所有电线,以确保它连接到电源,那么我就可以实现这个目标。但我不确定该怎么做。
我尝试在电线对象内部使用其他变量,比如代表电线是否连接到电源的self.sourced,但结果只能给一根电线供电(即使当电源断开时,电线也会停止工作,所以它还算有效)。无论如何,如果有人知道如何做到这一点,请传授你的知识。
以下是完整的源代码,仅供参考:
def update(self):
self.powered=False
for b in blocks:
#Find power sources/powered wires
if not b.powered:
continue
adjacent = False
if b.rect.collidepoint(self.rect.left,self.rect.top-5):
adjacent = True
if b.rect.collidepoint(self.rect.left,self.rect.bottom+5):
adjacent = True
if b.rect.collidepoint(self.rect.left-5,self.rect.top):
adjacent = True
if b.rect.collidepoint(self.rect.right+5,self.rect.top):
adjacent = True
if adjacent:
self.powered = True
break
if not self.powered:
pygame.draw.rect(screen, (0,0,0), self.rect, 0)
else:
pygame.draw.rect(screen, (200,0,0), self.rect, 0)
我希望能通过其他电线为电线提供电力,但前提是它们都连接到一个电源。所以我想,如果每个电线段可以递归地检查它连接到的所有电线,以确保它连接到电源,那么我就可以实现这个目标。但我不确定该怎么做。
我尝试在电线对象内部使用其他变量,比如代表电线是否连接到电源的self.sourced,但结果只能给一根电线供电(即使当电源断开时,电线也会停止工作,所以它还算有效)。无论如何,如果有人知道如何做到这一点,请传授你的知识。
以下是完整的源代码,仅供参考:
import pygame
from pygame.locals import *
pygame.init()
screen=pygame.display.set_mode((640,480))
blocks=[]
class PowerSource(object):
def __init__(self,pos):
self.posx=pos[0]
self.posy=pos[1]
self.rect=pygame.Rect(self.posx,self.posy,32,32)
self.powered=True
def update(self):
pygame.draw.rect(screen, (255,0,0), self.rect, 0)
def repos(self):
pass
class Circuit(object):
def __init__(self,pos):
self.powered=False
self.posx=pos[0]
self.posy=pos[1]
self.rect=pygame.Rect(self.posx,self.posy,32,32)
def update(self):
self.powered=False
for b in blocks:
if not b.powered:
continue
adjacent = False
if b.rect.collidepoint(self.rect.left,self.rect.top-5):
adjacent = True
if b.rect.collidepoint(self.rect.left,self.rect.bottom+5):
adjacent = True
if b.rect.collidepoint(self.rect.left-5,self.rect.top):
adjacent = True
if b.rect.collidepoint(self.rect.right+5,self.rect.top):
adjacent = True
if adjacent:
self.powered = True
break
if not self.powered:
pygame.draw.rect(screen, (0,0,0), self.rect, 0)
else:
pygame.draw.rect(screen, (200,0,0), self.rect, 0)
while True:
place=1
screen.fill((255,255,255))
mse=pygame.mouse.get_pos()
mse=((mse[0]/32)*32,(mse[1]/32)*32)
pressed=pygame.mouse.get_pressed()
if pressed==(1,0,0):
pressed='L'
elif pressed==(0,0,1):
pressed='R'
for b in blocks:
b.update()
pygame.draw.rect(screen, (255,0,0), (mse[0],mse[1],32,32), 2)
for e in pygame.event.get():
if e.type==QUIT:
exit()
key=pygame.key.get_pressed()
if key[K_SPACE]:
for b in blocks:
if b.rect.collidepoint(mse):
place=0
if place==1:
blocks.append(PowerSource(mse))
if pressed=='L':
for b in blocks:
if b.rect.collidepoint(mse):
place=0
if place==1:
blocks.append(Circuit(mse))
elif pressed=='R':
for b in blocks:
if b.rect.collidepoint(mse):
blocks.remove(b)
pygame.display.flip()