Subversion Repositories AndroidProjects

Rev

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

package com.gebauz.pingK.game;

import android.util.Log;

import com.gebauz.framework.util.GLUtil;
import com.gebauz.framework.util.Sprite2D;
import com.gebauz.pingK.MultitouchInput;
import com.gebauz.pingK.R;
import com.gebauz.pingK.MultitouchInput.Finger;

public class Paddle implements IReflectable
{      
        public static final int PLAYER_1 = 0;
        public static final int PLAYER_2 = 1;
       
        private GameLogic mGameLogic = null;
        private int mPlayerIndex = -1;
       
        private Sprite2D mPaddleSprite;
       
        private float mTargetPositionY = GameConsts.VIRTUAL_SCREEN_HEIGHT / 2.0f;
        private float mLastDeltaTime = 0.0f;
        private float mLastPositionY = mTargetPositionY;
       
        public Paddle(GameLogic gameLogic, int playerIndex)
        {
                mGameLogic = gameLogic;        
                mPlayerIndex = playerIndex;
               
                mGameLogic.addReflectable(this);
        }
       
        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 = mGameLogic.getVirtualPlayFieldHeight() / 2.0f;
                mTargetPositionY = mGameLogic.getVirtualPlayFieldHeight() / 2.0f;
                mLastPositionY = mTargetPositionY;
               
                mPaddleSprite = new Sprite2D();
                mPaddleSprite.init(R.drawable.paddle, x, y, GameConsts.PADDLE_WIDTH, GameConsts.PADDLE_HEIGHT);
                mPaddleSprite.angle = angle;
        }
       
        public void exit()
        {
                mPaddleSprite = null;
        }
       
        public void update(float deltaTime)
        {
                mLastPositionY = mPaddleSprite.y;
                mLastDeltaTime = deltaTime;
               
                // update positions
                if (mPlayerIndex == PLAYER_1)
                {
                        Finger finger = MultitouchInput.getInstance().getTouchPointInside(0, 0, GameConsts.VIRTUAL_SCREEN_WIDTH / 2.0f, GameConsts.VIRTUAL_SCREEN_HEIGHT);
                        if (finger != null)
                        {
                                mTargetPositionY = finger.y;
                        }
                }
                else
                {
                        Finger finger = MultitouchInput.getInstance().getTouchPointInside(GameConsts.VIRTUAL_SCREEN_WIDTH / 2.0f, 0, GameConsts.VIRTUAL_SCREEN_WIDTH, GameConsts.VIRTUAL_SCREEN_HEIGHT);
                        if (finger != null)
                        {
                                mTargetPositionY = finger.y;
                        }
                }
               
                float distanceFromEdgeY = mPaddleSprite.h / 2.0f + GameConsts.PADDLE_DISTANCE_FROM_EDGE_Y;
               
                if (mTargetPositionY < distanceFromEdgeY)
                        mTargetPositionY = distanceFromEdgeY;
                else if (mTargetPositionY > (mGameLogic.getVirtualPlayFieldHeight() - distanceFromEdgeY))
                        mTargetPositionY = (mGameLogic.getVirtualPlayFieldHeight() - 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);
        }
       
        public void render()
        {
                mPaddleSprite.render();
        }
       
        public float getMovementSpeed()
        {
                return (mPaddleSprite.y - mLastPositionY) / mLastDeltaTime;
        }
       
        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);                                  
                                }
                        }
                        else if (mPlayerIndex == PLAYER_2)
                        {
                                paddleX -= offset;
                                if ((ball.getX() >= paddleX) && (ball.getLastX() < paddleX))
                                {
                                        // paddle touched, reflect the ball
                                        ballHitsPaddleFront(ball, deltaTime);
                                }
                        }
                }
               
                // 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);
                        }
                        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);
                        }
                }
               
        }
       
        public void ballHitsPaddleFront(Ball ball, float deltaTime)
        {
                float yDifference = (ball.getY() - mPaddleSprite.y) * GameConsts.PADDLE_HIT_ZONE_DEVIATION;
               
                // TODO: concave handling
                float direction = 0.0f;
                float paddleDirection = 0.0f;
                float invertPlayer2Paddle = 0;
               
                if (mPlayerIndex == PLAYER_1)
                {
                        // left
                        paddleDirection = 270.0f;
                        direction = 90.0f - yDifference;
                        //newX += 6;
                        invertPlayer2Paddle = -1;
                }
                else if (mPlayerIndex == PLAYER_2)
                {
                        // right
                        paddleDirection = 90.0f;
                        direction = 270.0f + yDifference;
                        //newX -= 6;
                        invertPlayer2Paddle = 1;
                }
               
                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);
               
                //Log.v(GameConsts.LOG_TAG, "AngularVelocity = " + ball.getAngularVelocity() + angularSpeed);
        }

}