Subversion Repositories AndroidProjects

Rev

Rev 269 | 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.pingk.game.GameConsts;
import com.gebauz.pingk.game.GameLogic;

public class Paddle extends Entity implements IReflectable
{
        public static final int PLAYER_1 = 0;
        public static final int PLAYER_2 = 1;
       
        private int mPlayerIndex = -1;

        private Sprite mPaddleSprite;
       
        private boolean mIsAI = true;
        private float mAITimeOut = 0.0f;
        private float mAIRandom = 0.0f;
        private float mAIRandomTimer = 0.0f;
       
        private float mTargetPositionY = GameConsts.VIRTUAL_SCREEN_HEIGHT / 2.0f;
        private float mLastDeltaTime = 0.0f;
        private float mLastPositionY = mTargetPositionY;
       
        public Paddle(GameLogic gameLogic, int playerIndex)
        {
                super(gameLogic);
                mPlayerIndex = playerIndex;
                gameLogic.addReflectable(this);
        }
       
        @Override
        public void init()
        {
                float x = 0;
                float y = 0;
                float angle = 0;
               
                if (mPlayerIndex == PLAYER_1)
                {
                        x = GameConsts.PADDLE_DISTANCE_FROM_EDGE_X;
                        angle = 180.0f;
                }
                else
                {
                        x = GameConsts.VIRTUAL_SCREEN_WIDTH - GameConsts.PADDLE_DISTANCE_FROM_EDGE_X;
                }
               
                y = getGameLogic().getPlayField().getVirtualHeight() / 2.0f;

                mTargetPositionY = y;
                mLastPositionY = mTargetPositionY;
               
                mAITimeOut = 0.0f;
               
                // init sprite
                mPaddleSprite = new Sprite(getGameLogic().getGraphics(),
                                new Texture(Gdx.files.internal("data/textures/paddle.png")));
                mPaddleSprite.x = x;
                mPaddleSprite.y = y;
                mPaddleSprite.angle = angle;
                mPaddleSprite.centerPivot();
        }
       
        @Override
        public void exit()
        {
                if (mPaddleSprite != null)
                {
                        mPaddleSprite.dispose();
                        mPaddleSprite = null;
                }
        }
       
