Improve the game start with some simple Grandma dialog

This commit is contained in:
2023-11-16 14:15:26 +01:00
parent 0be7b2fa43
commit 990ad6519e
7 changed files with 99 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -84,10 +84,6 @@
"x": 3, "x": 3,
"y": 12, "y": 12,
"code": "/* \n * Following final parameters are available to use:\n * x: int - the x coordinate of tile the object has been created on\n * y: int - the y coordinate of tile the object has been created on \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nwarp(here, A.maps.hero_house.main.home);" "code": "/* \n * Following final parameters are available to use:\n * x: int - the x coordinate of tile the object has been created on\n * y: int - the y coordinate of tile the object has been created on \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nwarp(here, A.maps.hero_house.main.home);"
}, {
"x": 11,
"y": 7,
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nfriend(here, \"grandma\")\n\t.randomMovementAI(4f, here.toCoordinates(), 5)\n\t.interaction(this::triggerGrandmaDialog);"
}, { }, {
"x": 5, "x": 5,
"y": 4, "y": 4,
@@ -100,6 +96,10 @@
"x": 18, "x": 18,
"y": 12, "y": 12,
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nchest(here, \"enforced_chest_left\")\n\t.addItem(new MeleeWeapon(\"wooden_sword\"))\n\t.addItem(new Medicament(\"small_life_potion\", 4))\n\t.shuffle();" "code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nchest(here, \"enforced_chest_left\")\n\t.addItem(new MeleeWeapon(\"wooden_sword\"))\n\t.addItem(new Medicament(\"small_life_potion\", 4))\n\t.shuffle();"
}, {
"x": 13,
"y": 15,
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nfriend(here, \"grandma\")\n\t.followPath(this::grandmaPath)\n\t.interaction(this::triggerGrandmaDialog);"
}], }],
"labels": [{ "labels": [{
"label": "entry", "label": "entry",
@@ -109,6 +109,14 @@
"label": "Start", "label": "Start",
"x": 10, "x": 10,
"y": 14 "y": 14
}, {
"label": "Grandma Waking",
"x": 11,
"y": 14
}, {
"label": "Grandma Origin",
"x": 11,
"y": 7
}] }]
} }
}, { }, {

View File

@@ -204,6 +204,12 @@
"name": "Heart Emoji", "name": "Heart Emoji",
"rows": 6, "rows": 6,
"columns": 4 "columns": 4
}, {
"uid": "78563669-8a6c-4024-82c8-7e4da5b76edd",
"source": "78563669-8a6c-4024-82c8-7e4da5b76edd.png",
"name": "Zzz",
"rows": 7,
"columns": 4
}], }],
"sounds": [{ "sounds": [{
"uid": "1311327d-4b74-4252-94da-23ee4129e357", "uid": "1311327d-4b74-4252-94da-23ee4129e357",

View File

@@ -5,8 +5,10 @@ import com.bartlomiejpluta.base.api.ai.AI;
import com.bartlomiejpluta.base.api.ai.NPC; import com.bartlomiejpluta.base.api.ai.NPC;
import com.bartlomiejpluta.base.api.character.Character; import com.bartlomiejpluta.base.api.character.Character;
import com.bartlomiejpluta.base.api.context.ContextHolder; import com.bartlomiejpluta.base.api.context.ContextHolder;
import com.bartlomiejpluta.base.lib.ai.FollowPathAI;
import com.bartlomiejpluta.base.lib.ai.NoopAI; import com.bartlomiejpluta.base.lib.ai.NoopAI;
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI; import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
import com.bartlomiejpluta.base.util.path.Path;
import com.bartlomiejpluta.base.util.random.DiceRoller; import com.bartlomiejpluta.base.util.random.DiceRoller;
import com.bartlomiejpluta.demo.world.item.Item; import com.bartlomiejpluta.demo.world.item.Item;
import lombok.Getter; import lombok.Getter;
@@ -74,6 +76,20 @@ public class Friend extends Creature implements NPC {
return this; return this;
} }
public Friend followPath(@NonNull Path<Friend> path) {
var ai = new FollowPathAI<>(this);
ai.setPath(path);
this.strategy = ai;
return this;
}
public Friend followPath(@NonNull Function<Friend, Path<Friend>> pathSupplier) {
var ai = new FollowPathAI<>(this);
ai.setPath(pathSupplier.apply(this));
this.strategy = ai;
return this;
}
public Friend randomMovementAI(float intervalSeconds, Vector2ic origin, int radius) { public Friend randomMovementAI(float intervalSeconds, Vector2ic origin, int radius) {
this.strategy = new RandomMovementAI<>(this, intervalSeconds, origin, radius); this.strategy = new RandomMovementAI<>(this, intervalSeconds, origin, radius);
return this; return this;

View File

@@ -3,8 +3,14 @@ package com.bartlomiejpluta.demo.entity;
import com.bartlomiejpluta.base.api.character.Character; import com.bartlomiejpluta.base.api.character.Character;
import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.context.ContextHolder; import com.bartlomiejpluta.base.api.context.ContextHolder;
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
import com.bartlomiejpluta.base.lib.character.CharacterDelegate; import com.bartlomiejpluta.base.lib.character.CharacterDelegate;
import com.bartlomiejpluta.demo.runner.DemoRunner; import com.bartlomiejpluta.demo.runner.DemoRunner;
import lombok.NonNull;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
public abstract class NamedCharacter extends CharacterDelegate { public abstract class NamedCharacter extends CharacterDelegate {
protected final Context context; protected final Context context;
@@ -21,4 +27,22 @@ public abstract class NamedCharacter extends CharacterDelegate {
public int getDialogNameColor() { public int getDialogNameColor() {
return 0xFFFFFF; return 0xFFFFFF;
} }
public CompletableFuture<Void> runEmoji(@NonNull String animation) {
return runEmoji(animation, null);
}
public CompletableFuture<Void> runEmoji(@NonNull String animation, Consumer<SimpleAnimationRunner> customizer) {
var runner = AnimationRunner
.simple(animation)
.scale(0.4f)
.animationSpeed(1.6f)
.offset(0, -30);
if (customizer != null) {
customizer.accept(runner);
}
return runner.run(context, this);
}
} }

View File

@@ -41,6 +41,8 @@ public abstract class BaseMapHandler implements MapHandler {
protected boolean dayNightCycle = false; protected boolean dayNightCycle = false;
protected boolean controls = true;
@Override @Override
public void onCreate(Context context, GameMap map) { public void onCreate(Context context, GameMap map) {
this.context = context; this.context = context;
@@ -73,6 +75,10 @@ public abstract class BaseMapHandler implements MapHandler {
player.interact(); player.interact();
} }
if (!controls) {
return;
}
InputUtil.handleBasicControl(player, input); InputUtil.handleBasicControl(player, input);
} }

View File

@@ -1,25 +1,51 @@
package com.bartlomiejpluta.demo.map; package com.bartlomiejpluta.demo.map;
import A.animations;
import A.maps;
import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.map.model.GameMap; import com.bartlomiejpluta.base.api.map.model.GameMap;
import com.bartlomiejpluta.base.util.path.CharacterPath;
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
import com.bartlomiejpluta.base.util.pathfinder.PathFinder;
import com.bartlomiejpluta.demo.entity.Friend; import com.bartlomiejpluta.demo.entity.Friend;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import static com.bartlomiejpluta.base.lib.animation.AnimationRunner.simple; import static com.bartlomiejpluta.base.api.move.Direction.LEFT;
public class HeroHomeHandler extends BaseMapHandler { public class HeroHomeHandler extends BaseMapHandler {
private final PathFinder finder = new AstarPathFinder(100);
@Override @Override
public void onOpen(Context context, GameMap map) { public void onCreate(Context context, GameMap map) {
super.onCreate(context, map);
map.setAmbientColor(0.05f, 0.01f, 0.01f); map.setAmbientColor(0.05f, 0.01f, 0.01f);
dialog(player, "Ahhh, another beautiful day for an adventure... Let's go!"); }
protected CharacterPath<Friend> grandmaPath(Friend grandma) {
return new CharacterPath<Friend>()
.run(() -> controls = false)
.run(() -> player.runEmoji(A.animations.zzz.$, r -> r.repeat(5)))
.insertPath(finder.findPath(grandma.getLayer(), grandma, maps.hero_home.main.grandma_waking.toCoordinates()))
.wait(2f)
.turn(LEFT)
.wait(1f)
.suspend(() -> morningDialogWithGrandma(grandma))
.wait(1f)
.run(() -> controls = true)
.insertPath(finder.findPath(grandma.getLayer(), maps.hero_home.main.grandma_waking.toCoordinates(), maps.hero_home.main.grandma_origin.toCoordinates()))
.run(() -> grandma.randomMovementAI(4f, grandma.getCoordinates(), 4));
}
private CompletableFuture<Object> morningDialogWithGrandma(Friend grandma) {
return dialog(grandma, "Hello Honey, wake up, it's another beautiful day!")
.thenCompose(n -> dialog(player, "Ahhh, good morning Grandma!"))
.thenCompose(n -> dialog(grandma, "Have a wonderful day, Luna!"))
.thenCompose(n -> dialog(player, "Thank you Grandma, have a nice day too!"));
} }
protected CompletableFuture<Object> triggerGrandmaDialog(Friend grandma) { protected CompletableFuture<Object> triggerGrandmaDialog(Friend grandma) {
return dialog(player, "Good morning Grandma, how are you doing?") return dialog(grandma, "What are you going to do today, Luna?")
.thenCompose(n -> dialog(grandma, "Hello Honey... I'm fine thank you. Have a sit, I will bring you a breakfast in a moment."))
.thenCompose(n -> dialog(player, "Thank you Grandma."))
.thenCompose(n -> dialog(grandma, "What are you going to do today, Luna?"))
.thenCompose(n -> dialogChoice(player, .thenCompose(n -> dialogChoice(player,
"I'm going to fix your roof, Grandma", "I'm going to fix your roof, Grandma",
"I'd like to look for some hidden treasure around your house", "I'd like to look for some hidden treasure around your house",
@@ -46,8 +72,8 @@ public class HeroHomeHandler extends BaseMapHandler {
protected CompletableFuture<Object> triggerNekoDialog(Friend neko) { protected CompletableFuture<Object> triggerNekoDialog(Friend neko) {
return dialog(player, "Ohhh, here you are Kitty...") return dialog(player, "Ohhh, here you are Kitty...")
.thenCompose(n -> CompletableFuture.allOf( .thenCompose(n -> CompletableFuture.allOf(
simple(A.animations.heart_emoji.$).scale(0.4f).animationSpeed(1.7f).offset(0, -30).run(context, player), player.runEmoji(animations.heart_emoji.$),
simple(A.animations.heart_emoji.$).scale(0.4f).animationSpeed(1.7f).offset(0, -15).delay(100).run(context, neko) neko.runEmoji(animations.heart_emoji.$, r -> r.offset(0, -15).delay(100))
)) ))
.thenCompose(n -> dialog(neko, "Meow, meow...")) .thenCompose(n -> dialog(neko, "Meow, meow..."))
.thenCompose(n -> dialog(neko, "Purr, purr...")); .thenCompose(n -> dialog(neko, "Purr, purr..."));