Proper hitboxes, new colors, other rendering optimizations

This commit is contained in:
naomi 2025-03-27 03:46:46 +00:00
parent 55c301dec1
commit 0bb650e72e
7 changed files with 227 additions and 100 deletions

View file

@ -8,6 +8,7 @@ public class Ball {
short ballHeight = 7; short ballHeight = 7;
boolean isActive = false; boolean isActive = false;
byte ballColor = 0; byte ballColor = 0;
Hitbox hitBox;
byte speedX = 5; byte speedX = 5;
byte speedY = 5; byte speedY = 5;
@ -18,6 +19,7 @@ public class Ball {
this.ballWidth = (short) width; this.ballWidth = (short) width;
this.ballHeight = (short) height; this.ballHeight = (short) height;
this.ballColor = (byte) color; this.ballColor = (byte) color;
this.hitBox = new Hitbox(x, y, width, height, 1);
this.isActive = active; this.isActive = active;
} }
@ -41,11 +43,13 @@ public class Ball {
this.ballX += this.speedX; this.ballX += this.speedX;
this.ballY += this.speedY; this.ballY += this.speedY;
this.hitBox.moveTo(this.ballX, this.ballY, this.ballWidth, this.ballHeight);
this.checkCollision(); this.checkCollision();
} }
public void bounce(byte bounceType) { public void bounce(int bounceType) {
switch(bounceType) { switch((byte) bounceType) {
case 0: case 0:
this.speedY = (byte) -(this.speedY); this.speedY = (byte) -(this.speedY);
switch (VectorBreakout.chancey) { switch (VectorBreakout.chancey) {
@ -143,72 +147,59 @@ public class Ball {
// Check bricks // Check bricks
if (VectorBreakout.currentLevel != null) { if (VectorBreakout.currentLevel != null) {
for (short i = 0; i < VectorBreakout.currentLevel.levelBricks.length; i++) { for (short i = 0; i < VectorBreakout.currentLevel.levelBricks.length; i++) {
if (VectorBreakout.currentLevel.levelBricks[i] != null) { if (VectorBreakout.currentLevel.levelBricks[i] != null && !VectorBreakout.currentLevel.levelBricks[i].isBroken) {
if (VectorBreakout.currentLevel.levelBricks[i].brickY <= this.ballY && if (this.hitBox.collides(VectorBreakout.currentLevel.levelBricks[i].hitBox.bounds)) {
VectorBreakout.currentLevel.levelBricks[i].brickY + VectorBreakout.currentLevel.levelBricks[i].brickHeight >= this.ballY + this.ballHeight) { VectorBreakout.currentLevel.levelBricks[i].breakBrick();
if (VectorBreakout.currentLevel.levelBricks[i].brickX <= this.ballX && this.bounce((byte) 0);
VectorBreakout.currentLevel.levelBricks[i].brickX + VectorBreakout.currentLevel.levelBricks[i].brickWidth >= this.ballX + this.ballWidth) { return;
VectorBreakout.currentLevel.levelBricks[i].breakBrick();
this.bounce((byte) 0);
return;
} }
} }
} }
} }
}
// Check paddles // Check paddles
for (byte i = 0; i < VectorBreakout.currentPaddles.length; i++) { for (byte i = 0; i < VectorBreakout.currentPaddles.length; i++) {
if (VectorBreakout.currentPaddles[i] != null) { if (VectorBreakout.currentPaddles[i] != null) {
if (VectorBreakout.currentPaddles[i].paddleY <= this.ballY && if (this.hitBox.collides(VectorBreakout.currentPaddles[i].hitBox.bounds)) {
VectorBreakout.currentPaddles[i].paddleY + VectorBreakout.currentPaddles[i].paddleHeight >= this.ballY + this.ballHeight) {
if (VectorBreakout.currentPaddles[i].paddleX <= this.ballX && if (this.hitBox.collides(VectorBreakout.currentPaddles[i].hitBoxLeft.bounds)) {
VectorBreakout.currentPaddles[i].paddleX + VectorBreakout.currentPaddles[i].paddleWidth >= this.ballX + this.ballWidth) { this.bounce(2);
this.ballY -= 2;
// Check which section of paddle
short paddleSectionLength = (short) (VectorBreakout.currentPaddles[i].paddleWidth / 4);
// If on left edge
if (this.ballX + this.ballWidth < VectorBreakout.currentPaddles[i].paddleX + paddleSectionLength) {
this.bounce((byte) 2);
}
// If on right edge
else if (this.ballX > VectorBreakout.currentPaddles[i].paddleX + (paddleSectionLength * 3)) {
this.bounce((byte) 3);
}
// Center
else {
this.bounce((byte) 0);
}
// Draw particles
byte ballParticleGen = 0;
for (byte ii = 0; ii < VectorBreakout.currentParticles.length; ii++) {
if (VectorBreakout.currentParticles[ii] == null) {
ballParticleGen++;
switch(ballParticleGen) {
case 1:
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX, this.ballY - 10, 0, -2, 15, 2, 7, 3);
VectorBreakout.currentParticles[ii].spawn(5);
break;
case 2:
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX - 3, this.ballY - 10, -2, -4, 15, 2, 6, 3);
VectorBreakout.currentParticles[ii].spawn(5);
break;
case 3:
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX + 10, this.ballY - 10, 2, -4, 15, 2, 8, 3);
VectorBreakout.currentParticles[ii].spawn(5);
break;
}
if (ballParticleGen < 3) {continue;}
else {return;}
}
}
return;
} }
else if (this.hitBox.collides(VectorBreakout.currentPaddles[i].hitBoxRight.bounds)) {
this.bounce(3);
}
else {
this.bounce(0);
}
this.ballY -= 2;
// Draw particles
byte ballParticleGen = 0;
for (byte ii = 0; ii < VectorBreakout.currentParticles.length; ii++) {
if (VectorBreakout.currentParticles[ii] == null) {
ballParticleGen++;
switch(ballParticleGen) {
case 1:
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX, this.ballY - 10, 0, -2, 1, 2, 7, 3);
VectorBreakout.currentParticles[ii].spawn(5);
break;
case 2:
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX - 3, this.ballY - 10, -2, -4, 1, 2, 6, 3);
VectorBreakout.currentParticles[ii].spawn(5);
break;
case 3:
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX + 10, this.ballY - 10, 2, -4, 1, 2, 8, 3);
VectorBreakout.currentParticles[ii].spawn(5);
break;
}
if (ballParticleGen < 3) {continue;}
else {return;}
}
}
return;
} }
} }
} }
@ -221,19 +212,19 @@ public class Ball {
ballParticleGen++; ballParticleGen++;
switch(ballParticleGen) { switch(ballParticleGen) {
case 1: // Up left case 1: // Up left
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX - 3, this.ballY - 10, -2, -2, 15, 2, 6, 3); VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX - 3, this.ballY - 10, -2, -2, 1, 2, 6, 3);
VectorBreakout.currentParticles[ii].spawn(5); VectorBreakout.currentParticles[ii].spawn(5);
break; break;
case 2: // Up right case 2: // Up right
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX + 10, this.ballY - 10, 2, -2, 15, 2, 8, 3); VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX + 10, this.ballY - 10, 2, -2, 1, 2, 8, 3);
VectorBreakout.currentParticles[ii].spawn(5); VectorBreakout.currentParticles[ii].spawn(5);
break; break;
case 3: // Down right case 3: // Down right
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX - 3, this.ballY + 3, 2, 2, 15, 2, 2, 3); VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX - 3, this.ballY + 3, 2, 2, 1, 2, 2, 3);
VectorBreakout.currentParticles[ii].spawn(5); VectorBreakout.currentParticles[ii].spawn(5);
break; break;
case 4: // Down left case 4: // Down left
VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX + 10, this.ballY + 3, -2, 2, 15, 2, 4, 3); VectorBreakout.currentParticles[ii] = new Particle(0, this.ballX + 10, this.ballY + 3, -2, 2, 1, 2, 4, 3);
VectorBreakout.currentParticles[ii].spawn(5); VectorBreakout.currentParticles[ii].spawn(5);
break; break;
} }