        @Override
        public void update(float deltaTime)
        {
                mLastPositionY = mPaddleSprite.y;
                mLastDeltaTime = deltaTime;
                mAITimeOut += deltaTime;
                mAIRandomTimer += deltaTime;
               
                float virtualPlayfieldHeight = getGameLogic().getPlayField().getVirtualHeight();
               
                // update positions
/*              if (mPlayerIndex == PLAYER_1)
                {
                        Finger finger = MultitouchInput.getInstance().getTouchPointInside(0, 0, GameConsts.VIRTUAL_SCREEN_WIDTH / 2.0f, mGameLogic.getVirtualPlayFieldHeight());
                        if (finger != null)
                        {
                                mTargetPositionY = finger.y;
                                mIsAI = false;
                                mAITimeOut = 0.0f;
                        }
                }
                else
                {
                        Finger finger = MultitouchInput.getInstance().getTouchPointInside(GameConsts.VIRTUAL_SCREEN_WIDTH / 2.0f, 0, GameConsts.VIRTUAL_SCREEN_WIDTH, mGameLogic.getVirtualPlayFieldHeight());
                        if (finger != null)
                        {
                                mTargetPositionY = finger.y;
                                mIsAI = false;
                                mAITimeOut = 0.0f;
                        }
                }*/

               
                if ((!mIsAI) && (mAITimeOut > GameConsts.PADDLE_AI_TIMEOUT))
                {
                        mIsAI = true;
                }
               
                if (mIsAI)
                {
                        if (mAIRandomTimer > GameConsts.PADDLE_AI_RANDOM_TIMER)
                        {
                                mAIRandomTimer = 0.0f;
                                mAIRandom = getGameLogic().getGame().getRandomizer().nextFloat();
                        }
                       
                        // try to reach ball, but only react when ball is inside own territory
                        float ballX = getGameLogic().getBall().getX();
                        if ( ((mPlayerIndex == PLAYER_1) && (ballX < (GameConsts.VIRTUAL_SCREEN_WIDTH/1.5f))) ||
                                 ((mPlayerIndex == PLAYER_2) && (ballX > (GameConsts.VIRTUAL_SCREEN_WIDTH - (GameConsts.VIRTUAL_SCREEN_WIDTH/1.5f)))) )
                        {
                                float aiTargetY = getGameLogic().getBall().getY() + (-GameConsts.PADDLE_AI_VARIANCE + 2 * mAIRandom * GameConsts.PADDLE_AI_VARIANCE);
                               
                                float diff = aiTargetY - mTargetPositionY;
                                mTargetPositionY += (diff * deltaTime * GameConsts.PADDLE_AI_ACCEL);   
                        }
                        else
                        {
                                // slowly go to center
                                float centerTarget = virtualPlayfieldHeight / 2.0f + (-GameConsts.PADDLE_AI_VARIANCE2 + 2*mAIRandom * GameConsts.PADDLE_AI_VARIANCE2);                         
                                float diff = centerTarget - mTargetPositionY;
                                mTargetPositionY += (diff * deltaTime * GameConsts.PADDLE_AI_ACCEL_SLOW);      
                        }
                }
               
                float distanceFromEdgeY = mPaddleSprite.h / 2.0f + GameConsts.PADDLE_DISTANCE_FROM_EDGE_Y;
               
                if (mTargetPositionY < distanceFromEdgeY)
                        mTargetPositionY = distanceFromEdgeY;
                else if (mTargetPositionY > (virtualPlayfieldHeight - distanceFromEdgeY))
                        mTargetPositionY = (virtualPlayfieldHeight - distanceFromEdgeY);
               
                if (mTargetPositionY > mPaddleSprite.y)
                {
                        float diff = mTargetPositionY - mPaddleSprite.y;
                        mPaddleSprite.y += (diff * deltaTime * GameConsts.PADDLE_INPUT_ACCEL);
                        if (mPaddleSprite.y > mTargetPositionY)
                                mPaddleSprite.y = mTargetPositionY;
                }
                else if (mTargetPositionY < mPaddleSprite.y)
                {
                        float diff = mPaddleSprite.y - mTargetPositionY;
                        mPaddleSprite.y -= (diff * deltaTime * GameConsts.PADDLE_INPUT_ACCEL);
                        if (mPaddleSprite.y < mTargetPositionY)
                                mPaddleSprite.y = mTargetPositionY;
                }
               
                mPaddleSprite.update(deltaTime);
        }
       
        @Override
        public void render()
        {
                mPaddleSprite.render();
        }

