Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
7d909d1d52
|
|||
|
3eceb93559
|
|||
|
9ccd509b19
|
|||
|
dadb48e6d6
|
|||
|
fe828f9026
|
|||
|
1a96932bca
|
|||
|
2c1fc56a5f
|
|||
|
a8a12a022a
|
|||
|
e366f85de1
|
|||
|
8946297bd9
|
|||
|
4f7c6c6dc3
|
|||
|
b157d7bf26
|
|||
|
60acb5749d
|
|||
|
a6c0eebba2
|
|||
|
329e8a18c5
|
|||
|
933608b753
|
|||
|
1253139bfe
|
|||
|
d51a425b28
|
|||
|
ccd3e44130
|
|||
|
9124f5c58a
|
|||
|
7b778845ba
|
|||
|
f98806f2f9
|
|||
|
0f365410b0
|
|||
|
1e3e2e6abb
|
|||
|
1e4a9a02c9
|
|||
|
0bfe53cd8e
|
|||
|
bf04597af6
|
|||
|
ffdc9e930a
|
|||
|
b4f385db5c
|
|||
|
dd7a4bf304
|
|||
|
e28667c14e
|
|||
|
2bd9d077cc
|
|||
|
a2d95855c5
|
|||
|
ad30a8dcf5
|
|||
|
1eda877a09
|
|||
|
8dcbf5a972
|
|||
|
f28f647368
|
|||
|
da77d25f6d
|
|||
|
785e1ac524
|
|||
|
f581805efd
|
|||
|
620970fb10
|
|||
|
bbf0109080
|
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
build/
|
||||
data.trace.db
|
||||
|
||||
BIN
animations/0ddac391-4086-4e9c-8310-59db649419ff.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
animations/312cc4e6-8c44-43e7-828a-e7e2a77836f3.png
Normal file
|
After Width: | Height: | Size: 951 B |
BIN
animations/54f657bd-8108-464c-9bbe-63944fc14f6b.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
animations/e6f067f1-eba0-4e62-99c3-2fd867e6f142.png
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
audio/1311327d-4b74-4252-94da-23ee4129e357.ogg
Normal file
BIN
audio/7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg
Normal file
BIN
audio/cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.ogg
Normal file
BIN
audio/e452e215-f581-40fe-a5cf-f555d3db83b8.ogg
Normal file
BIN
charsets/0dcbaf26-d634-4ca8-9691-7a8ff966f702.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
BIN
charsets/1779ae2b-474a-4599-8fc3-be34f7d66965.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
charsets/61393836-8127-4277-853f-87b48022ae43.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
charsets/7a723b64-e54a-4fff-852d-108349133111.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
charsets/92ac46ff-8cf2-4748-907f-873030c8e378.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
charsets/c7ec2341-e5fc-4285-9ecb-a2dfc8a0ed67.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
charsets/e605b2b1-3cab-499f-882d-160ab65b49d8.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
charsets/f1113db3-4a6c-4a07-9b64-32ba8e653e4f.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
charsets/fbea4628-e1d3-4acc-800a-ed54c1bb51b6.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
data.mv.db
BIN
iconsets/ddc1e14f-0d1f-4291-a29d-0dc5d8e9242b.png
Normal file
|
After Width: | Height: | Size: 197 KiB |
BIN
maps/551e1afc-9cda-4d9f-8817-bfd831fc0a75.dat
Normal file
31
project.bep
@@ -1,9 +1,34 @@
|
||||
|
||||
BASE Demo*com.bartlomiejpluta.demo.runner.DemoRunner`
|
||||
$f845355e-b9ad-4884-a217-dd3a4c18a3fa(f845355e-b9ad-4884-a217-dd3a4c18a3fa.datForrest Temple"d
|
||||
$f845355e-b9ad-4884-a217-dd3a4c18a3fa(f845355e-b9ad-4884-a217-dd3a4c18a3fa.datForrest TempleY
|
||||
$551e1afc-9cda-4d9f-8817-bfd831fc0a75(551e1afc-9cda-4d9f-8817-bfd831fc0a75.datForrest"d
|
||||
$d314b030-f865-432e-a356-3845f8aac7bc(d314b030-f865-432e-a356-3845f8aac7bc.pngForrest Temple ](2Z
|
||||
$815a5c5c-4979-42f5-a42a-ccbbff9a97e5(815a5c5c-4979-42f5-a42a-ccbbff9a97e5.pngLuna (:`
|
||||
$0dcbaf26-d634-4ca8-9691-7a8ff966f702(0dcbaf26-d634-4ca8-9691-7a8ff966f702.pngGaro (2\
|
||||
$61393836-8127-4277-853f-87b48022ae43(61393836-8127-4277-853f-87b48022ae43.pngCorpse (2^
|
||||
$e605b2b1-3cab-499f-882d-160ab65b49d8(e605b2b1-3cab-499f-882d-160ab65b49d8.pngSkeleton (2Z
|
||||
$0ea0fe55-53b2-4eea-8fab-2011e694127b(0ea0fe55-53b2-4eea-8fab-2011e694127b.pngLuna (2\
|
||||
$92ac46ff-8cf2-4748-907f-873030c8e378(92ac46ff-8cf2-4748-907f-873030c8e378.pngChests (2\
|
||||
$fbea4628-e1d3-4acc-800a-ed54c1bb51b6(fbea4628-e1d3-4acc-800a-ed54c1bb51b6.pngBlanca (2[
|
||||
$7a723b64-e54a-4fff-852d-108349133111(7a723b64-e54a-4fff-852d-108349133111.pngEagle (2\
|
||||
$c7ec2341-e5fc-4285-9ecb-a2dfc8a0ed67(c7ec2341-e5fc-4285-9ecb-a2dfc8a0ed67.pngTurtle (2`
|
||||
$f1113db3-4a6c-4a07-9b64-32ba8e653e4f(f1113db3-4a6c-4a07-9b64-32ba8e653e4f.png
|
||||
Silver Bat (2Z
|
||||
$1779ae2b-474a-4599-8fc3-be34f7d66965(1779ae2b-474a-4599-8fc3-be34f7d66965.pngDeku (:`
|
||||
$2261c04f-b02e-4486-b388-8a0fa41622e9(2261c04f-b02e-4486-b388-8a0fa41622e9.ttfRoboto RegularB\
|
||||
$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 Menu
|
||||
$56ca6b39-f949-4212-9c23-312db25887e0(56ca6b39-f949-4212-9c23-312db25887e0.xml Game MenuBU
|
||||
$00bd0625-b3b8-4abf-97b7-91f42bce28ec(00bd0625-b3b8-4abf-97b7-91f42bce28ec.xmlHUDB[
|
||||
$c473a91a-ff25-4e71-9bec-b35e48102aeb(c473a91a-ff25-4e71-9bec-b35e48102aeb.xml EquipmentB^
|
||||
$53ca3e54-0f8d-44fa-8281-acd9c5bba743(53ca3e54-0f8d-44fa-8281-acd9c5bba743.xmlEq Item MenuB[
|
||||
$d78413cd-0dad-4b51-8dd1-54e33535fe53(d78413cd-0dad-4b51-8dd1-54e33535fe53.xml Loot MenuJZ
|
||||
$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 (J[
|
||||
$0ddac391-4086-4e9c-8310-59db649419ff(0ddac391-4086-4e9c-8310-59db649419ff.pngSlash (R]
|
||||
$1311327d-4b74-4252-94da-23ee4129e357(1311327d-4b74-4252-94da-23ee4129e357.oggSword slashR\
|
||||
$e452e215-f581-40fe-a5cf-f555d3db83b8(e452e215-f581-40fe-a5cf-f555d3db83b8.ogg
|
||||
Deku deathRW
|
||||
$cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df(cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.oggArrowR]
|
||||
$7c33cfee-e6a8-42b8-8b1d-c801b242dcf0(7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.oggArrow punchZ]
|
||||
$ddc1e14f-0d1f-4291-a29d-0dc5d8e9242b(ddc1e14f-0d1f-4291-a29d-0dc5d8e9242b.pngGeneric #(
|
||||
40
src/main/java/com/bartlomiejpluta/demo/ai/AnimalAI.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
|
||||
public class AnimalAI implements AI {
|
||||
private final Enemy animal;
|
||||
private final Creature creature;
|
||||
private final int range;
|
||||
private final AI idleAI;
|
||||
private final AI runawayAI;
|
||||
|
||||
public AnimalAI(Enemy animal, Creature creature, int range) {
|
||||
this.animal = animal;
|
||||
this.creature = creature;
|
||||
this.range = range;
|
||||
this.idleAI = new RandomMovementAI<>(animal, 4);
|
||||
this.runawayAI = new RunawayAI<>(animal, creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(ObjectLayer layer, float dt) {
|
||||
if (animal.isMoving()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var distance = animal.manhattanDistance(creature);
|
||||
|
||||
if (animal.getHp() < animal.getMaxHp() && distance < range) {
|
||||
runawayAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
idleAI.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/bartlomiejpluta/demo/ai/ArcherAI.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.lib.ai.KeepStraightDistanceAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
|
||||
public class ArcherAI extends KeepStraightDistanceAI<Enemy, Creature> {
|
||||
private static final int ASTAR_MAX_NODES = 100;
|
||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||
private final int range;
|
||||
private final AI idle;
|
||||
|
||||
public ArcherAI(Enemy enemy, Creature target, int minRange, int maxRange, int range) {
|
||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target, minRange, maxRange);
|
||||
this.range = range;
|
||||
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean sees(Enemy enemy, Creature target, ObjectLayer layer) {
|
||||
return enemy.manhattanDistance(target) < range;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void interact(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
enemy.attack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void follow(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void idle(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
idle.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/bartlomiejpluta/demo/ai/SimpleEnemyAI.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.lib.ai.FollowObjectAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
|
||||
public class SimpleEnemyAI extends FollowObjectAI<Enemy, Creature> {
|
||||
private static final int ASTAR_MAX_NODES = 100;
|
||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||
private final AI idle;
|
||||
private final int range;
|
||||
|
||||
public SimpleEnemyAI(Enemy enemy, Creature target, int range) {
|
||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target);
|
||||
this.range = range;
|
||||
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean sees(Enemy enemy, Creature target, ObjectLayer layer, int distance) {
|
||||
return distance < range;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void interact(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
enemy.attack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void follow(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void idle(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
idle.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class SimpleSniperAI implements AI {
|
||||
private final Enemy enemy;
|
||||
private Creature target;
|
||||
private int range;
|
||||
|
||||
@Override
|
||||
public void nextActivity(ObjectLayer layer, float dt) {
|
||||
var enemyCoords = enemy.getCoordinates();
|
||||
var targetCoords = target.getCoordinates();
|
||||
if (enemy.manhattanDistance(target) <= range && (enemyCoords.x() == targetCoords.x() || enemyCoords.y() == targetCoords.y())) {
|
||||
var direction = enemy.getDirectionTowards(target);
|
||||
enemy.setFaceDirection(direction);
|
||||
enemy.attack();
|
||||
}
|
||||
}
|
||||
}
|
||||
76
src/main/java/com/bartlomiejpluta/demo/ai/WeaponBasedAI.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class WeaponBasedAI implements AI {
|
||||
private static final int RANGE = 10;
|
||||
private static final int MIN_RANGE = 3;
|
||||
private static final int MAX_RANGE = 12;
|
||||
private final Enemy enemy;
|
||||
private final Creature target;
|
||||
private final RunawayAI<Enemy, Creature> runawayAI;
|
||||
private final SimpleEnemyAI meleeAI;
|
||||
private final ArcherAI archerAI;
|
||||
|
||||
public WeaponBasedAI(@NonNull Enemy enemy, @NonNull Creature target) {
|
||||
this.enemy = enemy;
|
||||
this.target = target;
|
||||
this.runawayAI = new RunawayAI<>(enemy, target);
|
||||
this.meleeAI = new SimpleEnemyAI(enemy, target, RANGE);
|
||||
this.archerAI = new ArcherAI(enemy, target, MIN_RANGE, MAX_RANGE, RANGE);
|
||||
}
|
||||
|
||||
public void recomputePath() {
|
||||
meleeAI.recomputePath();
|
||||
archerAI.recomputePath();
|
||||
}
|
||||
|
||||
public void recomputePath(@NonNull MoveEvent event) {
|
||||
meleeAI.recomputePath(event);
|
||||
archerAI.recomputePath(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(ObjectLayer layer, float dt) {
|
||||
var lastAttacker = enemy.getLastAttacker();
|
||||
if (lastAttacker instanceof Creature attacker) {
|
||||
if (attacker.isAlive()) {
|
||||
runawayAI.setDanger(attacker);
|
||||
meleeAI.setTarget(attacker);
|
||||
archerAI.setTarget(attacker);
|
||||
} else {
|
||||
runawayAI.setDanger(target);
|
||||
meleeAI.setTarget(target);
|
||||
archerAI.setTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
var meleeWeapon = enemy.getMeleeWeapon();
|
||||
var rangedWeapon = enemy.getRangedWeapon();
|
||||
|
||||
if (meleeWeapon == null && rangedWeapon == null) {
|
||||
runawayAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rangedWeapon == null || enemy.manhattanDistance(target) == 1 || enemy.getAmmunition() == null) {
|
||||
enemy.setWeapon(meleeWeapon);
|
||||
meleeAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enemy.getWeapon() instanceof MeleeWeapon) {
|
||||
meleeAI.nextActivity(layer, dt);
|
||||
}
|
||||
|
||||
enemy.setWeapon(rangedWeapon);
|
||||
archerAI.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.lib.entity.EntityDelegate;
|
||||
|
||||
public class Character extends EntityDelegate {
|
||||
protected final Context context;
|
||||
|
||||
public Character(@NonNull Context context, @NonNull Entity entity) {
|
||||
super(entity);
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/bartlomiejpluta/demo/entity/Chest.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class Chest extends MapObject {
|
||||
private final DemoRunner runner;
|
||||
|
||||
@Getter
|
||||
private final Item[] content = new Item[Enemy.MAX_LOOT];
|
||||
|
||||
public Chest(@NonNull String id) {
|
||||
super(id);
|
||||
runner = ((DemoRunner) ContextHolder.INSTANCE.getContext().getGameRunner());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interact(Creature creature) {
|
||||
super.interact(creature);
|
||||
|
||||
runner.openChestWindow(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldGoFurther(MapObject object) {
|
||||
return runner.openedWindows() == 0;
|
||||
}
|
||||
|
||||
public Chest addItem(Item item) {
|
||||
for (int i = 0; i < content.length; ++i) {
|
||||
if (content[i] == null) {
|
||||
content[i] = item;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Chest is full!");
|
||||
}
|
||||
}
|
||||
108
src/main/java/com/bartlomiejpluta/demo/entity/Creature.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import com.bartlomiejpluta.base.api.character.Character;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class Creature extends NamedCharacter {
|
||||
private static final Logger log = LoggerFactory.getLogger(Creature.class);
|
||||
|
||||
protected int attackCooldown = 0;
|
||||
|
||||
@Getter
|
||||
protected boolean alive = true;
|
||||
|
||||
@Getter
|
||||
protected boolean immortal = false;
|
||||
|
||||
@Getter
|
||||
protected int maxHp;
|
||||
|
||||
@Getter
|
||||
protected int hp;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Weapon weapon;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Ammunition ammunition;
|
||||
|
||||
@Getter
|
||||
private NamedCharacter lastAttacker;
|
||||
|
||||
public Creature(@NonNull Character entity) {
|
||||
super(entity);
|
||||
}
|
||||
|
||||
public void attack() {
|
||||
if (weapon == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attackCooldown >= weapon.getCooldown()) {
|
||||
if (weapon.attack(this)) {
|
||||
if(weapon instanceof RangedWeapon) {
|
||||
ammunition.decrease();
|
||||
|
||||
if(ammunition.getCount() == 0) {
|
||||
ammunition = null;
|
||||
}
|
||||
}
|
||||
|
||||
attackCooldown = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hit(NamedCharacter source, int dmg) {
|
||||
this.lastAttacker = source;
|
||||
|
||||
if (immortal) {
|
||||
return;
|
||||
}
|
||||
|
||||
hp -= dmg;
|
||||
}
|
||||
|
||||
public void useEquipmentItem(Item item) {
|
||||
if (item instanceof Weapon weapon) {
|
||||
setWeapon(weapon);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item instanceof Ammunition ammunition) {
|
||||
setAmmunition(ammunition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
super.update(dt);
|
||||
|
||||
if (weapon != null && attackCooldown < weapon.getCooldown()) {
|
||||
attackCooldown += (int) (dt * 1000f);
|
||||
}
|
||||
|
||||
if (hp <= 0 && alive && getLayer() != null) {
|
||||
alive = false;
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
protected void die() {
|
||||
if (isMoving()) {
|
||||
abortMove();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
}
|
||||
169
src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java
Normal file
@@ -0,0 +1,169 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import DB.EnemyDropDAO;
|
||||
import DB.dao;
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.ai.NPC;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||
import com.bartlomiejpluta.base.lib.ai.NoopAI;
|
||||
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.db.Relop;
|
||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.ai.*;
|
||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.junk.Junk;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import static com.bartlomiejpluta.demo.util.ListUtil.randomIntSequence;
|
||||
|
||||
|
||||
public class Enemy extends Creature implements NPC {
|
||||
public static final int MAX_LOOT = 4 * 4;
|
||||
|
||||
private final Random random = new Random();
|
||||
private final DB.model.EnemyModel template;
|
||||
private final AnimationRunner dieAnimation;
|
||||
|
||||
@Getter
|
||||
private final Item[] loot = new Item[MAX_LOOT];
|
||||
@Getter
|
||||
private final String name;
|
||||
private AI ai = NoopAI.INSTANCE;
|
||||
@Getter
|
||||
private MeleeWeapon meleeWeapon;
|
||||
@Getter
|
||||
private RangedWeapon rangedWeapon;
|
||||
|
||||
public Enemy(@NonNull String id) {
|
||||
this(DB.dao.enemy.find(id));
|
||||
}
|
||||
|
||||
public Enemy(@NonNull DB.model.EnemyModel template) {
|
||||
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.get(template.getCharset()).uid));
|
||||
this.template = template;
|
||||
name = template.getName();
|
||||
maxHp = DiceRoller.of(template.getHp()).roll();
|
||||
hp = maxHp;
|
||||
var speed = DiceRoller.of(template.getSpeed()).roll() / 10f;
|
||||
setSpeed(speed);
|
||||
setAnimationSpeed(speed / 2.0f);
|
||||
setBlocking(template.isBlocking());
|
||||
var meleeWeaponTemplate = template.getMeleeWeapon();
|
||||
var rangedWeaponTemplate = template.getRangedWeapon();
|
||||
|
||||
if (meleeWeaponTemplate != null) {
|
||||
this.meleeWeapon = new MeleeWeapon(meleeWeaponTemplate);
|
||||
}
|
||||
|
||||
if (rangedWeaponTemplate != null) {
|
||||
var split = rangedWeaponTemplate.split(",");
|
||||
|
||||
this.rangedWeapon = new RangedWeapon(split[0]);
|
||||
setAmmunition(new Ammunition(split[1], DiceRoller.of(split[2]).roll()));
|
||||
}
|
||||
|
||||
this.dieAnimation = new SimpleAnimationRunner(A.animations.get(template.getDieAnimation()).uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AI getStrategy() {
|
||||
return ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
changeCharacterSet(A.charsets.get(template.getDeadCharset()).uid);
|
||||
setScale(0.5f);
|
||||
setBlocking(false);
|
||||
setZIndex(-1);
|
||||
|
||||
ai = NoopAI.INSTANCE;
|
||||
|
||||
dieAnimation.run(context, getLayer(), this);
|
||||
context.playSound(A.sounds.get(template.getDieSound()).uid);
|
||||
context.fireEvent(new EnemyDiedEvent(this));
|
||||
|
||||
drawLoot();
|
||||
}
|
||||
|
||||
private void drawLoot() {
|
||||
var def = dao.enemy_drop.query()
|
||||
.where(EnemyDropDAO.Column.ENEMY, Relop.EQ, template.getId())
|
||||
.orderBy("rand()")
|
||||
.find();
|
||||
|
||||
var indexesIterator = randomIntSequence(0, loot.length).iterator();
|
||||
for (var d : def) {
|
||||
if (!indexesIterator.hasNext()) {
|
||||
break;
|
||||
}
|
||||
|
||||
var index = indexesIterator.next();
|
||||
|
||||
var split = d.getItem().split(":");
|
||||
loot[index] = switch (split[0]) {
|
||||
case "melee_weapon" -> new MeleeWeapon(split[1]);
|
||||
case "ranged_weapon" -> new RangedWeapon(split[1]);
|
||||
case "ammo" -> new Ammunition(split[1], DiceRoller.of(d.getAmount()).roll());
|
||||
case "junk" -> new Junk(split[1]);
|
||||
default -> throw new IllegalArgumentException("Unsupported item type");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Enemy followAndAttack(Creature target, int range) {
|
||||
var ai = new SimpleEnemyAI(this, target, range);
|
||||
|
||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy campAndHunt(Creature target, int range) {
|
||||
this.ai = new SimpleSniperAI(this, target, range);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy asAnimal(Creature source, int range) {
|
||||
this.ai = new AnimalAI(this, source, range);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy archer(Creature target, int minRange, int maxRange, int range) {
|
||||
var ai = new ArcherAI(this, target, minRange, maxRange, range);
|
||||
|
||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy defaultAI() {
|
||||
var ai = new WeaponBasedAI(this, runner.getPlayer());
|
||||
|
||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
85
src/main/java/com/bartlomiejpluta/demo/entity/MapObject.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.move.Direction;
|
||||
import com.bartlomiejpluta.base.util.path.CharacterPath;
|
||||
import com.bartlomiejpluta.base.util.path.PathExecutor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
public abstract class MapObject extends NamedCharacter {
|
||||
private final PathExecutor<MapObject> pathExecutor = new PathExecutor<>(this);
|
||||
private final DB.model.MapObjectModel template;
|
||||
private final Short frame;
|
||||
private final String interactSound;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
private boolean interacting = false;
|
||||
|
||||
public MapObject(@NonNull String id) {
|
||||
this(DB.dao.map_object.find(id));
|
||||
}
|
||||
|
||||
public MapObject(@NonNull DB.model.MapObjectModel template) {
|
||||
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.get(template.getCharset()).uid));
|
||||
this.template = template;
|
||||
this.frame = template.getFrame();
|
||||
this.name = template.getName();
|
||||
this.interactSound = A.sounds.get(template.getInteractSound()).uid;
|
||||
|
||||
setBlocking(true);
|
||||
disableAnimation();
|
||||
|
||||
if (frame != null) {
|
||||
setAnimationFrame(frame);
|
||||
}
|
||||
|
||||
pathExecutor.setPath(
|
||||
frame != null
|
||||
? new CharacterPath<MapObject>()
|
||||
.run(this::startInteraction)
|
||||
.turn(Direction.LEFT, frame)
|
||||
.wait(0.05f)
|
||||
.turn(Direction.RIGHT, frame)
|
||||
.wait(0.05f)
|
||||
.turn(Direction.UP, frame)
|
||||
.wait(0.5f)
|
||||
.suspend(this::shouldGoFurther)
|
||||
.turn(Direction.RIGHT, frame)
|
||||
.wait(0.05f)
|
||||
.turn(Direction.LEFT, frame)
|
||||
.wait(0.05f)
|
||||
.turn(Direction.DOWN, frame)
|
||||
.wait(0.5f)
|
||||
.run(this::finishInteraction)
|
||||
: new CharacterPath<>()
|
||||
);
|
||||
}
|
||||
|
||||
protected boolean shouldGoFurther(MapObject object) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void interact(Creature creature) {
|
||||
interacting = true;
|
||||
}
|
||||
|
||||
protected void startInteraction() {
|
||||
if (interactSound != null) {
|
||||
context.playSound(interactSound);
|
||||
}
|
||||
}
|
||||
|
||||
protected void finishInteraction() {
|
||||
interacting = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
if (interacting) {
|
||||
pathExecutor.execute(getLayer(), dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import com.bartlomiejpluta.base.api.character.Character;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.lib.character.CharacterDelegate;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
|
||||
public abstract class NamedCharacter extends CharacterDelegate {
|
||||
protected final Context context;
|
||||
protected final DemoRunner runner;
|
||||
|
||||
public NamedCharacter(Character character) {
|
||||
super(character);
|
||||
this.context = ContextHolder.INSTANCE.getContext();
|
||||
this.runner = (DemoRunner) context.getGameRunner();
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
}
|
||||
@@ -1,12 +1,153 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.character.Character;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
||||
import lombok.NonNull;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
public class Player extends Character {
|
||||
import java.util.List;
|
||||
|
||||
public Player(@NonNull Context context, @NonNull Entity entity) {
|
||||
super(context, entity);
|
||||
}
|
||||
public class Player extends Creature {
|
||||
private final Item[] equipment = new Item[4 * 4];
|
||||
private int interactionCooldown = 0;
|
||||
|
||||
public Player(@NonNull Character entity) {
|
||||
super(entity);
|
||||
this.hp = 500;
|
||||
this.maxHp = 500;
|
||||
}
|
||||
|
||||
public void interact() {
|
||||
if (interactionCooldown > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var coords = getCoordinates().add(getFaceDirection().vector, new Vector2i());
|
||||
var entities = getLayer().getEntities();
|
||||
for (var i = 0; i < entities.size(); ++i) {
|
||||
var entity = entities.get(i);
|
||||
|
||||
// Use some map object which player is looking at
|
||||
if (entity.getCoordinates().equals(coords) && entity instanceof MapObject object) {
|
||||
object.interact(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity.getCoordinates().equals(getCoordinates())) {
|
||||
|
||||
// Pick some item from the ground
|
||||
if (entity instanceof Item item) {
|
||||
pushItemToEquipment(item);
|
||||
getLayer().removeEntity(item);
|
||||
interactionCooldown = INTERACTION_COOLDOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
// Search the enemy corpse
|
||||
if (entity instanceof Enemy enemy && !enemy.isAlive()) {
|
||||
runner.openLootWindow(enemy);
|
||||
interactionCooldown = INTERACTION_COOLDOWN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean pushItemToEquipment(@NonNull Item item) {
|
||||
for (int i = 0; i < equipment.length; ++i) {
|
||||
if (equipment[i] == null) {
|
||||
equipment[i] = item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Item getEquipmentItem(int index) {
|
||||
return equipment[index];
|
||||
}
|
||||
|
||||
public void removeItemFromEquipment(@NonNull Item item) {
|
||||
for (int i = 0; i < equipment.length; ++i) {
|
||||
if (equipment[i] == item) {
|
||||
equipment[i] = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dropItemFromEquipment(@NonNull Item item) {
|
||||
removeItemFromEquipment(item);
|
||||
item.setCoordinates(getCoordinates());
|
||||
getLayer().addEntity(item);
|
||||
|
||||
if (item == getWeapon()) {
|
||||
setWeapon(null);
|
||||
}
|
||||
|
||||
if (item == getAmmunition()) {
|
||||
setAmmunition(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWeapon(Weapon weapon) {
|
||||
var currentWeapon = getWeapon();
|
||||
|
||||
if (weapon != null) {
|
||||
removeItemFromEquipment(weapon);
|
||||
}
|
||||
|
||||
if (currentWeapon != null) {
|
||||
pushItemToEquipment(currentWeapon);
|
||||
}
|
||||
|
||||
super.setWeapon(weapon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAmmunition(Ammunition ammunition) {
|
||||
var currentAmmo = getAmmunition();
|
||||
|
||||
if (currentAmmo != null && currentAmmo.getId().equals(ammunition.getId())) {
|
||||
currentAmmo.increase(ammunition.getCount());
|
||||
removeItemFromEquipment(ammunition);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ammunition != null) {
|
||||
removeItemFromEquipment(ammunition);
|
||||
}
|
||||
|
||||
if (currentAmmo != null) {
|
||||
pushItemToEquipment(currentAmmo);
|
||||
}
|
||||
|
||||
super.setAmmunition(ammunition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
runner.returnToStartMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Player";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
super.update(dt);
|
||||
|
||||
if (interactionCooldown > 0) {
|
||||
interactionCooldown = (int) Math.max(0, interactionCooldown - dt * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int INTERACTION_COOLDOWN = 300;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.bartlomiejpluta.demo.event;
|
||||
|
||||
import com.bartlomiejpluta.base.api.event.EventType;
|
||||
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class EnemyDiedEvent extends BaseEvent {
|
||||
public static final EventType<EnemyDiedEvent> TYPE = new EventType<>("ENEMY_DIED_EVENT");
|
||||
|
||||
private final Enemy enemy;
|
||||
|
||||
@Override
|
||||
public EventType<EnemyDiedEvent> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
22
src/main/java/com/bartlomiejpluta/demo/event/HitEvent.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.bartlomiejpluta.demo.event;
|
||||
|
||||
import com.bartlomiejpluta.base.api.event.EventType;
|
||||
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class HitEvent extends BaseEvent {
|
||||
public static final EventType<HitEvent> TYPE = new EventType<>("HIT_EVENT");
|
||||
|
||||
private final Creature attacker;
|
||||
private final Creature target;
|
||||
private final int damage;
|
||||
|
||||
@Override
|
||||
public EventType<HitEvent> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
66
src/main/java/com/bartlomiejpluta/demo/gui/Bar.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.Color;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.lib.gui.BaseComponent;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Bar extends BaseComponent {
|
||||
|
||||
private final Color stroke;
|
||||
private final Color fill;
|
||||
@Setter
|
||||
private float value = 1.0f;
|
||||
private float actualValue = 1.0f;
|
||||
private final float speed = 0.05f;
|
||||
|
||||
public Bar(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
|
||||
this.stroke = gui.createColor();
|
||||
this.fill = gui.createColor();
|
||||
|
||||
stroke.setAlpha(1f);
|
||||
fill.setAlpha(1f);
|
||||
}
|
||||
|
||||
public void setStrokeColor(Integer hex) {
|
||||
stroke.setRGB(hex);
|
||||
}
|
||||
|
||||
public void setFillColor(Integer hex) {
|
||||
fill.setRGB(hex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getContentWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getContentHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
var remainingDistance = value - actualValue;
|
||||
actualValue += remainingDistance * speed;
|
||||
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, Math.max(width * actualValue, 0), height);
|
||||
gui.setFillColor(fill);
|
||||
gui.fill();
|
||||
gui.closePath();
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, width, height);
|
||||
gui.setStrokeColor(stroke);
|
||||
gui.stroke();
|
||||
gui.closePath();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,54 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.Color;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.input.*;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||
import com.bartlomiejpluta.base.lib.gui.TextAlignment;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Button extends Label {
|
||||
private Color color;
|
||||
private final Color color;
|
||||
|
||||
@Setter
|
||||
private Runnable action;
|
||||
@Setter
|
||||
private Runnable action;
|
||||
|
||||
public Button(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
this.color = gui.createColor();
|
||||
this.color.setRGBA(1, 1, 1, 0);
|
||||
public Button(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.color = gui.createColor();
|
||||
this.color.setRGBA(1, 1, 1, 0);
|
||||
|
||||
setText("");
|
||||
setFontSize(17f);
|
||||
setAlignment(GUI.ALIGN_TOP | GUI.ALIGN_CENTER);
|
||||
setColor(0.4f, 0.7f, 0.0f, 1f);
|
||||
setPadding(10f);
|
||||
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||
}
|
||||
setText("");
|
||||
setFontSize(17f);
|
||||
setAlignment(TextAlignment.TOP, TextAlignment.CENTER);
|
||||
setColor(0.4f, 0.7f, 0.0f, 1f);
|
||||
setPadding(10f);
|
||||
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||
}
|
||||
|
||||
private void handleKeyEvent(KeyEvent event) {
|
||||
if(event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && action != null) {
|
||||
event.consume();
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
private void handleKeyEvent(KeyEvent event) {
|
||||
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && action != null) {
|
||||
event.consume();
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
color.setAlpha(focused ? 0.7f : 0f);
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
color.setAlpha(focused ? 0.7f : 0f);
|
||||
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillColor(color);
|
||||
gui.fill();
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillColor(color);
|
||||
gui.fill();
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,40 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.Color;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.gui.Paint;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.BaseWindow;
|
||||
|
||||
public abstract class DecoratedWindow extends BaseWindow {
|
||||
private Paint paint;
|
||||
private Color inner;
|
||||
private Color outer;
|
||||
import java.util.Map;
|
||||
|
||||
public DecoratedWindow(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
public class DecoratedWindow extends BaseWindow {
|
||||
private final Paint paint;
|
||||
private final Color inner;
|
||||
private final Color outer;
|
||||
|
||||
this.inner = gui.createColor();
|
||||
this.outer = gui.createColor();
|
||||
this.paint = gui.createPaint();
|
||||
public DecoratedWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
|
||||
inner.setRGBA(0.1f, 0.1f, 0.1f, 1f);
|
||||
outer.setRGBA(0.2f, 0.2f, 0.2f, 1f);
|
||||
}
|
||||
this.inner = gui.createColor();
|
||||
this.outer = gui.createColor();
|
||||
this.paint = gui.createPaint();
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillPaint(paint);
|
||||
gui.boxGradient(x, y, getWidth(), getHeight(), 10f, 100f, inner, outer, paint);
|
||||
gui.fill();
|
||||
gui.stroke();
|
||||
inner.setRGBA(0.1f, 0.1f, 0.1f, 1f);
|
||||
outer.setRGBA(0.2f, 0.2f, 0.2f, 1f);
|
||||
}
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillPaint(paint);
|
||||
gui.boxGradient(x, y, getWidth(), getHeight(), 10f, 100f, inner, outer, paint);
|
||||
gui.fill();
|
||||
gui.stroke();
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
}
|
||||
136
src/main/java/com/bartlomiejpluta/demo/gui/EquipmentWindow.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||
import com.bartlomiejpluta.base.lib.gui.VGridOptionChoice;
|
||||
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.item.Useable;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
|
||||
public class EquipmentWindow extends DecoratedWindow {
|
||||
private final DemoRunner runner;
|
||||
private final Player player;
|
||||
|
||||
private final Window eqItemMenuWindow;
|
||||
private final Button useBtn;
|
||||
private final Button dropBtn;
|
||||
private final Button cancelBtn;
|
||||
private final VOptionChoice eqItemMenu;
|
||||
|
||||
@Ref("eq")
|
||||
private VGridOptionChoice eqGrid;
|
||||
|
||||
@Ref("weapon")
|
||||
private ItemIconView weapon;
|
||||
|
||||
@Ref("ammo")
|
||||
private ItemIconView ammo;
|
||||
|
||||
@Ref("item-name")
|
||||
private Label nameLbl;
|
||||
|
||||
@Ref("item-details")
|
||||
private Label detailsLbl;
|
||||
|
||||
public EquipmentWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.runner = (DemoRunner) context.getGameRunner();
|
||||
this.player = runner.getPlayer();
|
||||
this.eqItemMenuWindow = gui.inflateWindow(A.widgets.eq_item_menu.uid);
|
||||
this.eqItemMenu = eqItemMenuWindow.reference("menu", VOptionChoice.class);
|
||||
this.useBtn = eqItemMenuWindow.reference("use", Button.class);
|
||||
this.dropBtn = eqItemMenuWindow.reference("drop", Button.class);
|
||||
this.cancelBtn = eqItemMenuWindow.reference("cancel", Button.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WindowManager manager, Object... args) {
|
||||
super.onOpen(manager, args);
|
||||
|
||||
cancelBtn.setAction(manager::close);
|
||||
eqGrid.setOnSelect(this::updateItemDetails);
|
||||
|
||||
updateEquipment();
|
||||
|
||||
eqGrid.select(0, 0);
|
||||
eqGrid.focus();
|
||||
}
|
||||
|
||||
private void updateEquipment() {
|
||||
var i = 0;
|
||||
for (var child : eqGrid.getChildren()) {
|
||||
var slot = (ItemIconView) child;
|
||||
slot.setItem(player.getEquipmentItem(i++));
|
||||
slot.setAction(handleClick(slot));
|
||||
}
|
||||
|
||||
weapon.setItem(player.getWeapon());
|
||||
ammo.setItem(player.getAmmunition());
|
||||
}
|
||||
|
||||
private Consumer<Item> handleClick(ItemIconView slot) {
|
||||
return item -> {
|
||||
useBtn.setText(getButtonTitle(item));
|
||||
eqItemMenu.select(0);
|
||||
eqItemMenu.focus();
|
||||
|
||||
manager.open(eqItemMenuWindow);
|
||||
|
||||
if (item instanceof Useable useable) {
|
||||
useBtn.setAction(() -> {
|
||||
useable.use(player);
|
||||
updateEquipment();
|
||||
manager.close();
|
||||
});
|
||||
}
|
||||
|
||||
dropBtn.setAction(() -> {
|
||||
player.dropItemFromEquipment(item);
|
||||
slot.setItem(null);
|
||||
updateItemDetails(slot);
|
||||
manager.close();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private void updateItemDetails(Component slot) {
|
||||
var item = ((ItemIconView) slot).getItem();
|
||||
|
||||
if (item == null) {
|
||||
nameLbl.setText("");
|
||||
detailsLbl.setText("");
|
||||
return;
|
||||
}
|
||||
|
||||
nameLbl.setText(item.getName());
|
||||
detailsLbl.setText("");
|
||||
|
||||
if (item instanceof MeleeWeapon weapon) {
|
||||
detailsLbl.setText(format("Damage: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getCooldown()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (item instanceof RangedWeapon weapon) {
|
||||
detailsLbl.setText(format("Damage: %s\nRange: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getRangeRoller(), weapon.getCooldown()));
|
||||
}
|
||||
}
|
||||
|
||||
private String getButtonTitle(Item item) {
|
||||
if (item instanceof Useable useable) {
|
||||
return useable.usageName();
|
||||
}
|
||||
|
||||
return "Use";
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,35 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.gui.Inflatable;
|
||||
import com.bartlomiejpluta.base.api.gui.Ref;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class GameMenuWindow extends DecoratedWindow implements Inflatable {
|
||||
|
||||
@Ref("resume_game")
|
||||
@Getter
|
||||
private Button resumeGameBtn;
|
||||
@Ref("resume_game")
|
||||
@Getter
|
||||
private Button resumeGameBtn;
|
||||
|
||||
@Ref("start_menu")
|
||||
@Getter
|
||||
private Button startMenuBtn;
|
||||
@Ref("start_menu")
|
||||
@Getter
|
||||
private Button startMenuBtn;
|
||||
|
||||
@Ref("exit")
|
||||
@Getter
|
||||
private Button exitBtn;
|
||||
@Ref("exit")
|
||||
@Getter
|
||||
private Button exitBtn;
|
||||
|
||||
public GameMenuWindow(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
}
|
||||
public GameMenuWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInflate() {
|
||||
resumeGameBtn.focus();
|
||||
}
|
||||
@Override
|
||||
public void onInflate() {
|
||||
resumeGameBtn.focus();
|
||||
}
|
||||
}
|
||||
98
src/main/java/com/bartlomiejpluta/demo/gui/HUD.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.gui.Ref;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.lib.gui.BorderLayout;
|
||||
import com.bartlomiejpluta.base.lib.gui.IconView;
|
||||
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.util.LimitedQueue;
|
||||
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class HUD extends BorderLayout {
|
||||
private static final int MAX_LOG_SIZE = 10;
|
||||
private static final float LOG_VISIBILITY_DURATION = 8000f;
|
||||
private static final float LOG_VISIBILITY_FADING_OUT = 1000f;
|
||||
private final DemoRunner runner;
|
||||
private final Player player;
|
||||
private final Runtime runtime;
|
||||
private final LimitedQueue<String> logger = new LimitedQueue<>(MAX_LOG_SIZE);
|
||||
|
||||
private float logVisibilityDuration = 0f;
|
||||
|
||||
private Weapon currentWeapon;
|
||||
|
||||
@Ref("hp")
|
||||
private Bar hp;
|
||||
|
||||
@Ref("debug")
|
||||
private Label debugLbl;
|
||||
|
||||
@Ref("log")
|
||||
private Label logLbl;
|
||||
|
||||
@Ref("weapon")
|
||||
private IconView weapon;
|
||||
|
||||
public HUD(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.runner = (DemoRunner) context.getGameRunner();
|
||||
this.player = runner.getPlayer();
|
||||
this.runtime = Runtime.getRuntime();
|
||||
context.addEventListener(HitEvent.TYPE, this::logHitEvent);
|
||||
context.addEventListener(EnemyDiedEvent.TYPE, this::logEnemyDiedEvent);
|
||||
}
|
||||
|
||||
private void logHitEvent(HitEvent event) {
|
||||
log(String.format("%s hits %s with damage = %d", event.getAttacker().getName(), event.getTarget().getName(), event.getDamage()));
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
logger.add(message);
|
||||
log.info(message);
|
||||
logLbl.setText(logger.stream().collect(Collectors.joining("\n")));
|
||||
logVisibilityDuration = LOG_VISIBILITY_DURATION;
|
||||
}
|
||||
|
||||
private void logEnemyDiedEvent(EnemyDiedEvent event) {
|
||||
log(String.format("%s has died with HP = %d", event.getEnemy().getName(), event.getEnemy().getHp()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
super.update(dt);
|
||||
|
||||
hp.setValue((float) player.getHp() / (float) player.getMaxHp());
|
||||
|
||||
if (logVisibilityDuration > 0) {
|
||||
logVisibilityDuration -= dt * 1000;
|
||||
} else {
|
||||
logVisibilityDuration = 0;
|
||||
}
|
||||
|
||||
|
||||
this.currentWeapon = player.getWeapon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
var coords = player.getCoordinates();
|
||||
var pos = player.getPosition();
|
||||
debugLbl.setText(String.format("FPS: %.2f\n" + "Mem: %.2f / %.2f [MB]\n" + "Coords: %d : %d\n" + "Pos: %.2f : %.2f\n" + "Entities: %d", runner.instantFPS(), runtime.totalMemory() / 1024f / 1024f, runtime.maxMemory() / 1024f / 1024f, coords.x(), coords.y(), pos.x(), pos.y(), player.getLayer().getEntities().size() - 1));
|
||||
|
||||
logLbl.setAlpha(Math.min(1f, logVisibilityDuration / LOG_VISIBILITY_FADING_OUT));
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
}
|
||||
111
src/main/java/com/bartlomiejpluta/demo/gui/ItemIconView.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import A.fonts;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.Color;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.lib.gui.IconView;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.item.ItemStack;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ItemIconView extends IconView {
|
||||
private final Color normal;
|
||||
private final Color hover;
|
||||
private final Color textColor;
|
||||
|
||||
@Getter
|
||||
private Item item;
|
||||
|
||||
@Setter
|
||||
private Consumer<Item> action;
|
||||
|
||||
public ItemIconView(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.normal = gui.createColor();
|
||||
this.hover = gui.createColor();
|
||||
this.textColor = gui.createColor();
|
||||
|
||||
normal.setRGBA(0x444444FF);
|
||||
hover.setRGBA(0x888888FF);
|
||||
textColor.setRGBA(0xFFFFFFFF);
|
||||
|
||||
super.setScale(2f);
|
||||
|
||||
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||
}
|
||||
|
||||
public void setItem(Item item) {
|
||||
this.item = item;
|
||||
super.setIcon(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(Icon icon) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconSet(String iconSetUid) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconSetRow(@NonNull Integer iconSetRow) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIconSetColumn(@NonNull Integer iconSetColumn) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void handleKeyEvent(KeyEvent event) {
|
||||
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && item != null && action != null) {
|
||||
event.consume();
|
||||
action.accept(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getContentWidth() {
|
||||
return 68f;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getContentHeight() {
|
||||
return 68f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillColor(focused ? hover : normal);
|
||||
gui.fill();
|
||||
gui.closePath();
|
||||
|
||||
super.draw(screen, gui);
|
||||
|
||||
if (item != null && item instanceof ItemStack stack) {
|
||||
gui.beginPath();
|
||||
gui.setFontFace(fonts.roboto_regular.uid);
|
||||
gui.setFontSize(17);
|
||||
gui.putText(x + 15, y + 5, String.valueOf(stack.getCount()));
|
||||
gui.setFillColor(textColor);
|
||||
gui.fill();
|
||||
gui.closePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
87
src/main/java/com/bartlomiejpluta/demo/gui/LootWindow.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||
import com.bartlomiejpluta.base.lib.gui.VGridOptionChoice;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class LootWindow extends DecoratedWindow implements Inflatable {
|
||||
private final Player player;
|
||||
|
||||
@Ref("title")
|
||||
private Label titleLbl;
|
||||
|
||||
@Ref("loot")
|
||||
private VGridOptionChoice lootMenu;
|
||||
|
||||
private Item[] loot;
|
||||
|
||||
private ItemIconView[] slots = new ItemIconView[Enemy.MAX_LOOT];
|
||||
|
||||
public LootWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.player = ((DemoRunner) context.getGameRunner()).getPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInflate() {
|
||||
for (int i = 0; i < Enemy.MAX_LOOT; ++i) {
|
||||
var itemView = new ItemIconView(context, gui, Map.of());
|
||||
itemView.setMargin(5f);
|
||||
lootMenu.add(itemView);
|
||||
slots[i] = itemView;
|
||||
itemView.setAction(this::handleClick);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WindowManager manager, Object[] args) {
|
||||
super.onOpen(manager, args);
|
||||
|
||||
this.loot = (Item[]) args[0];
|
||||
this.titleLbl.setText((String) args[1]);
|
||||
updateSlots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WindowManager manager) {
|
||||
super.onClose(manager);
|
||||
|
||||
clearSlots();
|
||||
this.loot = null;
|
||||
}
|
||||
|
||||
private void handleClick(Item item) {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.pushItemToEquipment(item)) {
|
||||
for (int i = 0; i < Enemy.MAX_LOOT; i++) {
|
||||
if (loot[i] == item) {
|
||||
loot[i] = null;
|
||||
slots[i].setItem(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSlots() {
|
||||
for (int i = 0; i < Enemy.MAX_LOOT; ++i) {
|
||||
slots[i].setItem(loot[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearSlots() {
|
||||
for (var slot : slots) {
|
||||
slot.setItem(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,35 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.gui.Inflatable;
|
||||
import com.bartlomiejpluta.base.api.gui.Ref;
|
||||
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class StartMenuWindow extends DecoratedWindow implements Inflatable {
|
||||
|
||||
@Ref("new_game")
|
||||
@Getter
|
||||
private Button newGameBtn;
|
||||
@Ref("new_game")
|
||||
@Getter
|
||||
private Button newGameBtn;
|
||||
|
||||
@Ref("exit")
|
||||
@Getter
|
||||
private Button exitBtn;
|
||||
@Ref("exit")
|
||||
@Getter
|
||||
private Button exitBtn;
|
||||
|
||||
public StartMenuWindow(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
}
|
||||
@Ref("menu")
|
||||
private VOptionChoice menu;
|
||||
|
||||
@Override
|
||||
public void onInflate() {
|
||||
newGameBtn.focus();
|
||||
}
|
||||
public StartMenuWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInflate() {
|
||||
menu.select(0);
|
||||
menu.focus();
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,134 @@
|
||||
package com.bartlomiejpluta.demo.map;
|
||||
|
||||
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
|
||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.api.camera.Camera;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.api.input.Input;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||
import com.bartlomiejpluta.base.api.move.Direction;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.camera.Camera;
|
||||
import com.bartlomiejpluta.base.api.input.*;
|
||||
|
||||
import com.bartlomiejpluta.base.lib.camera.*;
|
||||
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.base.lib.camera.CameraController;
|
||||
import com.bartlomiejpluta.base.lib.camera.FollowingCameraController;
|
||||
import com.bartlomiejpluta.base.util.world.CharacterSpawner;
|
||||
import com.bartlomiejpluta.base.util.world.Warp;
|
||||
import com.bartlomiejpluta.demo.entity.Chest;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import lombok.NonNull;
|
||||
|
||||
public abstract class BaseMapHandler implements MapHandler {
|
||||
protected Screen screen;
|
||||
protected Context context;
|
||||
protected DemoRunner runner;
|
||||
protected Camera camera;
|
||||
protected Player player;
|
||||
protected ObjectLayer mainLayer;
|
||||
protected CameraController cameraController;
|
||||
protected Screen screen;
|
||||
protected Context context;
|
||||
protected DemoRunner runner;
|
||||
protected Camera camera;
|
||||
protected GameMap map;
|
||||
protected Player player;
|
||||
protected ObjectLayer mainLayer;
|
||||
protected CameraController cameraController;
|
||||
|
||||
@Override
|
||||
public void onCreate(Context context, GameMap map) {
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
this.runner = (DemoRunner) context.getGameRunner();
|
||||
this.camera = context.getCamera();
|
||||
this.player = runner.getPlayer();
|
||||
this.cameraController = FollowingCameraController
|
||||
.on(screen, camera, map)
|
||||
.follow(player.getPosition());
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Context context, GameMap map) {
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
this.runner = (DemoRunner) context.getGameRunner();
|
||||
this.camera = context.getCamera();
|
||||
this.map = map;
|
||||
this.player = runner.getPlayer();
|
||||
this.cameraController = FollowingCameraController
|
||||
.on(screen, camera, map)
|
||||
.follow(player.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Input input) {
|
||||
if(context.isPaused()) {
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void input(Input input) {
|
||||
if (context.isPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(input.isKeyPressed(Key.KEY_LEFT_CONTROL)) {
|
||||
if(input.isKeyPressed(Key.KEY_DOWN)) {
|
||||
player.setFaceDirection(Direction.DOWN);
|
||||
} else if(input.isKeyPressed(Key.KEY_UP)) {
|
||||
player.setFaceDirection(Direction.UP);
|
||||
} else if(input.isKeyPressed(Key.KEY_LEFT)) {
|
||||
player.setFaceDirection(Direction.LEFT);
|
||||
} else if(input.isKeyPressed(Key.KEY_RIGHT)) {
|
||||
player.setFaceDirection(Direction.RIGHT);
|
||||
}
|
||||
} else {
|
||||
if(input.isKeyPressed(Key.KEY_DOWN)) {
|
||||
mainLayer.pushMovement(player.prepareMovement(Direction.DOWN));
|
||||
} else if(input.isKeyPressed(Key.KEY_UP)) {
|
||||
mainLayer.pushMovement(player.prepareMovement(Direction.UP));
|
||||
} else if(input.isKeyPressed(Key.KEY_LEFT)) {
|
||||
mainLayer.pushMovement(player.prepareMovement(Direction.LEFT));
|
||||
} else if(input.isKeyPressed(Key.KEY_RIGHT)) {
|
||||
mainLayer.pushMovement(player.prepareMovement(Direction.RIGHT));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (runner.openedWindows() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Context context, GameMap map, float dt) {
|
||||
cameraController.update();
|
||||
}
|
||||
if (input.isKeyPressed(Key.KEY_SPACE)) {
|
||||
player.attack();
|
||||
}
|
||||
|
||||
if (input.isKeyPressed(Key.KEY_ENTER)) {
|
||||
player.interact();
|
||||
}
|
||||
|
||||
if (input.isKeyPressed(Key.KEY_LEFT_CONTROL)) {
|
||||
if (input.isKeyPressed(Key.KEY_DOWN)) {
|
||||
player.setFaceDirection(Direction.DOWN);
|
||||
} else if (input.isKeyPressed(Key.KEY_UP)) {
|
||||
player.setFaceDirection(Direction.UP);
|
||||
} else if (input.isKeyPressed(Key.KEY_LEFT)) {
|
||||
player.setFaceDirection(Direction.LEFT);
|
||||
} else if (input.isKeyPressed(Key.KEY_RIGHT)) {
|
||||
player.setFaceDirection(Direction.RIGHT);
|
||||
}
|
||||
} else {
|
||||
if (input.isKeyPressed(Key.KEY_DOWN)) {
|
||||
player.getLayer().pushMovement(player.prepareMovement(Direction.DOWN));
|
||||
} else if (input.isKeyPressed(Key.KEY_UP)) {
|
||||
player.getLayer().pushMovement(player.prepareMovement(Direction.UP));
|
||||
} else if (input.isKeyPressed(Key.KEY_LEFT)) {
|
||||
player.getLayer().pushMovement(player.prepareMovement(Direction.LEFT));
|
||||
} else if (input.isKeyPressed(Key.KEY_RIGHT)) {
|
||||
player.getLayer().pushMovement(player.prepareMovement(Direction.RIGHT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Context context, GameMap map, float dt) {
|
||||
cameraController.update();
|
||||
}
|
||||
|
||||
public Enemy enemy(@NonNull String id) {
|
||||
return new Enemy(id);
|
||||
}
|
||||
|
||||
public Enemy enemy(ObjectLayer layer, int x, int y, @NonNull String id) {
|
||||
var enemy = new Enemy(id);
|
||||
enemy.setCoordinates(x, y);
|
||||
layer.addEntity(enemy);
|
||||
return enemy;
|
||||
}
|
||||
|
||||
public Chest chest(ObjectLayer layer, int x, int y, @NonNull String id) {
|
||||
var chest = new Chest(id);
|
||||
chest.setCoordinates(x, y);
|
||||
layer.addEntity(chest);
|
||||
return chest;
|
||||
}
|
||||
|
||||
public CharacterSpawner spawner(ObjectLayer layer, int x, int y) {
|
||||
var spawner = new CharacterSpawner().trackEntities(EnemyDiedEvent.TYPE);
|
||||
spawner.setCoordinates(x, y);
|
||||
layer.addEntity(spawner);
|
||||
return spawner;
|
||||
}
|
||||
|
||||
public Icon icon(ObjectLayer layer, int x, int y, String iconSetUid, int row, int column) {
|
||||
var icon = context.createIcon(iconSetUid, row, column);
|
||||
icon.setScale(1f);
|
||||
icon.setZIndex(-1);
|
||||
icon.setCoordinates(x, y);
|
||||
layer.addEntity(icon);
|
||||
return icon;
|
||||
}
|
||||
|
||||
public Warp warp(ObjectLayer layer, int x, int y, String targetMap, String targetLayer, int targetX, int targetY) {
|
||||
var warp = new Warp(A.maps.get(targetMap).uid, A.maps.getLayer(targetMap, targetLayer), targetX, targetY);
|
||||
warp.setEntity(player);
|
||||
warp.setCoordinates(x, y);
|
||||
layer.addEntity(warp);
|
||||
return warp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.bartlomiejpluta.demo.map;
|
||||
|
||||
public class ForrestHandler extends BaseMapHandler {
|
||||
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
package com.bartlomiejpluta.demo.map;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.input.Input;
|
||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
|
||||
public class ForrestTempleHandler extends BaseMapHandler {
|
||||
public static final String UID = "f845355e-b9ad-4884-a217-dd3a4c18a3fa";
|
||||
public static final A.maps.GameMapAsset_Layers_ForrestTemple LAYERS = A.maps.forrest_temple.layers;
|
||||
|
||||
public static final int MAIN_LAYER = 4;
|
||||
|
||||
@Override
|
||||
public void onCreate(Context context, GameMap map) {
|
||||
super.onCreate(context, map);
|
||||
this.mainLayer = map.getObjectLayer(MAIN_LAYER);
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Context context, GameMap map) {
|
||||
super.onCreate(context, map);
|
||||
this.mainLayer = map.getObjectLayer(MAIN_LAYER);
|
||||
}
|
||||
}
|
||||
@@ -1,88 +1,125 @@
|
||||
package com.bartlomiejpluta.demo.menu;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.function.*;
|
||||
|
||||
import A.widgets;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.input.*;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.gui.DisplayMode;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.gui.UpdateMode;
|
||||
import com.bartlomiejpluta.base.api.gui.WindowManager;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||
import com.bartlomiejpluta.demo.entity.Chest;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.gui.EquipmentWindow;
|
||||
import com.bartlomiejpluta.demo.gui.GameMenuWindow;
|
||||
import com.bartlomiejpluta.demo.gui.LootWindow;
|
||||
import com.bartlomiejpluta.demo.gui.StartMenuWindow;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.gui.*;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MenuManager {
|
||||
private final DemoRunner runner;
|
||||
private final Context context;
|
||||
private final GUI gui;
|
||||
private final WindowManager manager;
|
||||
private final DemoRunner runner;
|
||||
private final Context context;
|
||||
private final GUI gui;
|
||||
private final WindowManager manager;
|
||||
|
||||
private final StartMenuWindow startMenu;
|
||||
private final GameMenuWindow gameMenu;
|
||||
private final StartMenuWindow startMenu;
|
||||
private final GameMenuWindow gameMenu;
|
||||
private final EquipmentWindow equipment;
|
||||
private final LootWindow loot;
|
||||
private final Consumer<KeyEvent> gameMenuHandler = this::handleGameMenuKeyEvent;
|
||||
|
||||
private final Consumer<KeyEvent> gameMenuHandler = this::handleGameMenuKeyEvent;
|
||||
public MenuManager(@NonNull DemoRunner runner, @NonNull Context context) {
|
||||
this.runner = runner;
|
||||
this.context = context;
|
||||
this.gui = context.newGUI();
|
||||
this.manager = new WindowManager(context, DisplayMode.DISPLAY_TOP, UpdateMode.UPDATE_TOP);
|
||||
|
||||
public MenuManager(@NonNull DemoRunner runner, @NonNull Context context) {
|
||||
this.runner = runner;
|
||||
this.context = context;
|
||||
this.gui = context.newGUI();
|
||||
this.manager = new WindowManager(context, DisplayMode.DISPLAY_TOP, UpdateMode.UPDATE_TOP);
|
||||
this.gui.setRoot(this.manager);
|
||||
|
||||
this.gui.setRoot(this.manager);
|
||||
this.startMenu = gui.inflateWindow(A.widgets.start_menu.uid, StartMenuWindow.class);
|
||||
this.startMenu.getNewGameBtn().setAction(runner::newGame);
|
||||
this.startMenu.getExitBtn().setAction(runner::exit);
|
||||
|
||||
this.startMenu = (StartMenuWindow) gui.inflateWindow("ab9d40b4-eb28-45d7-bff2-9432a05eb41a");
|
||||
this.startMenu.getNewGameBtn().setAction(runner::newGame);
|
||||
this.startMenu.getExitBtn().setAction(runner::exit);
|
||||
this.gameMenu = gui.inflateWindow(A.widgets.game_menu.uid, GameMenuWindow.class);
|
||||
this.gameMenu.getResumeGameBtn().setAction(this::resumeGame);
|
||||
this.gameMenu.getStartMenuBtn().setAction(runner::returnToStartMenu);
|
||||
this.gameMenu.getExitBtn().setAction(runner::exit);
|
||||
|
||||
this.gameMenu = (GameMenuWindow) gui.inflateWindow("56ca6b39-f949-4212-9c23-312db25887e0");
|
||||
this.gameMenu.getResumeGameBtn().setAction(this::resumeGame);
|
||||
this.gameMenu.getStartMenuBtn().setAction(runner::returnToStartMenu);
|
||||
this.gameMenu.getExitBtn().setAction(runner::exit);
|
||||
}
|
||||
this.equipment = gui.inflateWindow(A.widgets.equipment.uid, EquipmentWindow.class);
|
||||
this.loot = gui.inflateWindow(widgets.loot_menu.uid, LootWindow.class);
|
||||
}
|
||||
|
||||
private void handleGameMenuKeyEvent(KeyEvent event) {
|
||||
if (event.getKey() == Key.KEY_ESCAPE && event.getAction() == KeyAction.PRESS) {
|
||||
if(manager.size() > 0) {
|
||||
manager.close();
|
||||
} else {
|
||||
manager.open(gameMenu);
|
||||
}
|
||||
private void handleGameMenuKeyEvent(KeyEvent event) {
|
||||
if (event.getKey() == Key.KEY_E && event.getAction() == KeyAction.PRESS) {
|
||||
if (manager.isEmpty()) {
|
||||
manager.open(equipment);
|
||||
} else if (manager.top() == equipment) {
|
||||
manager.close();
|
||||
}
|
||||
|
||||
if(manager.size() > 0) {
|
||||
context.pause();
|
||||
} else {
|
||||
context.resume();
|
||||
}
|
||||
event.consume();
|
||||
}
|
||||
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
if (event.getKey() == Key.KEY_ESCAPE && event.getAction() == KeyAction.PRESS) {
|
||||
if (manager.size() > 0) {
|
||||
manager.close();
|
||||
} else {
|
||||
manager.open(gameMenu);
|
||||
}
|
||||
|
||||
public void showStartMenu() {
|
||||
manager.closeAll();
|
||||
manager.open(startMenu);
|
||||
}
|
||||
if (manager.size() > 0) {
|
||||
context.pause();
|
||||
} else {
|
||||
context.resume();
|
||||
}
|
||||
|
||||
public void enableGameMenu() {
|
||||
manager.closeAll();
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
|
||||
context.getInput().addKeyEventHandler(gameMenuHandler);
|
||||
manager.setDisplayMode(DisplayMode.DISPLAY_STACK);
|
||||
}
|
||||
public int openedWindows() {
|
||||
return manager.size();
|
||||
}
|
||||
|
||||
public void disableGameMenu() {
|
||||
context.getInput().removeKeyEventHandler(gameMenuHandler);
|
||||
manager.setDisplayMode(DisplayMode.DISPLAY_TOP);
|
||||
}
|
||||
public void showStartMenu() {
|
||||
manager.closeAll();
|
||||
manager.open(startMenu);
|
||||
}
|
||||
|
||||
public void closeAll() {
|
||||
manager.closeAll();
|
||||
}
|
||||
public void enableGameMenu() {
|
||||
manager.closeAll();
|
||||
|
||||
private void resumeGame() {
|
||||
manager.closeAll();
|
||||
context.resume();
|
||||
}
|
||||
context.getInput().addKeyEventHandler(gameMenuHandler);
|
||||
manager.setDisplayMode(DisplayMode.DISPLAY_STACK);
|
||||
}
|
||||
|
||||
public void disableGameMenu() {
|
||||
context.getInput().removeKeyEventHandler(gameMenuHandler);
|
||||
manager.setDisplayMode(DisplayMode.DISPLAY_TOP);
|
||||
}
|
||||
|
||||
public void openLootWindow(@NonNull Enemy enemy) {
|
||||
manager.closeAll();
|
||||
|
||||
manager.open(loot, enemy.getLoot(), "Loot");
|
||||
}
|
||||
|
||||
public void openChestWindow(@NonNull Chest chest) {
|
||||
manager.closeAll();
|
||||
|
||||
manager.open(loot, chest.getContent(), chest.getName());
|
||||
}
|
||||
|
||||
public void closeAll() {
|
||||
manager.closeAll();
|
||||
}
|
||||
|
||||
private void resumeGame() {
|
||||
manager.closeAll();
|
||||
context.resume();
|
||||
}
|
||||
}
|
||||
@@ -1,100 +1,126 @@
|
||||
package com.bartlomiejpluta.demo.runner;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.util.profiler.FPSProfiler;
|
||||
import com.bartlomiejpluta.demo.entity.Chest;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.menu.MenuManager;
|
||||
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||
import lombok.Getter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.input.Input;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||
|
||||
import com.bartlomiejpluta.demo.map.ForrestTempleHandler;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.menu.MenuManager;
|
||||
|
||||
public class DemoRunner implements GameRunner {
|
||||
private static final Logger log = LoggerFactory.getLogger(DemoRunner.class);
|
||||
private final FPSProfiler fpsProfiler = FPSProfiler.create(20);
|
||||
private Screen screen;
|
||||
private Context context;
|
||||
private MenuManager menu;
|
||||
|
||||
private GUI hud;
|
||||
@Getter
|
||||
private Player player;
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
|
||||
configureScreen();
|
||||
configureCamera();
|
||||
initMenu();
|
||||
initPlayer();
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
|
||||
menu.showStartMenu();
|
||||
configureScreen();
|
||||
configureCamera();
|
||||
initPlayer();
|
||||
initHUD();
|
||||
initMenu();
|
||||
|
||||
screen.show();
|
||||
menu.showStartMenu();
|
||||
|
||||
screen.show();
|
||||
}
|
||||
|
||||
|
||||
private void configureScreen() {
|
||||
var resolution = screen.getCurrentResolution();
|
||||
screen.setSize(800, 600);
|
||||
screen.setPosition((resolution.x() - 800)/2, (resolution.y() - 600)/2);
|
||||
var resolution = screen.getCurrentResolution();
|
||||
screen.setSize(1800, 1000);
|
||||
screen.setPosition((resolution.x() - 1800) / 2, (resolution.y() - 1000) / 2);
|
||||
}
|
||||
|
||||
|
||||
private void configureCamera() {
|
||||
context.getCamera().setScale(2f);
|
||||
context.getCamera().setScale(2f);
|
||||
}
|
||||
|
||||
|
||||
private void initMenu() {
|
||||
this.menu = new MenuManager(this, context);
|
||||
this.menu = new MenuManager(this, context);
|
||||
}
|
||||
|
||||
public int openedWindows() {
|
||||
return this.menu.openedWindows();
|
||||
}
|
||||
|
||||
private void initHUD() {
|
||||
hud = context.newGUI();
|
||||
hud.hide();
|
||||
var hudComponent = hud.inflateComponent(A.widgets.hud.uid);
|
||||
hud.setRoot(hudComponent);
|
||||
}
|
||||
|
||||
private void initPlayer() {
|
||||
this.player = new Player(context, context.createEntity("815a5c5c-4979-42f5-a42a-ccbbff9a97e5"));
|
||||
this.player = new Player(context.createCharacter(A.charsets.luna.uid));
|
||||
}
|
||||
|
||||
|
||||
private void resetPlayer() {
|
||||
this.player.changeEntitySet("815a5c5c-4979-42f5-a42a-ccbbff9a97e5");
|
||||
this.player.setScale(1.0f);
|
||||
this.player.setSpeed(0.07f);
|
||||
this.player.setAnimationSpeed(0.005f);
|
||||
this.player.setBlocking(true);
|
||||
this.player.setCoordinates(0, 11);
|
||||
this.player.changeCharacterSet(A.charsets.luna.uid);
|
||||
this.player.setScale(1f);
|
||||
this.player.setSpeed(4f);
|
||||
this.player.setAnimationSpeed(1f);
|
||||
this.player.setBlocking(true);
|
||||
}
|
||||
|
||||
|
||||
public void newGame() {
|
||||
menu.closeAll();
|
||||
menu.enableGameMenu();
|
||||
resetPlayer();
|
||||
context.openMap(ForrestTempleHandler.UID);
|
||||
context.getMap().getObjectLayer(ForrestTempleHandler.MAIN_LAYER).addEntity(this.player);
|
||||
context.resume();
|
||||
menu.closeAll();
|
||||
menu.enableGameMenu();
|
||||
resetPlayer();
|
||||
context.openMap(A.maps.forrest.uid);
|
||||
context.getMap().getObjectLayer(A.maps.forrest.layers.main).addEntity(this.player);
|
||||
player.setCoordinates(5, 36);
|
||||
context.resume();
|
||||
hud.show();
|
||||
}
|
||||
|
||||
public void returnToStartMenu() {
|
||||
menu.closeAll();
|
||||
context.pause();
|
||||
context.closeMap();
|
||||
menu.disableGameMenu();
|
||||
menu.showStartMenu();
|
||||
menu.closeAll();
|
||||
hud.hide();
|
||||
context.pause();
|
||||
context.closeMap();
|
||||
menu.disableGameMenu();
|
||||
menu.showStartMenu();
|
||||
}
|
||||
|
||||
public void openLootWindow(Enemy enemy) {
|
||||
menu.openLootWindow(enemy);
|
||||
}
|
||||
|
||||
public void openChestWindow(Chest chest) {
|
||||
menu.openChestWindow(chest);
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
context.close();
|
||||
context.close();
|
||||
}
|
||||
|
||||
public double instantFPS() {
|
||||
return fpsProfiler.getInstantFPS();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
|
||||
fpsProfiler.update(dt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// Do something after game loop is end
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.bartlomiejpluta.demo.util;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class LimitedQueue<E> extends LinkedList<E> {
|
||||
private int limit;
|
||||
|
||||
@Override
|
||||
public boolean add(E o) {
|
||||
super.add(o);
|
||||
|
||||
while (size() > limit) {
|
||||
super.remove();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
21
src/main/java/com/bartlomiejpluta/demo/util/ListUtil.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.bartlomiejpluta.demo.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ListUtil {
|
||||
private static final Random random = new Random();
|
||||
|
||||
public static <T> T sample(List<T> list) {
|
||||
return list.get(random.nextInt(list.size()));
|
||||
}
|
||||
|
||||
public static List<Integer> randomIntSequence(int startInclusive, int endExclusive) {
|
||||
var ints = new ArrayList<>(IntStream.range(startInclusive, endExclusive).boxed().toList());
|
||||
Collections.shuffle(ints);
|
||||
return ints;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.demo.world.item;
|
||||
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
|
||||
public interface Item extends Icon {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.bartlomiejpluta.demo.world.item;
|
||||
|
||||
public interface ItemStack extends Item {
|
||||
int getCount();
|
||||
|
||||
void setCount(int count);
|
||||
|
||||
void decrease();
|
||||
|
||||
void increase();
|
||||
|
||||
void increase(int count);
|
||||
|
||||
void decrease(int count);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.bartlomiejpluta.demo.world.item;
|
||||
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
|
||||
public interface Useable {
|
||||
void use(Creature creature);
|
||||
|
||||
default String usageName() {
|
||||
return "Use";
|
||||
}
|
||||
}
|
||||
28
src/main/java/com/bartlomiejpluta/demo/world/junk/Junk.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.bartlomiejpluta.demo.world.junk;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.lib.icon.IconDelegate;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class Junk extends IconDelegate implements Item {
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
public Junk(@NonNull String id) {
|
||||
this(DB.dao.junk.find(id));
|
||||
}
|
||||
|
||||
public Junk(@NonNull DB.model.JunkModel template) {
|
||||
super(createIcon(template));
|
||||
this.name = template.getName();
|
||||
}
|
||||
|
||||
private static Icon createIcon(DB.model.JunkModel template) {
|
||||
var icons = template.getIcon().split(",");
|
||||
return ContextHolder.INSTANCE.getContext().createIcon(A.iconsets.get(icons[0]).uid, Integer.parseInt(icons[1]), Integer.parseInt(icons[2]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.bartlomiejpluta.demo.world.weapon;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.lib.icon.IconDelegate;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.world.item.ItemStack;
|
||||
import com.bartlomiejpluta.demo.world.item.Useable;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
public class Ammunition extends IconDelegate implements ItemStack, Useable {
|
||||
|
||||
@Getter
|
||||
private final String id;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int count;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final String appliesTo;
|
||||
|
||||
public Ammunition(@NonNull String id, int count) {
|
||||
this(DB.dao.ammunition.find(id), count);
|
||||
}
|
||||
|
||||
public Ammunition(@NonNull DB.model.AmmunitionModel template, int count) {
|
||||
super(createIcon(template));
|
||||
this.id = template.getId();
|
||||
this.name = template.getName();
|
||||
this.count = count;
|
||||
this.appliesTo = template.getAppliesTo();
|
||||
}
|
||||
|
||||
private static Icon createIcon(DB.model.AmmunitionModel template) {
|
||||
var icons = template.getIcon().split(",");
|
||||
return ContextHolder.INSTANCE.getContext().createIcon(A.iconsets.get(icons[0]).uid, Integer.parseInt(icons[1]), Integer.parseInt(icons[2]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrease() {
|
||||
if (count > 0) {
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increase() {
|
||||
++count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increase(int count) {
|
||||
this.count += count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrease(int count) {
|
||||
this.count = Math.max(0, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Creature creature) {
|
||||
creature.setAmmunition(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String usageName() {
|
||||
return "Equip";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.bartlomiejpluta.demo.world.weapon;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.RandomAnimationsRunner;
|
||||
import com.bartlomiejpluta.base.lib.icon.IconDelegate;
|
||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
public class MeleeWeapon extends IconDelegate implements Weapon {
|
||||
private final Context context;
|
||||
private final AnimationRunner animation;
|
||||
private final String sound;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final DiceRoller dmgRoller;
|
||||
|
||||
@Getter
|
||||
private final int cooldown;
|
||||
|
||||
public MeleeWeapon(@NonNull String id) {
|
||||
this(DB.dao.melee_weapon.find(id));
|
||||
}
|
||||
|
||||
public MeleeWeapon(@NonNull DB.model.MeleeWeaponModel template) {
|
||||
super(createIcon(template));
|
||||
|
||||
this.context = ContextHolder.INSTANCE.getContext();
|
||||
this.name = template.getName();
|
||||
this.dmgRoller = DiceRoller.of(template.getDamage());
|
||||
this.cooldown = template.getCooldown();
|
||||
this.animation = new RandomAnimationsRunner(2).nRange(0, 2f).nScale(0.2f, 0.15f).uAnimationSpeed(0.5f, 1f).nRotation(0, 10).offset(0, -10).uDelay(250, 500).with(A.animations.get(template.getAnimation()).uid);
|
||||
this.sound = A.sounds.get(template.getSound()).uid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attack(Creature 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 Creature character) {
|
||||
var damage = dmgRoller.roll();
|
||||
character.hit(attacker, damage);
|
||||
animation.run(context, character.getLayer(), character);
|
||||
context.playSound(sound);
|
||||
context.fireEvent(new HitEvent(attacker, character, damage));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Creature creature) {
|
||||
creature.setWeapon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String usageName() {
|
||||
return "Equip";
|
||||
}
|
||||
|
||||
private static Icon createIcon(DB.model.MeleeWeaponModel template) {
|
||||
var icons = template.getIcon().split(",");
|
||||
return ContextHolder.INSTANCE.getContext().createIcon(A.iconsets.get(icons[0]).uid, Integer.parseInt(icons[1]), Integer.parseInt(icons[2]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.bartlomiejpluta.demo.world.weapon;
|
||||
|
||||
import com.bartlomiejpluta.base.api.animation.Animation;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.api.move.Movable;
|
||||
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.BulletAnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.icon.IconDelegate;
|
||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class RangedWeapon extends IconDelegate implements Weapon {
|
||||
private final Context context;
|
||||
private final BulletAnimationRunner animation;
|
||||
private final String sound;
|
||||
private final AnimationRunner punchAnimation;
|
||||
private final String punchSound;
|
||||
private final AnimationRunner missAnimation;
|
||||
private final String missSound;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final String type;
|
||||
|
||||
@Getter
|
||||
private final DiceRoller dmgRoller;
|
||||
|
||||
@Getter
|
||||
private final DiceRoller rangeRoller;
|
||||
|
||||
@Getter
|
||||
private final int cooldown;
|
||||
|
||||
public RangedWeapon(@NonNull String id) {
|
||||
this(DB.dao.ranged_weapon.find(id));
|
||||
}
|
||||
|
||||
public RangedWeapon(@NonNull DB.model.RangedWeaponModel template) {
|
||||
super(createIcon(template));
|
||||
|
||||
this.context = ContextHolder.INSTANCE.getContext();
|
||||
this.name = template.getName();
|
||||
this.type = template.getType();
|
||||
this.dmgRoller = DiceRoller.of(template.getDamage());
|
||||
this.rangeRoller = DiceRoller.of(template.getRange());
|
||||
this.cooldown = template.getCooldown();
|
||||
this.animation = new BulletAnimationRunner(A.animations.get(template.getAnimation()).uid).infinite().offset(0, -15).onHit(this::onHit).onMiss(this::onMiss).speed(7f).animationSpeed(4f).scale(0.6f);
|
||||
this.sound = A.sounds.get(template.getSound()).uid;
|
||||
this.punchAnimation = new SimpleAnimationRunner(A.animations.get(template.getPunchAnimation()).uid);
|
||||
this.punchSound = A.sounds.get(template.getPunchSound()).uid;
|
||||
this.missAnimation = new SimpleAnimationRunner(A.animations.get(template.getMissAnimation()).uid).scale(0.4f);
|
||||
this.missSound = A.sounds.get(template.getMissSound()).uid;
|
||||
}
|
||||
|
||||
private void onHit(Movable attacker, Entity target) {
|
||||
if (target.isBlocking() && target instanceof Creature character) {
|
||||
var namedAttacker = (Creature) attacker;
|
||||
var damage = dmgRoller.roll();
|
||||
character.hit(namedAttacker, damage);
|
||||
punchAnimation.run(context, character.getLayer(), character);
|
||||
context.playSound(punchSound);
|
||||
context.fireEvent(new HitEvent(namedAttacker, character, damage));
|
||||
}
|
||||
}
|
||||
|
||||
private void onMiss(Movable attacker, Animation animation) {
|
||||
missAnimation.run(context, ((Creature) attacker).getLayer(), animation.getPosition());
|
||||
context.playSound(missSound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attack(Creature attacker) {
|
||||
var ammunition = attacker.getAmmunition();
|
||||
|
||||
if(ammunition == null || !ammunition.getAppliesTo().equals(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var direction = attacker.getFaceDirection();
|
||||
context.playSound(sound);
|
||||
animation.range(rangeRoller.roll()).direction(direction).rotation(direction.xAngle - 180).run(context, attacker.getLayer(), attacker);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Creature creature) {
|
||||
creature.setWeapon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String usageName() {
|
||||
return "Equip";
|
||||
}
|
||||
|
||||
private static Icon createIcon(DB.model.RangedWeaponModel template) {
|
||||
var icons = template.getIcon().split(",");
|
||||
return ContextHolder.INSTANCE.getContext().createIcon(A.iconsets.get(icons[0]).uid, Integer.parseInt(icons[1]), Integer.parseInt(icons[2]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.bartlomiejpluta.demo.world.weapon;
|
||||
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import com.bartlomiejpluta.demo.world.item.Useable;
|
||||
|
||||
public interface Weapon extends Item, Useable {
|
||||
|
||||
int getCooldown();
|
||||
|
||||
boolean attack(Creature attacker);
|
||||
}
|
||||
44
widgets/00bd0625-b3b8-4abf-97b7-91f42bce28ec.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<demo:HUD
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
height="relative"
|
||||
width="relative">
|
||||
|
||||
<base:BorderLayout-TopLeft>
|
||||
<demo:Bar
|
||||
ref="hp"
|
||||
strokeColor="0x111111"
|
||||
fillColor="0xFF0000"
|
||||
width="250f"
|
||||
height="20f"/>
|
||||
</base:BorderLayout-TopLeft>
|
||||
|
||||
<base:BorderLayout-TopRight>
|
||||
<base:IconView ref="weapon" scale="2f"/>
|
||||
</base:BorderLayout-TopRight>
|
||||
|
||||
<base:BorderLayout-BottomLeft>
|
||||
<base:Label
|
||||
ref="log"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="400f"
|
||||
height="25f"
|
||||
alignment="bottom|left"
|
||||
color="0xFFFFFF"
|
||||
fontSize="15f"/>
|
||||
</base:BorderLayout-BottomLeft>
|
||||
|
||||
<base:BorderLayout-BottomRight>
|
||||
<base:Label
|
||||
ref="debug"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="200f"
|
||||
height="25f"
|
||||
alignment="bottom|right"
|
||||
color="0xFFFFFF"
|
||||
fontSize="15f"/>
|
||||
</base:BorderLayout-BottomRight>
|
||||
|
||||
</demo:HUD>
|
||||
42
widgets/53ca3e54-0f8d-44fa-8281-acd9c5bba743.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<demo:DecoratedWindow
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="center"
|
||||
padding="20f"
|
||||
width="auto"
|
||||
height="auto">
|
||||
<base:VOptionChoice ref="menu" height="auto" width="auto">
|
||||
|
||||
<demo:Button
|
||||
ref="use"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Use
|
||||
</demo:Button>
|
||||
|
||||
<demo:Button
|
||||
ref="drop"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Drop
|
||||
</demo:Button>
|
||||
|
||||
<demo:Button
|
||||
ref="cancel"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Cancel
|
||||
</demo:Button>
|
||||
|
||||
</base:VOptionChoice>
|
||||
</demo:DecoratedWindow>
|
||||
@@ -1,63 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<demo:GameMenuWindow
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="WindowPosition.CENTER"
|
||||
margin="10f"
|
||||
padding="20f">
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="center"
|
||||
margin="10f"
|
||||
padding="20f">
|
||||
|
||||
<base:VLayout
|
||||
width="200f"
|
||||
widthMode="SizeMode.ABSOLUTE">
|
||||
<base:VLayout width="200f">
|
||||
|
||||
<base:Label
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
alignment="GUI.ALIGN_TOP | GUI.ALIGN_CENTER"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
alpha="0.5f"
|
||||
fontSize="30f">Game Menu</base:Label>
|
||||
<base:Label
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
alignment="top|center"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
alpha="0.5f"
|
||||
fontSize="30f">Game Menu
|
||||
</base:Label>
|
||||
|
||||
<base:VOptionChoice
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f">
|
||||
<base:VOptionChoice width="relative">
|
||||
<demo:Button
|
||||
ref="resume_game"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Resume game
|
||||
</demo:Button>
|
||||
|
||||
<demo:Button
|
||||
ref="resume_game"
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Resume game</demo:Button>
|
||||
<demo:Button
|
||||
ref="start_menu"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Back to start menu
|
||||
</demo:Button>
|
||||
|
||||
<demo:Button
|
||||
ref="start_menu"
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Back to start menu</demo:Button>
|
||||
<demo:Button
|
||||
ref="exit"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Exit
|
||||
</demo:Button>
|
||||
</base:VOptionChoice>
|
||||
|
||||
<demo:Button
|
||||
ref="exit"
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Exit</demo:Button>
|
||||
|
||||
</base:VOptionChoice>
|
||||
|
||||
</base:VLayout>
|
||||
</base:VLayout>
|
||||
|
||||
</demo:GameMenuWindow>
|
||||
@@ -1,53 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<demo:StartMenuWindow
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="WindowPosition.BOTTOM"
|
||||
margin="10f"
|
||||
padding="20f">
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="bottom"
|
||||
margin="10f"
|
||||
padding="20f">
|
||||
|
||||
<base:VLayout
|
||||
width="200f"
|
||||
widthMode="SizeMode.ABSOLUTE">
|
||||
<base:VLayout width="200f">
|
||||
<base:Label
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
alignment="top|center"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
alpha="0.5f"
|
||||
fontSize="30f">Menu
|
||||
</base:Label>
|
||||
|
||||
<base:Label
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
alignment="GUI.ALIGN_TOP | GUI.ALIGN_CENTER"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
alpha="0.5f"
|
||||
fontSize="30f">Menu</base:Label>
|
||||
<base:VOptionChoice ref="menu" width="relative">
|
||||
<demo:Button
|
||||
ref="new_game"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">New Game
|
||||
</demo:Button>
|
||||
|
||||
<base:VOptionChoice
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f">
|
||||
|
||||
<demo:Button
|
||||
ref="new_game"
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">New Game</demo:Button>
|
||||
|
||||
<demo:Button
|
||||
ref="exit"
|
||||
font=""2261c04f-b02e-4486-b388-8a0fa41622e9""
|
||||
widthMode="SizeMode.RELATIVE"
|
||||
width="1f"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Exit</demo:Button>
|
||||
|
||||
</base:VOptionChoice>
|
||||
|
||||
</base:VLayout>
|
||||
<demo:Button
|
||||
ref="exit"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
fontSize="17f">Exit
|
||||
</demo:Button>
|
||||
</base:VOptionChoice>
|
||||
</base:VLayout>
|
||||
|
||||
</demo:StartMenuWindow>
|
||||
70
widgets/c473a91a-ff25-4e71-9bec-b35e48102aeb.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<demo:EquipmentWindow
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="center"
|
||||
padding="20f"
|
||||
width="auto"
|
||||
height="auto">
|
||||
|
||||
<base:VLayout width="auto" height="auto">
|
||||
<base:Label
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
alignment="top|center"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
alpha="0.5f"
|
||||
fontSize="30f">Equipment
|
||||
</base:Label>
|
||||
|
||||
<base:HLayout>
|
||||
<base:VGridLayout columns="2" padding="20f" width="250f">
|
||||
<demo:ItemIconView ref="weapon" margin="5f"/>
|
||||
<demo:ItemIconView ref="ammo" margin="5f"/>
|
||||
</base:VGridLayout>
|
||||
|
||||
<base:VGridOptionChoice ref="eq" columns="4" width="auto" height="auto">
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
<demo:ItemIconView margin="5f"/>
|
||||
</base:VGridOptionChoice>
|
||||
|
||||
<base:VLayout height="relative" padding="20f" width="250f">
|
||||
<base:Label ref="item-name"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
alignment="top|center"
|
||||
color="0xFFFFFF"
|
||||
fontSize="20f"
|
||||
margin="5f"/>
|
||||
|
||||
<base:Label ref="item-details"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
alignment="top|left"
|
||||
color="0xFFFFFF"
|
||||
fontSize="15f"
|
||||
margin="5f"/>
|
||||
|
||||
</base:VLayout>
|
||||
|
||||
</base:HLayout>
|
||||
</base:VLayout>
|
||||
|
||||
</demo:EquipmentWindow>
|
||||
27
widgets/d78413cd-0dad-4b51-8dd1-54e33535fe53.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<demo:LootWindow
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="center"
|
||||
padding="20f"
|
||||
width="auto"
|
||||
height="auto">
|
||||
|
||||
<base:VLayout width="auto" height="auto">
|
||||
<base:Label
|
||||
ref="title"
|
||||
font="A.fonts.roboto_regular.uid"
|
||||
width="relative"
|
||||
alignment="top|center"
|
||||
red="1f"
|
||||
green="1f"
|
||||
blue="1f"
|
||||
alpha="0.5f"
|
||||
fontSize="30f"/>
|
||||
|
||||
<base:VGridOptionChoice ref="loot" columns="4" width="auto" height="auto"/>
|
||||
|
||||
</base:VLayout>
|
||||
|
||||
</demo:LootWindow>
|
||||