diff --git a/animations/312cc4e6-8c44-43e7-828a-e7e2a77836f3.png b/animations/312cc4e6-8c44-43e7-828a-e7e2a77836f3.png new file mode 100644 index 0000000..d82e1f1 Binary files /dev/null and b/animations/312cc4e6-8c44-43e7-828a-e7e2a77836f3.png differ diff --git a/animations/54f657bd-8108-464c-9bbe-63944fc14f6b.png b/animations/54f657bd-8108-464c-9bbe-63944fc14f6b.png new file mode 100644 index 0000000..ad3becf Binary files /dev/null and b/animations/54f657bd-8108-464c-9bbe-63944fc14f6b.png differ diff --git a/audio/7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg b/audio/7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg new file mode 100644 index 0000000..5b9a339 Binary files /dev/null and b/audio/7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg differ diff --git a/audio/cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.ogg b/audio/cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.ogg new file mode 100644 index 0000000..47dffff Binary files /dev/null and b/audio/cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.ogg differ diff --git a/data.mv.db b/data.mv.db index 4be0383..0bacdca 100644 Binary files a/data.mv.db and b/data.mv.db differ diff --git a/project.bep b/project.bep index 72e7e72..0a38f8d 100644 --- a/project.bep +++ b/project.bep @@ -10,7 +10,11 @@ $ab9d40b4-eb28-45d7-bff2-9432a05eb41a(ab9d40b4-eb28-45d7-bff2-9432a05eb41a.xml Start MenuB[ $56ca6b39-f949-4212-9c23-312db25887e0(56ca6b39-f949-4212-9c23-312db25887e0.xml Game MenuJ[ $61e67e44-a0cd-4210-8d1e-ccddcd62c78d(61e67e44-a0cd-4210-8d1e-ccddcd62c78d.pngSlash (JZ -$e6f067f1-eba0-4e62-99c3-2fd867e6f142(e6f067f1-eba0-4e62-99c3-2fd867e6f142.pngPoof (R] +$e6f067f1-eba0-4e62-99c3-2fd867e6f142(e6f067f1-eba0-4e62-99c3-2fd867e6f142.pngPoof (J[ +$312cc4e6-8c44-43e7-828a-e7e2a77836f3(312cc4e6-8c44-43e7-828a-e7e2a77836f3.pngArrow (J[ +$54f657bd-8108-464c-9bbe-63944fc14f6b(54f657bd-8108-464c-9bbe-63944fc14f6b.pngPunch (R] $1311327d-4b74-4252-94da-23ee4129e357(1311327d-4b74-4252-94da-23ee4129e357.ogg Sword slashR\ $e452e215-f581-40fe-a5cf-f555d3db83b8(e452e215-f581-40fe-a5cf-f555d3db83b8.ogg -Deku death \ No newline at end of file +Deku deathRW +$cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df(cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.oggArrowR] +$7c33cfee-e6a8-42b8-8b1d-c801b242dcf0(7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg Arrow punch \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/database/dao/RangedWeaponDAO.java b/src/main/java/com/bartlomiejpluta/demo/database/dao/RangedWeaponDAO.java new file mode 100644 index 0000000..b3b72ca --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/database/dao/RangedWeaponDAO.java @@ -0,0 +1,37 @@ +package com.bartlomiejpluta.demo.database.dao; + +import java.sql.*; +import java.util.*; + +import com.bartlomiejpluta.base.api.context.Context; + +import com.bartlomiejpluta.demo.database.model.RangedWeaponModel; + +public class RangedWeaponDAO { + private final Map items = new HashMap<>(); + + public void init(Context context) { + context.withDatabase(db -> { + var result = db.prepareStatement("SELECT * FROM `ranged_weapon`").executeQuery(); + + while(result.next()) { + var weapon = RangedWeaponModel.builder() + .id(result.getString("id")) + .name(result.getString("name")) + .damage(result.getString("damage")) + .cooldown(result.getInt("cooldown")) + .animation(result.getString("animation")) + .sound(result.getString("sound")) + .range(result.getInt("range")) + .punchAnimation(result.getString("punch_animation")) + .punchSound(result.getString("punch_sound")) + .build(); + items.put(result.getString("id"), weapon); + } + }); + } + + public RangedWeaponModel get(String id) { + return items.get(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/database/model/RangedWeaponModel.java b/src/main/java/com/bartlomiejpluta/demo/database/model/RangedWeaponModel.java new file mode 100644 index 0000000..b24c3b6 --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/database/model/RangedWeaponModel.java @@ -0,0 +1,17 @@ +package com.bartlomiejpluta.demo.database.model; + +import lombok.*; + +@Data +@Builder +public class RangedWeaponModel { + private final String id; + private final String name; + private final int cooldown; + private final String damage; + private final String animation; + private final String sound; + private final int range; + private final String punchAnimation; + private final String punchSound; +} \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Character.java b/src/main/java/com/bartlomiejpluta/demo/entity/Character.java index 3f3553e..8415628 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Character.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Character.java @@ -9,7 +9,7 @@ import com.bartlomiejpluta.base.lib.entity.EntityDelegate; import com.bartlomiejpluta.base.lib.animation.AnimationRunner; import com.bartlomiejpluta.demo.runner.DemoRunner; -import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon; +import com.bartlomiejpluta.demo.world.weapon.Weapon; public class Character extends EntityDelegate { private static final Logger log = LoggerFactory.getLogger(Character.class); @@ -28,7 +28,7 @@ public class Character extends EntityDelegate { protected int hp; @Setter - private MeleeWeapon weapon; + private Weapon weapon; public Character(@NonNull Context context, @NonNull Entity entity) { super(entity); @@ -42,12 +42,8 @@ public class Character extends EntityDelegate { } if(attackCooldown >= weapon.getCooldown()) { - var facingNeighbour = getCoordinates().add(getFaceDirection().vector, new Vector2i()); - for(var entity : getLayer().getEntities()) { - if(entity.getCoordinates().equals(facingNeighbour) && entity.isBlocking() && entity instanceof Character) { - weapon.attack((Character) entity); - attackCooldown = 0; - } + if(weapon.attack(this)) { + attackCooldown = 0; } } } @@ -61,10 +57,6 @@ public class Character extends EntityDelegate { hp -= dmg; } - public void runAnimation(AnimationRunner animationRunner) { - animationRunner.run(context, getLayer(), this); - } - @Override public void update(float dt) { super.update(dt); diff --git a/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java b/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java index 23da76a..3d42471 100644 --- a/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java +++ b/src/main/java/com/bartlomiejpluta/demo/runner/DemoRunner.java @@ -15,7 +15,7 @@ import com.bartlomiejpluta.demo.entity.Player; import com.bartlomiejpluta.demo.menu.MenuManager; import com.bartlomiejpluta.demo.database.dao.*; -import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon; +import com.bartlomiejpluta.demo.world.weapon.*; public class DemoRunner implements GameRunner { private static final Logger log = LoggerFactory.getLogger(DemoRunner.class); @@ -23,17 +23,20 @@ public class DemoRunner implements GameRunner { private Context context; private MenuManager menu; - @Getter + @Getter private MeleeWeaponDAO meleeWeaponDAO = new MeleeWeaponDAO(); - @Getter + @Getter + private RangedWeaponDAO rangedWeaponDAO = new RangedWeaponDAO(); + + @Getter private EnemyDAO enemyDAO = new EnemyDAO(); - @Getter - private Player player; + @Getter + private Player player; - @Override - public void init(Context context) { + @Override + public void init(Context context) { this.context = context; this.screen = context.getScreen(); @@ -61,6 +64,7 @@ public class DemoRunner implements GameRunner { private void initDAOs() { meleeWeaponDAO.init(context); enemyDAO.init(context); + rangedWeaponDAO.init(context); } private void initMenu() { @@ -78,7 +82,7 @@ public class DemoRunner implements GameRunner { this.player.setAnimationSpeed(0.005f); this.player.setBlocking(true); this.player.setCoordinates(0, 11); - this.player.setWeapon(new MeleeWeapon(context, meleeWeaponDAO.get("wooden_sword"))); + this.player.setWeapon(new RangedWeapon(context, rangedWeaponDAO.get("wooden_bow"))); } public void newGame() { diff --git a/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java b/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java index b3a40bf..10b50d4 100644 --- a/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java +++ b/src/main/java/com/bartlomiejpluta/demo/world/weapon/MeleeWeapon.java @@ -3,13 +3,14 @@ package com.bartlomiejpluta.demo.world.weapon; import java.util.Random; import lombok.*; +import org.joml.Vector2i; import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.lib.animation.*; import com.bartlomiejpluta.demo.database.model.MeleeWeaponModel; import com.bartlomiejpluta.demo.entity.Character; import com.bartlomiejpluta.demo.util.DiceRoller; -public class MeleeWeapon { +public class MeleeWeapon implements Weapon { private final Random random = new Random(); private final Context context; private final DiceRoller roller; @@ -37,9 +38,18 @@ public class MeleeWeapon { this.sound = template.getSound(); } - public void attack(Character character) { - character.hit(roller.roll()); - character.runAnimation(animation); - context.playSound(sound); + @Override + public boolean attack(Character attacker) { + var facingNeighbour = attacker.getCoordinates().add(attacker.getFaceDirection().vector, new Vector2i()); + for(var entity : attacker.getLayer().getEntities()) { + if(entity.getCoordinates().equals(facingNeighbour) && entity.isBlocking() && entity instanceof Character) { + ((Character) entity).hit(roller.roll()); + animation.run(context, entity.getLayer(), entity); + context.playSound(sound); + return true; + } + } + + return false; } } \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java b/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java new file mode 100644 index 0000000..a3210b3 --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/world/weapon/RangedWeapon.java @@ -0,0 +1,66 @@ +package com.bartlomiejpluta.demo.world.weapon; + +import java.util.Random; + +import lombok.*; +import com.bartlomiejpluta.base.api.context.Context; +import com.bartlomiejpluta.base.api.entity.Entity; +import com.bartlomiejpluta.base.api.move.Direction; +import com.bartlomiejpluta.base.lib.animation.*; +import com.bartlomiejpluta.demo.database.model.RangedWeaponModel; +import com.bartlomiejpluta.demo.entity.Character; +import com.bartlomiejpluta.demo.util.DiceRoller; + +public class RangedWeapon implements Weapon { + private final Random random = new Random(); + private final Context context; + private final DiceRoller roller; + private final BulletAnimationRunner animation; + private final String sound; + private final AnimationRunner punchAnimation; + private final String punchSound; + + @Getter + private String name; + + @Getter + private int cooldown; + + public RangedWeapon(@NonNull Context context, @NonNull RangedWeaponModel template) { + this.context = context; + this.name = template.getName(); + this.roller = DiceRoller.of(template.getDamage()); + this.cooldown = template.getCooldown(); + this.animation = new BulletAnimationRunner(template.getAnimation()) + .range(template.getRange()) + .infinite() + .offset(0, -15) + .onHit(this::onHit) + .speed(0.25f) + .animationSpeed(0.07f) + .scale(0.6f); + this.sound = template.getSound(); + this.punchAnimation = new SimpleAnimationRunner(template.getPunchAnimation()); + this.punchSound = template.getPunchSound(); + } + + private void onHit(Entity entity) { + if(entity.isBlocking() && entity instanceof Character) { + var character = (Character) entity; + character.hit(roller.roll()); + punchAnimation.run(context, character.getLayer(), character); + context.playSound(punchSound); + } + } + + @Override + public boolean attack(Character attacker) { + var direction = attacker.getFaceDirection(); + context.playSound(sound); + animation + .direction(direction) + .rotation(direction.xAngle - 180) + .run(context, attacker.getLayer(), attacker); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/world/weapon/Weapon.java b/src/main/java/com/bartlomiejpluta/demo/world/weapon/Weapon.java new file mode 100644 index 0000000..a58e072 --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/world/weapon/Weapon.java @@ -0,0 +1,9 @@ +package com.bartlomiejpluta.demo.world.weapon; + +import com.bartlomiejpluta.demo.entity.Character; + +public interface Weapon { + String getName(); + int getCooldown(); + boolean attack(Character attacker); +} \ No newline at end of file