This commit is contained in:
Love 2024-01-11 16:18:34 +01:00
commit 4f72ad85e7
22 changed files with 913 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
.idea/encodings.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

14
.idea/misc.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="temurin-1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

98
pom.xml Normal file
View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.billenius</groupId>
<artifactId>plingpong</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.0.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.billenius.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.billenius.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,7 @@
package com.billenius;
import java.awt.*;
public interface GetDimension {
Dimension get();
}

View File

@ -0,0 +1,32 @@
package com.billenius;
import javax.swing.*;
import java.awt.*;
public class Main extends JFrame {
public Main() throws HeadlessException {
super("Pling Pong!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(new Pong(this));
pack();
setVisible(true);
Timer timer = new Timer(10, e -> {
repaint();
});
timer.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException |
IllegalAccessException ignored) {
}
new Main();
});
}
}

View File

@ -0,0 +1,93 @@
package com.billenius;
import com.billenius.VisibleObjects.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Pong extends PongBackground implements KeyListener, ComponentListener {
private final PlayerPaddle[] playerPaddles = new PlayerPaddle[2];
private final VisibleObject[] visibleObjects;
public Pong(JFrame root) {
setPreferredSize(new Dimension(800, 600));
setFocusable(true);
addKeyListener(this);
addComponentListener(this);
playerPaddles[0] = new PlayerPaddle(Side.LEFT, this::getSize);
playerPaddles[1] = new PlayerPaddle(Side.RIGHT, this::getSize);
Score score = new Score(this::getSize, 5, (playerWon) -> {
String[] choices = new String[]{"Yes", "No"};
deSpawnAll();
int choice = JOptionPane.showOptionDialog(this,
String.format("Player %d won. Do you want to play again?", playerWon + 1),
"Game Finished",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
choices,
choices[1]
);
if (choice == 0)
spawnAll();
else {
root.dispatchEvent(new WindowEvent(root, WindowEvent.WINDOW_CLOSING));
}
});
Ball ball = new Ball(this::getSize, playerPaddles, score);
visibleObjects = new VisibleObject[]{playerPaddles[0], playerPaddles[1], ball, score};
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (VisibleObject visibleObject : visibleObjects)
visibleObject.paint(g2);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
for (PlayerPaddle playerPaddle : playerPaddles)
playerPaddle.startMoving(e.getKeyCode());
}
@Override
public void keyReleased(KeyEvent e) {
for (PlayerPaddle playerPaddle : playerPaddles)
playerPaddle.stopMoving(e.getKeyCode());
}
@Override
public void componentResized(ComponentEvent e) {
spawnAll();
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
private void spawnAll() {
for (VisibleObject visibleObject : visibleObjects)
visibleObject.spawn();
}
private void deSpawnAll() {
for (VisibleObject visibleObject : visibleObjects)
visibleObject.deSpawn();
}
}

View File

@ -0,0 +1,43 @@
package com.billenius;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;
public class PongBackground extends JPanel {
private static final int DASH_LENGTH = 10;
private static final int DASH_SPACE = 10;
private static final Color STRIPES_BACKGROUND = new Color(Color.WHITE.getRed(), Color.WHITE.getGreen(), Color.WHITE.getBlue(), 100);
@NotNull
private RadialGradientPaint getRadialGradientPaint() {
double radius = Math.sqrt(Math.pow(getWidth() / 2d, 2) + Math.pow(getHeight() / 2d, 2));
// Bright in center, dark in corners
return new RadialGradientPaint(
new Point2D.Double(getWidth() / 2d, getHeight() / 2d),
(float) radius,
new float[]{0f, 1f},
new Color[]{Color.BLUE.brighter(), Color.BLUE.darker().darker().darker().darker()}
);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
RadialGradientPaint radialGradientPaint = getRadialGradientPaint();
g2d.setPaint(radialGradientPaint);
g2d.fillRect(0, 0, getWidth(), getHeight());
// Draw the dashed line
g2d.setColor(STRIPES_BACKGROUND);
g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{DASH_LENGTH, DASH_SPACE}, 0));
g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
g2d.dispose();
}
}

