2015-09-23 3 views
-2

Ce code fait rebondir la balle autour de la toile:balle rebondit parfois ne parfois pas

//advance the ball 
ball.advance(); 
//check if ball should bounce off canvas sides 
if (ball.getCenterX() + ball.getRadius() > canvas.getWidth()) 
    ball.setDirectionX(LEFT); 
if (ball.getCenterX() - ball.getRadius() < 0) 
    ball.setDirectionX(RIGHT); 

if (ball.getCenterY() + ball.getRadius() > canvas.getHeight()) 
    ball.setDirectionY(UPWARDS); 
if (ball.getCenterY() - ball.getRadius() < 0) 
    ball.setDirectionY(DOWNWARDS); 

ressemble à ceci: https://gyazo.com/7b51794a6e5e474b508cf442ddebc8dc

Im essayant de faire rebondir sur la palette quand il frappe et J'ai utilisé ce code:

boolean bounceInY = ball.getCenterY()+ ball.getRadius() > paddle.getTopLeftY(); 
boolean bounceInX = (ball.getCenterX()+ ball.getRadius() > paddle.getTopLeftX()) && (ball.getCenterX()+ ball.getRadius() < paddle.getTopLeftX() + paddle.getWidth()); 

if (bounceInY && bounceInX) 
    ball.setDirectionY(UPWARDS); 

la question est im avoir qu'il est incohérent et parfois il rebondira correctement, parfois, il passera par la palette avant de rebondir, et SOMET imes, il passera à travers la pagaie et ne rebondira pas du tout. Cela ressemble à ceci: https://gyazo.com/d1b5c848290fc23183c9b7296f757a51 Je ne suis pas sûr de ce que je fais mal, le code de la balle pour rebondir sur la pagaie semble que cela devrait fonctionner pour moi. Toute aide est appréciée :)

+1

Avez-vous essayé de déboguer votre code avec quelques exemples de coordonnées X, Y? – mvd

+0

Vous devez créer et publier votre [mcve]. –

+0

Vous avez, à tout le moins, manqué un contrôle plus petit que sur y. – Dukeling

Répondre

2

Le code qui contrôle le rebond est désactivé un peu. Tout d'abord, ball.getCenterX()+ball.getRadius() est effectivement le côté droit de la balle, et c'est la seule partie que vous comparez à l'emplacement de la pagaie. Cela signifie que l'emplacement effectif de la pagaie est d'une valeur égale au rayon de la balle. Vous pouvez le voir dans votre image - la balle ne "rebondit" qu'une fois que le côté le plus à droite de la balle est aligné avec la pagaie. Deuxièmement, même après avoir modifié cette partie, votre code échouera toujours dans certaines conditions. Imaginez, par exemple, que la balle est directement sous la pagaie mais n'a pas encore heurté le mur. Vraisemblablement, vous voulez que la balle continue à descendre jusqu'à ce qu'elle frappe le mur, puis rebondir vers le haut. Cependant, avec le code que vous avez maintenant, la balle commencera immédiatement à se déplacer vers le haut dès que la pagaie est au-dessus de la balle - selon vos conditions booléennes, la balle est sous la pagaie et la coordonnée est entre les bords de la pagaie , il devrait donc "rebondir". Je suppose que vous êtes un débutant et que vous ne voulez probablement pas entrer dans beaucoup de maths, donc la façon la plus simple de résoudre ce problème est d'utiliser des AABB (bounding bounds) et de tester la collision en utilisant cette logique. Voici un exemple:

// I'm creating a bunch of variables here because I don't know 
// what properties your objects have available. 
int ballLeftSide  = ball.getCenterX() - ball.getRadius(); 
int ballRightSide = ball.getCenterX() + ball.getRadius(); 
int ballTopSide  = ball.getCenterY() - ball.getRadius(); 
int ballBottomSide = ball.getCenterY() + ball.getRadius(); 
int paddleLeftSide = paddle.getTopLeftX(); 
int paddleRightSide = paddle.getTopLeftX() + paddle.getWidth(); 
int paddleTopSide = paddle.getTopLeftY(); 
int paddleBottomSide = paddle.getTopLeftY() + paddle.getHeight(); 

bool ballOverlapsPaddle = ((ballLeftSide < paddleRightSide) && 
          (ballRightSide > paddleLeftSide) && 
          (ballTopSide < paddleBottomSide) && 
          (ballBottomSide > paddleTopSide)) 

// Only change ball direction if the ball hasn't already passed 
// the paddle. In this case, "passed" means the ball's center is 
// further down than the bottom of the paddle. 
if ((ballOverlapsPaddle) && (ball.getCenter() < paddleBottomSide)) 
    ball.setDirectionY(UPWARDS); 

Cette condition booléenne qui vérifie les chevauchements utilise une forme très simple du théorème de séparation Axe (SAT) en utilisant des boîtes de délimitation alignés axe (AABBs). Fondamentalement, il vérifie si deux formes rectangulaires sont en collision. Puisque l'une de vos formes est une balle, cette méthode la traite comme si elle était entourée d'un cadre rectangulaire lorsqu'elle effectue cette vérification. Maintenant, bien que cette solution soit très simple, elle soulève quelques complications. Puisque votre balle n'est évidemment PAS un rectangle, sa zone de délimitation effective va s'étendre un peu au-delà de la forme réelle de la balle. Cela signifie que vous aurez des "collisions" même s'il n'y en a pas visuellement, comme le montre l'exemple ci-dessous.

False positive "collision"

Il existe des méthodes de cours pour contourner ce problème, mais cela devient un peu trop détaillé et techy pour un Q + Un format. Si vous voulez regarder vous-même, this is the tutorial j'ai utilisé quand j'ai appris la première fois sur la détection de collision entre les formes.

+0

Merci beaucoup J'ai la balle et la pagaie qui fonctionnent maintenant. – user3390522