Subversion Repositories AndroidProjects

Rev

Rev 87 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
32 chris 1
package com.gebauz.pingK.game;
2
 
69 chris 3
import java.util.Random;
4
 
43 chris 5
import android.util.Log;
6
 
32 chris 7
import com.gebauz.framework.util.GLUtil;
8
import com.gebauz.framework.util.Sprite2D;
43 chris 9
import com.gebauz.pingK.MultitouchInput;
32 chris 10
import com.gebauz.pingK.R;
43 chris 11
import com.gebauz.pingK.MultitouchInput.Finger;
32 chris 12
 
46 chris 13
public class Paddle implements IReflectable
32 chris 14
{      
15
        public static final int PLAYER_1 = 0;
16
        public static final int PLAYER_2 = 1;
17
 
18
        private GameLogic mGameLogic = null;
19
        private int mPlayerIndex = -1;
69 chris 20
        private boolean mIsAI = true;
21
        private float mAITimeOut = 0.0f;
22
        private float mAIRandom = 0.0f;
23
        private float mAIRandomTimer = 0.0f;
32 chris 24
 
25
        private Sprite2D mPaddleSprite;
26
 
48 chris 27
        private float mTargetPositionY = GameConsts.VIRTUAL_SCREEN_HEIGHT / 2.0f;
28
        private float mLastDeltaTime = 0.0f;
29
        private float mLastPositionY = mTargetPositionY;
43 chris 30
 
32 chris 31
        public Paddle(GameLogic gameLogic, int playerIndex)
32
        {
33
                mGameLogic = gameLogic;        
34
                mPlayerIndex = playerIndex;
47 chris 35
 
36
                mGameLogic.addReflectable(this);
32 chris 37
        }
38
 
39
        public void init()
40
        {
41
                float x = 0;
42
                float y = 0;
43
                float angle = 0;
44
 
45
                if (mPlayerIndex == PLAYER_1)
46
                {
47
                        x = GameConsts.PADDLE_DISTANCE_FROM_EDGE_X;
48
                        angle = 180.0f;
49
                }
50
                else
51
                {
52
                        x = GameConsts.VIRTUAL_SCREEN_WIDTH - GameConsts.PADDLE_DISTANCE_FROM_EDGE_X;
53
                }
54
 
61 chris 55
                y = mGameLogic.getVirtualPlayFieldHeight() / 2.0f;
80 chris 56
 
57
                //y = mGameLogic.getVirtualPlayFieldHeight() - 15.0f;
58
 
59
                mTargetPositionY = y;
48 chris 60
                mLastPositionY = mTargetPositionY;
32 chris 61
 
62
                mPaddleSprite = new Sprite2D();
63
                mPaddleSprite.init(R.drawable.paddle, x, y, GameConsts.PADDLE_WIDTH, GameConsts.PADDLE_HEIGHT);
64
                mPaddleSprite.angle = angle;
69 chris 65
 
66
                mAITimeOut = 0.0f;
32 chris 67
        }
68
 
69
        public void exit()
70
        {
71
                mPaddleSprite = null;
72
        }
73
 
45 chris 74
        public void update(float deltaTime)
32 chris 75
        {
49 chris 76
                mLastPositionY = mPaddleSprite.y;
48 chris 77
                mLastDeltaTime = deltaTime;
69 chris 78
                mAITimeOut += deltaTime;
79
                mAIRandomTimer += deltaTime;
48 chris 80
 
81
                // update positions
43 chris 82
                if (mPlayerIndex == PLAYER_1)
83
                {
75 chris 84
                        Finger finger = MultitouchInput.getInstance().getTouchPointInside(0, 0, GameConsts.VIRTUAL_SCREEN_WIDTH / 2.0f, mGameLogic.getVirtualPlayFieldHeight());
43 chris 85
                        if (finger != null)
86
                        {
87
                                mTargetPositionY = finger.y;
69 chris 88
                                mIsAI = false;
89
                                mAITimeOut = 0.0f;
43 chris 90
                        }
91
                }
92
                else
93
                {
74 chris 94
                        Finger finger = MultitouchInput.getInstance().getTouchPointInside(GameConsts.VIRTUAL_SCREEN_WIDTH / 2.0f, 0, GameConsts.VIRTUAL_SCREEN_WIDTH, mGameLogic.getVirtualPlayFieldHeight());
43 chris 95
                        if (finger != null)
96
                        {
97
                                mTargetPositionY = finger.y;
69 chris 98
                                mIsAI = false;
99
                                mAITimeOut = 0.0f;
43 chris 100
                        }
101
                }
102
 
69 chris 103
                if ((!mIsAI) && (mAITimeOut > GameConsts.PADDLE_AI_TIMEOUT))
104
                {
105
                        mIsAI = true;
106
                }
107
 
108
                if (mIsAI)
109
                {
110
                        if (mAIRandomTimer > GameConsts.PADDLE_AI_RANDOM_TIMER)
111
                        {
112
                                mAIRandomTimer = 0.0f;
113
                                mAIRandom = mGameLogic.getRandomizer().nextFloat();
114
                        }
115
 
116
                        // try to reach ball, but only react when ball is inside own territory
117
                        float ballX = mGameLogic.getBall().getX();
118
                        if ( ((mPlayerIndex == PLAYER_1) && (ballX < (GameConsts.VIRTUAL_SCREEN_WIDTH/1.5f))) ||
119
                                 ((mPlayerIndex == PLAYER_2) && (ballX > (GameConsts.VIRTUAL_SCREEN_WIDTH - (GameConsts.VIRTUAL_SCREEN_WIDTH/1.5f)))) )
120
                        {
121
                                float aiTargetY = mGameLogic.getBall().getY() + (-GameConsts.PADDLE_AI_VARIANCE + 2 * mAIRandom * GameConsts.PADDLE_AI_VARIANCE);
122
 
123
                                float diff = aiTargetY - mTargetPositionY;
124
                                mTargetPositionY += (diff * deltaTime * GameConsts.PADDLE_AI_ACCEL);   
125
                        }
126
                        else
127
                        {
128
                                // slowly go to center
129
                                float centerTarget = mGameLogic.getVirtualPlayFieldHeight() / 2.0f + (-GameConsts.PADDLE_AI_VARIANCE2 + 2*mAIRandom * GameConsts.PADDLE_AI_VARIANCE2);                         
130
                                float diff = centerTarget - mTargetPositionY;
131
                                mTargetPositionY += (diff * deltaTime * GameConsts.PADDLE_AI_ACCEL_SLOW);      
132
                        }
133
                }
134
 
48 chris 135
                float distanceFromEdgeY = mPaddleSprite.h / 2.0f + GameConsts.PADDLE_DISTANCE_FROM_EDGE_Y;
44 chris 136
 
48 chris 137
                if (mTargetPositionY < distanceFromEdgeY)
138
                        mTargetPositionY = distanceFromEdgeY;
61 chris 139
                else if (mTargetPositionY > (mGameLogic.getVirtualPlayFieldHeight() - distanceFromEdgeY))
140
                        mTargetPositionY = (mGameLogic.getVirtualPlayFieldHeight() - distanceFromEdgeY);
48 chris 141
 
44 chris 142
                if (mTargetPositionY > mPaddleSprite.y)
143
                {
144
                        float diff = mTargetPositionY - mPaddleSprite.y;
145
                        mPaddleSprite.y += (diff * deltaTime * GameConsts.PADDLE_INPUT_ACCEL);
146
                        if (mPaddleSprite.y > mTargetPositionY)
147
                                mPaddleSprite.y = mTargetPositionY;
148
                }
149
                else if (mTargetPositionY < mPaddleSprite.y)
150
                {
151
                        float diff = mPaddleSprite.y - mTargetPositionY;
152
                        mPaddleSprite.y -= (diff * deltaTime * GameConsts.PADDLE_INPUT_ACCEL);
153
                        if (mPaddleSprite.y < mTargetPositionY)
154
                                mPaddleSprite.y = mTargetPositionY;
155
                }
156
 
45 chris 157
                mPaddleSprite.update(deltaTime);
32 chris 158
        }
159
 
160
        public void render()
161
        {
85 chris 162
                mPaddleSprite.mirrorX = mGameLogic.getPowerUpEffect().isConcaveActive();
32 chris 163
                mPaddleSprite.render();
164
        }
46 chris 165
 
48 chris 166
        public float getMovementSpeed()
167
        {
168
                return (mPaddleSprite.y - mLastPositionY) / mLastDeltaTime;
169
        }
170
 
46 chris 171
        public void reflect(Ball ball, float deltaTime)
172
        {
48 chris 173
                // check collision from the front
174
                if (Math.abs(ball.getY() - mPaddleSprite.y) < ((mPaddleSprite.h+ ball.getHeight())/2.0f))
47 chris 175
                {
48 chris 176
                        float offset = ((mPaddleSprite.w/2.0f)) - GameConsts.PADDLE_HIT_OFFSET;
47 chris 177
                        float paddleX = mPaddleSprite.x;
178
                        // if ball is within Y coordinate space of paddle, check the two positions
179
                        if (mPlayerIndex == PLAYER_1)
180
                        {
48 chris 181
                                paddleX += offset;
47 chris 182
                                if ((ball.getX() <= paddleX) && (ball.getLastX() > paddleX))
183
                                {
184
                                        // paddle touched, reflect the ball
66 chris 185
                                        ballHitsPaddleFront(ball, deltaTime);
186
                                        ball.setLastPaddleTouched(mPlayerIndex);
87 chris 187
                                        if (mGameLogic.getPowerUpEffect().isConcaveActive())
188
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x + GameConsts.PADDLE_IMPACT_CONCAVE_OFFSET, mPaddleSprite.y, 0.0f);
189
                                        else
190
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x, mPaddleSprite.y, 180.0f);
191
 
192
                                        mGameLogic.playSound(R.raw.paddleimpact);
193
 
101 chris 194
                                        mGameLogic.getCrystalHitCounter().resetHits();
195
 
69 chris 196
                                        return;
46 chris 197
                                }
198
                        }
47 chris 199
                        else if (mPlayerIndex == PLAYER_2)
200
                        {
48 chris 201
                                paddleX -= offset;
47 chris 202
                                if ((ball.getX() >= paddleX) && (ball.getLastX() < paddleX))
203
                                {
204
                                        // paddle touched, reflect the ball
48 chris 205
                                        ballHitsPaddleFront(ball, deltaTime);
66 chris 206
                                        ball.setLastPaddleTouched(mPlayerIndex);
87 chris 207
                                        if (mGameLogic.getPowerUpEffect().isConcaveActive())
208
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x - GameConsts.PADDLE_IMPACT_CONCAVE_OFFSET, mPaddleSprite.y, 180.0f);
209
                                        else
210
                                                mGameLogic.getPaddleImpact().addImpact(mPaddleSprite.x, mPaddleSprite.y, 0.0f);
211
 
212
                                        mGameLogic.playSound(R.raw.paddleimpact);
213
 
101 chris 214
                                        mGameLogic.getCrystalHitCounter().resetHits();
215
 
69 chris 216
                                        return;
48 chris 217
                                }
47 chris 218
                        }
