package com.gebauz.pingK.game;
import android.util.Log;
import com.gebauz.framework.util.MathUtil;
import com.gebauz.framework.util.Sprite2D;
import com.gebauz.framework.util.Vector2;
import com.gebauz.pingK.R;
public class Ball
{
static public final int DIRECTION_LEFT =
0;
static public final int DIRECTION_RIGHT =
1;
private GameLogic mGameLogic =
null;
private Sprite2D mBallSprite
;
private BallTrail mBallTrail
;
// movement parameters
private float mRotation = 0.0f
;
private float mSpeed = GameConsts.
BALL_INITIAL_SPEED;
private float mSpeedUpTimer = 0.0f
;
private float mAngularVelocity = 0.0f
;
private Vector2 mLastPosition =
new Vector2
();
public Ball
(GameLogic gameLogic
)
{
mGameLogic = gameLogic
;
}
public void init
()
{
mBallSprite =
new Sprite2D
();
mBallSprite.
init(R.
drawable.
ball, GameConsts.
VIRTUAL_SCREEN_WIDTH/2.0f, mGameLogic.
getVirtualPlayFieldHeight()/2.0f, GameConsts.
BALL_SIZE, GameConsts.
BALL_SIZE);
mBallTrail =
new BallTrail
(this);
reset
(DIRECTION_LEFT
);
}
public void exit
()
{
}
public void reset
(int direction
)
{
mSpeed = GameConsts.
BALL_INITIAL_SPEED;
mSpeedUpTimer = 0.0f
;
mAngularVelocity = 0.0f
;
if (direction == DIRECTION_LEFT
)
{
mRotation = 270.0f
;
}
else if (direction == DIRECTION_RIGHT
)
{
mRotation = 90.0f
;
}
mBallSprite.
x = GameConsts.
VIRTUAL_SCREEN_WIDTH / 2.0f
;
mBallSprite.
y = mGameLogic.
getVirtualPlayFieldHeight() / 2.0f
;
mBallTrail.
reset();
/* mRotation = 0.0f;
mBallSprite.x = GameConsts.PADDLE_DISTANCE_FROM_EDGE_X;
mBallSprite.y = 30.0f;*/
/*mBallTrail.addTrailPoint(200.0f, 200.0f, -1);
mBallTrail.addTrailPoint(250.0f, 200.0f, -1);
mBallTrail.addTrailPoint(300.0f, 200.0f, -1);
mBallTrail.addTrailPoint(250.0f, 300.0f, 0);
mBallTrail.addTrailPoint(300.0f, 300.0f, -1);*/
updateLastPosition
();
}
public void update
(float deltaTime
)
{
// store last position then move forward
speedUp
(deltaTime
);
updateLastPosition
();
processAngularVelocity
(deltaTime
);
moveForward
(deltaTime
);
// check for collisions
//collectPowerUps;
//reflectFromCrystals;
reflectFromBoard
(deltaTime
);
reflectFromEntities
(deltaTime
);
//updateBallSparks;
//updateTrail
checkPlayerGainsScore
();
mBallSprite.
update(deltaTime
);
}
public void render
()
{
mBallTrail.
render();
mBallSprite.
render();
}
public void speedUp
(float deltaTime
)
{
mSpeedUpTimer += deltaTime
;
if (mSpeedUpTimer
>= GameConsts.
BALL_SPEEDUP_TIMER)
{
mSpeedUpTimer = mSpeedUpTimer - GameConsts.
BALL_SPEEDUP_TIMER;
mSpeed += GameConsts.
BALL_SPEEDUP_INCREASE;
}
// decrease angular velocity
if (mAngularVelocity
> 0)
{
mAngularVelocity -=
(GameConsts.
BALL_ANGULAR_SPEED_DECREASE * deltaTime
);
if (mAngularVelocity
< 0.0f
)
{
mAngularVelocity = 0.0f
;
}
}
else if (mAngularVelocity
< 0)
{
mAngularVelocity +=
(GameConsts.
BALL_ANGULAR_SPEED_DECREASE * deltaTime
);
if (mAngularVelocity
> 0.0f
)
{
mAngularVelocity = 0.0f
;
}
}
}
public void processAngularVelocity
(float deltaTime
)
{
mRotation += mAngularVelocity
* deltaTime
;
}
public void moveForward
(float deltaTime
)
{
Vector2 move =
new Vector2
();
move.
x =
(float)Math.
sin(Math.
toRadians(mRotation
));
move.
y =
(float)Math.
cos(Math.
toRadians(mRotation
));
move.
setLength(mSpeed
* deltaTime
);
mBallSprite.
x += move.
x;
mBallSprite.
y += move.
y;
mBallTrail.
update(deltaTime
);
}
public void reflectFromBoard
(float deltaTime
)
{
if ((mBallSprite.
y < GameConsts.
PLAYFIELD_BORDER_Y) && (mLastPosition.
y >= GameConsts.
PLAYFIELD_BORDER_Y))
{
// upper bounce
reflectAlongNormal
(0.0f
);
clampToAngle
(GameConsts.
BALL_STEEPEST_ANGLE_REFLECT_FROM_BOARD); // clamp to steepest angle from board
//mGameMain.playSound(R.raw.wallimpact);
//mGameMain.getWallImpactEffect().spawnInstance(PLAYFIELD_BORDER, position.y, 90.0f);
}
else if (mBallSprite.
y > (mGameLogic.
getVirtualPlayFieldHeight() - GameConsts.
PLAYFIELD_BORDER_Y) &&
(mLastPosition.
y <=
(mGameLogic.
getVirtualPlayFieldHeight() - GameConsts.
PLAYFIELD_BORDER_Y)))
{
// lower bounce
reflectAlongNormal
(180.0f
);
clampToAngle
(GameConsts.
BALL_STEEPEST_ANGLE_REFLECT_FROM_BOARD); // clamp to steepest angle from board
//mGameMain.playSound(R.raw.wallimpact);
//mGameMain.getWallImpactEffect().spawnInstance(mGameMain.getWidth() - PLAYFIELD_BORDER, position.y, 270.0f);
}
mBallSprite.
y = MathUtil.
clampToRange(mBallSprite.
y,
0, mGameLogic.
getVirtualPlayFieldHeight());
}
public void reflectFromEntities
(float deltaTime
)
{
mGameLogic.
reflect(this, deltaTime
);
}
public void checkPlayerGainsScore
()
{
if (mBallSprite.
x < GameConsts.
PLAYFIELD_BORDER_X)
{
// reached top -> bottom player scores
//mGameMain.playerGainsScore(Paddle.PADDLE_BOTTOM, lastPaddleTouched);
reset
(DIRECTION_RIGHT
);
return;
}
else if (mBallSprite.
x > (GameConsts.
VIRTUAL_SCREEN_WIDTH - GameConsts.
PLAYFIELD_BORDER_X))
{
// reached bottom -> top player scores
//mGameMain.playerGainsScore(Paddle.PADDLE_TOP, lastPaddleTouched);
reset
(DIRECTION_LEFT
);
return;
}
}
public void updateLastPosition
()
{
mLastPosition.
x = mBallSprite.
x;
mLastPosition.
y = mBallSprite.
y;
}
public float getX
() { return mBallSprite.
x; }
public float getY
() { return mBallSprite.
y; }
public void setX
(float x
) { mBallSprite.
x = x
; }
public void setY
(float y
) { mBallSprite.
y = y
; }
public float getLastX
() { return mLastPosition.
x; }
public float getLastY
() { return mLastPosition.
y; }
public float getWidth
() { return mBallSprite.
w; }
public float getHeight
() { return mBallSprite.
h; }
public float getAngularVelocity
() { return mAngularVelocity
; }
public void setAngularVelocity
(float angularSpeed
)
{
mAngularVelocity = MathUtil.
clampToRange(angularSpeed, -GameConsts.
BALL_MAXIMUM_ANGULAR_SPEED, GameConsts.
BALL_MAXIMUM_ANGULAR_SPEED);
}
public void clampToAngle
(float steepestAngle
)
{
mRotation = MathUtil.
stayInDegrees0to360(mRotation
);
if (steepestAngle
<=
0)
return;
if (mRotation
< steepestAngle
)
mRotation = steepestAngle
;
if (mRotation
> (360.0f - steepestAngle
))
mRotation = 360.0f - steepestAngle
;
if ((mRotation
> (180.0f - steepestAngle
)) && (mRotation
<= 180.0f
))
mRotation = 180.0f - steepestAngle
;
if ((mRotation
< 180.0f + steepestAngle
) && (mRotation
>= 180.0f
))
mRotation = 180.0f + steepestAngle
;
}
public void reflectAlongNormal
(float rot
)
{
mRotation += 180.0f
;
mRotation = MathUtil.
stayInDegrees0to360(mRotation
);
float difference = rot - mRotation
;
mRotation = rot + difference
;
mRotation = MathUtil.
stayInDegrees0to360(mRotation
);
if (MathUtil.
turnDegrees(mRotation, rot
) >= 90.0f
)
{
mRotation = 360.0f - mRotation
;
mRotation = MathUtil.
stayInDegrees0to360(mRotation
);
}
mBallTrail.
addTrailPoint(getX
(), getY
(), rot
);
}
}