View File

@ -0,0 +1,10 @@
package com.billenius;
public class Utils {
public static boolean arrayContains(int[] array, int toCheck){
for (int value : array)
if (value == toCheck)
return true;
return false;
}
}

View File

@ -0,0 +1,5 @@
package com.billenius.Vector2D;
public enum BumpType {
WALL, PADDLE, BOTH;
}

View File

@ -0,0 +1,5 @@
package com.billenius.Vector2D;
public enum PaddleDirection {
UP, NOT_MOVING, DOWN
}

View File

@ -0,0 +1,64 @@
package com.billenius.Vector2D;
import com.billenius.VisibleObjects.Side;
import com.billenius.VisibleObjects.Wall;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.Random;
public class Vector2D {
private static final Random random = new Random();
private static final double HYPOTENUSE = 2;
double x, y;
/**
* Creates a vector and randomizes the angle
*/
public Vector2D() {
double angle = Math.toRadians(random.nextFloat() % 60 - 30);
int sign = random.nextBoolean() ? 1 : -1;
x = Math.cos(angle) * HYPOTENUSE * sign;
y = Math.sin(angle) * HYPOTENUSE * sign;
}
public void bump(@NotNull BumpType bumpType, @Nullable PaddleDirection paddleDirection) {
if (bumpType == BumpType.BOTH) {
x = -x;
y = -y;
} else if (bumpType == BumpType.WALL) {
y = -y;
} else if (bumpType == BumpType.PADDLE) {
x = -x;
double angle = 0;
if (paddleDirection != PaddleDirection.NOT_MOVING) {
double degrees = random.nextDouble() % 5 + 15;
degrees *= paddleDirection == PaddleDirection.UP ? -1 : 1;
angle = Math.toRadians(degrees);
// Adjusting y direction based on the angle
y = Math.sin(angle) * HYPOTENUSE;
}
}
}
/**
* This will modify the Point
*/
public void applyVector(Point point) {
point.x += (int) Math.round(x);
point.y += (int) Math.round(y);
}
public Side horizontalDirection() {
return x > 0 ? Side.RIGHT : Side.LEFT;
}
public Wall verticalDirection() {
return y > 0 ? Wall.DOWN : Wall.UP;
}
}

View File

