mirror of
https://codeberg.org/boyfailure/VectorBreakout.git
synced 2025-06-07 07:05:04 +10:00
Refactor Part 2: Lots of renaming, new classes, hitbox changes
This commit is contained in:
parent
475af2c03e
commit
98883aa62a
21 changed files with 1549 additions and 790 deletions
18
nb-configuration.xml
Normal file
18
nb-configuration.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<netbeans.hint.license>apache20</netbeans.hint.license>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
8
pom.xml
8
pom.xml
|
@ -4,9 +4,9 @@
|
|||
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>dev.boyfailure.quajra</groupId>
|
||||
<groupId>dev.boyfailure</groupId>
|
||||
<artifactId>VectorBreakout</artifactId>
|
||||
<version>20250411_test1</version>
|
||||
<version>1.0</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<exec.mainClass>dev.boyfailure.quajra.vectorbreakout.VectorBreakout</exec.mainClass>
|
||||
<exec.mainClass>dev.boyfailure.vectorbreakout.VectorBreakout</exec.mainClass>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
@ -30,7 +30,7 @@
|
|||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>dev.boyfailure.quajra.vectorbreakout.VectorBreakout</mainClass>
|
||||
<mainClass>dev.boyfailure.vectorbreakout.VectorBreakout</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
|
|
|
@ -1,235 +0,0 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Ball {
|
||||
|
||||
short ballX = 250;
|
||||
short ballY = 300;
|
||||
short ballWidth = 7;
|
||||
short ballHeight = 7;
|
||||
private boolean isActive = false;
|
||||
private boolean isInvincible = false;
|
||||
byte ballColor = 0;
|
||||
Hitbox hitBox;
|
||||
|
||||
byte speedX = 5;
|
||||
byte speedY = 5;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
public Ball(GameState gameState, int x, int y, int width, int height, int color, boolean active) {
|
||||
this.gameState = gameState;
|
||||
this.ballX = (short) x;
|
||||
this.ballY = (short) y;
|
||||
this.ballWidth = (short) width;
|
||||
this.ballHeight = (short) height;
|
||||
this.ballColor = (byte) color;
|
||||
this.hitBox = new Hitbox(x, y, width, height, 1);
|
||||
this.isActive = active;
|
||||
}
|
||||
|
||||
public void spawnBall(boolean useChancey) {
|
||||
if (useChancey) {
|
||||
this.ballX += (short) (gameState.getChancey() * 3);
|
||||
this.ballY += (short) gameState.getChancey();
|
||||
}
|
||||
gameState.ballsOnScreen++;
|
||||
this.isActive = true;
|
||||
gameState.lives--;
|
||||
gameState.textElementList.get(4).setText(String.valueOf(gameState.lives));
|
||||
}
|
||||
|
||||
public void spawnBall(int x, int y) {
|
||||
this.ballX = (short) x;
|
||||
this.ballY = (short) y;
|
||||
gameState.ballsOnScreen++;
|
||||
this.isActive = true;
|
||||
gameState.lives--;
|
||||
gameState.textElementList.get(4).setText(String.valueOf(gameState.lives));
|
||||
}
|
||||
|
||||
public void moveBall() {
|
||||
this.ballX += this.speedX;
|
||||
this.ballY += this.speedY;
|
||||
|
||||
this.hitBox.moveTo(this.ballX, this.ballY, this.ballWidth, this.ballHeight);
|
||||
|
||||
this.checkCollision();
|
||||
}
|
||||
|
||||
public void bounce(int bounceType) {
|
||||
switch((byte) bounceType) {
|
||||
case 0:
|
||||
this.speedY = (byte) -(this.speedY);
|
||||
switch (gameState.getChancey()) {
|
||||
case 0: break;
|
||||
case 1: this.speedX++; break;
|
||||
case 2: break;
|
||||
case 3: this.speedX--; break;
|
||||
case 4: break;
|
||||
case 5: this.speedY++;break;
|
||||
case 6: break;
|
||||
case 7: this.speedY--;break;
|
||||
case 8: break;
|
||||
case 9: this.speedY++;speedX++;break;
|
||||
case 10: break;
|
||||
case 11: this.speedY--;speedX--;break;
|
||||
case 12: break;
|
||||
case 13: this.speedY++;speedY++;break;
|
||||
case 14: break;
|
||||
case 15: this.speedY--;speedY--;break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this.speedX = (byte) -(this.speedX);
|
||||
break;
|
||||
case 2:
|
||||
if (this.speedX > 0) {
|
||||
this.speedX = (byte) -(this.speedX);
|
||||
}
|
||||
else {
|
||||
this.speedX -= 4;
|
||||
}
|
||||
this.speedY = (byte) -(this.speedY);
|
||||
break;
|
||||
case 3:
|
||||
if (this.speedX < 0) {
|
||||
this.speedX = (byte) -(this.speedX);
|
||||
}
|
||||
else {
|
||||
this.speedX += 4;
|
||||
}
|
||||
this.speedY = (byte) -(this.speedY);
|
||||
break;
|
||||
}
|
||||
if (this.speedX < 2 && this.speedX >= 0) {this.speedX = 2;}
|
||||
else if (this.speedX > -2 && this.speedX < 0) {this.speedX = -2;}
|
||||
else if (this.speedX > 11) {this.speedX -= 3;} // Slow down if too fast
|
||||
if (this.speedY < 4 && this.speedY >= 0) {this.speedY = 4;}
|
||||
else if (this.speedY > -4 && this.speedY < 0) {this.speedY = -4;}
|
||||
else if (this.speedY > 11) {this.speedY -= 3;} // Slow down if too fast
|
||||
}
|
||||
|
||||
public void destroyBall() {
|
||||
this.isActive = false;
|
||||
this.ballX = 32767;
|
||||
this.ballY = 32767;
|
||||
gameState.ballsOnScreen--;
|
||||
if (gameState.ballsOnScreen <= 0) {
|
||||
gameState.ballsOnScreen = 0;
|
||||
if (gameState.lives <= 0) {
|
||||
gameState.gameLose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks to see if the ball is in contact with bricks, paddles, or walls
|
||||
public void checkCollision() {
|
||||
|
||||
this.setInvincibilityState(true); // Delay bouncing again for a frame
|
||||
|
||||
// Check floor
|
||||
if (this.ballY >= gameState.getInternalResY()) {
|
||||
this.destroyBall();
|
||||
return;
|
||||
}
|
||||
// Check ceiling
|
||||
else if (this.ballY <= 0) {
|
||||
this.bounce(0);
|
||||
this.ballY = 0;
|
||||
this.wallBounceAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check walls
|
||||
if (this.ballX <= 20) {
|
||||
this.bounce(1);
|
||||
this.ballX = 22;
|
||||
this.wallBounceAnimation();
|
||||
return;
|
||||
}
|
||||
else if ((this.ballX + this.ballWidth) >= (gameState.getInternalResX() - 20 - this.ballWidth)) {
|
||||
this.bounce((byte) 1);
|
||||
this.ballX = (short) (gameState.getInternalResX() - 25 - this.ballWidth);
|
||||
this.wallBounceAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check bricks
|
||||
if (gameState.currentLevel != null) {
|
||||
if (gameState.currentLevel.brickList != null) {
|
||||
for (Brick brick : gameState.currentLevel.brickList) {
|
||||
if (this.hitBox.collides(brick.hitBox.getBounds())) {
|
||||
brick.breakBrick();
|
||||
this.bounce(0);
|
||||
gameState.brickCollector.add(brick);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check paddles
|
||||
for (Paddle paddle : gameState.paddleList) {
|
||||
if (this.hitBox.collides(paddle.hitBox.getBounds())) {
|
||||
if (this.hitBox.collides(paddle.hitBoxLeft.getBounds())) {
|
||||
this.bounce(2);
|
||||
}
|
||||
else if (this.hitBox.collides(paddle.hitBoxRight.getBounds())) {
|
||||
this.bounce(3);
|
||||
}
|
||||
else {
|
||||
this.bounce(0);
|
||||
}
|
||||
|
||||
this.ballY -= 2;
|
||||
|
||||
// Draw particles
|
||||
Particle particle1, particle2, particle3;
|
||||
particle1 = new Particle(gameState, 0, this.ballX, this.ballY - 10, 0, -2, 1, 2, 7, 3);
|
||||
particle2 = new Particle(gameState, 0, this.ballX - 3, this.ballY - 10, -2, -4, 1, 2, 6, 3);
|
||||
particle3 = new Particle(gameState, 0, this.ballX + 10, this.ballY - 10, 2, -4, 1, 2, 8, 3);
|
||||
gameState.particleList.add(particle1);
|
||||
gameState.particleList.add(particle2);
|
||||
gameState.particleList.add(particle3);
|
||||
particle1.spawn(5);
|
||||
particle2.spawn(5);
|
||||
particle3.spawn(5);
|
||||
|
||||
return; // Prevents bouncing multiple times
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void wallBounceAnimation() {
|
||||
Particle particle1, particle2, particle3, particle4;
|
||||
particle1 = new Particle(gameState, 0, this.ballX - 3, this.ballY - 10, -2, -2, 1, 2, 6, 3);
|
||||
particle2 = new Particle(gameState, 0, this.ballX + 10, this.ballY - 10, 2, -2, 1, 2, 8, 3);
|
||||
particle3 = new Particle(gameState, 0, this.ballX - 3, this.ballY + 3, 2, 2, 1, 2, 2, 3);
|
||||
particle4 = new Particle(gameState, 0, this.ballX + 10, this.ballY + 3, -2, 2, 1, 2, 4, 3);
|
||||
gameState.particleList.add(particle1);
|
||||
gameState.particleList.add(particle2);
|
||||
gameState.particleList.add(particle3);
|
||||
gameState.particleList.add(particle4);
|
||||
particle1.spawn(5);
|
||||
particle2.spawn(5);
|
||||
particle3.spawn(5);
|
||||
particle4.spawn(5);
|
||||
}
|
||||
|
||||
public boolean getActiveState() {
|
||||
return this.isActive;
|
||||
}
|
||||
public void setActiveState(boolean activeState) {
|
||||
this.isActive = activeState;
|
||||
}
|
||||
|
||||
public boolean getInvincibilityState() {
|
||||
return this.isInvincible;
|
||||
}
|
||||
public void setInvincibilityState(boolean invincibilityState) {
|
||||
this.isInvincible = invincibilityState;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
|
||||
public class Brick {
|
||||
|
||||
short brickX;
|
||||
short brickY;
|
||||
short brickWidth = 40;
|
||||
short brickHeight = 17;
|
||||
private boolean isBroken = false;
|
||||
byte brickColor = 0;
|
||||
byte scoreOnBreak = 10;
|
||||
byte specialAbility = 0;
|
||||
Hitbox hitBox;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
/**
|
||||
* Bricks.
|
||||
* @param gameState The GameState in which the Brick will reside.
|
||||
* @param x The x coordinate of the Brick.
|
||||
* @param y The y coordinate of the Brick.
|
||||
* @param isBroken Determines whether the Brick is broken.
|
||||
* @param brickColor The color code of the Brick.
|
||||
* @param score The score the Player earns upon breaking the Brick.
|
||||
* @param specialAbility A special event that occurs upon breaking the Brick.
|
||||
*/
|
||||
public Brick(GameState gameState, int x, int y, boolean isBroken, int brickColor, int score, int specialAbility) {
|
||||
this.gameState = gameState;
|
||||
this.brickX = (short) x;
|
||||
this.brickY = (short) y;
|
||||
this.isBroken = isBroken;
|
||||
this.brickColor = (byte) brickColor;
|
||||
this.scoreOnBreak = (byte) score;
|
||||
this.hitBox = new Hitbox(x, y, this.brickWidth, this.brickHeight, 0);
|
||||
this.specialAbility = (byte) specialAbility;
|
||||
}
|
||||
|
||||
public void breakBrick() {
|
||||
if (!isBroken) {
|
||||
isBroken = true;
|
||||
gameState.score += this.scoreOnBreak + (gameState.level - 1);
|
||||
gameState.textElementList.get(3).setText(String.valueOf(gameState.score));
|
||||
gameState.bricksOnScreen--;
|
||||
switch(this.specialAbility) {
|
||||
case 1:
|
||||
gameState.lives++;
|
||||
break;
|
||||
case 2:
|
||||
Ball ball = new Ball(gameState, 300, 300, 7, 7, 0, true);
|
||||
ball.spawnBall((this.brickX + (this.brickWidth / 2)), (this.brickY + (this.brickHeight / 2)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw particles
|
||||
Particle particle1, particle2, particle3;
|
||||
particle1 = new Particle(gameState, 0, this.brickX + 12, this.brickY + 3, 1, 1, this.brickColor, 2, 4, 1);
|
||||
particle2 = new Particle(gameState, 0, this.brickX + 20, this.brickY + 13, 1, 1, this.brickColor, 2, 3, 1);
|
||||
particle3 = new Particle(gameState, 0, this.brickX + 32, this.brickY + 7, 1, 1, this.brickColor, 2, 2, 1);
|
||||
gameState.particleList.add(particle1);
|
||||
gameState.particleList.add(particle2);
|
||||
gameState.particleList.add(particle3);
|
||||
particle1.spawn(5);
|
||||
particle2.spawn(5);
|
||||
particle3.spawn(5);
|
||||
|
||||
this.brickX = 32767;
|
||||
this.brickY = 32767;
|
||||
this.hitBox.moveTo(32760, 32760, 2, 2);
|
||||
}
|
||||
|
||||
public boolean getBrokenState() {
|
||||
return this.isBroken;
|
||||
}
|
||||
public void setBrokenState(boolean brokenState) {
|
||||
this.isBroken = brokenState;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
|
||||
public class Paddle {
|
||||
|
||||
short paddleX;
|
||||
short paddleY;
|
||||
short paddleWidth = 100;
|
||||
short paddleHeight = 7;
|
||||
byte paddleColor;
|
||||
byte paddleSpeed = 0;
|
||||
boolean isActive = true;
|
||||
float speedMultiplier = 1;
|
||||
Hitbox hitBox;
|
||||
Hitbox hitBoxLeft;
|
||||
Hitbox hitBoxRight;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
public Paddle(GameState gameState, int x, int y, int width, int height, int paddleColor) {
|
||||
this.gameState = gameState;
|
||||
this.paddleX = (short) x;
|
||||
this.paddleY = (short) y;
|
||||
this.paddleWidth = (short) width;
|
||||
this.paddleHeight = (short) height;
|
||||
this.paddleColor = (byte) paddleColor;
|
||||
this.hitBox = new Hitbox(x, y, width, height, 4);
|
||||
this.hitBoxLeft = new Hitbox(x, y, width / 5, height, 4);
|
||||
this.hitBoxRight = new Hitbox(x + ((width / 5) * 4), y, width / 5, height, 4);
|
||||
}
|
||||
|
||||
public void movePaddle(boolean direction) {
|
||||
if (this.paddleSpeed <= 15) {this.paddleSpeed += 3;}
|
||||
if (direction) {this.paddleX += (this.paddleSpeed * this.speedMultiplier);}
|
||||
else {this.paddleX -= (this.paddleSpeed * this.speedMultiplier);}
|
||||
if (this.paddleX <= 20) {this.paddleX = 20;}
|
||||
else if (this.paddleX >= (gameState.getInternalResX() - this.paddleWidth - 20)) {this.paddleX = (short) (gameState.getInternalResX() - this.paddleWidth - 20);}
|
||||
|
||||
this.hitBox.moveTo(this.paddleX, this.paddleY, this.paddleWidth, this.paddleHeight);
|
||||
this.hitBoxLeft.moveTo(this.paddleX, this.paddleY, this.paddleWidth / 5, this.paddleHeight);
|
||||
this.hitBoxRight.moveTo(this.paddleX + ((this.paddleWidth / 5) * 4), this.paddleY, this.paddleWidth / 5, this.paddleHeight);
|
||||
}
|
||||
|
||||
public void cullPaddle() {
|
||||
isActive = false;
|
||||
this.paddleX = 32767;
|
||||
this.paddleY = 32767;
|
||||
}
|
||||
|
||||
public boolean getActiveState() {
|
||||
return this.isActive;
|
||||
}
|
||||
public void setActiveState(boolean activeState) {
|
||||
this.isActive = activeState;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class TextElement {
|
||||
|
||||
String text;
|
||||
boolean active = true;
|
||||
private boolean isVisible = false;
|
||||
float textScale = 1;
|
||||
float vectorScale = 1;
|
||||
byte textColor;
|
||||
short x;
|
||||
short y;
|
||||
short duration = 0;
|
||||
long creationTime;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
/**
|
||||
* Text elements.
|
||||
* @param gameState The GameState in which the TextElement will reside.
|
||||
* @param text The text that will be displayed.
|
||||
* @param textScale The size of the text on screen.
|
||||
* @param x The x coordinate of the text's origin point.
|
||||
* @param y The y coordinate of the text's origin point.
|
||||
* @param textColor The color of the text.
|
||||
* @param vectorScale The scale of the text.
|
||||
*/
|
||||
public TextElement(GameState gameState, String text, float textScale, int x, int y, int textColor, float vectorScale) {
|
||||
this.gameState = gameState;
|
||||
this.text = text;
|
||||
this.textScale = textScale;
|
||||
this.x = (short) x;
|
||||
this.y = (short) y;
|
||||
this.textColor = (byte) textColor;
|
||||
this.vectorScale = vectorScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text elements with a fadeout timer.
|
||||
* @param gameState The GameState in which the TextElement will reside.
|
||||
* @param text The text that will be displayed.
|
||||
* @param textScale The size of the text on screen.
|
||||
* @param x The x coordinate of the text's origin point.
|
||||
* @param y The y coordinate of the text's origin point.
|
||||
* @param textColor The color of the text.
|
||||
* @param vectorScale The scale of the text.
|
||||
* @param duration How long the text will stay on screen, in milliseconds.
|
||||
*/
|
||||
public TextElement(GameState gameState, String text, float textScale, int x, int y, int textColor, float vectorScale, int duration) {
|
||||
this.gameState = gameState;
|
||||
this.text = text;
|
||||
this.textScale = textScale;
|
||||
this.x = (short) x;
|
||||
this.y = (short) y;
|
||||
this.textColor = (byte) textColor;
|
||||
this.vectorScale = vectorScale;
|
||||
this.duration = (short) duration;
|
||||
this.creationTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean getActiveState() {
|
||||
return this.active;
|
||||
}
|
||||
/**
|
||||
* Prepares the TextElement for rendering.
|
||||
*/
|
||||
public void activateTimer() {
|
||||
this.active = true;
|
||||
long testLong = this.creationTime;
|
||||
if (this.duration > 0) {
|
||||
Timer levelTitleGTFO = new Timer();
|
||||
levelTitleGTFO.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
TextElement.this.setVisibility(false);
|
||||
}
|
||||
}, this.duration);
|
||||
}
|
||||
this.setVisibility(true);
|
||||
}
|
||||
|
||||
public boolean getVisibility() {
|
||||
return this.isVisible;
|
||||
}
|
||||
public void setVisibility(boolean visibility) {
|
||||
this.isVisible = visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the TextElement for culling.
|
||||
*/
|
||||
public void cull() {
|
||||
this.active = false;
|
||||
this.x = 32767;
|
||||
this.y = 32767;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text that the TextElement will display.
|
||||
* @param text The text that the TextElement will display.
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text that the TextElement will display.
|
||||
* @param x The x coordinate of the text's origin point.
|
||||
* @param y The y coordinate of the text's origin point.
|
||||
*/
|
||||
public void moveTo(int x, int y) {
|
||||
this.x = (short) x;
|
||||
this.y = (short) y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the color of the text.
|
||||
* @param textColor The color code of the text.
|
||||
*/
|
||||
public void setColor(int textColor) {
|
||||
this.textColor = (byte) textColor;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.Timer;
|
||||
|
||||
public class VectorBreakout {
|
||||
|
||||
// The embeddable game
|
||||
public static GameState gameState = new GameState();
|
||||
|
||||
// The window for the game
|
||||
public static JFrame gameFrame = new JFrame();
|
||||
public static GameDisplay gameCanvas = new GameDisplay(gameState);
|
||||
|
||||
public VectorBreakout() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Enable OpenGL for hardware acceleration
|
||||
System.setProperty("sun.java2d.opengl", "true");
|
||||
|
||||
// Set the game window's properties
|
||||
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
gameFrame.setTitle(gameState.gameName);
|
||||
gameFrame.setSize(gameState.getInternalResX(), gameState.getInternalResY());
|
||||
gameFrame.getContentPane().setBackground(Color.black);
|
||||
gameFrame.getContentPane().add(gameCanvas);
|
||||
gameFrame.setVisible(true);
|
||||
|
||||
gameFrame.addKeyListener(gameState.getKeyListener());
|
||||
|
||||
// Adapts vector drawing scale when the window is resized
|
||||
gameFrame.addComponentListener(new ComponentAdapter() {
|
||||
public void componentResized(ComponentEvent componentEvent) {
|
||||
gameState.setWindowResX((short) gameFrame.getBounds().width);
|
||||
gameState.setWindowResY((short) gameFrame.getBounds().height);
|
||||
gameCanvas.setBeamScaleX(gameState.getWindowResX() / 800f);
|
||||
gameCanvas.setBeamScaleY(gameState.getWindowResY() / 600f);
|
||||
}
|
||||
});
|
||||
|
||||
Timer gameTick = new Timer((1000 / gameState.getGameTickRate()), gameState.getGameTickActionListener());
|
||||
gameTick.start();
|
||||
|
||||
Timer frameDisplay = new Timer((1000 / gameState.getTargetFrameRate()), new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
gameState.incrementFrameCounter();
|
||||
gameFrame.repaint();
|
||||
}
|
||||
});
|
||||
frameDisplay.start();
|
||||
|
||||
Timer gameCuller = new Timer(1000, gameState.getGameStateUpdateActionListener());
|
||||
gameCuller.start();
|
||||
|
||||
}
|
||||
|
||||
}
|
283
src/main/java/dev/boyfailure/vectorbreakout/Ball.java
Normal file
283
src/main/java/dev/boyfailure/vectorbreakout/Ball.java
Normal file
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
/**
|
||||
* The balls that move around the playfield and hit bricks.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250323
|
||||
*/
|
||||
public class Ball extends Entity {
|
||||
|
||||
private boolean isActive = false;
|
||||
private boolean isInvincible = false;
|
||||
byte ballColor = 0;
|
||||
|
||||
byte speedX = 5;
|
||||
byte speedY = 5;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
public Ball(GameState gameState, int x, int y, int width, int height, int color, boolean active) {
|
||||
this.gameState = gameState;
|
||||
this.posX = (short) x;
|
||||
this.posY = (short) y;
|
||||
this.width = (short) width;
|
||||
this.height = (short) height;
|
||||
this.ballColor = (byte) color;
|
||||
this.hitBox = new Hitbox(x, y, width, height, 1);
|
||||
this.isActive = active;
|
||||
}
|
||||
|
||||
public void spawnBall(boolean useLFSR) {
|
||||
if (useLFSR) {this.spawnBall(((gameState.getPokey().getDecimalValue() / 2) + gameState.getPokey().getShiftedDecimalValue() + 30), (this.posY + (gameState.getPokey().getDecimalValue() / 4)) - 40);}
|
||||
else {this.spawnBall(this.posX, this.posY);}
|
||||
}
|
||||
|
||||
public void spawnBall(int x, int y) {
|
||||
this.posX = (short) x;
|
||||
this.posY = (short) y;
|
||||
this.isActive = true;
|
||||
if (gameState.getBalls().size() <= 1) {
|
||||
gameState.removeLife();
|
||||
gameState.getTextElements().get(4).setText(String.valueOf(gameState.getLives()));
|
||||
}
|
||||
}
|
||||
|
||||
public void moveBall() {
|
||||
this.posX += this.speedX;
|
||||
this.posY += this.speedY;
|
||||
|
||||
this.hitBox.moveTo(this.posX, this.posY, this.width, this.height);
|
||||
|
||||
this.checkCollision();
|
||||
}
|
||||
|
||||
/**
|
||||
* Richochets the ball.
|
||||
* @param bounceType The code for which direction the ball bounces
|
||||
*/
|
||||
public void bounce(int bounceType) {
|
||||
switch((byte) bounceType) {
|
||||
case 0:
|
||||
this.speedY = (byte) -(this.speedY);
|
||||
byte randByte = (byte) (gameState.getPokey().getDecimalValue() / 16);
|
||||
if (randByte < 0) {randByte = 0;}
|
||||
else if (randByte > 15) {randByte = 15;}
|
||||
switch (randByte) {
|
||||
case 0: break;
|
||||
case 1: this.speedX++; break;
|
||||
case 2: break;
|
||||
case 3: this.speedX--; break;
|
||||
case 4: break;
|
||||
case 5: this.speedY++;break;
|
||||
case 6: break;
|
||||
case 7: this.speedY--;break;
|
||||
case 8: break;
|
||||
case 9: this.speedY++;speedX++;break;
|
||||
case 10: break;
|
||||
case 11: this.speedY--;speedX--;break;
|
||||
case 12: break;
|
||||
case 13: this.speedY++;speedY++;break;
|
||||
case 14: break;
|
||||
case 15: this.speedY--;speedY--;break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this.speedX = (byte) -(this.speedX);
|
||||
break;
|
||||
case 2:
|
||||
if (this.speedX > 0) {
|
||||
this.speedX = (byte) -(this.speedX);
|
||||
}
|
||||
else {
|
||||
this.speedX -= 4;
|
||||
}
|
||||
this.speedY = (byte) -(this.speedY);
|
||||
break;
|
||||
case 3:
|
||||
if (this.speedX < 0) {
|
||||
this.speedX = (byte) -(this.speedX);
|
||||
}
|
||||
else {
|
||||
this.speedX += 4;
|
||||
}
|
||||
this.speedY = (byte) -(this.speedY);
|
||||
break;
|
||||
}
|
||||
if (this.speedX < 2 && this.speedX >= 0) {this.speedX = 2;}
|
||||
else if (this.speedX > -2 && this.speedX < 0) {this.speedX = -2;}
|
||||
else if (this.speedX > 11) {this.speedX -= 3;} // Slow down if too fast
|
||||
if (this.speedY < 4 && this.speedY >= 0) {this.speedY = 4;}
|
||||
else if (this.speedY > -4 && this.speedY < 0) {this.speedY = -4;}
|
||||
else if (this.speedY > 11) {this.speedY -= 3;} // Slow down if too fast
|
||||
}
|
||||
|
||||
public void destroyBall() {
|
||||
this.isActive = false;
|
||||
this.posX = 32767;
|
||||
this.posY = 32767;
|
||||
this.hitBox.setBounds(32766, 32766, 32767, 32767);
|
||||
if (gameState.getBalls().size() <= 1) {
|
||||
if (gameState.getLives() <= 0) {
|
||||
gameState.gameLose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cull() {
|
||||
this.isActive = false;
|
||||
this.posX = 32767;
|
||||
this.posY = 32767;
|
||||
this.hitBox.setBounds(32766, 32766, 32767, 32767);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the ball is in contact with other Entities and walls.
|
||||
*/
|
||||
public synchronized void checkCollision() {
|
||||
|
||||
this.setInvincibilityState(true); // Delay bouncing again for a frame
|
||||
|
||||
// Check floor
|
||||
if (this.posY >= gameState.getInternalResY()) {
|
||||
this.destroyBall();
|
||||
return;
|
||||
}
|
||||
// Check ceiling
|
||||
else if (this.posY <= 0) {
|
||||
this.bounce(0);
|
||||
this.posY = 0;
|
||||
this.wallBounceAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check walls
|
||||
if (this.posX <= 20) {
|
||||
this.bounce(1);
|
||||
this.posX = 22;
|
||||
this.wallBounceAnimation();
|
||||
return;
|
||||
}
|
||||
else if ((this.posX + this.width) >= (gameState.getInternalResX() - 20 - this.width)) {
|
||||
this.bounce(1);
|
||||
this.posX = (short) (gameState.getInternalResX() - 25 - this.width);
|
||||
this.wallBounceAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check bricks
|
||||
if (gameState.getCurrentLevel() != null) {
|
||||
if (gameState.getCurrentLevel().brickList != null) {
|
||||
for (Brick brick : gameState.getCurrentLevel().brickList) {
|
||||
// Check for left bounce
|
||||
if (this.hitBox.collides(brick.hitBoxLeft.getBounds())) {
|
||||
if (this.hitBox.collides(brick.hitBox.getBounds())) {
|
||||
this.bounce(0);
|
||||
this.bounce(1);
|
||||
}
|
||||
else {
|
||||
this.bounce(1);
|
||||
}
|
||||
brick.breakBrick();
|
||||
return;
|
||||
}
|
||||
// Check for right bounce
|
||||
else if (this.hitBox.collides(brick.hitBoxRight.getBounds())) {
|
||||
if (this.hitBox.collides(brick.hitBox.getBounds())) {
|
||||
this.bounce(0);
|
||||
this.bounce(1);
|
||||
}
|
||||
else {
|
||||
this.bounce(1);
|
||||
}
|
||||
brick.breakBrick();
|
||||
return;
|
||||
}
|
||||
// Check for vertical bounce
|
||||
else if (this.hitBox.collides(brick.hitBox.getBounds())) {
|
||||
brick.breakBrick();
|
||||
this.bounce(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check paddles
|
||||
for (Paddle paddle : gameState.getPaddles()) {
|
||||
if (this.hitBox.collides(paddle.hitBox.getBounds())) {
|
||||
if (this.hitBox.collides(paddle.hitBoxLeft.getBounds())) {
|
||||
this.bounce(2);
|
||||
}
|
||||
else if (this.hitBox.collides(paddle.hitBoxRight.getBounds())) {
|
||||
this.bounce(3);
|
||||
}
|
||||
else {
|
||||
this.bounce(0);
|
||||
}
|
||||
|
||||
this.posY -= 2;
|
||||
|
||||
// Draw particles
|
||||
Particle particle1, particle2, particle3;
|
||||
particle1 = new Particle(gameState, 0, this.posX, this.posY - 10, 0, -2, 1, 2, 7, 3);
|
||||
particle2 = new Particle(gameState, 0, this.posX - 3, this.posY - 10, -2, -4, 1, 2, 6, 3);
|
||||
particle3 = new Particle(gameState, 0, this.posX + 10, this.posY - 10, 2, -4, 1, 2, 8, 3);
|
||||
gameState.getParticles().add(particle1);
|
||||
gameState.getParticles().add(particle2);
|
||||
gameState.getParticles().add(particle3);
|
||||
particle1.spawn(5);
|
||||
particle2.spawn(5);
|
||||
particle3.spawn(5);
|
||||
|
||||
return; // Prevents bouncing multiple times
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void wallBounceAnimation() {
|
||||
Particle particle1, particle2, particle3, particle4;
|
||||
particle1 = new Particle(gameState, 0, this.posX - 3, this.posY - 10, -2, -2, 1, 2, 6, 3);
|
||||
particle2 = new Particle(gameState, 0, this.posX + 10, this.posY - 10, 2, -2, 1, 2, 8, 3);
|
||||
particle3 = new Particle(gameState, 0, this.posX - 3, this.posY + 3, 2, 2, 1, 2, 2, 3);
|
||||
particle4 = new Particle(gameState, 0, this.posX + 10, this.posY + 3, -2, 2, 1, 2, 4, 3);
|
||||
gameState.getParticles().add(particle1);
|
||||
gameState.getParticles().add(particle2);
|
||||
gameState.getParticles().add(particle3);
|
||||
gameState.getParticles().add(particle4);
|
||||
particle1.spawn(5);
|
||||
particle2.spawn(5);
|
||||
particle3.spawn(5);
|
||||
particle4.spawn(5);
|
||||
}
|
||||
|
||||
public boolean getActiveState() {
|
||||
return this.isActive;
|
||||
}
|
||||
public void setActiveState(boolean activeState) {
|
||||
this.isActive = activeState;
|
||||
}
|
||||
|
||||
public boolean getInvincibilityState() {
|
||||
return this.isInvincible;
|
||||
}
|
||||
public void setInvincibilityState(boolean invincibilityState) {
|
||||
this.isInvincible = invincibilityState;
|
||||
}
|
||||
|
||||
}
|
120
src/main/java/dev/boyfailure/vectorbreakout/Brick.java
Normal file
120
src/main/java/dev/boyfailure/vectorbreakout/Brick.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
/**
|
||||
* The bricks that appear in each level.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250323
|
||||
*/
|
||||
public class Brick extends Entity {
|
||||
|
||||
private boolean isBroken = false;
|
||||
byte brickColor = 0;
|
||||
byte scoreOnBreak = 10;
|
||||
byte specialAbility = 0;
|
||||
Hitbox hitBoxLeft;
|
||||
Hitbox hitBoxRight;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
/**
|
||||
* Constructs a brick.
|
||||
* @param gameState The GameState in which the Brick will reside.
|
||||
* @param x The x coordinate of the Brick.
|
||||
* @param y The y coordinate of the Brick.
|
||||
* @param isBroken Determines whether the Brick is broken.
|
||||
* @param brickColor The color code of the Brick.
|
||||
* @param score The score the Player earns upon breaking the Brick.
|
||||
* @param specialAbility A special event that occurs upon breaking the Brick.
|
||||
*/
|
||||
public Brick(GameState gameState, int x, int y, boolean isBroken, int brickColor, int score, int specialAbility) {
|
||||
this.width = 40;
|
||||
this.height = 17;
|
||||
this.gameState = gameState;
|
||||
this.posX = (short) x;
|
||||
this.posY = (short) y;
|
||||
this.isBroken = isBroken;
|
||||
this.brickColor = (byte) brickColor;
|
||||
this.scoreOnBreak = (byte) score;
|
||||
this.hitBox = new Hitbox(x + 2, y, this.width - 4, this.height, 0);
|
||||
this.hitBoxLeft = new Hitbox(x, y + 2, 6, this.height - 4, 0);
|
||||
this.hitBoxRight = new Hitbox(x + this.width - 6, y + 2, 6, this.height - 4, 0);
|
||||
this.specialAbility = (byte) specialAbility;
|
||||
}
|
||||
|
||||
public void breakBrick() {
|
||||
if (!isBroken) {
|
||||
isBroken = true;
|
||||
gameState.addScore(this.scoreOnBreak + (gameState.getCurrentLevelID() - 1));
|
||||
gameState.getTextElements().get(3).setText(String.valueOf(gameState.getScore()));
|
||||
switch(this.specialAbility) {
|
||||
case 1:
|
||||
gameState.addLife();
|
||||
break;
|
||||
case 2:
|
||||
while (gameState.getCollectorActiveState()) {}
|
||||
Ball newBall = new Ball(gameState, 300, 300, 7, 7, 0, true);
|
||||
this.gameState.getBalls().add(newBall);
|
||||
newBall.spawnBall((this.posX + (this.width / 2)), (this.posY + (this.height / 2)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Show score on break
|
||||
TextElement bruh = new TextElement(this.gameState,
|
||||
String.valueOf(this.scoreOnBreak),
|
||||
0.25f,
|
||||
this.posX + (this.width / 3),
|
||||
this.posY - 3,
|
||||
this.brickColor,
|
||||
1,
|
||||
300);
|
||||
bruh.activateTimer();
|
||||
bruh.setActiveState(true);
|
||||
//bruh.moveUpOnFrame();
|
||||
this.gameState.getTextElements().add(bruh);
|
||||
}
|
||||
|
||||
// Draw particles
|
||||
Particle particle1, particle2, particle3;
|
||||
particle1 = new Particle(gameState, 0, this.posX + 12, this.posY + 3, 1, 1, this.brickColor, 2, 4, 1);
|
||||
particle2 = new Particle(gameState, 0, this.posX + 20, this.posY + 13, 1, 1, this.brickColor, 2, 3, 1);
|
||||
particle3 = new Particle(gameState, 0, this.posX + 32, this.posY + 7, 1, 1, this.brickColor, 2, 2, 1);
|
||||
gameState.getParticles().add(particle1);
|
||||
gameState.getParticles().add(particle2);
|
||||
gameState.getParticles().add(particle3);
|
||||
particle1.spawn(5);
|
||||
particle2.spawn(5);
|
||||
particle3.spawn(5);
|
||||
|
||||
this.posX = 32767;
|
||||
this.posY = 32767;
|
||||
this.hitBox.moveTo(32760, 32760, 2, 2);
|
||||
this.hitBoxLeft.moveTo(32760, 32760, 2, 2);
|
||||
this.hitBoxRight.moveTo(32760, 32760, 2, 2);
|
||||
}
|
||||
|
||||
public boolean getBrokenState() {
|
||||
return this.isBroken;
|
||||
}
|
||||
public void setBrokenState(boolean brokenState) {
|
||||
this.isBroken = brokenState;
|
||||
}
|
||||
|
||||
}
|
65
src/main/java/dev/boyfailure/vectorbreakout/Entity.java
Normal file
65
src/main/java/dev/boyfailure/vectorbreakout/Entity.java
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2025 naomi.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* Base class for all entities in the game.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 1.0
|
||||
*/
|
||||
public class Entity {
|
||||
|
||||
/** The horizontal position of the entity, in pixels. */
|
||||
short posX;
|
||||
/** The vertical position of the entity, in pixels. */
|
||||
short posY;
|
||||
/** The width of the entity, in pixels. */
|
||||
short width;
|
||||
/** The height of the entity, in pixels. */
|
||||
short height;
|
||||
/** The default hitbox of the entity. */
|
||||
Hitbox hitBox;
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Accessor methods (get/set) ">
|
||||
|
||||
/**
|
||||
* Returns the position of the entity as a Point.
|
||||
* @return the position of the entity
|
||||
*/
|
||||
public Point getPosition() {
|
||||
return new Point(this.posX, this.posY);
|
||||
}
|
||||
/**
|
||||
* Returns the horizontal position of the entity.
|
||||
* @return the horizontal position of the entity
|
||||
*/
|
||||
public short getPositionX() {
|
||||
return this.posX;
|
||||
}
|
||||
/**
|
||||
* Returns the vertical position of the entity.
|
||||
* @return the vertical position of the entity
|
||||
*/
|
||||
public short getPositionY() {
|
||||
return this.posY;
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
|
||||
}
|
|
@ -1,4 +1,20 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
|
@ -7,6 +23,11 @@ import java.awt.Graphics2D;
|
|||
import javax.swing.JComponent;
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
/**
|
||||
* The logic to draw the game on the screen.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250323
|
||||
*/
|
||||
public class GameDisplay extends JComponent {
|
||||
|
||||
// Change this to 1 if you build for older versions of Java. Older versions
|
||||
|
@ -45,7 +66,7 @@ public class GameDisplay extends JComponent {
|
|||
this.beamThicknessScale = beamScale;
|
||||
}
|
||||
|
||||
public void paint(Graphics gameGraphics) {
|
||||
public synchronized void paint(Graphics gameGraphics) {
|
||||
|
||||
super.paint(gameGraphics);
|
||||
|
||||
|
@ -65,18 +86,18 @@ public class GameDisplay extends JComponent {
|
|||
}
|
||||
|
||||
// Bricks
|
||||
if (gameState.currentLevel != null) {
|
||||
if (gameState.currentLevel.brickList != null) {
|
||||
for (Brick brick : gameState.currentLevel.brickList) {
|
||||
if (gameState.getCurrentLevel() != null) {
|
||||
if (gameState.getCurrentLevel().brickList != null) {
|
||||
for (Brick brick : gameState.getCurrentLevel().brickList) {
|
||||
if (!brick.getBrokenState()) {
|
||||
resetBeam();
|
||||
g2.setStroke(bt(3));
|
||||
moveBeam(brick.brickX + 1, brick.brickY + 1);
|
||||
moveBeam(brick.posX + 1, brick.posY + 1);
|
||||
g2.setColor(vc(brick.brickColor));
|
||||
g2.draw(drawVec(brick.brickWidth - 2, 0));
|
||||
g2.draw(drawVec(0, -(brick.brickHeight - 2)));
|
||||
g2.draw(drawVec(-(brick.brickWidth - 2), 0));
|
||||
g2.draw(drawVec(0, brick.brickHeight - 2));
|
||||
g2.draw(drawVec(brick.width - 2, 0));
|
||||
g2.draw(drawVec(0, -(brick.height - 2)));
|
||||
g2.draw(drawVec(-(brick.width - 2), 0));
|
||||
g2.draw(drawVec(0, brick.height - 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,34 +105,34 @@ public class GameDisplay extends JComponent {
|
|||
|
||||
// Paddles
|
||||
g2.setColor(Color.white);
|
||||
for (Paddle paddle : gameState.paddleList) {
|
||||
for (Paddle paddle : gameState.getPaddles()) {
|
||||
if (paddle.getActiveState()) {
|
||||
resetBeam();
|
||||
g2.setStroke(bt(3));
|
||||
moveBeam(paddle.paddleX, paddle.paddleY);
|
||||
g2.draw(drawVec(paddle.paddleWidth, 0));
|
||||
g2.draw(drawVec(0, -(paddle.paddleHeight)));
|
||||
g2.draw(drawVec(-(paddle.paddleWidth), 0));
|
||||
g2.draw(drawVec(0, paddle.paddleHeight));
|
||||
moveBeam(paddle.posX, paddle.posY);
|
||||
g2.draw(drawVec(paddle.width, 0));
|
||||
g2.draw(drawVec(0, -(paddle.height)));
|
||||
g2.draw(drawVec(-(paddle.width), 0));
|
||||
g2.draw(drawVec(0, paddle.height));
|
||||
}
|
||||
}
|
||||
|
||||
// Balls
|
||||
g2.setStroke(bt(3));
|
||||
g2.setColor(Color.yellow);
|
||||
for (Ball ball : gameState.ballList) {
|
||||
for (Ball ball : gameState.getBalls()) {
|
||||
if (ball.getActiveState()) {
|
||||
resetBeam();
|
||||
moveBeam(ball.ballX, ball.ballY);
|
||||
g2.draw(drawVec(ball.ballWidth, 0));
|
||||
g2.draw(drawVec(0, -ball.ballHeight));
|
||||
g2.draw(drawVec(-ball.ballWidth, 0));
|
||||
g2.draw(drawVec(0, ball.ballHeight));
|
||||
moveBeam(ball.posX, ball.posY);
|
||||
g2.draw(drawVec(ball.width, 0));
|
||||
g2.draw(drawVec(0, -ball.height));
|
||||
g2.draw(drawVec(-ball.width, 0));
|
||||
g2.draw(drawVec(0, ball.height));
|
||||
}
|
||||
}
|
||||
|
||||
// Particles
|
||||
for (Particle particle : gameState.particleList) {
|
||||
for (Particle particle : gameState.getParticles()) {
|
||||
if (particle.getActiveState()) {
|
||||
resetBeam();
|
||||
moveBeam(particle.particleX, particle.particleY);
|
||||
|
@ -121,10 +142,11 @@ public class GameDisplay extends JComponent {
|
|||
}
|
||||
}
|
||||
|
||||
/* TextElements
|
||||
/*
|
||||
* TextElements
|
||||
*
|
||||
* Note on rendering numbers:
|
||||
*
|
||||
*
|
||||
* I am aware that I could be using a switch statement for these.
|
||||
* However, this did not compile when testing in JDK 1.5, as it would
|
||||
* refuse to accept anything other than numbers in a switch statement.
|
||||
|
@ -132,24 +154,25 @@ public class GameDisplay extends JComponent {
|
|||
* systems, I used these goofy if/else statements so I could compile
|
||||
* on the older JDKs and play on my older systems...
|
||||
*/
|
||||
for (TextElement element : gameState.textElementList) {
|
||||
if (element.getActiveState() && element.getVisibility()) {
|
||||
for (TextElement element : gameState.getTextElements()) {
|
||||
if (element.getActiveState() && element.getVisibleState()) {
|
||||
if (element.movesUpOnFrame()) {element.moveTo(element.getPositionX(), element.getPositionY() - 1);}
|
||||
resetBeam();
|
||||
moveBeam(element.x, element.y);
|
||||
moveBeam(element.getPositionX(), element.getPositionY());
|
||||
|
||||
// Save the current beam scale to revert once TextElement is done rendering
|
||||
float oldBeamScaleX = beamScaleX;
|
||||
float oldBeamScaleY = beamScaleY;
|
||||
float oldBeamScaleX = this.beamScaleX;
|
||||
float oldBeamScaleY = this.beamScaleY;
|
||||
|
||||
// Adjust the beam scale to accomodate the scale of the TextElement
|
||||
beamScaleX = beamScaleX * element.textScale;
|
||||
beamScaleY = beamScaleY * element.textScale;
|
||||
this.beamScaleX *= element.getTextScale();
|
||||
this.beamScaleY *= element.getTextScale();
|
||||
|
||||
// Render the TextElement
|
||||
g2.setColor(vc(element.textColor));
|
||||
g2.setStroke(bt(element.vectorScale));
|
||||
String stringToSplit = String.valueOf(element.text);
|
||||
String[] stringToRender = stringToSplit.split("");
|
||||
g2.setColor(vc(element.getColor()));
|
||||
g2.setStroke(bt(element.getVectorThickness()));
|
||||
String[] stringToRender = element.getText().split("");
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Beam routines for letters/numbers ">
|
||||
for (short i = iStart; i < stringToRender.length; i++) {
|
||||
if ("1".equals(stringToRender[i])) {
|
||||
|
@ -233,7 +256,7 @@ public class GameDisplay extends JComponent {
|
|||
}
|
||||
// Simulates a newline in a TextElement
|
||||
else if ("\\".equals(stringToRender[i])) {
|
||||
moveBeam(-(beamX - element.x), 30);
|
||||
moveBeam(-(beamX - element.getPositionX()), 30);
|
||||
}
|
||||
else if ("A".equals(stringToRender[i])) {
|
||||
g2.draw(drawVec(0, -17));
|
||||
|
@ -477,67 +500,81 @@ public class GameDisplay extends JComponent {
|
|||
//</editor-fold>
|
||||
|
||||
// Revert back to the previous beam scale
|
||||
beamScaleX = oldBeamScaleX;
|
||||
beamScaleY = oldBeamScaleY;
|
||||
this.beamScaleX = oldBeamScaleX;
|
||||
this.beamScaleY = oldBeamScaleY;
|
||||
}
|
||||
}
|
||||
|
||||
gameState.actualFrames++; // Count up actual frames rendered
|
||||
gameState.incrementActualFrames(); // Count up actual frames rendered
|
||||
|
||||
// Debug Menu
|
||||
if (gameState.getDebugMenuState()) {
|
||||
g2.setColor(Color.white);
|
||||
g2.drawString(gameState.gameName + " v" + gameState.gameVersion, 1, 12);
|
||||
g2.drawString("frame: " + gameState.getFrameCounter(), 1, 24);
|
||||
g2.drawString("beamScaleX: " + beamScaleX, 1, 36);
|
||||
g2.drawString("beamScaleY: " + beamScaleY, 1, 48);
|
||||
g2.drawString("isPaused: " + gameState.getPausedState(), 1, 60);
|
||||
g2.drawString("targetFrameRate: " + gameState.getTargetFrameRate(), 150, 24);
|
||||
g2.drawString("actualFrameRate: " + gameState.getActualFrameRate(), 150, 36);
|
||||
g2.drawString("actualFrames: " + gameState.actualFrames, 150, 48);
|
||||
g2.drawString("chancey: " + gameState.getChancey(), 150, 60);
|
||||
g2.drawString("ballsOnScreen: " + gameState.ballsOnScreen, 300, 24);
|
||||
g2.drawString(gameState.getGameName() + " v" + gameState.getGameVersion(), 1, 12);
|
||||
g2.drawString("Frame: " + gameState.getFrameCounter(), 1, 24);
|
||||
g2.drawString("Horizontal beamscale: " + beamScaleX, 1, 36);
|
||||
g2.drawString("Vertical beamscale: " + beamScaleY, 1, 48);
|
||||
g2.drawString("Paused: " + gameState.getPausedState(), 1, 60);
|
||||
g2.drawString("Target framerate: " + gameState.getTargetFrameRate(), 150, 24);
|
||||
g2.drawString("Actual framerate: " + gameState.getActualFrameRate(), 150, 36);
|
||||
g2.drawString("actualFrames: " + gameState.getActualFrames(), 150, 48);
|
||||
g2.drawString("LFSR: " + gameState.getPokey().getDecimalValue(), 150, 60);
|
||||
g2.drawString("Ball count: " + gameState.getBalls().size(), 300, 24);
|
||||
g2.drawString("Particle count: " + gameState.getParticles().size(), 300, 36);
|
||||
g2.drawString("Paddle count: " + gameState.getPaddles().size(), 300, 48);
|
||||
g2.drawString("Text count: " + gameState.getTextElements().size(), 300, 60);
|
||||
g2.drawString("Brick count: " + gameState.getCurrentLevel().brickList.size(), 300, 72);
|
||||
short padBoxX, padBoxY, padBoxX2, padBoxY2;
|
||||
g2.setStroke(new BasicStroke(1));
|
||||
|
||||
// Paddles
|
||||
g2.setColor(vc(10, 0.5f));
|
||||
for (Paddle paddle : gameState.paddleList) {
|
||||
for (Paddle paddle : gameState.getPaddles()) {
|
||||
padBoxX = (short) paddle.hitBox.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) paddle.hitBox.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) paddle.hitBox.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) paddle.hitBox.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - paddle.paddleHeight), padBoxX2, padBoxY2);
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - paddle.height), padBoxX2, padBoxY2);
|
||||
padBoxX = (short) paddle.hitBoxLeft.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) paddle.hitBoxLeft.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) paddle.hitBoxLeft.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) paddle.hitBoxLeft.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - paddle.paddleHeight), padBoxX2, padBoxY2);
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - paddle.height), padBoxX2, padBoxY2);
|
||||
padBoxX = (short) paddle.hitBoxRight.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) paddle.hitBoxRight.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) paddle.hitBoxRight.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) paddle.hitBoxRight.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - paddle.paddleHeight), padBoxX2, padBoxY2);
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - paddle.height), padBoxX2, padBoxY2);
|
||||
}
|
||||
|
||||
// Balls
|
||||
g2.setColor(vc(11, 1.0f));
|
||||
for (Ball ball : gameState.ballList) {
|
||||
for (Ball ball : gameState.getBalls()) {
|
||||
padBoxX = (short) ball.hitBox.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) ball.hitBox.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) ball.hitBox.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) ball.hitBox.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - ball.ballHeight), padBoxX2, padBoxY2);
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - ball.height), padBoxX2, padBoxY2);
|
||||
}
|
||||
|
||||
// Bricks
|
||||
g2.setColor(vc(12, 0.5f));
|
||||
for (Brick brick : gameState.currentLevel.brickList) {
|
||||
for (Brick brick : gameState.getCurrentLevel().brickList) {
|
||||
padBoxX = (short) brick.hitBox.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) brick.hitBox.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) brick.hitBox.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) brick.hitBox.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - brick.brickHeight), padBoxX2, padBoxY2);
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - brick.height), padBoxX2, padBoxY2);
|
||||
padBoxX = (short) brick.hitBoxLeft.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) brick.hitBoxLeft.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) brick.hitBoxLeft.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) brick.hitBoxLeft.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - brick.height), padBoxX2, padBoxY2);
|
||||
padBoxX = (short) brick.hitBoxRight.getBounds().getBounds2D().getMinX();
|
||||
padBoxY = (short) brick.hitBoxRight.getBounds().getBounds2D().getMinY();
|
||||
padBoxX2 = (short) brick.hitBoxRight.getBounds().getBounds2D().getWidth();
|
||||
padBoxY2 = (short) brick.hitBoxRight.getBounds().getBounds2D().getHeight();
|
||||
g2.fillRect(padBoxX, padBoxY + (40 - brick.height), padBoxX2, padBoxY2);
|
||||
}
|
||||
}
|
||||
|
70
src/main/java/dev/boyfailure/vectorbreakout/GameFrame.java
Normal file
70
src/main/java/dev/boyfailure/vectorbreakout/GameFrame.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
* The window in which the game is displayed.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 1.0
|
||||
*/
|
||||
public class GameFrame extends JFrame {
|
||||
|
||||
private GameState gameState;
|
||||
private GameDisplay gameDisplay;
|
||||
|
||||
public GameFrame(GameState gameState, GameDisplay gameDisplay) {
|
||||
this.gameState = gameState;
|
||||
this.gameDisplay = gameDisplay;
|
||||
|
||||
// Set the game window's properties
|
||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setTitle(this.gameState.getGameName());
|
||||
this.setSize(this.gameState.getWindowResX(), this.gameState.getWindowResY());
|
||||
this.getContentPane().setBackground(Color.black);
|
||||
this.getContentPane().add(this.gameDisplay);
|
||||
|
||||
// Add the component adapter to change vector drawing scale when the window is resized
|
||||
this.addComponentListener(this.getComponentAdapter());
|
||||
|
||||
// Add the key listener to get player input
|
||||
this.addKeyListener(this.gameState.getKeyListener());
|
||||
}
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Event listeners ">
|
||||
|
||||
public ComponentAdapter getComponentAdapter() {
|
||||
return new GameComponentAdapter();
|
||||
}
|
||||
class GameComponentAdapter extends ComponentAdapter {
|
||||
public void componentResized(ComponentEvent componentEvent) {
|
||||
GameFrame.this.gameState.setWindowResX((short) GameFrame.this.getBounds().width);
|
||||
GameFrame.this.gameState.setWindowResY((short) GameFrame.this.getBounds().height);
|
||||
GameFrame.this.gameDisplay.setBeamScaleX(GameFrame.this.gameState.getWindowResX() / 800f);
|
||||
GameFrame.this.gameDisplay.setBeamScaleY(GameFrame.this.gameState.getWindowResY() / 600f);
|
||||
if (GameFrame.this.gameDisplay.getBeamScaleX() <= GameFrame.this.gameDisplay.getBeamScaleY()) {GameFrame.this.gameDisplay.setBeamThicknessScale(GameFrame.this.gameDisplay.getBeamScaleX());}
|
||||
else {GameFrame.this.gameDisplay.setBeamThicknessScale(GameFrame.this.gameDisplay.getBeamScaleY());}
|
||||
}
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
|
||||
}
|
|
@ -1,4 +1,20 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
@ -6,58 +22,70 @@ import java.awt.event.KeyEvent;
|
|||
import java.awt.event.KeyListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The embeddable game object which contains the main loop and logic.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250511
|
||||
*/
|
||||
public class GameState {
|
||||
|
||||
public String gameName = "Vector Breakout";
|
||||
public String gameVersion = "20250511";
|
||||
|
||||
/** The name of the game. */
|
||||
private String gameName = "Vector Breakout";
|
||||
/** The version of the game. */
|
||||
private String gameVersion = "1.0";
|
||||
/** Determines whether the game has been started. */
|
||||
private boolean isGameStarted = false;
|
||||
/** Determines whether the game has been paused. */
|
||||
private boolean isPaused = false;
|
||||
/** Determines whether the debug menu has been enabled. */
|
||||
private boolean debugMenuEnabled = false;
|
||||
public boolean isLost = false;
|
||||
public boolean movingLeft = false;
|
||||
public boolean movingRight = false;
|
||||
public boolean confettiMode = false;
|
||||
public boolean collectorActive = false;
|
||||
public byte lives = 5;
|
||||
private byte chancey = 0;
|
||||
private final byte maxChanceyValue = 16;
|
||||
public byte ballsOnScreen = 0;
|
||||
/** Determines whether the game has been lost. */
|
||||
private boolean isLost = false;
|
||||
/** Determines whether the player is moving left. */
|
||||
private boolean movingLeft = false;
|
||||
/** Determines whether the player is moving right. */
|
||||
private boolean movingRight = false;
|
||||
/** Determines whether "Confetti Mode" (long-lasting particles) has been enabled. */
|
||||
private boolean confettiMode = false;
|
||||
/** Determines whether the collector function is running. */
|
||||
private boolean collectorActive = false;
|
||||
/** The number of lives the player has. */
|
||||
private byte lives = 5;
|
||||
/** The target frame rate for the game. */
|
||||
private short targetFrameRate = 60;
|
||||
public short actualFrames = 0;
|
||||
private short actualFrames = 0;
|
||||
private short actualFrameRate = 0;
|
||||
public byte gameTickRate = 60;
|
||||
private byte gameTickRate = 60;
|
||||
private short internalResX = 800;
|
||||
private short internalResY = 600;
|
||||
private short windowResX = 1024;
|
||||
private short windowResY = 768;
|
||||
public short level = 1;
|
||||
public short bricksOnScreen = 0;
|
||||
public int score = 0;
|
||||
private short windowResX = 1280;
|
||||
private short windowResY = 960;
|
||||
private short level = 1;
|
||||
private short bricksOnScreen = 0;
|
||||
private int score = 0;
|
||||
private long frameCounter = 0;
|
||||
|
||||
public ArrayList<Ball> ballList;
|
||||
public ArrayList<Particle> particleList;
|
||||
public ArrayList<Paddle> paddleList;
|
||||
public ArrayList<TextElement> textElementList;
|
||||
private Level currentLevel;
|
||||
|
||||
public ArrayList<Ball> ballCollector;
|
||||
public ArrayList<Particle> particleCollector;
|
||||
public ArrayList<Paddle> paddleCollector;
|
||||
public ArrayList<TextElement> textElementCollector;
|
||||
public ArrayList<Brick> brickCollector;
|
||||
private ArrayList<Ball> ballList;
|
||||
private ArrayList<Particle> particleList;
|
||||
private ArrayList<Paddle> paddleList;
|
||||
private ArrayList<TextElement> textElementList;
|
||||
|
||||
private ArrayList<Ball> ballCollector;
|
||||
private ArrayList<Particle> particleCollector;
|
||||
private ArrayList<Paddle> paddleCollector;
|
||||
private ArrayList<TextElement> textElementCollector;
|
||||
private ArrayList<Brick> brickCollector;
|
||||
|
||||
private LFSR pokey;
|
||||
|
||||
public Level currentLevel;
|
||||
|
||||
// Debug stuffs
|
||||
public boolean debugSpawnAllBalls = false;
|
||||
public boolean debugUseGiantPaddle = false;
|
||||
public short debugStartLevel = 1;
|
||||
|
||||
public GameState() {
|
||||
this.initComponents();
|
||||
this.showTitleScreen();
|
||||
}
|
||||
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Event listeners ">
|
||||
|
||||
public KeyListener getKeyListener() {
|
||||
return new GameKeyListener();
|
||||
}
|
||||
|
@ -79,37 +107,29 @@ public class GameState {
|
|||
class GameKeyListener implements KeyListener {
|
||||
public void keyPressed(KeyEvent e) {
|
||||
switch(e.getKeyCode()) {
|
||||
case 27: // Escape
|
||||
case 27: // Escape - Toggle debug menu
|
||||
toggleDebugMenu();
|
||||
break;
|
||||
case 10: // Enter
|
||||
if (GameState.this.getGameStartedState()) {
|
||||
GameState.this.togglePausedState();
|
||||
if (!GameState.this.getPausedState()) {
|
||||
GameState.this.textElementList.get(6).setVisibility(false);
|
||||
}
|
||||
else {
|
||||
GameState.this.textElementList.get(6).setVisibility(true);
|
||||
}
|
||||
}
|
||||
case 10: // Enter - Pause/unpause
|
||||
if (GameState.this.getGameStartedState()) {GameState.this.togglePausedState();}
|
||||
break;
|
||||
case 35: // End
|
||||
case 35: // End - Start debug level
|
||||
if (isLost || !GameState.this.getGameStartedState()) {GameState.this.setGameStartedState(true);GameState.this.newGame(true);}
|
||||
break;
|
||||
case 32: // Space
|
||||
case 32: // Space - Start normal game, spawn ball
|
||||
if (isLost || !GameState.this.getGameStartedState()) {GameState.this.setGameStartedState(true);GameState.this.newGame();}
|
||||
else if (!GameState.this.getPausedState()) {
|
||||
if (ballsOnScreen < 1) {
|
||||
if (GameState.this.getBalls().size() < 1) {
|
||||
Ball newBall = new Ball(GameState.this, 200, 300, 7, 7, 0, true);
|
||||
GameState.this.ballList.add(newBall);
|
||||
newBall.spawnBall(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 37: // Left
|
||||
case 37: // Left - move left
|
||||
if (GameState.this.getGameStartedState()) {movingLeft = true;}
|
||||
break;
|
||||
case 39: // Right
|
||||
case 39: // Right - move right
|
||||
if (GameState.this.getGameStartedState()) {movingRight = true;}
|
||||
break;
|
||||
}
|
||||
|
@ -126,9 +146,9 @@ public class GameState {
|
|||
}
|
||||
public void keyTyped(KeyEvent e) {}
|
||||
}
|
||||
|
||||
|
||||
class GameStateUpdateListener implements ActionListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
public synchronized void actionPerformed(ActionEvent e) {
|
||||
|
||||
GameState.this.collectorActive = true;
|
||||
GameState.this.ballCollector = new ArrayList<>();
|
||||
|
@ -145,7 +165,6 @@ public class GameState {
|
|||
for (Brick brick : GameState.this.currentLevel.brickList) {
|
||||
if (brick.getBrokenState()) {
|
||||
GameState.this.brickCollector.add(brick);
|
||||
//GameState.this.currentLevel.brickList.remove(brick);
|
||||
}
|
||||
else {
|
||||
bricksOnScreen++;
|
||||
|
@ -156,14 +175,12 @@ public class GameState {
|
|||
|
||||
for (Ball ball : GameState.this.ballList) {
|
||||
if (!ball.getActiveState()) {
|
||||
//GameState.this.ballList.remove(ball);
|
||||
GameState.this.ballCollector.add(ball);
|
||||
}
|
||||
}
|
||||
|
||||
for (Particle particle: GameState.this.particleList) {
|
||||
if (!particle.getActiveState()) {
|
||||
//GameState.this.particleList.remove(particle);
|
||||
GameState.this.particleCollector.add(particle);
|
||||
}
|
||||
}
|
||||
|
@ -186,56 +203,129 @@ public class GameState {
|
|||
}
|
||||
}
|
||||
|
||||
public void incrementFrameCounter() {
|
||||
this.frameCounter++;
|
||||
}
|
||||
public long getFrameCounter() {
|
||||
return this.frameCounter;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
public void incrementChancey() {
|
||||
this.chancey++;
|
||||
if (this.chancey >= this.maxChanceyValue) {
|
||||
this.chancey = 0;
|
||||
}
|
||||
}
|
||||
public byte getChancey() {
|
||||
return this.chancey;
|
||||
}
|
||||
//<editor-fold defaultstate="collapsed" desc=" Accessor methods (get/set) ">
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Version information accessors ">
|
||||
/**
|
||||
* Gets the name of the game.
|
||||
* @return the name of the game
|
||||
*/
|
||||
public String getGameName() {
|
||||
return this.gameName;
|
||||
}
|
||||
/**
|
||||
* Gets the version number of the game.
|
||||
* @return the version number of the game
|
||||
*/
|
||||
public String getGameVersion() {
|
||||
return this.gameVersion;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Pokey accessors ">
|
||||
/**
|
||||
* Gets the current instance of "Pokey", the game's LFSR.
|
||||
* @return pokey
|
||||
*/
|
||||
public LFSR getPokey() {
|
||||
return this.pokey;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Tick rate accessors ">
|
||||
/**
|
||||
* Gets the current game tick rate, in Hz.
|
||||
* @return the current game tick rate (in Hz)
|
||||
*/
|
||||
public byte getGameTickRate() {
|
||||
return this.gameTickRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current game tick rate, in Hz.
|
||||
* @param newTickRate the game tick rate, in Hz
|
||||
*/
|
||||
public void setGameTickRate(byte newTickRate) {
|
||||
this.gameTickRate = (byte) newTickRate;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Frame rate accessors ">
|
||||
/**
|
||||
* Gets the target game frame rate, in Hz.
|
||||
* @return the target game frame rate (in Hz)
|
||||
*/
|
||||
public short getTargetFrameRate() {
|
||||
return this.targetFrameRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the actual game frame rate, in Hz.
|
||||
* @return the actual game frame rate (in Hz)
|
||||
*/
|
||||
public short getActualFrameRate() {
|
||||
return this.actualFrameRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the frame counter.
|
||||
*/
|
||||
public void incrementFrameCounter() {
|
||||
this.frameCounter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the frame counter.
|
||||
* @return the value of the frame counter
|
||||
*/
|
||||
public long getFrameCounter() {
|
||||
return this.frameCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the actual frames drawn during the last second.
|
||||
* @return the actual frames drawn during the last second.
|
||||
*/
|
||||
public short getActualFrames() {
|
||||
return this.actualFrames;
|
||||
}
|
||||
public void incrementActualFrames() {
|
||||
this.actualFrames++;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Pause state accessors ">
|
||||
public boolean getPausedState() {
|
||||
return this.isPaused;
|
||||
}
|
||||
public void togglePausedState() {
|
||||
this.isPaused = !this.isPaused;
|
||||
if (this.getPausedState()) {this.textElementList.get(6).getVisibleState(true);}
|
||||
else {this.textElementList.get(6).getVisibleState(false);}
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Debug menu state accessors ">
|
||||
public boolean getDebugMenuState() {
|
||||
return this.debugMenuEnabled;
|
||||
}
|
||||
public void toggleDebugMenu() {
|
||||
this.debugMenuEnabled = !this.debugMenuEnabled;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Game start state accessors ">
|
||||
public boolean getGameStartedState() {
|
||||
return this.isGameStarted;
|
||||
}
|
||||
public void setGameStartedState(boolean startState) {
|
||||
this.isGameStarted = startState;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Resolution accessors ">
|
||||
public short getInternalResX() {
|
||||
return this.internalResX;
|
||||
}
|
||||
|
@ -254,25 +344,94 @@ public class GameState {
|
|||
public void setWindowResY(short resolution) {
|
||||
this.windowResY = resolution;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Lives accessors ">
|
||||
public byte getLives() {
|
||||
return this.lives;
|
||||
}
|
||||
public void addLives(int livesAdded) {
|
||||
if (livesAdded >= 127) {livesAdded = 127;}
|
||||
else if (livesAdded < 0) {livesAdded = 0;}
|
||||
this.lives += (byte) livesAdded;
|
||||
}
|
||||
public void addLife() {
|
||||
this.addLives(1);
|
||||
}
|
||||
public void removeLife() {
|
||||
this.lives--;
|
||||
if (this.lives < 0) {this.lives = 0;}
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Score accessors ">
|
||||
public int getScore() {
|
||||
return this.score;
|
||||
}
|
||||
public void addScore(int scoreAdded) {
|
||||
this.score += scoreAdded;
|
||||
}
|
||||
public void resetScore() {
|
||||
this.score = 0;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Level accessors ">
|
||||
public short getCurrentLevelID() {
|
||||
return this.level;
|
||||
}
|
||||
public void setCurrentLevelID(short levelID) {
|
||||
this.level = levelID;
|
||||
}
|
||||
public Level getCurrentLevel() {
|
||||
return this.currentLevel;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" List accessors ">
|
||||
public ArrayList<Ball> getBalls() {
|
||||
return this.ballList;
|
||||
}
|
||||
public ArrayList<Particle> getParticles() {
|
||||
return this.particleList;
|
||||
}
|
||||
public ArrayList<Paddle> getPaddles() {
|
||||
return this.paddleList;
|
||||
}
|
||||
public ArrayList<TextElement> getTextElements() {
|
||||
return this.textElementList;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Collector accessors ">
|
||||
public boolean getCollectorActiveState() {
|
||||
return this.collectorActive;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//</editor-fold>
|
||||
|
||||
public synchronized void onGameTick() {
|
||||
|
||||
public void onGameTick() {
|
||||
this.incrementChancey();
|
||||
|
||||
if (this.getPausedState()) {return;}
|
||||
|
||||
|
||||
// Move player if keys are held
|
||||
for (Paddle paddle : this.paddleList) {
|
||||
if (this.movingLeft) {
|
||||
paddle.movePaddle(false);
|
||||
}
|
||||
else if (this.movingRight) {
|
||||
paddle.movePaddle(true);
|
||||
}
|
||||
else {
|
||||
paddle.paddleSpeed = 0;
|
||||
try {
|
||||
for (Paddle paddle : this.paddleList) {
|
||||
if (this.movingLeft) {
|
||||
paddle.movePaddle(false);
|
||||
}
|
||||
else if (this.movingRight) {
|
||||
paddle.movePaddle(true);
|
||||
}
|
||||
else {
|
||||
paddle.paddleSpeed = 0;
|
||||
}
|
||||
}
|
||||
} catch(java.util.ConcurrentModificationException except) {
|
||||
System.err.println("ConcurrentModificationException, onGameTick() Paddle iteration " + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
// Ball logic (movement, collision checks)
|
||||
try {
|
||||
for (Ball ball : this.ballList) {
|
||||
|
@ -281,27 +440,28 @@ public class GameState {
|
|||
}
|
||||
}
|
||||
} catch(java.util.ConcurrentModificationException except) {
|
||||
System.err.println("ConcurrentModificationException, onGameTick() Ball iteration\n"
|
||||
+ "Resetting ballList ArrayList.");
|
||||
// except.printStackTrace();
|
||||
this.ballList = new ArrayList<>();
|
||||
System.err.println("ConcurrentModificationException, onGameTick() Ball iteration " + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
// Particles
|
||||
for (Particle particle : this.particleList) {
|
||||
if (particle.getActiveState()) {
|
||||
particle.update();
|
||||
try {
|
||||
for (Particle particle : this.particleList) {
|
||||
if (particle.getActiveState()) {
|
||||
particle.update();
|
||||
}
|
||||
}
|
||||
} catch(java.util.ConcurrentModificationException except) {
|
||||
System.err.println("ConcurrentModificationException, onGameTick() Particle iteration " + System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showTitleScreen() {
|
||||
textElementList.get(0).activateTimer();
|
||||
textElementList.get(1).activateTimer();
|
||||
textElementList.get(2).activateTimer();
|
||||
}
|
||||
|
||||
public void gameLose() {
|
||||
|
||||
public synchronized void gameLose() {
|
||||
if (this.currentLevel != null) {
|
||||
for (Brick brick : this.currentLevel.brickList) {
|
||||
brick.setBrokenState(true);
|
||||
|
@ -314,22 +474,22 @@ public class GameState {
|
|||
}
|
||||
for (Paddle paddle : this.paddleList) {
|
||||
paddle.setActiveState(false);
|
||||
paddle.cullPaddle();
|
||||
this.paddleCollector.add(paddle);
|
||||
}
|
||||
this.isLost = true;
|
||||
this.ballsOnScreen = 0;
|
||||
this.textElementList.get(3).setVisibility(false);
|
||||
this.textElementList.get(4).setVisibility(false);
|
||||
this.textElementList.get(5).setVisibility(false);
|
||||
this.textElementList.get(8).setVisibility(true);
|
||||
this.textElementList.get(9).setVisibility(true);
|
||||
this.textElementList.get(3).getVisibleState(false);
|
||||
this.textElementList.get(4).getVisibleState(false);
|
||||
this.textElementList.get(5).getVisibleState(false);
|
||||
this.textElementList.get(8).getVisibleState(true);
|
||||
this.textElementList.get(9).getVisibleState(true);
|
||||
this.getGameStateUpdateActionListener().actionPerformed(new ActionEvent(this, 0, ""));
|
||||
}
|
||||
|
||||
|
||||
public void newGame() {
|
||||
newGame(false);
|
||||
}
|
||||
|
||||
|
||||
public void newGame(boolean debugLevel) {
|
||||
lives = 5;
|
||||
isLost = false;
|
||||
|
@ -337,39 +497,33 @@ public class GameState {
|
|||
if (debugLevel) {level = 32767;}
|
||||
else {level = 1;}
|
||||
frameCounter = 0;
|
||||
ballsOnScreen = 0;
|
||||
movingLeft = false;
|
||||
movingRight = false;
|
||||
if (debugUseGiantPaddle) {this.paddleList.add(new Paddle(this, 0, 500, 800, 60, 0));}
|
||||
else {this.paddleList.add(new Paddle(this, 350, 500, 100, 15, 0));}
|
||||
if (this.debugUseGiantPaddle) {
|
||||
this.paddleList.add(new Paddle(this, 0, 500, 800, 60, 0));
|
||||
}
|
||||
else {
|
||||
this.paddleList.add(new Paddle(this, 350, 500, 100, 15, 0));
|
||||
}
|
||||
this.textElementList.get(0).setVisibility(false);
|
||||
this.textElementList.get(1).setVisibility(false);
|
||||
this.textElementList.get(2).setVisibility(false);
|
||||
this.textElementList.get(3).setVisibility(true);
|
||||
this.textElementList.get(4).setVisibility(true);
|
||||
this.textElementList.get(5).setVisibility(true);
|
||||
this.paddleList.add(new Paddle(this, 350, 500, 100, 15, 0));
|
||||
this.textElementList.get(0).getVisibleState(false);
|
||||
this.textElementList.get(1).getVisibleState(false);
|
||||
this.textElementList.get(2).getVisibleState(false);
|
||||
this.textElementList.get(3).getVisibleState(true);
|
||||
this.textElementList.get(4).getVisibleState(true);
|
||||
this.textElementList.get(5).getVisibleState(true);
|
||||
textElementList.get(3).setText(String.valueOf(this.score));
|
||||
textElementList.get(4).setText(String.valueOf(this.lives));
|
||||
textElementList.get(5).setText(String.valueOf(this.level));
|
||||
this.textElementList.get(8).setVisibility(false);
|
||||
this.textElementList.get(9).setVisibility(false);
|
||||
if (debugStartLevel > 1) {level = debugStartLevel;}
|
||||
this.textElementList.get(8).getVisibleState(false);
|
||||
this.textElementList.get(9).getVisibleState(false);
|
||||
this.currentLevel = new Level(this, level);
|
||||
this.currentLevel.constructLevel();
|
||||
this.updateStaticTextElements();
|
||||
}
|
||||
|
||||
public void initComponents() {
|
||||
public synchronized void initComponents() {
|
||||
this.ballList = new ArrayList<>();
|
||||
this.particleList = new ArrayList<>();
|
||||
this.paddleList = new ArrayList<>();
|
||||
this.textElementList = new ArrayList<>();
|
||||
|
||||
this.pokey = new LFSR();
|
||||
|
||||
// List of indices
|
||||
textElementList.add(new TextElement(this, "VECTOR BREAKOUT", 2.5f, 67, 280, 15, 2)); // 0 - Title
|
||||
textElementList.add(new TextElement(this, "MMXXV BOYFAILURE.DEV", 0.75f, 259, 315, 15, 1)); // 1 - Copyright
|
|
@ -1,7 +1,28 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* Invisible regions in each object that dictate when it collides with other objects.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250327
|
||||
*/
|
||||
public class Hitbox {
|
||||
|
||||
private Rectangle2D bounds;
|
98
src/main/java/dev/boyfailure/vectorbreakout/LFSR.java
Normal file
98
src/main/java/dev/boyfailure/vectorbreakout/LFSR.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.Timer;
|
||||
|
||||
/**
|
||||
* A software implementation of a LFSR-based (linear frequency shift register) pseudo-random number generator.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 1.0
|
||||
*/
|
||||
public class LFSR {
|
||||
|
||||
private static boolean[] originalArray = new boolean[] {true,false,true,true,true,true,true,true,false,true,false,false,false,true,true,false,false};
|
||||
|
||||
private boolean[] bitArray;
|
||||
private int bitCount;
|
||||
private int bitsReturned;
|
||||
private int firstXorIndex;
|
||||
private int secondXorIndex;
|
||||
|
||||
private Timer lfsrTimer;
|
||||
|
||||
public LFSR(int bitCount, int bitsReturned, int firstXorIndex, int secondXorIndex) {
|
||||
this.bitCount = bitCount;
|
||||
this.bitsReturned = bitsReturned;
|
||||
this.firstXorIndex = firstXorIndex;
|
||||
this.secondXorIndex = secondXorIndex;
|
||||
if (bitsReturned > bitCount) {bitsReturned = bitCount;}
|
||||
bitArray = new boolean[bitCount];
|
||||
for (int i = 0; i < bitCount; i++) {
|
||||
if (i < 17) {bitArray[i] = LFSR.originalArray[i];}
|
||||
else {
|
||||
bitArray[i] = bitArray[i - 3] ^ bitArray[i - 8];
|
||||
}
|
||||
}
|
||||
this.lfsrTimer = new Timer(1, new ActionListener(){public void actionPerformed(ActionEvent e) {LFSR.this.shift();}});
|
||||
this.lfsrTimer.start();
|
||||
}
|
||||
public LFSR() {
|
||||
this(17, 8, 11, 16);
|
||||
}
|
||||
|
||||
public int getDecimalValue() {
|
||||
int regValue = 0;
|
||||
int bitIndex = this.bitCount - 1;
|
||||
|
||||
for (int i = 0; i < this.bitsReturned; i++) {
|
||||
if (this.bitArray[bitIndex]) {
|
||||
regValue += Math.pow(2, i);
|
||||
}
|
||||
bitIndex--;
|
||||
}
|
||||
|
||||
return regValue;
|
||||
}
|
||||
public int getShiftedDecimalValue() {
|
||||
this.shift();
|
||||
return this.getDecimalValue();
|
||||
}
|
||||
|
||||
public void shift() {
|
||||
for (int i = (this.bitCount - 1); i > 0; i--) {
|
||||
this.bitArray[i] = this.bitArray[i - 1];
|
||||
}
|
||||
this.bitArray[0] = this.bitArray[this.firstXorIndex] ^ this.bitArray[this.secondXorIndex];
|
||||
}
|
||||
|
||||
public String getBits() {
|
||||
String result = "";
|
||||
for (int i = 0; i < this.bitCount; i++) {
|
||||
if (this.bitArray[i] == true) {
|
||||
result += "1";
|
||||
}
|
||||
else {
|
||||
result += "0";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,28 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The progressive levels that contain different brick layouts.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250325
|
||||
*/
|
||||
public class Level {
|
||||
|
||||
short levelID;
|
||||
|
@ -17,8 +38,8 @@ public class Level {
|
|||
public Level(GameState gameState, int id) {
|
||||
this.gameState = gameState;
|
||||
this.levelID = (short) id;
|
||||
|
||||
switch(id) {
|
||||
|
||||
switch(this.levelID) {
|
||||
case 1:
|
||||
this.levelName = "HELLO WORLD";
|
||||
this.levelLayout = new byte[]
|
||||
|
@ -29,35 +50,35 @@ public class Level {
|
|||
this.colorMap = new byte[]
|
||||
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
|
||||
break;
|
||||
case 2:
|
||||
this.levelName = "DOUBLE TROUBLE";
|
||||
this.levelLayout = new byte[]
|
||||
{4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
{4,4,4,4,4, 4,4,4,4,4,4,4,4, 4,4,4,4,4,4,
|
||||
3,3,3,3,3,16,3,3,3,3,3,3,3,16,3,3,3,3,3,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||
2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,
|
||||
1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1};
|
||||
this.colorMap = new byte[]
|
||||
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,18,13,13,13,13,13,13,13,18,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
|
||||
break;
|
||||
case 3:
|
||||
this.levelName = "THE GAP";
|
||||
this.levelLayout = new byte[]
|
||||
{5,5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,5,5,5,
|
||||
4,4,4,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,
|
||||
{5,5,5,5,5, 5,5,5,0,0,0,5,5, 5,5,5,5,5,5,
|
||||
4,4,4,4,4, 4,4,4,0,0,0,4,4, 4,4,4,4,4,4,
|
||||
3,3,3,3,3,16,3,3,0,0,0,3,3,16,3,3,3,3,3,
|
||||
2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,2,2,
|
||||
1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1};
|
||||
2,2,2,2,2, 2,2,2,0,0,0,2,2, 2,2,2,2,2,2,
|
||||
1,1,1,1,1, 1,1,1,0,0,0,1,1, 1,1,1,1,1,1};
|
||||
this.colorMap = new byte[]
|
||||
{14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
|
||||
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,18,13,13,13,13,13,13,13,18,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
|
||||
break;
|
||||
case 4:
|
||||
|
@ -70,7 +91,7 @@ public class Level {
|
|||
this.colorMap = new byte[]
|
||||
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
|
||||
break;
|
||||
case 5:
|
||||
|
@ -88,12 +109,12 @@ public class Level {
|
|||
this.colorMap = new byte[]
|
||||
{10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
|
||||
break;
|
||||
case 6:
|
||||
|
@ -112,11 +133,11 @@ public class Level {
|
|||
{14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
|
||||
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
|
||||
break;
|
||||
case 1001:
|
||||
|
@ -130,14 +151,13 @@ public class Level {
|
|||
this.colorMap = new byte[]
|
||||
{20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};
|
||||
break;
|
||||
case 1002:
|
||||
this.levelName = "I USE ARCH BTW";
|
||||
this.levelLayout = new byte[]
|
||||
//1 2 3 4 5 6 7 8 9 0
|
||||
{0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,
|
||||
|
@ -168,17 +188,17 @@ public class Level {
|
|||
7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,
|
||||
1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5};
|
||||
this.colorMap = new byte[]
|
||||
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
|
||||
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,0,
|
||||
2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,0,1,
|
||||
3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,0,1,2,
|
||||
4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,0,1,2,3,
|
||||
5,6,7,8,9,10,11,12,13,14,15,16,17,18,0,1,2,3,4,
|
||||
6,7,8,9,10,11,12,13,14,15,16,17,18,0,1,2,3,4,5,
|
||||
7,8,9,10,11,12,13,14,15,16,17,18,0,1,2,3,4,5,6};
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18, 0,
|
||||
2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18, 0, 1,
|
||||
3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18, 0, 1, 2,
|
||||
4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18, 0, 1, 2, 3,
|
||||
5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18, 0, 1, 2, 3, 4,
|
||||
6, 7, 8, 9,10,11,12,13,14,15,16,17,18, 0, 1, 2, 3, 4, 5,
|
||||
7, 8, 9,10,11,12,13,14,15,16,17,18, 0, 1, 2, 3, 4, 5, 6};
|
||||
break;
|
||||
default:
|
||||
this.levelName = "LEVEL 404: NOT FOUND (" + levelID + ")";
|
||||
this.levelName = "LEVEL 404: NOT FOUND (" + this.levelID + ")";
|
||||
this.levelLayout = new byte[]
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
|
@ -191,7 +211,7 @@ public class Level {
|
|||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void constructLevel() {
|
||||
|
@ -234,9 +254,8 @@ public class Level {
|
|||
}
|
||||
|
||||
public void startLevel() {
|
||||
gameState.bricksOnScreen = (short) this.brickList.size();
|
||||
gameState.textElementList.set(7, new TextElement(gameState, this.levelName, 1, 24, 480, 15, 2, 3000));
|
||||
gameState.textElementList.get(7).activateTimer();
|
||||
gameState.getTextElements().set(7, new TextElement(gameState, this.levelName, 1, 24, 480, 15, 2, 3000));
|
||||
gameState.getTextElements().get(7).activateTimer();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +1,28 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Customizable game menus.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 1.0
|
||||
*/
|
||||
public class Menu {
|
||||
|
||||
public String menuTitle = "Menu";
|
75
src/main/java/dev/boyfailure/vectorbreakout/Paddle.java
Normal file
75
src/main/java/dev/boyfailure/vectorbreakout/Paddle.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
/**
|
||||
* The player-controlled paddle that guides balls into bricks.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250323
|
||||
*/
|
||||
public class Paddle extends Entity {
|
||||
|
||||
byte paddleColor;
|
||||
byte paddleSpeed = 0;
|
||||
boolean isActive = true;
|
||||
float speedMultiplier = 1;
|
||||
Hitbox hitBoxLeft;
|
||||
Hitbox hitBoxRight;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
public Paddle(GameState gameState, int x, int y, int width, int height, int paddleColor) {
|
||||
this.gameState = gameState;
|
||||
this.posX = (short) x;
|
||||
this.posY = (short) y;
|
||||
this.width = (short) width;
|
||||
this.height = (short) height;
|
||||
this.paddleColor = (byte) paddleColor;
|
||||
this.hitBox = new Hitbox(x, y, width, height, 4);
|
||||
this.hitBoxLeft = new Hitbox(x, y, width / 5, height, 4);
|
||||
this.hitBoxRight = new Hitbox(x + ((width / 5) * 4), y, width / 5, height, 4);
|
||||
}
|
||||
|
||||
public void movePaddle(boolean direction) {
|
||||
if (this.paddleSpeed <= 15) {this.paddleSpeed += 3;}
|
||||
if (direction) {this.posX += (this.paddleSpeed * this.speedMultiplier);}
|
||||
else {this.posX -= (this.paddleSpeed * this.speedMultiplier);}
|
||||
if (this.posX <= 20) {this.posX = 20;}
|
||||
else if (this.posX >= (gameState.getInternalResX() - this.width - 20)) {this.posX = (short) (gameState.getInternalResX() - this.width - 20);}
|
||||
|
||||
this.hitBox.moveTo(this.posX, this.posY, this.width, this.height);
|
||||
this.hitBoxLeft.moveTo(this.posX, this.posY, this.width / 5, this.height);
|
||||
this.hitBoxRight.moveTo(this.posX + ((this.width / 5) * 4), this.posY, this.width / 5, this.height);
|
||||
}
|
||||
|
||||
public void cullPaddle() {
|
||||
isActive = false;
|
||||
this.posX = 32767;
|
||||
this.posY = 32767;
|
||||
this.hitBox.setBounds(32766, 32766, 32767, 32767);
|
||||
this.hitBoxLeft.setBounds(32766, 32766, 32767, 32767);
|
||||
this.hitBoxRight.setBounds(32766, 32766, 32767, 32767);
|
||||
}
|
||||
|
||||
public boolean getActiveState() {
|
||||
return this.isActive;
|
||||
}
|
||||
public void setActiveState(boolean activeState) {
|
||||
this.isActive = activeState;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,26 @@
|
|||
package dev.boyfailure.quajra.vectorbreakout;
|
||||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
/**
|
||||
* Small graphical effects that appear on screen.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250325
|
||||
*/
|
||||
public class Particle {
|
||||
|
||||
byte particleID;
|
||||
|
@ -32,8 +53,9 @@ public class Particle {
|
|||
|
||||
public void spawn(int lifetime) {
|
||||
this.isActive = true;
|
||||
if (gameState.confettiMode) {this.particleLifetime = 400;}
|
||||
else {this.particleLifetime = (short) lifetime;}
|
||||
// if (gameState.getConfettiMode()) {this.particleLifetime = 400;}
|
||||
// else {this.particleLifetime = (short) lifetime;}
|
||||
this.particleLifetime = (short) lifetime;
|
||||
}
|
||||
|
||||
public void update() {
|
247
src/main/java/dev/boyfailure/vectorbreakout/TextElement.java
Normal file
247
src/main/java/dev/boyfailure/vectorbreakout/TextElement.java
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Fields of text that display on screen.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250326
|
||||
*/
|
||||
public class TextElement {
|
||||
|
||||
private String text;
|
||||
private boolean active = true;
|
||||
private boolean isVisible = false;
|
||||
private boolean moveUpOnFrame = false;
|
||||
private float textScale = 1;
|
||||
private float vectorThickness = 1;
|
||||
private byte textColor;
|
||||
private short x;
|
||||
private short y;
|
||||
private short duration = 0;
|
||||
private long creationTime;
|
||||
|
||||
private GameState gameState;
|
||||
|
||||
/**
|
||||
* Text elements.
|
||||
* @param gameState the GameState in which the TextElement will reside
|
||||
* @param text the text that will be displayed
|
||||
* @param textScale the size of the text on screen
|
||||
* @param x the x coordinate of the text's origin point
|
||||
* @param y the y coordinate of the text's origin point
|
||||
* @param textColor the color of the text
|
||||
* @param vectorThickness the thickness of the vector lines
|
||||
*/
|
||||
public TextElement(GameState gameState, String text, float textScale, int x, int y, int textColor, float vectorThickness) {
|
||||
this.gameState = gameState;
|
||||
this.text = text;
|
||||
this.textScale = textScale;
|
||||
this.x = (short) x;
|
||||
this.y = (short) y;
|
||||
this.textColor = (byte) textColor;
|
||||
this.vectorThickness = vectorThickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text elements with a fadeout timer
|
||||
* @param gameState the GameState in which the TextElement will reside
|
||||
* @param text the text that will be displayed
|
||||
* @param textScale the size of the text on screen
|
||||
* @param x the x coordinate of the text's origin point
|
||||
* @param y the y coordinate of the text's origin point
|
||||
* @param textColor the color of the text
|
||||
* @param vectorThickness the thickness of the vector lines
|
||||
* @param duration how long the text will stay on screen, in milliseconds
|
||||
*/
|
||||
public TextElement(GameState gameState, String text, float textScale, int x, int y, int textColor, float vectorThickness, int duration) {
|
||||
this.gameState = gameState;
|
||||
this.text = text;
|
||||
this.textScale = textScale;
|
||||
this.x = (short) x;
|
||||
this.y = (short) y;
|
||||
this.textColor = (byte) textColor;
|
||||
this.vectorThickness = vectorThickness;
|
||||
this.duration = (short) duration;
|
||||
this.creationTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Accessor methods (get/set) ">
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Active state accessors ">
|
||||
/**
|
||||
* Gets the active status of the TextElement.
|
||||
* @return the active status of the TextElement
|
||||
*/
|
||||
public boolean getActiveState() {
|
||||
return this.active;
|
||||
}
|
||||
/**
|
||||
* Sets the active status of the TextElement.
|
||||
* @param activeState the active status of the TextElement
|
||||
*/
|
||||
public void setActiveState(boolean activeState) {
|
||||
this.active = activeState;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Visibility state accessors ">
|
||||
/**
|
||||
* Gets the visibility state of the TextElement.
|
||||
* @return the visibility state of the TextElement
|
||||
*/
|
||||
public boolean getVisibleState() {
|
||||
return this.isVisible;
|
||||
}
|
||||
/**
|
||||
* Sets the visible state of the TextElement.
|
||||
* @param visibleState the visible state of the TextElement
|
||||
*/
|
||||
public void getVisibleState(boolean visibleState) {
|
||||
this.isVisible = visibleState;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Color code accessors ">
|
||||
/**
|
||||
* Gets the color code of the TextElement.
|
||||
* @return the color code of the TextElement
|
||||
*/
|
||||
public byte getColor() {
|
||||
return this.textColor;
|
||||
}
|
||||
/**
|
||||
* Sets the color code of the TextElement.
|
||||
* @param textColor the color code of the TextElement
|
||||
*/
|
||||
public void setColor(int textColor) {
|
||||
this.textColor = (byte) textColor;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Scaling accessors ">
|
||||
/**
|
||||
* Returns the thickness of the TextElement's vector lines.
|
||||
* @return the thickness of the TextElement's vector lines
|
||||
*/
|
||||
public float getVectorThickness() {
|
||||
return this.vectorThickness;
|
||||
}
|
||||
/**
|
||||
* Sets the thickness of the TextElement's vector lines.
|
||||
* @param vectorThickness the new thickness of the TextElement's vector lines
|
||||
*/
|
||||
public void setVectorThickness(float vectorThickness) {
|
||||
this.vectorThickness = vectorThickness;
|
||||
}
|
||||
/**
|
||||
* Returns the scale of the text.
|
||||
* @return the scale of the text
|
||||
*/
|
||||
public float getTextScale() {
|
||||
return this.textScale;
|
||||
}
|
||||
/**
|
||||
* Sets the scale of the text.
|
||||
* @param textScale the new scale of the text
|
||||
*/
|
||||
public void setTextScale(float textScale) {
|
||||
this.textScale = textScale;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Text value accessors ">
|
||||
/**
|
||||
* Gets the text in the TextElement.
|
||||
* @return the text in the TextElement
|
||||
*/
|
||||
public String getText() {
|
||||
return this.text;
|
||||
}
|
||||
/**
|
||||
* Changes the text that the TextElement will display.
|
||||
* @param text the text that the TextElement will display
|
||||
*/
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Moves up on frame accessors ">
|
||||
public boolean movesUpOnFrame() {
|
||||
return this.moveUpOnFrame;
|
||||
}
|
||||
public void moveUpOnFrame() {
|
||||
this.moveUpOnFrame = true;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold defaultstate="collapsed" desc=" Position accessors ">
|
||||
public Point getPosition() {
|
||||
return new Point(this.x, this.y);
|
||||
}
|
||||
public short getPositionX() {
|
||||
return this.x;
|
||||
}
|
||||
public short getPositionY() {
|
||||
return this.y;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//</editor-fold>
|
||||
|
||||
/**
|
||||
* Prepares the TextElement for rendering.
|
||||
*/
|
||||
public void activateTimer() {
|
||||
this.setActiveState(true);
|
||||
long testLong = this.creationTime;
|
||||
if (this.duration > 0) {
|
||||
Timer levelTitleGTFO = new Timer();
|
||||
levelTitleGTFO.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
TextElement.this.getVisibleState(false);
|
||||
}
|
||||
}, this.duration);
|
||||
}
|
||||
this.getVisibleState(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the TextElement for culling.
|
||||
*/
|
||||
public void cull() {
|
||||
this.active = false;
|
||||
this.x = 32767;
|
||||
this.y = 32767;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the text that the TextElement will display.
|
||||
* @param x The x coordinate of the text's origin point.
|
||||
* @param y The y coordinate of the text's origin point.
|
||||
*/
|
||||
public void moveTo(int x, int y) {
|
||||
this.x = (short) x;
|
||||
this.y = (short) y;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2025 Naomi (boyfailure.dev).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.boyfailure.vectorbreakout;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.Timer;
|
||||
|
||||
/**
|
||||
* The initial code to launch the game.
|
||||
* @author Naomi (boyfailure.dev)
|
||||
* @since 20250323
|
||||
*/
|
||||
public class VectorBreakout {
|
||||
|
||||
public static GameState gameState;
|
||||
public static GameDisplay gameDisplay;
|
||||
public static GameFrame gameFrame;
|
||||
|
||||
/**
|
||||
* This empty constructor is currently only in here because the main class
|
||||
* constructor generated in new projects on NetBeans 4. Will investigate to
|
||||
* see if this is necessary in JDK 1.5 next time I am using those tools.
|
||||
*/
|
||||
public VectorBreakout() {}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Enable OpenGL for hardware acceleration
|
||||
System.setProperty("sun.java2d.opengl", "true");
|
||||
|
||||
// Initialize the components
|
||||
gameState = new GameState();
|
||||
gameDisplay = new GameDisplay(gameState);
|
||||
gameFrame = new GameFrame(gameState, gameDisplay);
|
||||
|
||||
Timer gameTick = new Timer((1000 / gameState.getGameTickRate()), gameState.getGameTickActionListener());
|
||||
gameTick.start();
|
||||
|
||||
Timer frameDisplay = new Timer((1000 / gameState.getTargetFrameRate()), new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
gameState.incrementFrameCounter();
|
||||
gameFrame.repaint();
|
||||
}
|
||||
});
|
||||
frameDisplay.start();
|
||||
|
||||
Timer gameCuller = new Timer(1000, gameState.getGameStateUpdateActionListener());
|
||||
gameCuller.start();
|
||||
|
||||
// Show the game window
|
||||
gameState.showTitleScreen();
|
||||
gameFrame.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue