Breakout Ball and Paddle Behaviors
by David Reagan · in Torque Game Builder · 03/25/2008 (11:32 pm) · 2 replies
So I have been trying to create a breakout clone. I figure that using behaviors is a nice easy way to set things up. So I created two behaviors, one for how the paddle acts, and the other for how the ball acts.
I want my ball to bounce off the paddle at different angles depending on where it hits the paddle. The farther from the center it is, the more obtuse the angle. This sort of works. But sometimes when it hits on the right, it acts like it hit on the far left, and bounces wrong. Any suggestions? Is my math wrong?
Also, do you have any suggestions on how this could be programmed better?
Posting code in replies due to length...
I want my ball to bounce off the paddle at different angles depending on where it hits the paddle. The farther from the center it is, the more obtuse the angle. This sort of works. But sometimes when it hits on the right, it acts like it hit on the far left, and bounces wrong. Any suggestions? Is my math wrong?
Also, do you have any suggestions on how this could be programmed better?
Posting code in replies due to length...
About the author
#2
// Breakout Ball Behavior
// Copyright (C) David Reagan
// Started 3-25-2008
// Pulled mouse movement code from the followMouseExBehavior.
//
// Collision GUI Settings
// Send Physics and Callback = Yes.
// Detection Mode = Circle
// Superscribe Ellipse = no.
// Collision Resonse = bounce
//
// Physics GUI Settings
// Immovable = yes.
//-----------------------------------------------------------------------------
if (!isObject(BreakoutBallBehavior))
{
%template = new BehaviorTemplate(BreakoutBallBehavior);
%template.friendlyName = "Breakout Ball";
%template.behaviorType = "Breakout Behaviors";
%template.description = "Make an object act like a ball.";
%template.addBehaviorField(breakoutPaddle, "The object to use as a paddle", object, "", t2dSceneObject);
%template.addBehaviorField(ballSpeed, "The speed the ball will move at initially.", float, 200.0);
%template.addBehaviorField(ballSpeedSlowDown, "How fast the ball will slow down.", float, 0);
}
function BreakoutBallBehavior::onBehaviorAdd(%this)
{
%this.owner.setCollisionActiveReceive(true);
%this.owner.setCollisionActiveSend(true);
%this.owner.setUseMouseEvents(true);
%this.owner.enableUpdateCallback();
//%this.owner.setCollisionResponse( bounce );
// %this.owner.setPositionX(%this.breakoutPaddle.getPositionX());
// %this.owner.setPositionY(%this.breakoutPaddle.getPositionY()-10);
}
function BreakoutBallBehavior::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
if(%dstObj.lives==1)
%dstObj.removeFromScene();
//%this.ballBounce(%this,%dstObj);
}
//Not using this function right now. For future use with bricks?
function BreakoutBallBehavior::ballBounce(%this,%obj)
{
echo("Ball bounce from the brick");
%currentVelX = %this.owner.getLinearVelocityX();
%currentVelY = %this.owner.getLinearVelocityY();
%currentPaddlePosX = %obj.owner.getPositionX();
//echo(%currentPaddlePosX);
//echo("Paddle X: " , paddle1.getPositionX());
%currentPaddlePosY = %obj.owner.getPositionY();
//echo(%currentPaddlePosY);
//echo("Paddle Y: " , paddle1.getPositionY());
%currentBallPosX = %this.owner.getPositionX();
%currentBallPosY = %this.owner.getPositionY();
/*test code to check if things work.
echo("VelX: " , %currentVelX);
echo("VelY: " , %currentVelY);
echo("PaddlePosX: " , %currentPaddlePosX);
echo("PaddlePosY: " , %currentPaddlePosY);
echo("BallPosX: " , %currentBallPosX);
echo("BallPosX: " , %currentBallPosY);
*/
if(%currentBallPosX < %currentPaddlePosX)
{
%this.ballSpeed+=10;
%this.owner.setLinearVelocityPolar(225, %this.ballSpeed);
}
if(%currentBallPosX < %currentPaddlePosX/2)
{
%this.ballSpeed+=20;
%this.owner.setLinearVelocityPolar(255, %this.ballSpeed);
}
if(%currentBallPosX > %currentPaddlePosX)
{
%this.ballSpeed+=10;
%this.owner.setLinearVelocityPolar(135, %this.ballSpeed);
}
if(%currentBallPosX > (%currentPaddlePosX+(%currentPaddlePosX/2)))
{
%this.ballSpeed+=20;
%this.owner.setLinearVelocityPolar(110, %this.ballSpeed);
}
}
function BreakoutBallBehavior::onUpdate(%this)
{
%this.owner.ballSpeed = %this.owner.ballSpeed - %this.owner.ballSpeedSlowDown;
}
/////////////////////////////////////////////
//
// End BreakoutBallBehavior
//
////////////////////////////////////////////
03/25/2008 (11:33 pm)
//-----------------------------------------------------------------------------// Breakout Ball Behavior
// Copyright (C) David Reagan
// Started 3-25-2008
// Pulled mouse movement code from the followMouseExBehavior.
//
// Collision GUI Settings
// Send Physics and Callback = Yes.
// Detection Mode = Circle
// Superscribe Ellipse = no.
// Collision Resonse = bounce
//
// Physics GUI Settings
// Immovable = yes.
//-----------------------------------------------------------------------------
if (!isObject(BreakoutBallBehavior))
{
%template = new BehaviorTemplate(BreakoutBallBehavior);
%template.friendlyName = "Breakout Ball";
%template.behaviorType = "Breakout Behaviors";
%template.description = "Make an object act like a ball.";
%template.addBehaviorField(breakoutPaddle, "The object to use as a paddle", object, "", t2dSceneObject);
%template.addBehaviorField(ballSpeed, "The speed the ball will move at initially.", float, 200.0);
%template.addBehaviorField(ballSpeedSlowDown, "How fast the ball will slow down.", float, 0);
}
function BreakoutBallBehavior::onBehaviorAdd(%this)
{
%this.owner.setCollisionActiveReceive(true);
%this.owner.setCollisionActiveSend(true);
%this.owner.setUseMouseEvents(true);
%this.owner.enableUpdateCallback();
//%this.owner.setCollisionResponse( bounce );
// %this.owner.setPositionX(%this.breakoutPaddle.getPositionX());
// %this.owner.setPositionY(%this.breakoutPaddle.getPositionY()-10);
}
function BreakoutBallBehavior::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
if(%dstObj.lives==1)
%dstObj.removeFromScene();
//%this.ballBounce(%this,%dstObj);
}
//Not using this function right now. For future use with bricks?
function BreakoutBallBehavior::ballBounce(%this,%obj)
{
echo("Ball bounce from the brick");
%currentVelX = %this.owner.getLinearVelocityX();
%currentVelY = %this.owner.getLinearVelocityY();
%currentPaddlePosX = %obj.owner.getPositionX();
//echo(%currentPaddlePosX);
//echo("Paddle X: " , paddle1.getPositionX());
%currentPaddlePosY = %obj.owner.getPositionY();
//echo(%currentPaddlePosY);
//echo("Paddle Y: " , paddle1.getPositionY());
%currentBallPosX = %this.owner.getPositionX();
%currentBallPosY = %this.owner.getPositionY();
/*test code to check if things work.
echo("VelX: " , %currentVelX);
echo("VelY: " , %currentVelY);
echo("PaddlePosX: " , %currentPaddlePosX);
echo("PaddlePosY: " , %currentPaddlePosY);
echo("BallPosX: " , %currentBallPosX);
echo("BallPosX: " , %currentBallPosY);
*/
if(%currentBallPosX < %currentPaddlePosX)
{
%this.ballSpeed+=10;
%this.owner.setLinearVelocityPolar(225, %this.ballSpeed);
}
if(%currentBallPosX < %currentPaddlePosX/2)
{
%this.ballSpeed+=20;
%this.owner.setLinearVelocityPolar(255, %this.ballSpeed);
}
if(%currentBallPosX > %currentPaddlePosX)
{
%this.ballSpeed+=10;
%this.owner.setLinearVelocityPolar(135, %this.ballSpeed);
}
if(%currentBallPosX > (%currentPaddlePosX+(%currentPaddlePosX/2)))
{
%this.ballSpeed+=20;
%this.owner.setLinearVelocityPolar(110, %this.ballSpeed);
}
}
function BreakoutBallBehavior::onUpdate(%this)
{
%this.owner.ballSpeed = %this.owner.ballSpeed - %this.owner.ballSpeedSlowDown;
}
/////////////////////////////////////////////
//
// End BreakoutBallBehavior
//
////////////////////////////////////////////
Torque Owner David Reagan
// Breakout Paddle Behavior
// Copyright (C) David Reagan
// Started 3-25-2008
// Pulled mouse movement code from the followMouseExBehavior.
//
// Collision GUI Settings:
// Send Collision = yes
// Receive Collision = yes
// Send or Receive Physics = no.
// Callback = yes
// Detection Mode = FULL
// Collision Response = BOUNCE
//
// Physics GUI Settings:
// Immovable = Yes
// Everything else unchanged.
//-----------------------------------------------------------------------------
if (!isObject(BreakoutPaddleBehavior))
{
%template = new BehaviorTemplate(BreakoutPaddleBehavior);
%template.friendlyName = "Breakout Paddle";
%template.behaviorType = "Breakout Behaviors";
%template.description = "Make an object act like a paddle.";
%template.addBehaviorField(breakoutBall, "The object to use as a ball", object, "", t2dSceneObject);
%template.addBehaviorField(trackingSpeed, "The rate at which the object will move toward the mouse", float, 15.0);
%template.addBehaviorField(ballSpeed, "The speed the ball will bounce off at.", float, 200.0);
}
function BreakoutPaddleBehavior::onBehaviorAdd(%this)
{
%this.owner.setCollisionActiveReceive(true);
%this.owner.setUseMouseEvents(true);
%this.owner.enableUpdateCallback();
}
function BreakoutPaddleBehavior::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
echo("paddle collision");
%this.bounce();
%this.ballSpeed+=20;
}
function BreakoutPaddleBehavior::bounce(%this)
{
%currentVelX = %this.breakoutBall.getLinearVelocityX();
%currentVelY = %this.breakoutBall.getLinearVelocityY();
%currentPaddlePosX = %this.owner.getPositionX();
%currentPaddlePosY = %this.owner.getPositionY();
%currentBallPosX = %this.breakoutBall.getPositionX();
%currentBallPosY = %this.breakoutBall.getPositionY();
echo(%this.ballSpeed);
/*test code to check if things work.
echo("VelX: " , %currentVelX);
echo("VelY: " , %currentVelY);
echo("PaddlePosX: " , %currentPaddlePosX);
echo("PaddlePosY: " , %currentPaddlePosY);
echo("BallPosX: " , %currentBallPosX);
echo("BallPosX: " , %currentBallPosY);
*/
//calculate new velocity depending on where the ball hits the paddle.
if (%currentBallPosX == %currentPaddlePosX)
{
echo("middle");
%this.ballSpeed+=20;
%this.breakoutBall.setLinearVelocityPolar(0, %this.ballSpeed);
}
else if(%currentBallPosX < %currentPaddlePosX/2)
{
echo("far left");
%this.ballSpeed+=20;
%this.breakoutBall.setLinearVelocityPolar(290, %this.ballSpeed);
}
else if(%currentBallPosX < %currentPaddlePosX)
{
echo("near left");
%this.ballSpeed+=10;
%this.breakoutBall.setLinearVelocityPolar(315, %this.ballSpeed);
}
else if(%currentBallPosX > (%currentPaddlePosX+(%currentPaddlePosX/2)))
{
%this.ballSpeed+=20;
echo("far right");
%this.breakoutBall.setLinearVelocityPolar(70, %this.ballSpeed);
}
else if(%currentBallPosX > %currentPaddlePosX)
{
echo("near right");
%this.ballSpeed+=10;
%this.breakoutBall.setLinearVelocityPolar(45, %this.ballSpeed);
}
}
//Follow the mouse, modified code from followMouseEx behavior.
function BreakoutPaddleBehavior::onUpdate(%this)
{
if (!isObject(sceneWindow2d))
return;
%mousePos = sceneWindow2D.getMousePosition();
%position = %this.owner.position;
%difference = t2dVectorSub(%mousePos, %position);
%amount = t2dVectorScale(%difference, %this.trackingSpeed);
%this.owner.setLinearVelocityX(%amount.x);
if (%this.followY)
%this.owner.setLinearVelocityY(%amount.y);
}
/////////////////////////////////////////////
//
// End BreakoutPaddleBehavior
//
////////////////////////////////////////////