Subversion Repositories AndroidProjects

Rev

Rev 101 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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();
        private int mLastPaddleTouched = -1;
       
        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);
               
                reset(DIRECTION_LEFT);
        }
       
        public void exit()
        {

        }
       
        public void reset(int direction)
        {
                mSpeed = GameConsts.BALL_INITIAL_SPEED;
                mSpeedUpTimer = 0.0f;
                mAngularVelocity = 0.0f;
               
                mLastPaddleTouched = -1;
               
                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;
               
                //mBallSprite.y = mGameLogic.getVirtualPlayFieldHeight() - 10.0f;
               
                mGameLogic.getBallTrail().reset();
                mGameLogic.getBallTrail().addTrailPoint(mBallSprite.x, mBallSprite.y, mRotation);
               
               
/*              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;
            reflectFromEntities(deltaTime);
            reflectFromBoard(deltaTime);
            //updateBallSparks;
           
            //updateTrail
            checkPlayerGainsScore();
           
            mGameLogic.getBackground().setMonkeyRotationSpeed(mAngularVelocity);
               
                mBallSprite.update(deltaTime);         
        }
       
        public void 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;
        }
       
        public void reflectFromBoard(float deltaTime)
        {
                float newY = MathUtil.clampToRange(mBallSprite.y, GameConsts.PLAYFIELD_BORDER_Y, mGameLogic.getVirtualPlayFieldHeight() - GameConsts.PLAYFIELD_BORDER_Y);
                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
                        mGameLogic.getPlayField().createImpact(mBallSprite.x, GameConsts.PLAYFIELD_BORDER_Y - GameConsts.PLAYFIELD_IMPACT_OFFSET_Y, 180.0f);
                        mGameLogic.playSound(R.raw.wallimpact);
                       
                        if (mGameLogic.getPowerUpEffect().isCrystalActive())
                        {
                                mGameLogic.getCrystals().spawnCrystal(getX(), newY + GameConsts.POWERUP_CRYSTAL_RADIUS/2.0f, new Vector2(0.0f, 1.0f));
                                mGameLogic.getPowerUpEffect().deactivateCrystal();
                        }
                }
                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
                        mGameLogic.getPlayField().createImpact(mBallSprite.x, (mGameLogic.getVirtualPlayFieldHeight() - GameConsts.PLAYFIELD_BORDER_Y + GameConsts.PLAYFIELD_IMPACT_OFFSET_Y), 0.0f);
                        mGameLogic.playSound(R.raw.wallimpact);
                       
                        if (mGameLogic.getPowerUpEffect().isCrystalActive())
                        {
                                mGameLogic.getCrystals().spawnCrystal(getX(), newY - GameConsts.POWERUP_CRYSTAL_RADIUS/2.0f, new Vector2(0.0f, -1.0f));
                                mGameLogic.getPowerUpEffect().deactivateCrystal();
                        }
                }
               
                mBallSprite.y = newY;
        }
       
        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);
                        mGameLogic.playerGainsScore(Paddle.PLAYER_2, mLastPaddleTouched);
                        mGameLogic.getBallTrail().addTrailPoint(mBallSprite.x, mBallSprite.y, 270.0f);
                        //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);
                        mGameLogic.playerGainsScore(Paddle.PLAYER_1, mLastPaddleTouched);
                        mGameLogic.getBallTrail().addTrailPoint(mBallSprite.x, mBallSprite.y, 90.0f);
                        //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);
                }
               
                mGameLogic.getBallTrail().addTrailPoint(getX(), getY(), rot);
        }

        public void setLastPaddleTouched(int paddle)
        {
                mLastPaddleTouched = paddle;
        }
}