Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.

Comments

Add Paddle Components, refactor codebase and ci#10

Merged
thnhmai06 merged 33 commits intomainfrom
feature/paddle
Oct 21, 2025
Merged

Add Paddle Components, refactor codebase and ci#10
thnhmai06 merged 33 commits intomainfrom
feature/paddle

Conversation

@ManhTanTran
Copy link
Collaborator

🏓 Summary

This pull request introduces the Paddle module to the BounceVerse project, providing the core player-controlled paddle and its special variants.

🔧 Implemented Features

  • PaddleComponent: base paddle logic (movement, reset position)
  • ExpandPaddle: larger paddle with increased width
  • ShrinkPaddle: smaller paddle with reduced width
  • LaserPaddle: paddle that shoots bullets upward
  • PaddleFactory: registers all paddle entities for FXGL spawning

@ManhTanTran ManhTanTran requested review from Copilot and thnhmai06 and removed request for Copilot October 7, 2025 18:23
@ManhTanTran ManhTanTran self-assigned this Oct 7, 2025
@thnhmai06 thnhmai06 closed this Oct 8, 2025
@thnhmai06 thnhmai06 deleted the feature/paddle branch October 8, 2025 04:17
@thnhmai06 thnhmai06 restored the feature/paddle branch October 8, 2025 04:18
@thnhmai06 thnhmai06 reopened this Oct 8, 2025
@thnhmai06 thnhmai06 force-pushed the main branch 7 times, most recently from a5a9815 to a54ee1a Compare October 8, 2025 05:04
Copilot AI review requested due to automatic review settings October 9, 2025 11:08
Copy link
Member

@thnhmai06 thnhmai06 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to update to new Component system

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 56 out of 69 changed files in this pull request and generated 8 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


