From 9daa9af2e9e96b5c4ceb8cd587956d1e93ddb7d3 Mon Sep 17 00:00:00 2001 From: David96 Date: Mon, 4 Jan 2021 19:45:13 +0100 Subject: [PATCH] Add some background color animation depending on level --- GameScreen.java | 43 ++++++++++++++- LinearColorAnimator.java | 115 +++++++++++++++++++++++++++++++++++++++ Rectangle.java | 5 ++ World.java | 18 +++++- build/FlappyTurtle.jar | Bin 14353 -> 16553 bytes 5 files changed, 176 insertions(+), 5 deletions(-) create mode 100644 LinearColorAnimator.java diff --git a/GameScreen.java b/GameScreen.java index 0ca6fe0..570f40a 100644 --- a/GameScreen.java +++ b/GameScreen.java @@ -1,17 +1,24 @@ +import java.awt.Color; import java.util.List; import java.util.ArrayList; -class GameScreen +class GameScreen implements LinearColorAnimator.AnimationListener { + private final static int LEVEL_TIME = 10; + private final List _drawables; private final Bird _bird; private final World _world; + private final LinearColorAnimator _backgroundAnimator; private double _totalTime; private int _try; + private int _level; public GameScreen() { _drawables = new ArrayList(); + _backgroundAnimator = new LinearColorAnimator(Color.BLACK, Color.WHITE, 1, this); + _backgroundAnimator.start(); _bird = new Bird(this); _world = new World(this); _totalTime = 0; @@ -25,10 +32,24 @@ class GameScreen { _bird.update(elapsed); _world.update(elapsed); + _backgroundAnimator.update(elapsed); _totalTime += elapsed; System.out.print("\r" + _try + " - Time survived: " + (int)(_totalTime * 1e-3) + "s, " + "speed: " + (int)_world.getSpeed() + "px/s"); + if (_totalTime / (LEVEL_TIME * 1e3) > _level + 1) + { + ++_level; + // Would be nice to add some more levels with different colors + if (_level == 1) + { + _world.setObstacleColor("grau"); + _backgroundAnimator.setStart(Color.WHITE); + _backgroundAnimator.setEnd(Color.BLACK); + _backgroundAnimator.start(); + } + } + Rectangle birdRect = _bird.getRect(); if (_world.checkCollision(_bird.getRect()) || birdRect.getY() + birdRect.getHeight() > TurtleWelt.HEIGHT @@ -36,16 +57,32 @@ class GameScreen { System.out.print("\n"); ++_try; - _totalTime = 0; + _totalTime = _level = 0; _bird.reset(); _world.reset(); + + // If the background is currently not white, smoothly animate it back + if (_backgroundAnimator.getCurrentColor().getRGB() != Color.WHITE.getRGB()) + { + _backgroundAnimator.setStart(_backgroundAnimator.getCurrentColor()); + _backgroundAnimator.setEnd(Color.WHITE); + _backgroundAnimator.start(); + } } } + public void onAnimationFinished() + { + if (_backgroundAnimator.getEnd().getRGB() == Color.BLACK.getRGB()) + { + _world.setObstacleColor("weiss"); + } + } public void draw(Turtle turtle, double elapsed) { - TurtleWelt.globaleWelt.bildschirmEinfaerben(255, 255, 255); + Color bg = _backgroundAnimator.getCurrentColor(); + TurtleWelt.globaleWelt.bildschirmEinfaerben(bg.getRed(), bg.getGreen(), bg.getBlue()); for (Drawable d : _drawables) { d.draw(turtle, elapsed); diff --git a/LinearColorAnimator.java b/LinearColorAnimator.java new file mode 100644 index 0000000..a7ce786 --- /dev/null +++ b/LinearColorAnimator.java @@ -0,0 +1,115 @@ +import java.awt.Color; + +class LinearColorAnimator +{ + private Color _start, _end; + private final AnimationListener _listener; + private int _duration; + private double _elapsed; + private boolean _started; + private boolean _finished; + + /* + * @param duration Duration in seconds + */ + public LinearColorAnimator(Color start, Color end, int duration, AnimationListener listener) + { + _start = start; + _end = end; + _duration = duration; + _listener = listener; + } + + /* + * @param elapsed Elapsed time since last call in ms + */ + public void update(double elapsed) + { + if (_started) + { + _elapsed += elapsed * 1e-3; + + if (_elapsed > _duration) + { + _started = false; + _finished = true; + if (_listener != null) + { + _listener.onAnimationFinished(); + } + } + } + } + + public void start() + { + _started = true; + _finished = false; + _elapsed = 0; + } + + public void reset() + { + _started = _finished = false; + _elapsed = 0; + } + + public void setStart(Color c) + { + _start = c; + } + + public void setEnd(Color c) + { + _end = c; + } + + public void setDuration(int duration) + { + _duration = duration; + } + + public boolean hasStarted() + { + return _started; + } + + public boolean hasFinished() + { + return _finished; + } + + public Color getStart() + { + return _start; + } + + public Color getEnd() + { + return _end; + } + + public Color getCurrentColor() + { + if (_finished) + { + return _end; + } + if (!_started) + { + return _start; + } + int diffR = _end.getRed() - _start.getRed(); + int diffG = _end.getGreen() - _start.getGreen(); + int diffB = _end.getBlue() - _start.getBlue(); + double elapsedRatio = _elapsed / _duration; + return new Color((int)(_start.getRed() + diffR * elapsedRatio), + (int)(_start.getGreen() + diffG * elapsedRatio), + (int)(_start.getBlue() + diffB * elapsedRatio)); + } + + interface AnimationListener + { + public abstract void onAnimationFinished(); + } +} diff --git a/Rectangle.java b/Rectangle.java index 61bf1e7..df51fd5 100644 --- a/Rectangle.java +++ b/Rectangle.java @@ -86,4 +86,9 @@ class Rectangle implements Drawable { _x = x; _y = y; } + + public void setColor(String c) + { + _color = c; + } } diff --git a/World.java b/World.java index 4c7411c..2318bec 100644 --- a/World.java +++ b/World.java @@ -8,6 +8,7 @@ class World implements Drawable private static final int ACCELERATION = 2; private final ArrayList _obstacles; + private String _obstacleColor; private double _speed; private final Random _random; @@ -22,15 +23,28 @@ class World implements Drawable public void reset() { _obstacles.clear(); + _obstacleColor = "schwarz"; createObstacle(TurtleWelt.WIDTH); _speed = START_SPEED; } + public void setObstacleColor(String c) + { + for (Drawable d : _obstacles) + { + if (d instanceof Rectangle) + { + ((Rectangle)d).setColor(c); + } + } + _obstacleColor = c; + } + private void createObstacle(int x) { int gap = _random.nextInt(TurtleWelt.HEIGHT - 200) + 50; - _obstacles.add(new Rectangle(x, 0, 30, gap, "black", false)); - _obstacles.add(new Rectangle(x, gap + 100, 30, TurtleWelt.HEIGHT, "black", false)); + _obstacles.add(new Rectangle(x, 0, 30, gap, _obstacleColor, false)); + _obstacles.add(new Rectangle(x, gap + 100, 30, TurtleWelt.HEIGHT, _obstacleColor, false)); } public void update(double elapsed) diff --git a/build/FlappyTurtle.jar b/build/FlappyTurtle.jar index 76a3f913282605f4c8abbc1b64989484fd2097b5..1c15ed4ec1264e1eb925fce1a24fd32a48c2d679 100644 GIT binary patch delta 6555 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 URZt)Qo+NyDoFBZhi2t_!A5Uw}+yDRo delta 4368 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