Add support for ranged weapons

This commit is contained in:
2022-08-17 22:35:35 +02:00
parent f28f647368
commit 8dcbf5a972
13 changed files with 166 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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
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

View File

@@ -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<String, RangedWeaponModel> 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);
}
}

View File

@@ -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;
}

View File

@@ -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,15 +42,11 @@ 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);
if(weapon.attack(this)) {
attackCooldown = 0;
}
}
}
}
public void hit(int dmg) {
if(immortal) {
@@ -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);

View File

@@ -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);
@@ -26,6 +26,9 @@ public class DemoRunner implements GameRunner {
@Getter
private MeleeWeaponDAO meleeWeaponDAO = new MeleeWeaponDAO();
@Getter
private RangedWeaponDAO rangedWeaponDAO = new RangedWeaponDAO();
@Getter
private EnemyDAO enemyDAO = new EnemyDAO();
@@ -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() {

View File

@@ -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);
@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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}