public static void main(String[] args) {
launchOption = new LaunchOption(args);
static void main(String[] args) {
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main method must be public to be recognized by the JVM as the application entry point. Change to public static void main(String[] args).

Suggested change
static void main(String[] args) {
public static void main(String[] args) {

Copilot uses AI. Check for mistakes.
protected void onActionBegin() {
FXGL.getGameWorld()
.getEntitiesByType(EntityType.PADDLE)
.forEach(e -> e.getComponent(Velocity.class).left());
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Velocity has no left() method; this will not compile. Replace with setting the vector explicitly, e.g. e.getComponent(Velocity.class).setVector(new com.almasb.fxgl.core.math.Vec2(-400, 0)).

Copilot uses AI. Check for mistakes.
protected void onActionBegin() {
FXGL.getGameWorld()
.getEntitiesByType(EntityType.PADDLE)
.forEach(e -> e.getComponent(Velocity.class).right());
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Velocity has no right() method; this will not compile. Replace with e.getComponent(Velocity.class).setVector(new com.almasb.fxgl.core.math.Vec2(400, 0)).

Copilot uses AI. Check for mistakes.
.type(EntityType.BULLET)
.viewWithBBox(new Circle(4, Color.YELLOW))
.with(new CollidableComponent(true))
.with(new BulletVelocity(data.get("speed"), data.get("direction")))
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructor arguments do not match any BulletVelocity overload (expects Vec2, Point2D, or two doubles). Build a velocity vector from speed and direction, e.g. new BulletVelocity(((javafx.geometry.Point2D) data.get("direction")).multiply((Double) data.get("speed"))).

Copilot uses AI. Check for mistakes.
Comment on lines 63 to 76
protected void onCollision(Entity paddle, Entity wall) {
if (wall.hasComponent(Border.class)) {
var wallProp = wall.getComponent(Wall.class);
var move = paddle.getComponentOptional(Velocity.class);

move.ifPresent(m -> m.setVector(0));

switch (wallProp.getSide()) {
case LEFT -> paddle.setX(wall.getRightX());
case RIGHT -> paddle.setX(wall.getX() - paddle.getWidth());
default ->
throw new IllegalArgumentException(
"Unexpected value: " + wallProp.getSide());
}
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent component types and an invalid setter: checking Border.class then retrieving Wall.class is inconsistent, and setVector(0) is invalid (expects a Vec2). Use a single wall component type consistently (e.g., Wall.class) and stop the paddle with move.ifPresent(Velocity::stop) or setVector(new Vec2(0, 0)). Also ensure the correct Wall/Border class is imported.

Copilot uses AI. Check for mistakes.
public static UserSetting getSetting() {
final var filepath = getFilepath();
try {
final var file = new Toml().read(filepath.toString());
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Toml.read(String) reads TOML content, not a file path. Use a File when reading from disk: new Toml().read(new java.io.File(filepath.toUri())) to correctly load the user's settings file.

Suggested change
final var file = new Toml().read(filepath.toString());
final var file = new Toml().read(new File(filepath.toUri()));

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +39
double px = FXGL.getAppWidth() / 2.0 - 60;
double py = FXGL.getAppHeight() - 40;
FXGL.spawn("paddle", px, py);
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Avoid magic numbers for centering the paddle; compute based on the spawned entity’s width, e.g., spawn the paddle first then setX(appWidth / 2.0 - paddle.getWidth() / 2.0).

Suggested change
double px = FXGL.getAppWidth() / 2.0 - 60;
double py = FXGL.getAppHeight() - 40;
FXGL.spawn("paddle", px, py);
double py = FXGL.getAppHeight() - 40;
var paddle = FXGL.spawn("paddle", 0, py);
paddle.setX(FXGL.getAppWidth() / 2.0 - paddle.getWidth() / 2.0);

Copilot uses AI. Check for mistakes.
* [skip ci] refactor: replace `For*` interface with `Suitable*` annotation (remove `Tag` system)

* [skip ci] chore: reformat code and optimize import

* [skip ci] chore: update JAVA_LANGUAGE to 24_PREVIEW

* [skip ci] refactor: Assign new `For*` annotation for components

* [skip ci] fix: fix null ref on `Utils.Time.Cooldown#current`
Copilot AI review requested due to automatic review settings October 20, 2025 14:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 68 out of 76 changed files in this pull request and generated 6 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

.type(EntityType.WALL)
.at(0, 0)
.viewWithBBox(new Rectangle(WALL_THICKNESS, FXGL.getAppHeight()))
.with(new Wall(Side.LEFT))
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Wall class is referenced but the import statement and class definition are missing from this PR. This will cause a compilation error.

Copilot uses AI. Check for mistakes.
@Override
protected void onCollision(Entity paddle, Entity wall) {
if (wall.hasComponent(Border.class)) {
var wallProp = wall.getComponent(Wall.class);
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Wall class is referenced but not imported. The import at line 8 references Wall from components.properties.wall.Border but here it's used as Wall.class without proper import.

Copilot uses AI. Check for mistakes.
private final Vec2 vector;

UnitVelocity(double vx, double vy) {
this.vector = new Vec2(vx, vy).normalize();
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normalizing a zero vector (0, 0) for STAND will produce NaN values. The STAND case should not call normalize() or should handle the zero vector specially.

Suggested change
this.vector = new Vec2(vx, vy).normalize();
Vec2 v = new Vec2(vx, vy);
this.vector = (vx == 0 && vy == 0) ? v : v.normalize();

Copilot uses AI. Check for mistakes.
*
* @see Vec2
*/
public class Velocity extends Component implements Property {
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing convenience methods for common movement directions. Consider adding left(), right(), up(), down() methods to work with UnitVelocity enum, as these are referenced in InputSystem but not defined here.

Copilot uses AI. Check for mistakes.
Comment on lines 35 to 36
double leftX = entity.getCenter().getX() - halfWidth + 4;
double rightX = entity.getCenter().getX() + halfWidth - 8;
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic numbers 4 and 8 are used for bullet spawn positions without explanation. These should be extracted as named constants (e.g., BULLET_OFFSET_LEFT, BULLET_OFFSET_RIGHT) or calculated based on bullet radius.

Copilot uses AI. Check for mistakes.
* nên, một thuộc tính kiểu trong Entity như này là cần thiết.
*
* @see OptionalTag
* @see Optional
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid @see reference to Optional which is not a relevant class in this context. This should likely reference a different class or be removed entirely.

Suggested change
* @see Optional

Copilot uses AI. Check for mistakes.
Introduce Attack and Attributes classes to manage damage and defense mechanics for entities. The Attack class allows entities to inflict damage based on their attributes, while the Attributes class holds general property values like defense. This enhances gameplay dynamics by enabling combat interactions.
Copilot AI review requested due to automatic review settings October 21, 2025 17:23
@thnhmai06 thnhmai06 marked this pull request as ready for review October 21, 2025 17:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 72 out of 80 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

final var theirAttributes = obj.getComponentOptional(Attributes.class);
final var theirDefense = theirAttributes.map(Attributes::getDefense).orElse(0);

final var actualDamage = damage >= 0 ? Math.min(0, damage - theirDefense) : damage;
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The damage calculation logic is incorrect. For positive damage, Math.min(0, damage - theirDefense) will always return a non-positive value (0 or negative), which means no damage will be dealt. This should be Math.max(0, damage - theirDefense) to ensure damage is reduced by defense but never goes below 0.

Suggested change
final var actualDamage = damage >= 0 ? Math.min(0, damage - theirDefense) : damage;
final var actualDamage = damage >= 0 ? Math.max(0, damage - theirDefense) : damage;

Copilot uses AI. Check for mistakes.
* @return {@code true} nếu đã thực thi, {@code false} nếu chưa
*/
public final boolean isActive() {
return current != null && current.isExpired() && modified != null;
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition checks if current.isExpired() is true to determine if active, but this is inverted logic. An expired timer action means the behavior has completed, not that it's currently active. This should be !current.isExpired() to check if the timer is still running.

Suggested change
return current != null && current.isExpired() && modified != null;
return current != null && !current.isExpired() && modified != null;

Copilot uses AI. Check for mistakes.
*
* <h1>{@link CanExecute}</h1>
*
* Có thể thưc thi hành động nào đó.
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misspelled 'thực' as 'thưc' in Vietnamese comment.

Suggested change
* thể thưc thi hành động nào đó.
* thể thực thi hành động nào đó.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 72 out of 80 changed files in this pull request and generated 2 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

*
* <h1>{@link CanExecute}</h1>
*
* Có thể thưc thi hành động nào đó.
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'thưc' to 'thực'.

Suggested change
* thể thưc thi hành động nào đó.
* thể thực thi hành động nào đó.

Copilot uses AI. Check for mistakes.
Comment on lines 11 to 18
* <h1>{@link HeathDeath}</h1>
*
* Hành động chết <s>vì yêu :<</s> vì hết máu. <br>
* <b>Yêu cầu entity có {@link HealthIntComponent} trước.</b>
*/
@Required(HealthIntComponent.class)
@ForEntity({})
public class HeathDeath extends Behavior {
Copy link

Copilot AI Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class name 'HeathDeath' is misspelled. It should be 'HealthDeath' (referring to death from health loss).

Suggested change
* <h1>{@link HeathDeath}</h1>
*
* Hành động chết <s> yêu :<</s> hết máu. <br>
* <b>Yêu cầu entity {@link HealthIntComponent} trước.</b>
*/
@Required(HealthIntComponent.class)
@ForEntity({})
public class HeathDeath extends Behavior {
* <h1>{@link HealthDeath}</h1>
*
* Hành động chết <s> yêu :<</s> hết máu. <br>
* <b>Yêu cầu entity {@link HealthIntComponent} trước.</b>
*/
@Required(HealthIntComponent.class)
@ForEntity({})
public class HealthDeath extends Behavior {

Copilot uses AI. Check for mistakes.
Modified CI configuration to use startsWith instead of contains for detecting '[skip ci]' in commit messages, improving clarity and functionality.
Renamed `HeathDeath` to `HealthDeath` and fixed spelling in `CanExecute` documentation. These changes improve code readability and maintainability.
Copilot AI review requested due to automatic review settings October 21, 2025 17:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 72 out of 80 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Member

@thnhmai06 thnhmai06 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look fine

@thnhmai06 thnhmai06 changed the title ✨ feat(paddle): add PaddleComponent and variants (Expand, Shrink, Laser, Bullet) with PaddleFactory Add Paddle Components, refactor codebase and ci Oct 21, 2025
@thnhmai06 thnhmai06 merged commit 9d105b2 into main Oct 21, 2025
7 checks passed
@thnhmai06 thnhmai06 deleted the feature/paddle branch October 21, 2025 17:55
thnhmai06 added a commit that referenced this pull request Oct 21, 2025
* feat: Brick

* feat(brick): add PowerBrick and update Brick, ExoplodeBrick, ProtectedBrick

* docs(brick): add Javadoc for Brick, ExoplodeBrick, PowerBrick, ProtectedBrick

* refactor(brick): remove NormalBrick and StrongBrick

* feat(paddle): add ExpendPaddle, LaserPaddle, ShrinkPaddle and update Paddle

* feat(paddle): add ExpendPaddle, LaserPaddle, ShrinkPaddle and update Paddle

* refactor: remove brick and gameManager packages

* feat(brick): refactor and document brick module (Factory, Component, Protected, Explode)

* feat(game): add GameManager and BounceVerseApp for game initialization

* feat(paddle): add PaddleComponent and variants (Expand, Shrink, Laser, Bullet) with factory integration

* feat(brick): implement explosion logic and health management refactor

* feat(components): add new paddle behaviors and properties (Bullet, Width); refactor brick to components structure

* refactor: migrate paddle and bullet systems to new structure

* refactor(paddle): adjust PaddleFactory, Shoot  and Width property for move and scaling

* feat(wall): add WallFactory and Wall components with Move property for paddle collision

* feat(physics): handle paddle-wall collision in CollisionSystem

* feat(data): add WALL entity type for collision system

* feat(behavior): update BrickExplode logic for new collision handling

* feat(paddle-wall): add Move component update and WallFactory with correct sides and spawn registration

* (skip ci) refactor: rename components and update imports for consistency

Refactored various components by renaming `BehaviorComponent` to `Behavior`, `OptionalTag` to `Optional`, and `PropertyComponent` to `Property`. Updated imports accordingly to maintain consistency across the codebase.

* [skip ci] Add and refactor Systems, Core (#15)

* [skip ci] feat(core): implement game systems and refactor initialization

- Introduced GameSystem, InputSystem, PhysicSystem, and UISystem for better organization and modularity (applies game logic, input handling, physics, and UI settings).
- Refactored Bounceverse to utilize new systems for initialization and configuration management.
- Updated credits and settings files for improved user experience.

* [skip ci] ci: update CI configuration for Spotless checks and builds

- Rename linting.yml to spotlessCheck.yml for clarity
- Add concurrency settings to optimize CI runs
- Modify job conditions to skip CI based on commit messages
- Implement automatic code formatting application on failure

* [skip ci] feat(core): initialize Video instance in UserSetting

Add a new Video instance to the UserSetting class to ensure proper initialization and avoid null references. This change enhances the reliability of video settings management.

* [skip ci] refactor: rename spotlessCheck.yml to spotless.yml for consistency

* [skip ci] chore: Remove log files

* Replace `For*` interface tag by annotation (#16)

* [skip ci] refactor: replace `For*` interface with `Suitable*` annotation (remove `Tag` system)

* [skip ci] chore: reformat code and optimize import

* [skip ci] chore: update JAVA_LANGUAGE to 24_PREVIEW

* [skip ci] refactor: Assign new `For*` annotation for components

* [skip ci] fix: fix null ref on `Utils.Time.Cooldown#current`

* feat: add Attack and Attributes components for entity interactions

Introduce Attack and Attributes classes to manage damage and defense mechanics for entities. The Attack class allows entities to inflict damage based on their attributes, while the Attributes class holds general property values like defense. This enhances gameplay dynamics by enabling combat interactions.

* fix(paddle): fix freeze paddle

* ci: update CI conditions to use startsWith for skip ci

Modified CI configuration to use startsWith instead of contains for detecting '[skip ci]' in commit messages, improving clarity and functionality.

* chore: correct spelling and rename classes for consistency

Renamed `HeathDeath` to `HealthDeath` and fixed spelling in `CanExecute` documentation. These changes improve code readability and maintainability.

---------

Co-authored-by: Mai Thành <62001770+thnhmai06@users.noreply.github.com>
ManhTanTran added a commit that referenced this pull request Oct 22, 2025
* feat: Brick

* feat(brick): add PowerBrick and update Brick, ExoplodeBrick, ProtectedBrick

* docs(brick): add Javadoc for Brick, ExoplodeBrick, PowerBrick, ProtectedBrick

* refactor(brick): remove NormalBrick and StrongBrick

* feat(paddle): add ExpendPaddle, LaserPaddle, ShrinkPaddle and update Paddle

* feat(paddle): add ExpendPaddle, LaserPaddle, ShrinkPaddle and update Paddle

* refactor: remove brick and gameManager packages

* feat(brick): refactor and document brick module (Factory, Component, Protected, Explode)

* feat(game): add GameManager and BounceVerseApp for game initialization

* feat(paddle): add PaddleComponent and variants (Expand, Shrink, Laser, Bullet) with factory integration

* feat(brick): implement explosion logic and health management refactor

* feat(components): add new paddle behaviors and properties (Bullet, Width); refactor brick to components structure

* refactor: migrate paddle and bullet systems to new structure

* refactor(paddle): adjust PaddleFactory, Shoot  and Width property for move and scaling

* feat(wall): add WallFactory and Wall components with Move property for paddle collision

* feat(physics): handle paddle-wall collision in CollisionSystem

* feat(data): add WALL entity type for collision system

* feat(behavior): update BrickExplode logic for new collision handling

* feat(paddle-wall): add Move component update and WallFactory with correct sides and spawn registration

* (skip ci) refactor: rename components and update imports for consistency

Refactored various components by renaming `BehaviorComponent` to `Behavior`, `OptionalTag` to `Optional`, and `PropertyComponent` to `Property`. Updated imports accordingly to maintain consistency across the codebase.

* [skip ci] Add and refactor Systems, Core (#15)

* [skip ci] feat(core): implement game systems and refactor initialization

- Introduced GameSystem, InputSystem, PhysicSystem, and UISystem for better organization and modularity (applies game logic, input handling, physics, and UI settings).
- Refactored Bounceverse to utilize new systems for initialization and configuration management.
- Updated credits and settings files for improved user experience.

* [skip ci] ci: update CI configuration for Spotless checks and builds

- Rename linting.yml to spotlessCheck.yml for clarity
- Add concurrency settings to optimize CI runs
- Modify job conditions to skip CI based on commit messages
- Implement automatic code formatting application on failure

* [skip ci] feat(core): initialize Video instance in UserSetting

Add a new Video instance to the UserSetting class to ensure proper initialization and avoid null references. This change enhances the reliability of video settings management.

* [skip ci] refactor: rename spotlessCheck.yml to spotless.yml for consistency

* [skip ci] chore: Remove log files

* Replace `For*` interface tag by annotation (#16)

* [skip ci] refactor: replace `For*` interface with `Suitable*` annotation (remove `Tag` system)

* [skip ci] chore: reformat code and optimize import

* [skip ci] chore: update JAVA_LANGUAGE to 24_PREVIEW

* [skip ci] refactor: Assign new `For*` annotation for components

* [skip ci] fix: fix null ref on `Utils.Time.Cooldown#current`

* feat: add Attack and Attributes components for entity interactions

Introduce Attack and Attributes classes to manage damage and defense mechanics for entities. The Attack class allows entities to inflict damage based on their attributes, while the Attributes class holds general property values like defense. This enhances gameplay dynamics by enabling combat interactions.

* fix(paddle): fix freeze paddle

* ci: update CI conditions to use startsWith for skip ci

Modified CI configuration to use startsWith instead of contains for detecting '[skip ci]' in commit messages, improving clarity and functionality.

* chore: correct spelling and rename classes for consistency

Renamed `HeathDeath` to `HealthDeath` and fixed spelling in `CanExecute` documentation. These changes improve code readability and maintainability.

---------

Co-authored-by: Mai Thành <62001770+thnhmai06@users.noreply.github.com>
@thnhmai06 thnhmai06 restored the feature/paddle branch October 27, 2025 05:46
@thnhmai06 thnhmai06 deleted the feature/paddle branch October 27, 2025 07:48
@thnhmai06 thnhmai06 restored the feature/paddle branch October 27, 2025 07:51
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants