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
);
}
}