@ -0,0 +1,118 @@
package com.billenius.VisibleObjects;
import com.billenius.GetDimension;
import com.billenius.Vector2D.BumpType;
import com.billenius.Vector2D.Vector2D;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import static java.util.Objects.nonNull;
public class Ball implements VisibleObject {
private static final int RADIUS = 12;
private static final Color COLOR = Color.WHITE;
Vector2D vector = null;
/** NULL before the ball is spawned */
Point point = null;
GetDimension gameDimension;
PlayerPaddle[] playerPaddles;
Score score;
public Ball(GetDimension gameDimension, PlayerPaddle[] playerPaddles, Score score) {
this.gameDimension = gameDimension;
this.playerPaddles = playerPaddles;
this.score = score;
}
@Override
public void spawn() {
Dimension dimension = gameDimension.get();
point = new Point(dimension.width / 2, dimension.height / 2);
vector = new Vector2D();
}
@Override
public boolean isSpawned() {
return point != null;
}
@Override
public void deSpawn() {
point = null;
vector = null;
}
@Override
public void paint(Graphics2D g2) {
if (!isSpawned())
return;
Side scored = sideScored();
if (nonNull(scored)){
score.incrementPlayerScore(scored.toInt());
spawn();
return;
}
move();
vector.applyVector(point);
Stroke stroke = g2.getStroke();
g2.setStroke(new BasicStroke(0));
g2.setColor(COLOR);
g2.fillOval(point.x, point.y, RADIUS, RADIUS);
g2.setStroke(stroke);
}
private @Nullable Side sideScored() {
Dimension dimension = gameDimension.get();
if (point.x >= dimension.width)
return Side.LEFT;
if (point.x <= 0)
return Side.RIGHT;
return null;
}
public void move() {
Wall wall = collidedWithWall();
PlayerPaddle paddle = collidedWithPaddle(playerPaddles);
if (nonNull(wall) && nonNull(paddle)) vector.bump(BumpType.BOTH, null);
else if (nonNull(wall) && vector.verticalDirection() == wall) {
vector.bump(BumpType.WALL, null);
} else if (nonNull(paddle) && vector.horizontalDirection() == paddle.getSide()) {
vector.bump(BumpType.PADDLE, paddle.getPaddleDirection());
} else vector.applyVector(point);
}
@Nullable PlayerPaddle collidedWithPaddle(PlayerPaddle[] playerPaddles) {
for (PlayerPaddle playerPaddle : playerPaddles) {
int paddleX = playerPaddle.getX();
int paddleY = playerPaddle.getY();
int paddleWidth = playerPaddle.getWidth();
int paddleHeight = playerPaddle.getHeight();
// Check if the ball is within the x and y range of the paddle
if (point.x + RADIUS >= paddleX && point.x - RADIUS <= paddleX + paddleWidth / 2 &&
point.y + RADIUS >= paddleY && point.y - RADIUS <= paddleY + paddleHeight) {
return playerPaddle;
}
}
return null;
}
protected int getHeight() {
return RADIUS;
}
public @Nullable Wall collidedWithWall() {
Dimension dimension = gameDimension.get();
if (point.y <= 0)
return Wall.UP;
if (point.y + getHeight() >= dimension.height)
return Wall.DOWN;
return null;
}
}

View File

@ -0,0 +1,114 @@
package com.billenius.VisibleObjects;
import com.billenius.GetDimension;
import com.billenius.Utils;
import com.billenius.Vector2D.PaddleDirection;
import java.awt.*;
import java.awt.event.KeyEvent;
public class PlayerPaddle implements VisibleObject {
protected static final int height = 80, width = 20;
private static final int MOVE_PER_TICK = 5;
private final int[] upDown;
private final Color color;
private boolean movingDown = false, movingUp = false;
private final GetDimension gameDimension;
private final Side side;
private int y = Integer.MIN_VALUE;
public PlayerPaddle(Side side, GetDimension gameDimension) {
upDown = getUpDown(side);
this.gameDimension = gameDimension;
this.side = side;
color = (side == Side.LEFT ? Color.YELLOW : Color.RED).brighter().brighter();
}
protected int getX() {
if (side == Side.LEFT)
return 0;
return gameDimension.get().width - width;
}
protected int getY() {
return y;
}
private static int[] getUpDown(Side side) {
return side == Side.LEFT ? new int[]{KeyEvent.VK_W, KeyEvent.VK_S} : new int[]{KeyEvent.VK_UP, KeyEvent.VK_DOWN};
}
public void paint(Graphics2D g2) {
if (!isSpawned())
return;
move();
g2.setColor(color);
g2.fillRect(getX(), getY(), width, height);
}
protected int getHeight() {
return height;
}
protected int getWidth() {
return width;
}
private void move() {
// We can't move both up and down. Don't move if we are down
if (movingUp && movingDown)
return;
boolean canMoveDown = getY() + getHeight() < gameDimension.get().getHeight();
boolean canMoveUp = getY() > 0;
if (movingUp && canMoveUp)
y -= MOVE_PER_TICK;
else if (movingDown && canMoveDown)
y += MOVE_PER_TICK;
}
public void startMoving(int keyCode) {
if (!Utils.arrayContains(upDown, keyCode))
return;
if (keyCode == upDown[0])
movingUp = true;
else movingDown = true;
}
public void stopMoving(int keyCode) {
if (!Utils.arrayContains(upDown, keyCode))
return;
movingUp = false;
movingDown = false;
}
protected PaddleDirection getPaddleDirection() {
if (movingUp != movingDown)
return PaddleDirection.NOT_MOVING;
else if (movingUp)
return PaddleDirection.UP;
return PaddleDirection.DOWN;
}
@Override
public void spawn() {
y = gameDimension.get().height / 2 - height / 2;
}
@Override
public boolean isSpawned() {
return getY() != Integer.MIN_VALUE;
}
@Override
public void deSpawn() {
y = Integer.MIN_VALUE;
}
public Side getSide() {
return side;
}
}

