Subversion Repositories AndroidProjects

Rev

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

package com.gebauz.pingK;

import java.util.Vector;

import com.gebauz.pingK.entities.Ball;
import com.gebauz.pingK.entities.BaseEntity;
import com.gebauz.pingK.entities.Paddle;
import com.gebauz.pingK.entities.PlayField;
import com.gebauz.pingK.entities.PowerUp;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;


public class GameMain {
       
        public static final float SCORED_COUNT_DOWN = 2.0f;
       
        public static final float POWERUP_SPAWN_TIME_MINIMUM = 3.0f;
        public static final float POWERUP_SPAWN_TIME_RANGE = 10.0f;
        public static final int POWERUP_MAX_SPAWNED = 4;
       
        public static final int PAUSE_MENU_BUTTON_COUNT = 3;   
        boolean mIsPaused = false;
        GameButton mGameButtons[] = new GameButton[PAUSE_MENU_BUTTON_COUNT];
       
        Resources mResources;
        TextRender mTextRender;
        ScoreDisplay mScoreDisplay;
       
        PlayField mPlayField = null;
        Ball mBall = null;
        Paddle mPaddles[] = new Paddle[2];
        Vector<PowerUp> mPowerUpEntities = new Vector<PowerUp>();
       
        int mWidth = 0;
        int mHeight = 0;
       
        int lastPlayerScored = -1;
        float scoredCountdown = 0.0f;
        boolean wasOwnGoal = false;
       
        int mScores[] = new int[2];
       
        float mVolumeControlStripSize = 32.0f;
       
        PowerUps mPowerUps;
        float mPowerUpCountdown = getNewPowerUpSpawnTime();
       
        WallImpactEffect mWallImpact;
       
        Bitmap offscreenBitmap;
        Canvas offscreenCanvas;
       
        Bitmap blurBitmap;
        Canvas blurCanvas;
        int blurPingPong = 0;
       
        Bitmap mosaicBitmap;
        Canvas mosaicCanvas;
        public static final float MOSAIC_SIZE = 8.0f;
       
        Sounds mSounds;
       
        int soundIds[] = {
                R.raw.paddleimpact,
                R.raw.wallimpact,
                R.raw.score,
                R.raw.newball,
                R.raw.pickup,
                R.raw.powerup_appears,
        };
       
        public void init(Context context, Resources resources, int w, int h) {
                mResources = resources;
                mWidth = w;
                mHeight = h;
               
                mGameButtons[0] = new GameButton(this);
                mGameButtons[0].setArea(40, 60, 50, 200);
                mGameButtons[0].setText("RESTART");
                mGameButtons[0].setTextAlign(75, 90, 90);
                mGameButtons[1] = new GameButton(this);
                mGameButtons[1].setArea(40, 300, 50, 200);
                mGameButtons[1].setText("TO TITLE");
                mGameButtons[1].setTextAlign(75, 320, 90);
                mGameButtons[2] = new GameButton(this);
                mGameButtons[2].setArea(40, 540, 50, 200);
                mGameButtons[2].setText("SOUND OFF");
                mGameButtons[2].setTextAlign(75, 555, 90);
               
                mTextRender = new TextRender(resources);
               
                mScoreDisplay = new ScoreDisplay(resources);
               
                mSounds = new Sounds(soundIds);
                mSounds.init(context);
               
                mPowerUps = new PowerUps();
                mPowerUps.init(resources);
               
                mWallImpact = new WallImpactEffect();
                mWallImpact.init(resources);
       
                mPlayField = new PlayField(this);
                mBall = new Ball(this);
                mPaddles[Paddle.PADDLE_TOP] = new Paddle(this, Paddle.PADDLE_TOP);
                mPaddles[Paddle.PADDLE_BOTTOM] = new Paddle(this, Paddle.PADDLE_BOTTOM);
               
                mPlayField.init();
                mBall.init();
                mPaddles[Paddle.PADDLE_TOP].init();
                mPaddles[Paddle.PADDLE_BOTTOM].init();
               
                lastPlayerScored = 3;
                scoredCountdown = -1.0f;
               
               
                offscreenBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                offscreenCanvas = new Canvas(offscreenBitmap);
               
                blurBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                blurCanvas = new Canvas(blurBitmap);
               
                mosaicBitmap = Bitmap.createBitmap((int)(w/MOSAIC_SIZE), (int)(h/MOSAIC_SIZE), Bitmap.Config.ARGB_8888);
                mosaicCanvas = new Canvas(mosaicBitmap);
               
                resetGame();
        }
       