        @Override
        public void reflect(Ball ball, float deltaTime)
        {
                // check collision from the front
                if (Math.abs(ball.getY() - mPaddleSprite.y) < ((mPaddleSprite.h+ ball.getHeight())/2.0f))
                {
                        float offset = ((mPaddleSprite.w/2.0f)) - GameConsts.PADDLE_HIT_OFFSET;
                        float paddleX = mPaddleSprite.x;
                        // if ball is within Y coordinate space of paddle, check the two positions
                        if (mPlayerIndex == PLAYER_1)
                        {
                                paddleX += offset;
                                if ((ball.getX() <= paddleX) && (ball.getLastX() > paddleX))
                                {
                                        // paddle touched, reflect the ball
                                        ballHitsPaddleFront(ball, deltaTime);
                                        ball.setLastPaddleTouched(mPlayerIndex);
/*                                      if (mGameLogic.getPowerUpEffect().isConcaveActive())
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x + GameConsts.PADDLE_IMPACT_CONCAVE_OFFSET, mPaddleSprite.y, 0.0f);
                                        else
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x, mPaddleSprite.y, 180.0f);
                                       
                                        mGameLogic.playSound(R.raw.paddleimpact);
                                       
                                        mGameLogic.getCrystalHitCounter().resetHits();*/

                                       
                                        return;
                                }
                        }
                        else if (mPlayerIndex == PLAYER_2)
                        {
                                paddleX -= offset;
                                if ((ball.getX() >= paddleX) && (ball.getLastX() < paddleX))
                                {
                                        // paddle touched, reflect the ball
                                        ballHitsPaddleFront(ball, deltaTime);
                                        ball.setLastPaddleTouched(mPlayerIndex);
/*                                      if (mGameLogic.getPowerUpEffect().isConcaveActive())
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x - GameConsts.PADDLE_IMPACT_CONCAVE_OFFSET, mPaddleSprite.y, 180.0f);
                                        else
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x, mPaddleSprite.y, 0.0f);
                                       
                                        mGameLogic.playSound(R.raw.paddleimpact);
                                       
                                        mGameLogic.getCrystalHitCounter().resetHits();*/

                                       
                                        return;
                                }
                        }
                }
               
                // check collision from below & above
                if (Math.abs(ball.getX() - mPaddleSprite.x) < (mPaddleSprite.w/2.0f))
                {
                        float halfHeight = mPaddleSprite.h/2.0f;
                        // for sides, use simple reflection
                        if ((ball.getY() >= (mPaddleSprite.y - halfHeight)) && (ball.getLastY() < (mPaddleSprite.y - halfHeight)))                                     
                        {
                                // above
                                ball.reflectAlongNormal(180.0f);
                                ball.clampToAngle(GameConsts.BALL_STEEPEST_ANGLE_HIT_PADDLE_SIDE);
                                ball.setLastPaddleTouched(mPlayerIndex);
                               
/*                              mGameLogic.playSound(R.raw.paddleimpact);
                               
                                mGameLogic.getCrystalHitCounter().resetHits();*/

                        }
                        else if ((ball.getY() <= (mPaddleSprite.y + halfHeight)) && (ball.getLastY() > (mPaddleSprite.y + halfHeight)))
                        {
                                // below
                                ball.reflectAlongNormal(0.0f);
                                ball.clampToAngle(GameConsts.BALL_STEEPEST_ANGLE_HIT_PADDLE_SIDE);
                                ball.setLastPaddleTouched(mPlayerIndex);
                               
/*                              mGameLogic.playSound(R.raw.paddleimpact);
                               
                                mGameLogic.getCrystalHitCounter().resetHits();*/

                        }
                }              
        }
       
        public void ballHitsPaddleFront(Ball ball, float deltaTime)
        {
                float newX = mPaddleSprite.x;
                float yDifference = (ball.getY() - mPaddleSprite.y) * GameConsts.PADDLE_HIT_ZONE_DEVIATION;
               
/*              if (mGameLogic.getPowerUpEffect().isConcaveActive())
                        yDifference = -yDifference;*/

               
                float direction = 0.0f;
                float paddleDirection = 0.0f;
                float invertPlayer2Paddle = 0;
               
                if (mPlayerIndex == PLAYER_1)
                {
                        // left
                        paddleDirection = 270.0f;
                        direction = 90.0f - yDifference;
                        newX += mPaddleSprite.w/3.0f;
                       
                        invertPlayer2Paddle = -1;
                }
                else if (mPlayerIndex == PLAYER_2)
                {
                        // right
                        paddleDirection = 90.0f;
                        direction = 270.0f + yDifference;
                        newX -= mPaddleSprite.w/3.0f;
                        invertPlayer2Paddle = 1;
                }
               
                ball.setX(newX);               
                ball.reflectAlongNormal(direction);
               
                float angularSpeed = getMovementSpeed() * GameConsts.BALL_TOP_SPIN_INTENSITY * invertPlayer2Paddle;            
                ball.setAngularVelocity(ball.getAngularVelocity() + angularSpeed);
                ball.clampToAngle(GameConsts.BALL_STEEPEST_ANGLE_HIT_PADDLE_FRONT);            
        }
       
        public float getMovementSpeed()
        {
                return (mPaddleSprite.y - mLastPositionY) / mLastDeltaTime;
        }
}