View File

@ -0,0 +1,88 @@
package com.billenius.VisibleObjects;
import com.billenius.GetDimension;
import java.awt.*;
import java.util.Arrays;
public class Score implements VisibleObject {
private static final Color COLOR = Color.BLUE.brighter().brighter().brighter();
private final int[] playerScores = new int[]{0, 0};
private final int winningScore;
private final WinAction winAction;
private final GetDimension gameDimension;
private boolean spawned = false;
public Score(GetDimension gameDimension, int winningScore, WinAction winAction) {
this.gameDimension = gameDimension;
this.winAction = winAction;
this.winningScore = winningScore;
}
public void incrementPlayerScore(int player) {
playerScores[player]++;
int playerWon = playerHasWon();
if (playerWon != -1)
winAction.run(playerWon);
}
public int playerHasWon() {
for (int i = 0; i < playerScores.length; i++) {
if (playerScores[i] == winningScore) {
return i;
}
}
return -1;
}
@Override
public void spawn() {
spawned = true;
Arrays.fill(playerScores, 0);
}
@Override
public boolean isSpawned() {
return spawned;
}
@Override
public void deSpawn() {
spawned = false;
}
private static final Color SHADOW_COLOR = Color.GRAY;
private static final Color TEXT_COLOR = Color.WHITE;
private static final int SHADOW_OFFSET = 3;
public void paint(Graphics2D g2) {
if (!isSpawned())
return;
/* We don't want to have the minus anywhere else than the in the middle */
String measure = "0 - 0";
String score = String.format("%d - %d", playerScores[0], playerScores[1]);
g2.setColor(SHADOW_COLOR);
Font font = g2.getFont().deriveFont(Font.BOLD, 42f);
g2.setFont(font);
FontMetrics metrics = g2.getFontMetrics();
int width = metrics.stringWidth(measure);
int height = metrics.getHeight();
int x = gameDimension.get().width / 2 - width / 2;
int y = height - 3;
// Draw shadow
g2.setColor(SHADOW_COLOR);
g2.drawString(score, x + SHADOW_OFFSET, y + SHADOW_OFFSET);
// Create gradient from white to yellow from left to right across the text
GradientPaint gradient = new GradientPaint(
x, y, Color.YELLOW.brighter().brighter(), // start point for gradient (left edge of text)
x + width, y, Color.RED.brighter().brighter()); // end point for gradient (right edge of text)
// Apply gradient and draw text
g2.setPaint(gradient);
g2.drawString(score, x, y);
}
}

View File

@ -0,0 +1,16 @@
package com.billenius.VisibleObjects;
public enum Side {
LEFT(0), RIGHT(1);
private final int value;
Side(int value) {
this.value = value;
}
public int toInt() {
return value;
}
}

View File

@ -0,0 +1,13 @@
package com.billenius.VisibleObjects;
import java.awt.*;
public interface VisibleObject {
void spawn();
boolean isSpawned();
void deSpawn();
void paint(Graphics2D g2);
}

View File

@ -0,0 +1,5 @@
package com.billenius.VisibleObjects;
public enum Wall {
UP, DOWN;
}

View File

@ -0,0 +1,5 @@
package com.billenius.VisibleObjects;
public interface WinAction {
void run(int playerWon);
}