        public void destroy() {        
                mPlayField.destroy();
                mBall.destroy();
                mPaddles[Paddle.PADDLE_TOP].destroy();
                mPaddles[Paddle.PADDLE_BOTTOM].destroy();
                mSounds.destroy();
                mPowerUpEntities.removeAllElements();
        }
       
        public void resetGame() {
                mPaddles[0].reset();
                mPaddles[1].reset();
                mScores[0] = 0;
                mScores[1] = 0;
                mPowerUps.reset();
                mBall.reset(Ball.DIRECTION_RANDOM);    
                lastPlayerScored = -1;
                scoredCountdown = 0.0f;
                wasOwnGoal = false;
                mPowerUpEntities.removeAllElements();
        }
       
        public void handleInput(GameView.TouchPoint touchPoints[]) {
               
                if (isPaused())
                {
                        handlePausedInput(touchPoints);
                        return;
                }
               
                // find first touch point in upper half
                for (int i = 0; i < touchPoints.length; i++) {
                        if (touchPoints[i].isActive && (touchPoints[i].Y < ((mHeight - mVolumeControlStripSize) / 2))) {
                                mPaddles[Paddle.PADDLE_TOP].handleInput(touchPoints[i].X, touchPoints[i].Y);
                                break;
                        }
                       
                        // reaching last -> no input
                        if (i == touchPoints.length-1)
                                mPaddles[Paddle.PADDLE_TOP].clearInput();
                }
               
                // find first touch point in lower half
                for (int i = 0; i < touchPoints.length; i++) {
                        if (touchPoints[i].isActive && (touchPoints[i].Y > ((mHeight + mVolumeControlStripSize) / 2))) {
                                mPaddles[Paddle.PADDLE_BOTTOM].handleInput(touchPoints[i].X, touchPoints[i].Y);
                                break;
                        }
                       
                        // reaching last -> no input
                        if (i == touchPoints.length-1)
                                mPaddles[Paddle.PADDLE_BOTTOM].clearInput();
                }
               
                // find first touch point in volume control strip
                for (int i = 0; i < touchPoints.length; i++) {
                        if (touchPoints[i].isActive &&
                                (touchPoints[i].Y < ((mHeight + mVolumeControlStripSize) / 2)) &&
                                (touchPoints[i].Y > ((mHeight - mVolumeControlStripSize) / 2))) {
                               
                                // switch sound on/off
                                // TODO:
                               
                                break;
                        }
                }
        }
       
        public void handlePausedInput(GameView.TouchPoint touchPoints[]) {
                // no multitouch here - just take the first touchpoint
                for (int j = 0; j < mGameButtons.length; j++) {
                        GameView.TouchPoint touchPoint = touchPoints[j];
                        if (!touchPoint.isActive)
                                continue;
                        for (int i = 0; i < mGameButtons.length; i++) {
                                if (mGameButtons[i].isInArea((int)touchPoint.X, (int)touchPoint.Y)) {
                                        onGameButtonClick(i);
                                }
                        }
                }
               
                //for (int i = 0; i < touchPoints.length; i++) {
                                               
                //}
        }
       
        public void onGameButtonClick(int whichButton) {
                switch (whichButton) {
                case 0:
                        // restart & unpause
                        resetGame();
                        pauseGame(false);
                        break;
                case 1:
                        // to title
                        break;
                case 2:
                        // sound toggle
                        mSounds.setSoundsOn(!mSounds.isSoundsOn());
                        if (mSounds.isSoundsOn()) {
                                mGameButtons[2].setText("SOUNDS ON");
                        } else {
                                mGameButtons[2].setText("SOUNDS OFF");                         
                        }
                        break;
                }
        }
       
        public void onPressMenu() {
                // pause/unpause game
               
                pauseGame(!isPaused());
        }
       
        public void pauseGame(boolean doPause) {
                mIsPaused = doPause;
        }
       