219
                }
85 chris 220
 
48 chris 221
                // check collision from below & above
222
                if (Math.abs(ball.getX() - mPaddleSprite.x) < (mPaddleSprite.w/2.0f))
223
                {
224
                        float halfHeight = mPaddleSprite.h/2.0f;
225
                        // for sides, use simple reflection
226
                        if ((ball.getY() >= (mPaddleSprite.y - halfHeight)) && (ball.getLastY() < (mPaddleSprite.y - halfHeight)))                                     
227
                        {
228
                                // above
229
                                ball.reflectAlongNormal(180.0f);
230
                                ball.clampToAngle(GameConsts.BALL_STEEPEST_ANGLE_HIT_PADDLE_SIDE);
66 chris 231
                                ball.setLastPaddleTouched(mPlayerIndex);
87 chris 232
 
233
                                mGameLogic.playSound(R.raw.paddleimpact);
101 chris 234
 
235
                                mGameLogic.getCrystalHitCounter().resetHits();
236
 
237
                                // TODO: impact
48 chris 238
                        }
239
                        else if ((ball.getY() <= (mPaddleSprite.y + halfHeight)) && (ball.getLastY() > (mPaddleSprite.y + halfHeight)))
240
                        {
241
                                // below
242
                                ball.reflectAlongNormal(0.0f);
243
                                ball.clampToAngle(GameConsts.BALL_STEEPEST_ANGLE_HIT_PADDLE_SIDE);
66 chris 244
                                ball.setLastPaddleTouched(mPlayerIndex);
87 chris 245
 
246
                                mGameLogic.playSound(R.raw.paddleimpact);
101 chris 247
 
248
                                mGameLogic.getCrystalHitCounter().resetHits();
249
 
250
                                // TODO: impact
48 chris 251
                        }
85 chris 252
                }