View file

@ -10,6 +10,7 @@ public class Brick {
byte brickColor = 0; byte brickColor = 0;
byte scoreOnBreak = 10; byte scoreOnBreak = 10;
byte specialAbility = 0; byte specialAbility = 0;
Hitbox hitBox;
/** /**
* Bricks. * Bricks.
@ -26,6 +27,7 @@ public class Brick {
this.isBroken = isBroken; this.isBroken = isBroken;
this.brickColor = (byte) brickColor; this.brickColor = (byte) brickColor;
this.scoreOnBreak = (byte) score; this.scoreOnBreak = (byte) score;
this.hitBox = new Hitbox(x, y, this.brickWidth, this.brickHeight, 0);
this.specialAbility = (byte) specialAbility; this.specialAbility = (byte) specialAbility;
} }
@ -79,6 +81,7 @@ public class Brick {
this.brickX = 32767; this.brickX = 32767;
this.brickY = 32767; this.brickY = 32767;
this.hitBox.moveTo(32760, 32760, 2, 2);
} }
} }

View file

@ -82,9 +82,9 @@ public class GameDisplay extends JComponent {
resetBeam(); resetBeam();
moveBeam(VectorBreakout.currentBalls[i].ballX, VectorBreakout.currentBalls[i].ballY); moveBeam(VectorBreakout.currentBalls[i].ballX, VectorBreakout.currentBalls[i].ballY);
g2.draw(drawVec(VectorBreakout.currentBalls[i].ballWidth, 0)); g2.draw(drawVec(VectorBreakout.currentBalls[i].ballWidth, 0));
g2.draw(drawVec(0, VectorBreakout.currentBalls[i].ballHeight));
g2.draw(drawVec(-VectorBreakout.currentBalls[i].ballWidth, 0));
g2.draw(drawVec(0, -VectorBreakout.currentBalls[i].ballHeight)); g2.draw(drawVec(0, -VectorBreakout.currentBalls[i].ballHeight));
g2.draw(drawVec(-VectorBreakout.currentBalls[i].ballWidth, 0));
g2.draw(drawVec(0, VectorBreakout.currentBalls[i].ballHeight));
} }
} }
} }
@ -410,6 +410,51 @@ public class GameDisplay extends JComponent {
g2.drawString("actualFrames: " + VectorBreakout.actualFrames, 150, 48); g2.drawString("actualFrames: " + VectorBreakout.actualFrames, 150, 48);
g2.drawString("chancey: " + VectorBreakout.chancey, 150, 60); g2.drawString("chancey: " + VectorBreakout.chancey, 150, 60);
g2.drawString("ballsOnScreen: " + VectorBreakout.ballsOnScreen, 300, 24); g2.drawString("ballsOnScreen: " + VectorBreakout.ballsOnScreen, 300, 24);
short padBoxX, padBoxY, padBoxX2, padBoxY2;
g2.setStroke(new BasicStroke(1));
// Paddles
g2.setColor(vc(10, 0.5f));
for (byte i = 0; i < VectorBreakout.currentPaddles.length; i++) {
if (VectorBreakout.currentPaddles[i] != null) {
padBoxX = (short) VectorBreakout.currentPaddles[i].hitBox.bounds.getBounds2D().getMinX();
padBoxY = (short) VectorBreakout.currentPaddles[i].hitBox.bounds.getBounds2D().getMinY();
padBoxX2 = (short) VectorBreakout.currentPaddles[i].hitBox.bounds.getBounds2D().getWidth();
padBoxY2 = (short) VectorBreakout.currentPaddles[i].hitBox.bounds.getBounds2D().getHeight();
g2.fillRect(padBoxX, padBoxY + (40 - VectorBreakout.currentPaddles[i].paddleHeight), padBoxX2, padBoxY2);
padBoxX = (short) VectorBreakout.currentPaddles[i].hitBoxLeft.bounds.getBounds2D().getMinX();
padBoxY = (short) VectorBreakout.currentPaddles[i].hitBoxLeft.bounds.getBounds2D().getMinY();
padBoxX2 = (short) VectorBreakout.currentPaddles[i].hitBoxLeft.bounds.getBounds2D().getWidth();
padBoxY2 = (short) VectorBreakout.currentPaddles[i].hitBoxLeft.bounds.getBounds2D().getHeight();
g2.fillRect(padBoxX, padBoxY + (40 - VectorBreakout.currentPaddles[i].paddleHeight), padBoxX2, padBoxY2);
padBoxX = (short) VectorBreakout.currentPaddles[i].hitBoxRight.bounds.getBounds2D().getMinX();
padBoxY = (short) VectorBreakout.currentPaddles[i].hitBoxRight.bounds.getBounds2D().getMinY();
padBoxX2 = (short) VectorBreakout.currentPaddles[i].hitBoxRight.bounds.getBounds2D().getWidth();
padBoxY2 = (short) VectorBreakout.currentPaddles[i].hitBoxRight.bounds.getBounds2D().getHeight();
g2.fillRect(padBoxX, padBoxY + (40 - VectorBreakout.currentPaddles[i].paddleHeight), padBoxX2, padBoxY2);
}
}
// Balls
g2.setColor(vc(11, 1.0f));
for (byte i = 0; i < VectorBreakout.currentBalls.length; i++) {
if (VectorBreakout.currentBalls[i] != null) {
padBoxX = (short) VectorBreakout.currentBalls[i].hitBox.bounds.getBounds2D().getMinX();
padBoxY = (short) VectorBreakout.currentBalls[i].hitBox.bounds.getBounds2D().getMinY();
padBoxX2 = (short) VectorBreakout.currentBalls[i].hitBox.bounds.getBounds2D().getWidth();
padBoxY2 = (short) VectorBreakout.currentBalls[i].hitBox.bounds.getBounds2D().getHeight();
g2.fillRect(padBoxX, padBoxY + (40 - VectorBreakout.currentBalls[i].ballHeight), padBoxX2, padBoxY2);
}
}
// Bricks
g2.setColor(vc(12, 0.5f));
for (short i = 0; i < VectorBreakout.currentLevel.levelBricks.length; i++) {
if (VectorBreakout.currentLevel.levelBricks[i] != null) {
padBoxX = (short) VectorBreakout.currentLevel.levelBricks[i].hitBox.bounds.getBounds2D().getMinX();
padBoxY = (short) VectorBreakout.currentLevel.levelBricks[i].hitBox.bounds.getBounds2D().getMinY();
padBoxX2 = (short) VectorBreakout.currentLevel.levelBricks[i].hitBox.bounds.getBounds2D().getWidth();
padBoxY2 = (short) VectorBreakout.currentLevel.levelBricks[i].hitBox.bounds.getBounds2D().getHeight();
g2.fillRect(padBoxX, padBoxY + (40 - VectorBreakout.currentLevel.levelBricks[i].brickHeight), padBoxX2, padBoxY2);
}
}
} }
} }
@ -422,17 +467,32 @@ public class GameDisplay extends JComponent {
return new Line2D.Float(oldBeamX, oldBeamY, beamX, beamY); return new Line2D.Float(oldBeamX, oldBeamY, beamX, beamY);
} }
public Color vc(int col) { public Color vc(int colorID) {
switch ((byte) col) { return vc(colorID, 1.0f);
case 0: return Color.red; }
case 1: return Color.getHSBColor(25, 258, 77);
case 2: return Color.cyan; public Color vc(int colorID, float alpha) {
case 3: return Color.green; switch ((byte) colorID) {
case 4: return Color.magenta; case 0: return new Color(0, 0, 0, alpha); // black
case 5: return Color.yellow; // default is white but will be written elsewhere as 1
case 15: return Color.white; case 2: return new Color(0.66f, 0.66f, 0.66f, alpha); // grey
case 16: return Color.getHSBColor(313, 34, 100); // pink test case 3: return new Color(0.5f, 0.5f, 0.5f, alpha); // dark grey
default: return Color.white; case 4: return new Color(0.66f, 0, 0, alpha); // dark red
case 5: return new Color(0, 0.66f, 0, alpha); // dark green
case 6: return new Color(0, 0, 0.66f, alpha); // dark blue
case 7: return new Color(1, 0, 0, alpha); // red
case 8: return new Color(0, 1, 0, alpha); // green
case 9: return new Color(0, 0, 1, alpha); // blue
case 10: return new Color(1, 0.5f, 0.5f, alpha); // light red
case 11: return new Color(0.5f, 1, 0.5f, alpha); // light green
case 12: return new Color(0.5f, 0.5f, 1, alpha); // light blue
case 13: return new Color(1, 0.66f, 0, alpha); // orange
case 14: return new Color(1, 1, 0, alpha); // yellow
case 15: return new Color(0, 0.66f, 0.66f, alpha); // cyan
case 16: return new Color(0, 1, 1, alpha); // aqua
case 17: return new Color(0.66f, 0, 0.66f, alpha); // purple
case 18: return new Color(1, 0, 1, alpha); // magenta
default: return new Color(1, 1, 1, alpha); // white
} }
} }

View file

@ -0,0 +1,28 @@
package dev.boyfailure.quajra.vectorbreakout;
import java.awt.geom.Rectangle2D;
public class Hitbox {
Rectangle2D bounds;
byte padding = 0;
public Hitbox(int x, int y, int x2, int y2, int padding) {
this.padding = (byte) padding;
this.bounds = new Rectangle2D.Float(x - padding, y - padding, x2 + padding, y2 + padding);
}
public boolean collides(Rectangle2D hitBox2) {
if (this.bounds.intersects(hitBox2)) {
return true;
}
else {
return false;
}
}
public void moveTo(int x, int y, int x2, int y2) {
this.bounds.setRect(x - this.padding, y - this.padding, x2 + padding, y2 + padding);
}
}

View file

@ -9,6 +9,7 @@ public class Level {
byte rowHeight = 21; byte rowHeight = 21;
String levelName = "LEVEL"; String levelName = "LEVEL";
byte[] levelLayout; // 19 bricks per row byte[] levelLayout; // 19 bricks per row
byte[] colorMap;
Brick[] levelBricks; Brick[] levelBricks;
public Level(int id) { public Level(int id) {
@ -17,15 +18,20 @@ public class Level {
switch(id) { switch(id) {
case 1: case 1:
this.levelName = "HELLO WORLD"; this.levelName = "HELLO WORLD";
levelLayout = new byte[] 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,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 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}; 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,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,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12};
break; break;
case 2: case 2:
this.levelName = "DOUBLE TROUBLE"; this.levelName = "DOUBLE TROUBLE";
levelLayout = new byte[] 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,5,3,3,3,3,3,3,3,5,3,3,3,3,3, 3,3,3,3,3,5,3,3,3,3,3,3,3,5,3,3,3,3,3,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
@ -33,7 +39,7 @@ public class Level {
break; break;
case 3: case 3:
this.levelName = "THINKY THINKY..."; this.levelName = "THINKY THINKY...";
levelLayout = new byte[] this.levelLayout = new byte[]
{4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2, {4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,
3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1, 3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,
2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4, 2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,
@ -41,7 +47,7 @@ public class Level {
break; break;
case 4: case 4:
this.levelName = "HOLES!!"; this.levelName = "HOLES!!";
levelLayout = new byte[] 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,0,0,3,3,3,3,0,0,0,3,3,3,3,0,0,3,3, 3,3,0,0,3,3,3,3,0,0,0,3,3,3,3,0,0,3,3,
2,2,0,0,2,2,2,2,0,0,0,2,2,2,2,0,0,2,2, 2,2,0,0,2,2,2,2,0,0,0,2,2,2,2,0,0,2,2,
@ -49,7 +55,7 @@ public class Level {
break; break;
case 1001: case 1001:
this.levelName = "TRANS RIGHTS"; this.levelName = "TRANS RIGHTS";
levelLayout = new byte[] this.levelLayout = new byte[]
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
@ -61,9 +67,30 @@ public class Level {
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
break; break;
case 32767:
this.levelName = "DEBUG.LEVEL;";
this.levelLayout = new byte[]
{1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,
2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,
3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,
4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,
5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,
6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,
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};
break;
default: default:
this.levelName = "LEVEL " + levelID; this.levelName = "LEVEL " + levelID;
levelLayout = new byte[] 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,
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,
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,
@ -81,25 +108,25 @@ public class Level {
for (int i = 0; i < this.levelLayout.length; i++) { for (int i = 0; i < this.levelLayout.length; i++) {
switch (this.levelLayout[i]) { switch (this.levelLayout[i]) {
case 1: case 1:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 3, 4, 0); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 4, 0);
break; break;
case 2: case 2:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 2, 8, 0); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 8, 0);
break; break;
case 3: case 3:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 1, 16, 0); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 16, 0);
break; break;
case 4: case 4:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 0, 32, 0); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 32, 0);
break; break;
case 5: case 5:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 4, 8, 2); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 8, 2);
break; break;
case 6: case 6:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 4, 8, 0); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 8, 0);
break; break;
case 7: case 7:
this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, 15, 8, 0); this.levelBricks[i] = new Brick(brickLeftPlacement, (((int) (i / 19)) * this.rowHeight) + 50, false, this.colorMap[i], 8, 0);
break; break;
default: default:
this.levelBricks[i] = null; this.levelBricks[i] = null;

View file

@ -10,14 +10,19 @@ public class Paddle {
byte paddleSpeed = 0; byte paddleSpeed = 0;
boolean isActive = true; boolean isActive = true;
float speedMultiplier = 1; float speedMultiplier = 1;
Hitbox hitBox;
Hitbox hitBoxLeft;
Hitbox hitBoxRight;
public Paddle(int x, int y, int w, int h, int bc, float sm) { public Paddle(int x, int y, int width, int height, int paddleColor) {
this.paddleX = (short) x; this.paddleX = (short) x;
this.paddleY = (short) y; this.paddleY = (short) y;
this.paddleWidth = (short) w; this.paddleWidth = (short) width;
this.paddleHeight = (short) h; this.paddleHeight = (short) height;
this.paddleColor = (byte) bc; this.paddleColor = (byte) paddleColor;
this.speedMultiplier = sm; 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) { public void movePaddle(boolean direction) {
@ -26,6 +31,10 @@ public class Paddle {
else {this.paddleX -= (this.paddleSpeed * this.speedMultiplier);} else {this.paddleX -= (this.paddleSpeed * this.speedMultiplier);}
if (this.paddleX <= 20) {this.paddleX = 20;} if (this.paddleX <= 20) {this.paddleX = 20;}
else if (this.paddleX >= (VectorBreakout.gameResX - this.paddleWidth - 20)) {this.paddleX = (short) (VectorBreakout.gameResX - this.paddleWidth - 20);} else if (this.paddleX >= (VectorBreakout.gameResX - this.paddleWidth - 20)) {this.paddleX = (short) (VectorBreakout.gameResX - 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() { public void cullPaddle() {

View file

@ -65,6 +65,9 @@ public class VectorBreakout {
case 10: // Enter case 10: // Enter
if (isGameStarted) {isPaused = !isPaused;} if (isGameStarted) {isPaused = !isPaused;}
break; break;
case 35: // End
if (isLost || !isGameStarted) {isGameStarted = true;newGame(true);return;}
break;
case 32: // Space case 32: // Space
if (isLost || !isGameStarted) {isGameStarted = true;newGame();return;} if (isLost || !isGameStarted) {isGameStarted = true;newGame();return;}
if (!isPaused) { if (!isPaused) {
@ -103,6 +106,7 @@ public class VectorBreakout {
// Adapts vector drawing scale when the window is resized // Adapts vector drawing scale when the window is resized
gameFrame.addComponentListener(new ComponentAdapter() { gameFrame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent componentEvent) { public void componentResized(ComponentEvent componentEvent) {
// Experiment for ensuring scaling at a 4:3 ratio gameFrame.setSize((int) Math.abs(gameFrame.getSize().height * 1.333), gameFrame.getSize().height);
gameCanvas.beamScaleX = gameFrame.getBounds().width / 800f; gameCanvas.beamScaleX = gameFrame.getBounds().width / 800f;
gameCanvas.beamScaleY = gameFrame.getBounds().height / 600f; gameCanvas.beamScaleY = gameFrame.getBounds().height / 600f;
if (gameCanvas.beamScaleX <= gameCanvas.beamScaleY) {gameCanvas.beamThicknessScale = gameCanvas.beamScaleX;} if (gameCanvas.beamScaleX <= gameCanvas.beamScaleY) {gameCanvas.beamThicknessScale = gameCanvas.beamScaleX;}
@ -237,22 +241,27 @@ public class VectorBreakout {
} }
public static void newGame() { public static void newGame() {
newGame(false);
}
public static void newGame(boolean debugLevel) {
for (byte i = 0; i < currentTextElements.length; i++) { for (byte i = 0; i < currentTextElements.length; i++) {
currentTextElements[i] = null; currentTextElements[i] = null;
} }
lives = 5; lives = 5;
isLost = false; isLost = false;
score = 0; score = 0;
level = 1; if (debugLevel) {level = 32767;}
else {level = 1;}
frameCounter = 0; frameCounter = 0;
ballsOnScreen = 0; ballsOnScreen = 0;
movingLeft = false; movingLeft = false;
movingRight = false; movingRight = false;
currentPaddles[0] = new Paddle(350, 500, 100, 15, 0, 1); currentPaddles[0] = new Paddle(350, 500, 100, 15, 0);
//test currentPaddles[0] = new Paddle(0, 500, 800, 60, 0, 1); //test currentPaddles[0] = new Paddle(0, 500, 800, 60, 0);
currentTextElements[0] = new TextElement(String.valueOf(score), 1, 20, -13, 15, 2); currentTextElements[0] = new TextElement(String.valueOf(score), 1, 20, -13, 1, 2);
currentTextElements[1] = new TextElement(String.valueOf(lives), 1, 200, -13, 15, 2); currentTextElements[1] = new TextElement(String.valueOf(lives), 1, 200, -13, 1, 2);
currentTextElements[2] = new TextElement(String.valueOf(level), 1, 380, -13, 15, 2); currentTextElements[2] = new TextElement(String.valueOf(level), 1, 380, -13, 1, 2);
currentTextElements[0].activate(); currentTextElements[0].activate();
currentTextElements[1].activate(); currentTextElements[1].activate();
currentTextElements[2].activate(); currentTextElements[2].activate();