        public boolean isPaused() {
                return mIsPaused;
        }
       
       
        public void update(float deltaTime) {
               
                if (mIsPaused)
                        return;
               
                if (mPowerUps.getCurrentPowerUp() == PowerUps.POWERUP_HOURGLASS)
                        deltaTime /= 2.0f;
               
                mPowerUps.update(deltaTime);
               
                mPlayField.update(deltaTime);
                mPaddles[Paddle.PADDLE_TOP].update(deltaTime);
                mPaddles[Paddle.PADDLE_BOTTOM].update(deltaTime);
               
                for (int i = 0; i < mPowerUpEntities.size(); i++) {
                        mPowerUpEntities.get(i).update(deltaTime);
                }

                if (lastPlayerScored != -1)     {
                        // play scored text!
                       
                        mScoreDisplay.update(deltaTime);                       
                        scoredCountdown -= deltaTime;
                       
                        if (scoredCountdown < 0.0f) {
                                mBall.reset(lastPlayerScored+1);
                                lastPlayerScored = -1;
                                scoredCountdown = 0.0f;
                                wasOwnGoal = false;
                                playSound(R.raw.newball);
                        }
                       
                        return;        
                }              

                // only update ball if not displaying "scored" text
                mBall.update(deltaTime);
               
                mWallImpact.update(deltaTime);
               
                // check if ball touches a powerup
                for (int i = 0; i < mPowerUpEntities.size(); i++) {
                        PowerUp powerUp = mPowerUpEntities.get(i);
                        float size = mPowerUps.getBubbleIcon().getWidth() / 2.0f + 3.0f;
                        if (((float)Math.abs(mBall.getPosition().x - powerUp.getPosition().x) < 32.0f) &&
                                ((float)Math.abs(mBall.getPosition().y - powerUp.getPosition().y) < 32.0f)) {
                                // activate powerup
                                playSound(R.raw.pickup);
                                // TODO:
                                mPowerUps.activatePowerUp(powerUp.getType());
                                // unspawn
                                mPowerUpEntities.remove(i);
                                // only one at a time
                                break;
                        }
                }
               
                // only continue spawning if not displaying "scored" text
                mPowerUpCountdown -= deltaTime;
                if (mPowerUpCountdown < 0.0f) {
                        // spawn new powerup, but only if there are less than 4 already spawned
                        if (mPowerUpEntities.size() < POWERUP_MAX_SPAWNED) {
                                PowerUp powerUp = PowerUp.spawnPowerUp(this);
                                mPowerUpEntities.add(powerUp);
                        }
                       
                        mPowerUpCountdown = getNewPowerUpSpawnTime();
                }      
        }
       
        public void playerGainsScore(int scoringPlayer, int lastPaddleTouched) {
               
                if (scoringPlayer != lastPaddleTouched)
                {
                        // own goal!
                        wasOwnGoal = true;
                }
               
                lastPlayerScored = scoringPlayer;              
                scoredCountdown = SCORED_COUNT_DOWN;
               
                mScores[lastPlayerScored]++;
               
                playSound(R.raw.score);
               
                // start animation for winning
                mScoreDisplay.startAnimation(wasOwnGoal, SCORED_COUNT_DOWN, scoringPlayer);
        }
       
        public void render(Canvas canvas) {
                Paint paint = new Paint();
                Matrix matrix = new Matrix();
               
                //Paint blackPaint = new Paint();
            //blackPaint.setARGB(255, 0, 0, 0);
               
            //offscreenCanvas.drawRect(0, 0, offscreenCanvas.getWidth(), offscreenCanvas.getHeight(), blackPaint);
               
                if (mPowerUps.getCurrentPowerUp() == PowerUps.POWERUP_HOURGLASS) {
                       
                        Canvas canvas1 = blurCanvas;
                        Canvas canvas2 = offscreenCanvas;
                        Bitmap bitmap1 = blurBitmap;
                        Bitmap bitmap2 = offscreenBitmap;
                       
                        if (blurPingPong == 1) {
                                blurPingPong = 0;
                                canvas1 = offscreenCanvas;
                                canvas2 = blurCanvas;
                                bitmap1 = offscreenBitmap;
                                bitmap2 = blurBitmap;
                        }
                        else {
                                blurPingPong = 1;
                        }
                       
                        // render directly to canvas, and overlay last frame's image
                        doRender(canvas1);
                       
                        int color = Color.argb(64, 64, 64, 64);
                        paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
                        canvas1.drawBitmap(bitmap2, matrix, paint);
                       
                        canvas.drawBitmap(bitmap1, matrix, new Paint());                                               
                } else {
                        offscreenCanvas.drawARGB(255, 0, 0, 0);                
                        doRender(offscreenCanvas);
                       
                        if (mPowerUps.getCurrentPowerUp() == PowerUps.POWERUP_MOSAIC) {
                                matrix.setScale(1.0f/MOSAIC_SIZE, 1.0f/MOSAIC_SIZE);
                       
                                mosaicCanvas.drawBitmap(offscreenBitmap, matrix, paint);
                       
                                matrix.setScale(MOSAIC_SIZE, MOSAIC_SIZE);
                       
                                canvas.drawBitmap(mosaicBitmap, matrix, paint);
                        } else {
                                canvas.drawBitmap(offscreenBitmap, matrix, paint);
                        }
                }
               
        }
               
               
        public void doRender(Canvas canvas) {                          
               
                if (!isPaused()) {
                        mBall.render(canvas);
                        mPaddles[Paddle.PADDLE_TOP].render(canvas);
                        mPaddles[Paddle.PADDLE_BOTTOM].render(canvas);
       
                        for (int i = 0; i < mPowerUpEntities.size(); i++) {
                                mPowerUpEntities.get(i).render(canvas);
                        }
                               
                        mWallImpact.render(canvas);
                }
               
                // play field clips the rest
                mPlayField.render(canvas);
               
                if (!isPaused()) {
               
                        if (lastPlayerScored != -1)     {
        /*              Paint paint = new Paint();
                        paint.setStyle(Paint.Style.FILL);
                        paint.setColor(Color.RED);
                        paint.setTextSize(30.0f);
                        if (wasOwnGoal)
                                canvas.drawText("OWN GOAL!", (canvas.getWidth() - 200.0f) / 2.0f, (canvas.getHeight() - 20.0f) / 2.0f, paint);
                        else
                                canvas.drawText("SCORE!", (canvas.getWidth() - 200.0f) / 2.0f, (canvas.getHeight() - 20.0f) / 2.0f, paint);*/

                                mScoreDisplay.render(canvas);
                        }
                }
               
                mTextRender.setColor(Color.argb(255, 255, 0, 153));
                mTextRender.setRotation(180.0f);
                String score1 = Integer.toString(mScores[Paddle.PADDLE_TOP]);
                while (score1.length() < 4)
                        score1 = "0" + score1;
                mTextRender.drawText(canvas, score1, getWidth() - 10.0f, 40.0f, 2.0f);
               
                mTextRender.setRotation(0.0f);
                String score2 = Integer.toString(mScores[Paddle.PADDLE_BOTTOM]);
                while (score2.length() < 4)
                        score2 = "0" + score2;
                mTextRender.drawText(canvas, score2, 10, getHeight() - 40.0f, 2.0f);
               
                if (isPaused()) {
                        mTextRender.setRotation(90.0f);
                        mTextRender.drawText(canvas, "-GAME PAUSED-", getWidth() - 40, getHeight()/2.0f - 250.0f, 4.0f);
                       
                        for (int i = 0; i < mGameButtons.length; i++) {
                                mGameButtons[i].render(canvas);                        
                        }                              
                }                      
        }
       
        public void setDimensions(int w, int h) {
                mWidth = w;
                mHeight = h;
        }
       
        public Resources getResources() {
                return mResources;
        }
       
        public float getWidth() {
                return mWidth;
        }
       
        public float getHeight() {
                return mHeight;
        }
       
        public Paddle[] getPaddles() {
                return mPaddles;
        }
       
        public TextRender getTextRender() {
                return mTextRender;
        }
       
        public void playSound(int id) {
                mSounds.playSound(id);
        }
       
        public PowerUps getPowerUps() {
                return mPowerUps;
        }
       
        public WallImpactEffect getWallImpactEffect() {
                return mWallImpact;
        }
       
        static public float getNewPowerUpSpawnTime() {
                return (POWERUP_SPAWN_TIME_MINIMUM + (float)Math.random() * POWERUP_SPAWN_TIME_RANGE);
        }
}