2015-01-05 3 views
0

Так что я делаю довольно простую игру на питоне, в основном используя tkinter. Игра такова: вы - лист бумаги, и пеницы стреляют из четырех основных направлений (вверх по левому и правому краям). Вам нужно избегать карандашей, и когда вы попадаете, вы «умираете», и игра заканчивается. Поэтому в mainloop() у меня есть бумага, привязанная к клавишам со стрелками. Мне нужно уметь снимать карандаши с четырех сторон на заднем плане. В то время как mainloop происходит, функция pencilAttack() должна работать непрерывно. Я работаю с Python 2.7.5 и открыт для использования (и, вероятно, придется использовать) многопоточности/обработки. Вот весь мой код, и он почти работает, но не совсем. ЕСЛИ у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь спрашивать. Спасибо за помощь!Как я могу запустить процесс в фоновом режиме в python?

import Tkinter 
import tkMessageBox 
from Tkinter import * 
import random 
import time 

def key(event): #"IB" stands for in bounds, "OOB" stands for out of bounds 
    right="IB"; left="IB"; top="IB"; bottom="IB" 
    cntr1=0; cntr2=0; cntr3=0; cntr4=0 
    while cntr1<len(C.find_overlapping(760,41,760,559)): 
     if C.find_overlapping(760,41,760,559)[cntr1]==17: 
      right="OOB" 
      break 
     cntr1+=1 
    while cntr2<len(C.find_overlapping(40,41,40,559)): 
     if C.find_overlapping(40,41,40,559)[cntr2]==17: 
      left="OOB"  
      break 
     cntr2+=1 
    while cntr3<len(C.find_overlapping(41,40,759,40)): 
     if C.find_overlapping(41,40,759,40)[cntr3]==17: 
      top="OOB" 
      break 
     cntr3+=1 
    while cntr4<len(C.find_overlapping(41,560,759,560)): 
     if C.find_overlapping(41,560,759,560)[cntr4]==17: 
      bottom="OOB" 
      break 
     cntr4+=1 
    if (event.keysym == 'Right') and (right!="OOB"): 
     C.move(paper, 20, 0) 
    if (event.keysym == 'Left') and (left!="OOB"): 
     C.move(paper, -20, 0) 
    if (event.keysym == 'Up') and (top!="OOB"): 
     C.move(paper, 0, -20) 
    if (event.keysym == 'Down') and (bottom!="OOB"): 
     C.move(paper, 0, 20) 

def ifDead(): 
    cntr5=0 
    bbox=C.bbox(17) 
    while cntr5<len(C.find_overlapping(*bbox)): 
     if C.find_overlapping(*bbox)[cntr5]>=18 and C.find_overlapping(*bbox)[cntr5]<=65: 
      return True 
     cntr5+=1 

def pencilAttack(): 
    currentPencil=random.choice(allPencils) 
    print currentPencil 
    print type(currentPencil) 
    cntr=0 
    dead=False 
    if currentPencil>=18 and currentPencil<=27: 
     C.move(currentPencil, 70, 0) 
     time.sleep(.5) 
     while cntr<200: 
      print cntr 
      C.move(currentPencil, 5, 0) 
      if ifDead()==True: 
       dead=True 
       break 
      cntr+=1 
     C.move(currentPencil, -1070, 0)   
    if currentPencil>=28 and currentPencil<=41: 
     C.move(currentPencil, -70, 0) 
     time.sleep(.5) 
     while cntr<200: 
      print cntr 
      C.move(currentPencil, -5, 0) 
      if ifDead()==True: 
       dead=True 
       break 
      cntr+=1 
     C.move(currentPencil, 1070, 0) 
    if currentPencil>=42 and currentPencil<=51: 
     C.move(currentPencil, 0, 70) 
     time.sleep(.5) 
     while cntr<200: 
      print cntr 
      C.move(currentPencil, 0, 5) 
      if ifDead()==True: 
       dead=True 
       break 
      cntr+=1 
     C.move(currentPencil, 0, -1070) 
    if currentPencil>=52 and currentPencil<=65: 
     C.move(currentPencil, 0, -70) 
     time.sleep(.5) 
     while cntr<200: 
      print cntr 
      C.move(currentPencil, 0, -5) 
      if ifDead()==True: 
       dead=True 
       break 
      cntr+=1 
     C.move(currentPencil, 0, 1070) 

    if dead: 
     top.destroy() 

top = Tkinter.Tk() 

C = Tkinter.Canvas(top, bg="light goldenrod", height=600, width=800) 
#this below creates the background 
C.create_line(760,41,760,559, fill="green")#light goldenrod 
C.create_line(40,41,40,559, fill="blue") 
C.create_line(41,40,759,40, fill="black") 
C.create_line(41,560,759,560, fill="red") 
C.create_line(0,100,1000,100, fill="deep sky blue") 
C.create_line(0,150,1000,150, fill="deep sky blue") 
C.create_line(0,200,1000,200, fill="deep sky blue") 
C.create_line(0,250,1000,250, fill="deep sky blue") 
C.create_line(0,300,1000,300, fill="deep sky blue") 
C.create_line(0,350,1000,350, fill="deep sky blue") 
C.create_line(0,400,1000,400, fill="deep sky blue") 
C.create_line(0,450,1000,450, fill="deep sky blue") 
C.create_line(0,500,1000,500, fill="deep sky blue") 
C.create_line(0,550,1000,550, fill="deep sky blue") 
C.create_line(0,600,1000,600, fill="deep sky blue") 
C.create_line(75,0,75,1000, fill="red") 

#this below creates the photos 
rPencil = PhotoImage(file="H:\Computer Programming\Pencil right.gif") 
lPencil = PhotoImage(file="H:\Computer Programming\Pencil left.gif") 
tPencil = PhotoImage(file="H:\Computer Programming\Pencil top.gif") 
bPencil = PhotoImage(file="H:\Computer Programming\Pencil bottom.gif") 
paperpic = PhotoImage(file="H:\Computer Programming\paper2.gif") 
paper = C.create_image(400,400, image = paperpic) 


