2017-09-23 4 views
0

J'ai le code suivant qui réussit à faire rebondir une balle sur les extrémités supérieure et inférieure de l'écran.mouvement de balle avec classes et tkinter

Code de travail pour rebondir sur le dessus et le bas

from tkinter import * 
import random 
import time 

class Ball: 
    def __init__(self,canvas,color): 
     self.canvas=canvas 
     self.id=canvas.create_oval(30,30,50,50,fill=color) 
     self.canvas.move(self.id,100,200) 

     #ADD THESE LINES TO OUR __INIT__ METHOD 
     self.x=0 
     self.y=-1 
     self.canvas_height=self.canvas.winfo_height() 

    def draw(self): 
     self.canvas.move(self.id,self.x,self.y) 
     pos=self.canvas.coords(self.id) 

     if pos[1] <=0: 
      self.y=1 
     if pos[3] >=self.canvas_height: 
      self.y=-1 


def main(): 
    tk=Tk() 
    tk.title("My 21st Century Pong Game") 
    tk.resizable(0,0) 
    tk.wm_attributes("-topmost",1) 
    canvas=Canvas(tk,bg="white",width=500,height=400,bd=0,highlightthickness=0) 
    canvas.pack() 
    tk.update() 

    ball1=Ball(canvas,'green') 
    while 1: 
     tk.update() 
     ball1.draw() #call the ball draw method here 
     time.sleep(0.01) 
main() 

Lorsque vous essayez de le faire arriver à gauche à droite (rebond sur la gauche et le mur à droite), je ne peux pas tout à fait comprendre la logique ou de résoudre mon erreur comme ci-dessous.

Ce que j'ai essayé de rebondir à gauche et à droite

self.x=1 #set the object variable x to 0 (don't move the ball horizontally) 
     self.y=-0 #set the object variable y to -1 (this means keep moving the ball UP on initilisation) 
     self.canvas_height=self.canvas.winfo_height() #set the canvas height by calling the canvas function winfo_height (it gives us the current canvas height) 

    def draw(self): 
     self.canvas.move(self.id,self.x,self.y) 
     pos=self.canvas.coords(self.id) 

     if pos[2] <=0: #if you hit the top of the screen then stop subtracting 1 as defined in the __init__ method and therefore stop moving up -reverse directions 
      self.x=-1 
     if pos[3] >=self.canvas_height: #if the bottom coordinates are greater or equal to canvas height, then reverse again, and set y back to -1 (go up) 
      self.x=1 

Pour une réponse,

Quelqu'un pourrait-il fournir une explication simple à la logique qui est nécessaire pour résoudre le problème, d'où viennent les coordonnées et ce à quoi se réfèrent pos [0], pos [1] etc. J'ai une idée, mais ce n'est pas clair du tout et cela serait bénéfique (comme je l'imagine) d'une certaine clarté. Donc, je suis après une solution d'explication + solution codée (en utilisant mon code original) pour résoudre le problème.

Répondre

0

Le code est presque correct. En fait, c'est presque comme si un moment de réflexion supplémentaire vous aurait probablement donné la réponse. Votre code 'move x' a été copié-collé à partir du code 'move y', mais pas assez changé. Méfiez-vous de faire cela.

En réponse à «quoi pos [0] etc signifie», je vous invite à lire Get coords of an oval in Tkinter. Habituellement, les coordonnées d'un rectangle sont données comme (gauche, haut, droite, bas).

Vous remarquerez que j'ai changé certaines choses ci-dessous, en plus de corriger vos erreurs:

  1. J'ai changé les variables x & y-vx et vy. Les valeurs sont les vitesses de la balle, pas la position.
  2. Le nom de la fonction est maintenant move, et non draw, car la fonction se déplace et ne dessine pas.
  3. La variable alive avec la ligne tk.protocol donne au programme un nettoyage ordonné après que l'utilisateur ferme la fenêtre.

.

from tkinter import * 
import random 
import time 

class Ball: 
    def __init__(self,canvas,color): 
     self.alive = True 
     self.canvas = canvas 
     self.id = canvas.create_oval(30, 30, 50, 50, fill=color) 
     self.canvas.move(self.id, 100, 200) 

     #ADD THESE LINES TO OUR __INIT__ METHOD 
     self.vx = 1 
     self.vy = -1 
     self.canvas_width = self.canvas.winfo_width() 
     self.canvas_height = self.canvas.winfo_height() 

    def move(self): 
     self.canvas.move(self.id, self.vx, self.vy) 
     pos = self.canvas.coords(self.id) 
     if pos[0] <= 0: 
      self.vx = 1 
     if pos[2] >= self.canvas_width: 
      self.vx = -1 
     if pos[1] <= 0: 
      self.vy = 1 
     if pos[3] >= self.canvas_height: 
      self.vy = -1 

    def kill(self): 
     self.alive = False 

def main(): 
    tk = Tk() 
    tk.title("My 21st Century Pong Game") 
    tk.resizable(0, 0) 
    tk.wm_attributes("-topmost", 1) 
    canvas = Canvas(tk, bg="white", width=500, height=400, bd=0, highlightthickness=0) 
    canvas.pack() 
    tk.update() 

    tk.protocol("WM_DELETE_WINDOW", lambda: ball1.kill()) 

    ball1 = Ball(canvas, 'green') 
    while ball1.alive: 
     tk.update() 
     ball1.move() #call the ball move method here 
     time.sleep(0.01) 
    tk.destroy() 

if __name__ == "__main__": 
    main()