48 chris 253
 
87 chris 254
 
255
                // TODO: clamp ball's coordinates to play field
46 chris 256
        }
47 chris 257
 
48 chris 258
        public void ballHitsPaddleFront(Ball ball, float deltaTime)
47 chris 259
        {
85 chris 260
                float newX = mPaddleSprite.x;
49 chris 261
                float yDifference = (ball.getY() - mPaddleSprite.y) * GameConsts.PADDLE_HIT_ZONE_DEVIATION;
47 chris 262
 
85 chris 263
                if (mGameLogic.getPowerUpEffect().isConcaveActive())
264
                        yDifference = -yDifference;
265
 
47 chris 266
                // TODO: concave handling
267
                float direction = 0.0f;
268
                float paddleDirection = 0.0f;
48 chris 269
                float invertPlayer2Paddle = 0;
47 chris 270
 
271
                if (mPlayerIndex == PLAYER_1)
272
                {
273
                        // left
274
                        paddleDirection = 270.0f;
275
                        direction = 90.0f - yDifference;
85 chris 276
                        newX += mPaddleSprite.w/3.0f;
277
 
49 chris 278
                        invertPlayer2Paddle = -1;
47 chris 279
                }
280
                else if (mPlayerIndex == PLAYER_2)
281
                {
282
                        // right
283
                        paddleDirection = 90.0f;
284
                        direction = 270.0f + yDifference;
85 chris 285
                        newX -= mPaddleSprite.w/3.0f;
49 chris 286
                        invertPlayer2Paddle = 1;
47 chris 287
                }
288
 
85 chris 289
                ball.setX(newX);               
47 chris 290
                ball.reflectAlongNormal(direction);
291
 
85 chris 292
                float angularSpeed = getMovementSpeed() * GameConsts.BALL_TOP_SPIN_INTENSITY * invertPlayer2Paddle;            
48 chris 293
                ball.setAngularVelocity(ball.getAngularVelocity() + angularSpeed);
85 chris 294
                ball.clampToAngle(GameConsts.BALL_STEEPEST_ANGLE_HIT_PADDLE_FRONT);            
49 chris 295
 
85 chris 296
                /*
297
 
298
  if (paddle.paddle.belongtoplayer = 1) then
299
  begin
300
    paddledirection := 0;
301
    direction:= 90 - ydifference;
302
    newx := newx + 6;
303
    invertplayer2paddle := 1;
304
  end else
305
  begin
306
    paddledirection := 180;
307
    direction:= 270 + ydifference;
308
    newx := newx - 6;
309
    invertplayer2paddle := -1;
310
  end;
311
 
312
  ball.lasthitplayer:=paddle.paddle.belongtoplayer;
313
  settings.pos.x := newx;
314
  reflectAlongNormal(direction);
315
 
316
  generateImpact(paddle.settings.pos,paddledirection, SX_EIMPACT_MODE_PADDLE);
317
 
318
  angularspeed := paddle.getMovementSpeed * getTopSpinIntensity * invertplayer2paddle;
319
  setAngularVelocity(ball.angularspeed + angularspeed);
320
  clampToAngle(getBallSteepestAngleHitPaddle);
321
                 */
322
 
49 chris 323
                //Log.v(GameConsts.LOG_TAG, "AngularVelocity = " + ball.getAngularVelocity() + angularSpeed);
47 chris 324
        }
325
 
32 chris 326
}