2016-05-19 2 views
0

Ich habe zwei Probleme, ich brauche Hilfe bei der Fixierung. Einer ist, wenn der Pong-Ball die Mitte der linken oder rechten Seite trifft - er zuckt heftig, bis sich das Paddel darüber bewegt. Was es tun sollte, ist, statt heftig zu zucken, sollte es nach außen und weg von der Wand springen.Warum funktionieren die Trefferfelder und Kollisionen in meinem Pong-Spiel nicht korrekt?

Das zweite Problem bezieht sich auf die Hit-Box der Paddel. Gerade jetzt, wenn der Pong Ball die Mitte der Paddel trifft, verhält er sich wie erwartet, aber wenn er die obere Kante oder die untere Kante trifft, lässt er den Ball durch.

Ich fragte mich, ob jemand mir helfen könnte festzustellen, warum diese Probleme passieren, und was getan werden könnte, um sie zu korrigieren.

from tkinter import * 
import random 
from math import * 
##MAIN GAME PART## 
window = Tk() 
canvas = Canvas(window,width=400,height=400) 
canvas.pack() 
sideX = -1 
sideY = 0 
##FUNCTIONS## 
def movePaddles(event): 
    key=event.keysym 
    if key == 'Up': 
     canvas.move(PaddleTwo,0,-10) 
    elif key == 'Down': 
     canvas.move(PaddleTwo,0,10) 
    if key == 'w': 
     canvas.move(PaddleOne,0,-10) 
    elif key == 's': 
     canvas.move(PaddleOne,0,10) 

def distance(target1,target2): 
    target1coords = canvas.coords(target1) 
    target2coords = canvas.coords(target2) 
    x1 = (target1coords[0] + target1coords[2])/2 
    y1 = (target1coords[1] + target1coords[3])/2 
    x2 = (target2coords[0] + target2coords[2])/2 
    y2 = (target2coords[1] + target2coords[3])/2 
    d = sqrt((x2-x1)** 2 + (y2-y1)** 2) 
    return d 

def checkCollisions(): 
    global sideX 
    global sideY 
    for e in PaddleList: 
     if distance(PingPongBall,e) < 20: 
      if e == 1: 
       sideX = 1 
       sideY = random.randint(0,1) 
      elif e == 2: 
       sideX = -1 
       sideY = random.randint(0,1) 
     canvas.move(PingPongBall,sideX,sideY) 
def moveBall(): 
    ##Found no other way of changing these variables without global## 
    global sideY 
    global sideX 
    for e in BallList: 
     xcor = canvas.coords(e)[0] 
     ycor = canvas.coords(e)[1] 
     if xcor >= 400: ##Right side of screen 
      if sideY == -1: 
       sideY = 1 
       sideX = 1 
      elif sideY == 1: 
       sideY = -1 
       sideX = -1 
      elif sideX == 1: 
       sideX = -1 
     if xcor <= 0: ##Left side of screen 
      if sideY == -1: 
       sideY = 1 
       sideX = 1 
      elif sideY == 1: 
       sideY = -1 
       sideX = -1 
      elif sideX == -1: 
       sideX = 1 
     if ycor >= 400: ##Top of screen 
      if sideY == -1: 
       sideY = 1 
      elif sideY == 1: 
       sideY = -1 
     if ycor <= 0: ##Bottom of screen 
      if sideY == -1: 
       sideY = 1 
      elif sideY == 1: 
       sideY = -1 
##SET UP TIMER AKA INFINITE LOOP WITHOUT LAG## 
timeLeft = 1 
##PADDLES AND OTHER STUFF##  
PaddleOne = canvas.create_rectangle(10 ,150 ,25 ,250 ,fill='blue') 
PaddleTwo = canvas.create_rectangle(400,150 ,385 ,250 ,fill='blue') 
PingPongBall = canvas.create_rectangle(200, 200, 210 ,210 ,fill='red') 
PaddleList = [PaddleOne,PaddleTwo] 
BallList = [PingPongBall] 
Target = PaddleList[0] 
##KEY BINDINGS## 
canvas.bind_all('<Key>',movePaddles) 
##INFINITE LOOP## 
while timeLeft > 0: 
    checkCollisions() 
    moveBall() 
    window.update() 
+0

betrachtet nicht 'mit' 'from package import *' '' Beste zu importieren, was Sie von jedem Paket benötigen wie '' 'from package import class''' – JasTonAChair

+0

@ JasTonAChair Danke, dass ich das für Squar getan habe e Root-Objekt – Riderfighter

+0

@JasTonAChair: Wildcard-Importe wie 'from package import *' werden in PEP8 ausdrücklich nicht empfohlen und sollten vermieden werden. –

Antwort

0

betrachten diese Strukturkontrolle:

if xcor >= 400: ##Right side of screen 
    if sideY == -1: 
     sideY = 1 
     sideX = 1 
    elif sideY == 1: 
     sideY = -1 
     sideX = -1 
    elif sideX == 1: 
     sideX = -1 

lässt so gehen durch die möglichen Szenarien:

Der Ball geht an die rechte Wand, während hinauf (Sidey == -1)

  1. sideY ist -1, also setzeYY auf 1 und sideX auf 1
  2. nach rechts bewegt, um ein Pixel (weiter in Wand) und ein Pixel nach unten
  3. Sidey 1 ist nun so Sidey auf -1 gesetzt und Sidex
  4. bewegt sich ein Pixel nach links (nach wie vor in der Wand) und ein Pixel auf -1 bis
  5. zurück zu Schritt 1. seit xcor>=400 ist immer noch True.

Das für Ihr glitchy Verhalten ausmachen wird, wird außer Kraft gesetzt, wenn der Ball den Schläger berührt (I hitbox in einem Moment erklären), aber wirklich nur Ihr conditionals sollte wie folgt sein:

if xcor >= 400: ##Right side of screen 
     #make it go left 
     sideX = -1 
    if xcor <= 0: ##Left side of screen 
     #make it go right 
     sideX = 1 
    if ycor >= 400: ##Bottom of screen 
     #make it go up 
     sideY = -1 
    if ycor <= 0: ##Top of screen 
     #make it go down 
     sideY = 1 

was Ihre hitbox werden Überprüfung Sie nur, wenn der Abstand von der Mitte der Kugel in der Mitte des Paddels sind weniger als 20:

if distance(PingPongBall,e) < 20: 

Diese Konten nur für das mittlere 40% oder so des Paddels der ist nicht was Sie wollen, wollen Sie wissen, ob sie überlappende sind die unter Verwendung der in Betreiber, die .find_overlapping-Methode und die .bbox Methode (beide diese Methoden sind described here)

def is_overlapping(tag1,tag2): 
    return tag1 in canvas.find_overlapping(*canvas.bbox(tag2)) 

dann können Sie prüfen, getan werden kann, wenn das Paddel berührt den Ball mit nur:

if is_overlapping(PingPongBall,e): 
Verwandte Themen