Subversion Repositories AndroidProjects

Rev

Rev 269 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.pingk.entities;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.gebauz.Bauzoid.graphics.sprite.Sprite;
import com.gebauz.Bauzoid.math.MathUtil;
import com.gebauz.Bauzoid.math.Vector2;
import com.gebauz.pingk.game.GameConsts;
import com.gebauz.pingk.game.GameLogic;

public class Ball extends Entity
{
        static public final int DIRECTION_LEFT = 0;
        static public final int DIRECTION_RIGHT = 1;

        private Sprite mBallSprite = null;
       
        // 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)
        {
                super(gameLogic);
        }

        @Override
        public void init()
        {
                mBallSprite = new Sprite(getGameLogic().getGraphics(),
                                new Texture(Gdx.files.internal("data/textures/ball.png")));
                mBallSprite.x = GameConsts.VIRTUAL_SCREEN_WIDTH/2.0f;
                mBallSprite.y = getGameLogic().getPlayField().getVirtualHeight()/2.0f;
                mBallSprite.w = GameConsts.BALL_SIZE;
                mBallSprite.h = GameConsts.BALL_SIZE;
                mBallSprite.centerPivot();
               
                reset(DIRECTION_LEFT);
        }

        @Override
        public void exit()
        {

        }

        /** Reset the ball for a new game round. */
        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 = getGameLogic().getPlayField().getVirtualHeight() / 2.0f;
               
                //mGameLogic.getBallTrail().reset();
                //mGameLogic.getBallTrail().addTrailPoint(mBallSprite.x, mBallSprite.y, mRotation);
               
                //updateLastPosition();

        }
       
        @Override
        public void update(float deltaTime)
        {
                // store last position then move forward
                speedUp(deltaTime);
                updateLastPosition();          
            processAngularVelocity(deltaTime);
            moveForward(deltaTime);        
           
            // check for collisions        
            reflectFromEntities(deltaTime);
            reflectFromBoard(deltaTime);
            checkPlayerGainsScore();
           
//          mGameLogic.getBackground().setMonkeyRotationSpeed(mAngularVelocity);
               
                mBallSprite.update(deltaTime);
        }

        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 virtualPlayFieldHeight = getGameLogic().getPlayField().getVirtualHeight();
                float newY = MathUtil.clamp(mBallSprite.y, GameConsts.PLAYFIELD_BORDER_Y,
                                getGameLogic().getPlayField().getVirtualHeight() - 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 > (virtualPlayFieldHeight - GameConsts.PLAYFIELD_BORDER_Y) &&
                                (mLastPosition.y <= (virtualPlayFieldHeight - 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)
        {
                for (int i = 0; i < getGameLogic().getNumReflectables(); i++)
                {
                        IReflectable reflectable = getGameLogic().getReflectable(i);
                        reflectable.reflect(this, deltaTime);
                }
        }
       
        public void checkPlayerGainsScore()
        {
                if (mBallSprite.x < GameConsts.PLAYFIELD_BORDER_X)
                {
                        // reached left -> left player scores                  
                        //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 right -> right player scores
                        //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 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;
        }
       
        @Override
        public void render()
        {
                mBallSprite.render();
        }

        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.clamp(angularSpeed, -GameConsts.BALL_MAXIMUM_ANGULAR_SPEED, GameConsts.BALL_MAXIMUM_ANGULAR_SPEED);        
        }
}