allPencils=[] 
#ignore the one right under this 
#lPencils-> -30x rPencils-> 830x tPencil-> -30y bPencil-> 630y 
#all these below create the pencils out of bounds to later be moved into place 
pencil1=C.create_image(-100, 66, image = lPencil, tags="Lpencil");allPencils.append(pencil1) 
pencil2=C.create_image(-100, 118, image = lPencil, tags="Lpencil");allPencils.append(pencil2) 
pencil3=C.create_image(-100, 170, image = lPencil, tags="Lpencil");allPencils.append(pencil3) 
pencil4=C.create_image(-100, 222, image = lPencil, tags="Lpencil");allPencils.append(pencil4) 
pencil5=C.create_image(-100, 274, image = lPencil, tags="Lpencil");allPencils.append(pencil5) 
pencil6=C.create_image(-100, 326, image = lPencil, tags="Lpencil");allPencils.append(pencil6) 
pencil7=C.create_image(-100, 378, image = lPencil, tags="Lpencil");allPencils.append(pencil7) 
pencil8=C.create_image(-100, 430, image = lPencil, tags="Lpencil");allPencils.append(pencil8) 
pencil9=C.create_image(-100, 482, image = lPencil, tags="Lpencil");allPencils.append(pencil9) 
pencil10=C.create_image(-100, 534, image = lPencil, tags="Lpencil");allPencils.append(pencil10) 
pencil11=C.create_image(900, 534, image = rPencil, tags="Rpencil");allPencils.append(pencil11) 
pencil12=C.create_image(900, 482, image = rPencil, tags="Rpencil");allPencils.append(pencil12) 
pencil13=C.create_image(900, 430, image = rPencil, tags="Rpencil");allPencils.append(pencil13) 
pencil14=C.create_image(900, 378, image = rPencil, tags="Rpencil");allPencils.append(pencil14) 
pencil15=C.create_image(900, 326, image = rPencil, tags="Rpencil");allPencils.append(pencil15) 
pencil16=C.create_image(900, 274, image = rPencil, tags="Rpencil");allPencils.append(pencil16) 
pencil17=C.create_image(900, 222, image = rPencil, tags="Rpencil");allPencils.append(pencil17) 
pencil18=C.create_image(900, 170, image = rPencil, tags="Rpencil");allPencils.append(pencil18) 
pencil19=C.create_image(900, 118, image = rPencil, tags="Rpencil");allPencils.append(pencil19) 
pencil20=C.create_image(900, 66, image = rPencil, tags="Rpencil");allPencils.append(pencil20) 
pencil21=C.create_image(66, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil21) 
pencil22=C.create_image(118, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil22) 
pencil23=C.create_image(170, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil23) 
pencil24=C.create_image(222, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil24) 
pencil25=C.create_image(274, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil25) 
pencil26=C.create_image(326, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil26) 
pencil27=C.create_image(378, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil27) 
pencil28=C.create_image(430, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil28) 
pencil29=C.create_image(482, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil29) 
pencil30=C.create_image(534, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil30) 
pencil31=C.create_image(586, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil31) 
pencil32=C.create_image(638, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil32) 
pencil33=C.create_image(690, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil33) 
pencil34=C.create_image(742, -100, image = tPencil, tags="Tpencil");allPencils.append(pencil34) 
pencil35=C.create_image(66, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil35) 
pencil36=C.create_image(118, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil36) 
pencil37=C.create_image(170, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil37) 
pencil38=C.create_image(222, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil38) 
pencil39=C.create_image(274, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil39) 
pencil40=C.create_image(326, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil40) 
pencil41=C.create_image(378, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil41) 
pencil42=C.create_image(430, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil42) 
pencil43=C.create_image(482, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil43) 
pencil44=C.create_image(534, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil44) 
pencil45=C.create_image(586, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil45) 
pencil46=C.create_image(638, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil46) 
pencil47=C.create_image(690, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil47) 
pencil48=C.create_image(742, 700, image = bPencil, tags="Bpencil");allPencils.append(pencil48) 

C.pack() 


top.bind_all('<Key>', key) 
top.after(1000,pencilAttack) 
top.mainloop() 

ответ

3

Вы не должны использовать нитки для этого. Почти во всех инфраструктурах GUI существует один поток «цикла событий», который отправляет события ввода пользователя и обновляет пользовательский интерфейс. Если вы попытаетесь обновить пользовательский интерфейс из другого потока, ничего хорошего не произойдет. Если вам повезет, структура поймает вас и поднимет ошибку, говоря вам, что вы этого не сделаете, иначе вам просто сложно отлаживать условия гонки.

Вместо sleep в вашей pencilAttack функции, которая будет блокировать пользовательский интерфейс нитку, я хотел бы предложить выполнять действия немедленно, а затем планировать функцию pencilAttack снова top.after(500, pencilAttack).

Как в стороне, единственная причина использовать потоки в программе gui состоит в том, чтобы выполнять тяжелую блокировку в фоновом режиме, например. загрузку ресурсов из сети или выполнение каких-либо CPU-вычислений. В этом случае ваша инфраструктура GUI будет предоставлять методы для отправки вызова функции из фонового потока в поток приложения.

+1

@Isaac: Я думаю, важно отметить, что 'pencilAttack()' может перенести себя, чтобы снова запустить с вызовом 'top.after()' в конце функции (если это не 'dead'). Также возможно обновить дисплей сразу после изменений, используя универсальный метод виджетов 'widget.update_idletasks()'. Использование этого может быть полезно в функции 'pencilAttack()', которая, как представляется, может сделать много таких изменений. – martineau

+0

Спасибо, ребята, так много! Я использовал то, что предлагали оба, и отлично работает! Мне просто нужно настроить некоторые вещи, но тогда это должно быть полным! Вы, ребята, рок! –

Смежные вопросы