diff --git a/src/com/annimon/gipgame/Background.java b/src/com/annimon/gipgame/Background.java index afa63cc..90ebc79 100644 --- a/src/com/annimon/gipgame/Background.java +++ b/src/com/annimon/gipgame/Background.java @@ -3,58 +3,49 @@ package com.annimon.gipgame; import android.graphics.Canvas; import android.graphics.Paint; +/** + * Smoothly change background color. + * @author aNNiMON + */ public class Background { - private int yBackground, squareSize; - private BackgroundCreator creator; + private static final int MAX_SPACE_COLOR = 70; + private static final int TICKS_TO_SHIFT_COLOR = 1000; + private static final int COLORS_IN_ARRAY = 2; + private int tickCounter; + private int currentColor; + private int[] colors; public Background() { - yBackground = 0; - squareSize = 20; - creator = new BackgroundCreator(); + tickCounter = 0; + + colors = new int[COLORS_IN_ARRAY]; + for (int i = 0; i < COLORS_IN_ARRAY; i++) { + colors[i] = Util.randomSpaceColor(MAX_SPACE_COLOR); + } + currentColor = colors[0]; } public void draw(Canvas canvas, Paint paint) { - int[][] array = creator.getBackground(); - final int rowWidth = array[0].length; - final int width = canvas.getWidth(); - final int height = canvas.getHeight(); - squareSize = width / rowWidth + 1; - creator.setHeight(height / squareSize + 4); + // Fill screen by bg color. + canvas.drawColor(currentColor); + } + + public void update() { + tickCounter++; - // Fill rectangles. - paint.setStyle(Paint.Style.FILL); - for(int y = -1; y < array.length - 2; y++) { - int[] row = array[2 + y]; - - int top = y * squareSize + yBackground; - if (top > height) break; - - for (int x = 0; x < rowWidth; x++) { - int left = x * squareSize; - int right = left + squareSize; - int bottom = top + squareSize; - - paint.setColor(row[x]); - canvas.drawRect(left, top, right, bottom, paint); - } + currentColor = Util.getSmoothColor(colors[0], colors[1], + (float) tickCounter / TICKS_TO_SHIFT_COLOR); + + // Remove last and add new background color. + if (tickCounter >= TICKS_TO_SHIFT_COLOR) { + tickCounter = 0; + System.arraycopy(colors, 1, colors, 0, COLORS_IN_ARRAY - 1); + colors[COLORS_IN_ARRAY - 1] = Util.randomSpaceColor(MAX_SPACE_COLOR); } } - public void update(int addValue) { - if (addValue > 200) { - // When game is finished, speed up background. - yBackground += 2; - addValue /= 2; - } - yBackground++; - - // Remove last and add new row in background. - if (yBackground >= squareSize) { - creator.updateBackground(addValue); - yBackground = 0; - } - } + } diff --git a/src/com/annimon/gipgame/BackgroundCreator.java b/src/com/annimon/gipgame/BackgroundCreator.java deleted file mode 100644 index 7181ae1..0000000 --- a/src/com/annimon/gipgame/BackgroundCreator.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.annimon.gipgame; - -import java.util.ArrayList; - - -public class BackgroundCreator { - - private static final boolean ANTI_ALIAS = true; - - private static final int WIDTH = 5; - private int height = 12; - - private ArrayList background; - - public BackgroundCreator() { - background = new ArrayList(); - - createBackground(); - } - - public void setHeight(int height) { - this.height = height; - } - - public int[][] getBackground() { - int[][] array = background.toArray(new int[0][]); - if (!ANTI_ALIAS) return array; - - // Smooth background colors. - int[][] antialias = new int[height][WIDTH]; - for(int y = 0; y < height; y++) { - for (int x = 0; x < WIDTH; x++) { - int top = (y > 0) ? array[y - 1][x] : 0; - int bottom = (y < (height - 1)) ? array[y + 1][x] : 0; - int left = (x > 0) ? array[y][x - 1] : 0; - int right = (x < (WIDTH - 1)) ? array[y][x + 1] : 0; - int center = array[y][x]; - - antialias[y][x] = getAntiAliasColor(new int[] {top, bottom, left, right, center}); - } - } - return antialias; - } - - private int getAntiAliasColor(int[] colors) { - int red = 0; - int green = 0; - int blue = 0; - - for (int i = 0; i < 4; i++) { - int color = colors[i]; - red += (color >> 16) & 0xFF; - green += (color >> 8) & 0xFF; - blue += color & 0xFF; - } - - red /= 4; - green /= 4; - blue /= 4; - - red += (colors[4] >> 16) & 0xFF; - green += (colors[4] >> 8) & 0xFF; - blue += colors[4] & 0xFF; - - return 0xFF000000 | (red << 16) | (green << 8) | blue; - } - - public void updateBackground(int addValue) { - background.remove(height - 1); - background.add(0, createRow(addValue)); - } - - - private void createBackground() { - for (int i = 0; i < height; i++) { - background.add(createRow(0)); - } - } - - private int[] createRow(int addValue) { - int[] row = new int[WIDTH]; - for (int i = 0; i < WIDTH; i++) { - row[i] = Util.randomSpaceColor(15 + (addValue / 2)); - } - if (Util.rand(8) == 5) { - // Create star. - int x = Util.rand(WIDTH); - int add = (addValue / 2); - row[x] = Util.randomColor(10 + add, 60 + add); - } - return row; - } -} diff --git a/src/com/annimon/gipgame/GameView.java b/src/com/annimon/gipgame/GameView.java index 7626314..b0b8f73 100644 --- a/src/com/annimon/gipgame/GameView.java +++ b/src/com/annimon/gipgame/GameView.java @@ -9,15 +9,19 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.View; public class GameView extends View implements SensorEventListener, Runnable { + private static final int PLANET_COUNT = 2; private static final int BONUS_COUNT = 10; private Background background; + private Stars stars; private PlayerShip player; + private Planet[] planets; private Bonus[] bonus; private Paint paint; @@ -43,6 +47,11 @@ public class GameView extends View implements SensorEventListener, Runnable { private void initView(Context context) { background = new Background(); player = new PlayerShip(this); + planets = new Planet[PLANET_COUNT]; + /*for (int i = 0; i < PLANET_COUNT; i++) { + planets[i] = new Planet(); + }*/ + bonus = new Bonus[BONUS_COUNT]; for (int i = 0; i < BONUS_COUNT; i++) { bonus[i] = new Bonus(); @@ -60,10 +69,19 @@ public class GameView extends View implements SensorEventListener, Runnable { if (player == null) player = new PlayerShip(this); player.init(getResources().getDisplayMetrics()); - Bonus.initBonusSize(this, getResources().getDisplayMetrics()); + DisplayMetrics metrics = getResources().getDisplayMetrics(); + Planet.initSize(this, metrics); + for (int i = 0; i < PLANET_COUNT; i++) { + planets[i] = new Planet(i); + } + + Bonus.initBonusSize(this, metrics); for (int i = 0; i < BONUS_COUNT; i++) { bonus[i] = new Bonus(); } + + Stars.initSize(this); + stars = new Stars(); } @Override @@ -71,6 +89,10 @@ public class GameView extends View implements SensorEventListener, Runnable { canvas.drawColor(Color.BLACK); background.draw(canvas, paint); + stars.draw(canvas, paint); + for (int i = 0; i < PLANET_COUNT; i++) { + planets[i].draw(canvas, paint); + } player.draw(canvas, paint); if (!player.gameIsFinished()) { for (int i = 0; i < BONUS_COUNT; i++) { @@ -83,7 +105,12 @@ public class GameView extends View implements SensorEventListener, Runnable { } private void update() { - background.update(player.getScore()); + background.update(); + if (stars != null) stars.update(); + for (int i = 0; i < PLANET_COUNT; i++) { + if (planets[i] == null) break; + planets[i].update(); + } if (player.gameIsFinished()) return; diff --git a/src/com/annimon/gipgame/Planet.java b/src/com/annimon/gipgame/Planet.java new file mode 100644 index 0000000..20d74bb --- /dev/null +++ b/src/com/annimon/gipgame/Planet.java @@ -0,0 +1,78 @@ +package com.annimon.gipgame; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RadialGradient; +import android.graphics.Shader.TileMode; +import android.util.DisplayMetrics; +import android.view.View; + +/** + * Planet. + * @author aNNiMON + */ +public class Planet { + + private static int width, height; + private static float dpFactor; + + public static void initSize(View view, DisplayMetrics metrics) { + width = view.getWidth(); + height = view.getHeight(); + + dpFactor = Util.convertDpToPixel(100, metrics) / 100; + } + + private int color1, color2; + private int radius; + private float x, y, dirX, dirY; + + private Bitmap bitmap; + + public Planet(int id) { + initStar(); + if (id != 0) { + y -= height * id; + } + } + + public void draw(Canvas canvas, Paint paint) { + canvas.drawBitmap(bitmap, x, y, paint); + } + + public void update() { + x += dirX; + y += dirY; + + if (y >= height) { + initStar(); + } + } + + private void initStar() { + radius = (int) (Util.rand(5, width / 3) * dpFactor); + x = Util.rand(width); + y = - (radius * 2) - Util.rand(height); + dirX = Util.rand(-0.7f, 0.7f); + dirY = Util.rand(0.4f, 5f); + + color1 = Util.randomColor(120, 255); + color2 = Util.randomColor(0, 50) | (Util.rand(128) << 24); + + makeBitmap(); + } + + private void makeBitmap() { + RadialGradient gradient = new RadialGradient(radius, radius, radius, + color1, color2, TileMode.CLAMP); + Paint paint = new Paint(); + paint.setDither(true); + paint.setShader(gradient); + + bitmap = Bitmap.createBitmap(radius * 2, radius * 2, Config.ARGB_8888); + Canvas c = new Canvas(bitmap); + c.drawCircle(radius, radius, radius, paint); + } +} diff --git a/src/com/annimon/gipgame/Stars.java b/src/com/annimon/gipgame/Stars.java new file mode 100644 index 0000000..2f33820 --- /dev/null +++ b/src/com/annimon/gipgame/Stars.java @@ -0,0 +1,61 @@ +package com.annimon.gipgame; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.view.View; + +/** + * Stars. + * @author aNNiMON + */ +public class Stars { + + private static final int STARS_COUNT = 200; + + private static int width, height; + + public static void initSize(View view) { + width = view.getWidth(); + height = view.getHeight(); + } + + private float[] x, y, dirY; + private int[] color; + + public Stars() { + init(); + } + + public void draw(Canvas canvas, Paint paint) { + for (int i = 0; i < STARS_COUNT; i++) { + paint.setColor(color[i]); + canvas.drawPoint(x[i], y[i], paint); + } + } + + public void update() { + for (int i = 0; i < STARS_COUNT; i++) { + y[i] += dirY[i]; + if (y[i] >= height) { + initStar(i); + } + } + } + + private void init() { + x = new float[STARS_COUNT]; + y = new float[STARS_COUNT]; + dirY = new float[STARS_COUNT]; + color = new int[STARS_COUNT]; + for (int i = 0; i < STARS_COUNT; i++) { + initStar(i); + } + } + + private void initStar(int i) { + x[i] = Util.rand(width); + y[i] = Util.rand(height); + dirY[i] = Util.rand(0.5f, 5f); + color[i] = Util.randomColor(80, 255); + } +} diff --git a/src/com/annimon/gipgame/Util.java b/src/com/annimon/gipgame/Util.java index 7e05a23..2c3f55f 100644 --- a/src/com/annimon/gipgame/Util.java +++ b/src/com/annimon/gipgame/Util.java @@ -40,6 +40,29 @@ public class Util { return 0xFF000000 | (red << 16) | (green << 8) | blue; } + /** + * + * @param color1 + * @param color2 + * @param weight - percent of weight (0..1) + * @return + */ + public static int getSmoothColor(int color1, int color2, float weight) { + int r1 = (color1 >> 16) & 0xFF; + int g1 = (color1 >> 8) & 0xFF; + int b1 = color1 & 0xFF; + + int r2 = (color2 >> 16) & 0xFF; + int g2 = (color2 >> 8) & 0xFF; + int b2 = color2 & 0xFF; + + int red = r1 + (int) ((r2 - r1) * weight); + int green = g1 + (int) ((g2 - g1) * weight); + int blue = b1 + (int) ((b2 - b1) * weight); + + return 0xFF000000 | (red << 16) | (green << 8) | blue; + } + public static float convertDpToPixel(float dp, DisplayMetrics metrics) { float px = dp * (metrics.densityDpi / 160f); return px;