所以作为我在 Code Academy 之外的第一个 Python 项目,我决定在 pygame 上制作一个基本的分子动力学模拟器。它可以正常工作一段时间,但是一旦电子开始移动得太快,并且将所有其他电子从它们的原子中剥离出来,我就会在标题中看到 TypeError。我不知道这是从哪里来的,只有在程序运行了足够长的时间让我搞砸了所有物理之后才会出现。
现在我知道错误告诉我我正在尝试将列表传递到我不应该传递的地方,但是我查看了程序并且无法弄清楚在哪里。错误出现在告诉电子如何绕其原子运行的位中,该位angle = findA(particles[el], particles[nuc]) + 0.001
由靠近末尾的代码块控制,该代码块告诉程序以何种顺序进行物理,每个电子的轨道列表是由另一个点控制,以此类推。
所以我决定只给你所有的代码。
import sys, pygame, math
from pygame.locals import *
pygame.init()
sizeScreen = width, height = 1000, 700
sizeMenu = width, height = 652, 700
e = 1.6 * 10 ** -19
particles = {}
mx, my = 0, 0
selected = []
def findOrbital(el):
for a in particles:
if a != el and particles[a][4] != 'el':
if findD(particles[el], particles[a]) < 5 * 10 ** -11 and PTI[particles[a][4]][7] > len(particles[a][5]):
particles[a][5].append(el)
particles[el][5].append(a)
def searcher(List, item):
for a in List:
if a == item:
return True
return False
def moveAtEls(el, nuc):
angle = findA(particles[el], particles[nuc]) + 0.001
particles[el][0] = particles[nuc][0] + 50 * math.cos(angle)
particles[el][1] = particles[nuc][1] + 50 * math.sin(angle)
def check(each):
if particles[each][0] < 175:
particles[each][2] = -particles[each][2]
particles[each][0] = 175
elif particles[each][0] > 1000:
particles[each][2] = -particles[each][2]
particles[each][0] = 1000
if particles[each][1] < 0:
particles[each][3] = -particles[each][3]
particles[each][1] = 0
elif particles[each][1] > 700:
particles[each][3] = -particles[each][3]
particles[each][1] = 700
if particles[each][4] == 'el':
a = 'n'
findOrbital(each)
if a != 'n':
particles[each][5].append(a)
particles[a][5].append(each)
def findD(self, other):
return math.hypot((self[0] - other[0]), (self[1] - other[1])) * 0.62 * 10 ** -12
def findA(self, other):
return math.atan2((self[1] - other[1]), (self[0] - other[0]))
def move(self):
for other in particles:
if particles[other] != self and self[5] != particles[other] [5] and not searcher(self[5], other):
D = findD(self, particles[other])
if D == 0:
self[5].append(other)
particles[other][5].append(self)
break
angle = findA(self, particles[other])
F = 8987550000 * (PTI[self[4]][4] * PTI[particles[other][4]][4] * e ** 2)/D ** 2
a = int(F/PTI[self[4]][5])
ax = a * math.cos(angle)
ay = a * math.sin(angle)
self[2] += ax/(10 ** 16)
self[3] += ay/(10 ** 16)
self[0] += self[2]/(10 ** 8)
self[1] += self[3]/(10 ** 8)
pressed = ''
press = {'Katom':[2,148,2,32,0],'Knuc':[2,148,36,66,0],'Kel':[2,148,70,100,0]}
PTI = {'el':[0, 0, 0, 0, -1, 9.11 * 10 ** -31, pygame.image.load("electron.png"), 2],
'HNuc' : [185, 214, 8, 37, 1, 1.7 * 10 ** -27, pygame.image.load("nuc/HNuc.png"), 2, 1],
'HeNuc': [586, 613, 8, 37, 2, 6.6 * 10 ** -27, pygame.image.load("nuc/HeNuc.png"), 2, 2],
'LiNuc': [185, 214, 40, 69, 1, 1.16 * 10 ** -26, pygame.image.load("nuc/LiNuc.png"), 8, 1],
'BeNuc': [216, 246, 40, 69, 2, 1.53 * 10 ** -26, pygame.image.load("nuc/BeNuc.png"), 8, 2],
'BNuc' : [428, 457, 40, 69, 3, 1.84 * 10 ** -26, pygame.image.load("nuc/BNuc.png"), 8, 3],
'CNuc' : [460, 489, 40, 69, 4, 2.04 * 10 ** -26, pygame.image.load("nuc/CNuc.png"), 8, 4],
'NNuc' : [492, 520, 40, 69, 5, 2.38 * 10 ** -26, pygame.image.load("nuc/NNuc.png"), 8, 5],
'ONuc' : [523, 551, 40, 69, 6, 2.72 * 10 ** -26, pygame.image.load("nuc/ONuc.png"), 8, 6],
'FNuc' : [554, 583, 40, 69, 7, 3.23 * 10 ** -26, pygame.image.load("nuc/FNuc.png"), 8, 7],
'NeNuc': [586, 613, 40, 69, 8, 3.43 * 10 ** -26, pygame.image.load("nuc/NeNuc.png"), 8, 8]}
menu = pygame.display.set_mode(sizeMenu)
screenColor = pygame.Color(255, 255, 220)
screen = pygame.display.set_mode(sizeScreen)
edgeObj = pygame.image.load("edge.png")
addEl = [pygame.image.load('addElectron1.png'), pygame.image.load('addElectron2.png')]
addAtom = [pygame.image.load("addAtom1.png"), pygame.image.load("addAtom2.png"), pygame.image.load("atomTable.png")]
addNucleus = [pygame.image.load("addNuc1.png"), pygame.image.load("addNuc2.png"), pygame.image.load("NucTable.png")]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
elif event.type == MOUSEMOTION:
mx, my = event.pos
mouseState = pygame.mouse.get_pressed()
if mouseState[0]:
for key in press:
if press[key][0] < mx <press[key][1] and press[key][2] < my < press[key][3]:
pressed = key
press[key][4] = 1
if not mouseState[0] and pressed == 'Kel':
particles[len(particles)] = [mx, my, 0, 0, 'el', []]
pressed = ''
press['Kel'][4] = 0
if pressed != '':
if not mouseState[0]:
if press[pressed][0] < mx <press[pressed][1] and press[pressed][2] < my < press[pressed][3]:
press[pressed][4] = 2
pressed = ''
if press['Knuc'][4] == 2 or press['Katom'][4] == 2:
if mouseState[0]:
if 621 < mx < 651 and 2 < my < 14:
press['Knuc'][4] = 0
press['Katom'][4] = 0
if press['Knuc'][4] == 2:
for nuc in PTI:
if PTI[nuc][0] < mx < PTI[nuc][1] and PTI[nuc][2] < my < PTI[nuc][3]:
press['Knuc'][4] = 0
selected.append(nuc)
if press['Katom'][4] == 2:
for nuc in PTI:
if PTI[nuc][0] < mx < PTI[nuc][1] and PTI[nuc][2] < my < PTI[nuc][3]:
a = 0
selected.append(nuc)
while a < PTI[nuc][8]:
selected.append('el')
a += 1
press['Katom'][4] = 0
if selected != []:
if not mouseState[0]:
a = len(particles)
particles[a] = [mx, my, 0, 0, selected[0], [b for b in range(a+1, len(selected)-1)]]
for item in selected:
if item != selected[0]:
particles[len(particles)] = [mx, my, 0, 0, item, [a]]
selected = []
for each in particles:
check(each)
move(particles[each])
check(each)
if len(particles[each][5]) > 0 and particles[each][4] == 'el':
moveAtEls(each, particles[each][5][0])
particles[each][5] = []
screen.fill(screenColor)
for a in particles:
screen.blit(PTI[particles[a][4]][6], (particles[a][0] - 29, particles[a][1] - 31))
menu.blit(edgeObj, (0, 0))
menu.blit(addNucleus[press['Knuc'][4]], (2, 2))
menu.blit(addAtom[press['Katom'][4]], (2, 2))
menu.blit(addEl[press['Kel'][4]], (2, 2))
pygame.display.flip()
抱歉,如果我发布所有代码会造成麻烦,但我是一个完整的 n00b,我很惊讶我在没有帮助的情况下走到了这一步。我知道整个事情很不整洁,但如果你能帮助解决这个错误,我将不胜感激。
下次我会坚持print("Hello, World!")