Midway on #10: Basic conversation engine works, but AI does not stop playing its movement animation

This commit is contained in:
2014-07-09 22:14:20 -07:00
parent 18d0ae90f2
commit ce098c1e37
6 changed files with 216 additions and 43 deletions

View File

@@ -354,6 +354,25 @@
"width":0,
"x":320,
"y":608
},
{
"gid":3544,
"height":0,
"name":"BigTopCustomer2",
"properties":
{
"sprite_canmove":"true",
"sprite_facing":"right",
"sprite_group":"townsfolk-male",
"sprite_has_treasure":"true",
"sprite_name":"townsfolk-male-3",
"sprite_route":"BigTopRoute2"
},
"type":"AI",
"visible":true,
"width":0,
"x":576,
"y":512
}],
"opacity":1,
"type":"objectgroup",
@@ -646,6 +665,32 @@
"width":0,
"x":160,
"y":512
},
{
"height":0,
"name":"BigTopRoute2",
"polyline":[
{
"x":0,
"y":0
},
{
"x":-32,
"y":32
},
{
"x":-448,
"y":32
}],
"properties":
{
},
"type":"",
"visible":true,
"width":0,
"x":576,
"y":480
}],
"opacity":1,
"type":"objectgroup",

View File

@@ -138,6 +138,11 @@ var AISprite = function(game, x, y, key, frame) {
this.target != player )
this.target = null;
if ( hasState(this, STATE_CONVERSING) == true &&
( state == STATE_CONCERNED ||
state == STATE_ALERTED ) )
purgeConversation(this, this.conversation_partner);
awardPlayerScoreByState(state);
this.state_changed_at = new Phaser.Point(this.x, this.y);
this.startAwarenessTimer();
@@ -177,20 +182,39 @@ var AISprite = function(game, x, y, key, frame) {
this.enableWordBubble = function() {
this.enable_word_bubble = true;
this.timer = game.time.create(false);
if ( this.bubble_immediate == true ) {
this.bubble_immediate = false;
this.setWordBubble();
} else {
var timerdelta = 10000 + (game.rnd.integerInRange(0, 20) * 1000);
timerev = this.timer.add(timerdelta, this.setWordBubble, this);
this.timer.start()
if ( isSet(this.conversation_partner) == true &&
hasState(this, STATE_CONVERSING_YOURTURN) == true) {
this.setWordBubble();
} else {
var timerdelta = 10000 + (game.rnd.integerInRange(0, 20) * 1000);
this.timer = game.time.create(false);
timerev = this.timer.add(timerdelta, this.setWordBubble, this);
this.timer.start()
}
}
}
this.clearWordBubble = function() {
if ( isSet(this.bubble_text) )
this.clear_bubble = true;
this.clearWordBubble = function(autoadvance) {
autoadvance = (typeof autoadvance == 'undefined' ? true : autoadvance);
if ( isSet(this.bubble_text) ) {
this.bubble_text.destroy();
this.bubble_sprite.destroy();
this.bubble_text = null;
this.bubble_sprite = null;
}
if ( isSet(this.conversation_partner) == true &&
hasState(this, STATE_CONVERSING_YOURTURN) == true ) {
delState(this, STATE_CONVERSING_YOURTURN);
addState(this.conversation_partner, STATE_CONVERSING_YOURTURN);
this.enable_word_bubble = false;
if ( autoadvance == true )
this.conversation_partner.enableWordBubble();
return;
}
this.enable_word_bubble = false;
this.timer = game.time.create(false);
timerev = this.timer.add(1000, this.enableWordBubble, this);
@@ -199,7 +223,7 @@ var AISprite = function(game, x, y, key, frame) {
this.setWordBubble = function()
{
if ( isSet(this.bubble_text) ||
if ( isSet(this.bubble_text) == true ||
this.sprite_group == undefined ||
this.enable_world_bubble == false) {
return;
@@ -225,9 +249,20 @@ var AISprite = function(game, x, y, key, frame) {
}
}
var mylines = moonlightDialog['status'][this.sprite_group][aistate];
if ( isSet(this.conversation_partner) == true ) {
if ( hasState(this, STATE_CONVERSING_YOURTURN) == false )
return;
if ( this.conversation_index >= this.current_conversation['lines'].length ) {
purgeConversation(this, this.conversation_partner);
return;
}
var text = this.current_conversation['lines'][this.conversation_index];
this.conversation_index += 2;
} else {
var mylines = moonlightDialog['status'][this.sprite_group][aistate];
var text = mylines[game.rnd.integerInRange(0, mylines.length-1)];
}
bubbleimg = game.cache.getImage('wordbubble');
text = mylines[game.rnd.integerInRange(0, mylines.length-1)];
style = {font: '14px Arial Bold', fill: '#ffffff'}
this.text_size = stringSize(text, style['font']);
if ( isSet(this.bubble_sprite) == true )
@@ -365,16 +400,29 @@ var AISprite = function(game, x, y, key, frame) {
}
this.resetPathOnCollision = function() {
if ( hasState(this, STATE_CONVERSING) == true )
return true;
var aiSprites = game.state.states.game.aiSprites;
var hasBeenReset = false;
aiSprites.forEach(function(spr) {
if ( hasBeenReset == true || spr == this)
return;
if ( game.physics.arcade.overlap(spr, this) ) {
var last = this.path[this.path.length - 1];
this.path_tween_stop();
this.path_purge();
hasBeenReset = true;
if ( spr.conversation_partner == null &&
getAwarenessState(spr) == STATE_UNAWARE &&
getAwarenessState(this) == STATE_UNAWARE &&
game.rnd.integerInRange(0, 100) >= 50 ) {
setMovingState(this, getFaceState(this));
addState(this, STATE_CONVERSING);
setConversation(spr, this);
spr.path_tween_stop();
spr.path_purge();
addState(spr, STATE_CONVERSING);
setMovingState(spr, getFaceState(spr));
}
}
}, this);
return hasBeenReset;
@@ -674,17 +722,16 @@ var AISprite = function(game, x, y, key, frame) {
}
if ( isSet(this.bubble_text) ) {
if ( this.clear_bubble == true ) {
this.bubble_text.destroy();
this.bubble_sprite.destroy();
this.bubble_text = null;
this.bubble_sprite = null;
this.clear_bubble = false;
} else {
if ( isSet(this.bubble_sprite) == true ) {
this.snap_bubble_position();
}
}
if ( hasState(this, STATE_CONVERSING) &&
hasState(this, STATE_UNAWARE) ) {
return;
}
if ( hasState(this, STATE_ALERTED) ) {
if ( this.sprite_group == "townsfolk-guard" ) {
this.action_chaseplayer();
@@ -790,6 +837,9 @@ var AISprite = function(game, x, y, key, frame) {
this.sprite_group = "townsfolk-male";
this.sprite_route = null;
this.sprite_route_index = 0;
this.current_conversation = null;
this.conversation_partner = null;
this.conversation_index = 0;
this.update_new_values();
}

View File

@@ -37,6 +37,8 @@ STATE_RUNNINGTOLIGHT = 1 << 11;
STATE_RUNNINGTOREPORT = 1 << 12;
STATE_LOOKINGFORTARGET = 1 << 13;
STATE_STEALING = 1 << 13;
STATE_CONVERSING = 1 << 14;
STATE_CONVERSING_YOURTURN = 1 << 15;
STATES_AWARENESS = (STATE_UNAWARE | STATE_CONCERNED | STATE_ALERTED | STATE_LOSTHIM);
STATES_MOVEMENT = (STATE_MOVING | STATE_RUNNING);

View File

@@ -220,7 +220,7 @@ var moonlightDialog = {
},
"conversations": [
{
"members": ["townsfolk-male", "townsfolk-male"],
"members": [/townsfolk-male/, /townsfolk-male/],
"starter": "",
"lines": [
"'Allo me old china - wot\nsay we pop round the Jack\nfer a pigs ear?",
@@ -231,7 +231,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-female", "townsfolk-male"],
"members": [/townsfolk-female/, /townsfolk-male/],
"starter": "townsfolk-male",
"lines": [
"Hey there. I was wondering\nif youd like to maybe go to\nthe Summer festival with me?",
@@ -241,7 +241,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-male", "townsfolk-guard"],
"members": [/townsfolk-male/, /townsfolk-guard/],
"starter": "townsfolk-guard",
"lines": [
"Move along citizen! There'll\nbe no loitering here.",
@@ -251,7 +251,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-female", "townsfolk-female"],
"members": [/townsfolk-female/, /townsfolk-female/],
"starter": "",
"lines": [
"Have you heard about all\nthe burglaries lately?",
@@ -261,7 +261,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-female", "townsfolk-guard"],
"members": [/townsfolk-female/, /townsfolk-guard/],
"starter": "",
"lines": [
"Here, I baked some pies to thank\nyou guards for keeping us all safe.",
@@ -274,7 +274,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-guard", "townsfolk-guard"],
"members": [/townsfolk-guard/, /townsfolk-guard/],
"starter": "",
"lines": [
"Hey soldier, whatre you doing\nsitting down on the job?",
@@ -284,7 +284,7 @@ var moonlightDialog = {
],
},
{
"members": ["townsfolk-female", "townsfolk-male"],
"members": [/townsfolk-female/, /townsfolk-male/],
"starter": "townsfolk-male",
"lines": [
"You look like you need looking after, dear.",
@@ -296,7 +296,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-[fm]*"],
"members": [/townsfolk-[fm]*/, /townsfolk-[fm]*/],
"starter": "",
"lines": [
"Alright.",
@@ -308,7 +308,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-[fm]*"],
"members": [/townsfolk-[fm]*/, /townsfolk-[fm]*/],
"starter": "",
"lines": [
"Have you seen a cat around here?",
@@ -322,7 +322,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-[fm]*"],
"members": [/townsfolk-[fm]*/, /townsfolk-[fm]*/],
"starter": "",
"lines": [
"Have you seen a cat\naround here?",
@@ -333,7 +333,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-[fm]*"],
"members": [/townsfolk-[fm]*/, /townsfolk-[fm]*/],
"starter": "",
"lines": [
"See the Duke raised our\ntaxes again?",
@@ -344,7 +344,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-[fm]*"],
"members": [/townsfolk-[fm]*/, /townsfolk-[fm]*/],
"starter": "",
"lines": [
"Nice weather, ain't it?",
@@ -355,7 +355,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-guard"],
"members": [/townsfolk-[fm]*/, /townsfolk-guard/],
"starter": "townsfolk-[fm]*",
"lines": [
"Fancy a pint or three later?",
@@ -367,7 +367,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-guard"],
"members": [/townsfolk-[fm]*/, /townsfolk-guard/],
"starter": "townsfolk-[fm]*",
"lines": [
"Do you like being a guard?",
@@ -377,7 +377,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-guard"],
"members": [/townsfolk-[fm]*/, /townsfolk-guard/],
"starter": "townsfolk-[fm]*",
"lines": [
"Want to buy a fine\nleather jacket?",
@@ -388,7 +388,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-guard"],
"members": [/townsfolk-[fm]*/, /townsfolk-guard/],
"starter": "townsfolk-[fm]*",
"lines": [
"Excuse me, have you\nseen a cat?",
@@ -400,7 +400,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-[fm]*", "townsfolk-guard"],
"members": [/townsfolk-[fm]*/, /townsfolk-guard/],
"starter": "townsfolk-[fm]*",
"lines": [
"Is it true the Duke is here? ",
@@ -412,7 +412,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-guard", "townsfolk-guard"],
"members": [/townsfolk-guard/, /townsfolk-guard/],
"starter": "",
"lines": [
"Anything to report?",
@@ -424,7 +424,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-guard", "townsfolk-guard"],
"members": [/townsfolk-guard/, /townsfolk-guard/],
"starter": "",
"lines": [
"Stay alert, soldier!",
@@ -435,7 +435,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-guard", "townsfolk-guard"],
"members": [/townsfolk-guard/, /townsfolk-guard/],
"starter": "",
"lines": [
"Seen anything interesting?",
@@ -446,7 +446,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-guard", "townsfolk-guard"],
"members": [/townsfolk-guard/, /townsfolk-guard/],
"starter": "",
"lines": [
"What is it we're guarding anyway?",
@@ -458,7 +458,7 @@ var moonlightDialog = {
]
},
{
"members": ["townsfolk-guard", "townsfolk-guard"],
"members": [/townsfolk-guard/, /townsfolk-guard/],
"starter": "",
"lines": [
"Dammit. I lost my sandwich.",

View File

@@ -299,7 +299,7 @@ GameState.prototype.update = function()
}
this.staticSounds.forEach(_fix_audio_relative, this);
function _inner_collide(x) {
function _player_collide(x) {
if ( x.collide_with_map == true ) {
for ( var ln in this.map_collision_layers ) {
layer = this.map_collision_layers[ln];
@@ -397,9 +397,9 @@ GameState.prototype.update = function()
}
}
// this.effectSprites.forEach(_inner_collide, this);
// this.effectSprites.forEach(_player_collide, this);
this.aiSprites.forEach(_inner_collide, this);
this.aiSprites.forEach(_player_collide, this);
this.updateShadowTexture();
if ( this.aiSprites.debug == false ) {

View File

@@ -353,3 +353,79 @@ function getRouteByName(name)
}
throw("Could not locate path " + name);
}
function matchAny(regexes, str)
{
for ( var i = 0; i < regexes.length; i++ ) {
if ( regexes[i].test(str) == true )
return true;
}
return false;
}
function matchPair(regexes, str1, str2)
{
return (( regexes[0].test(str1) && regexes[1].test(str2)) ||
( regexes[0].test(str2) && regexes[1].test(str1))
);
}
function conversationCandidates(obj1, obj2)
{
candidates = [];
moonlightDialog['conversations'].forEach(function(convo) {
if ( matchPair(convo['members'], obj1.sprite_group, obj2.sprite_group) == false )
return;
candidates.push(convo)
}, this);
if ( candidates.length < 1 )
throw "Unable to find conversation for " + obj1.sprite_group + " and " + obj2.sprite_group;
return candidates;
}
function purgeConversation(obj1, obj2)
{
obj1.conversation_partner = null;
obj1.current_conversation = null;
obj1.conversation_index = 0;
delState(obj1, STATE_CONVERSING);
delState(obj1, STATE_CONVERSING_YOURTURN);
obj2.conversation_partner = null;
obj2.current_conversation = null;
obj2.conversation_index = 0;
delState(obj2, STATE_CONVERSING);
delState(obj2, STATE_CONVERSING_YOURTURN);
obj1.clearWordBubble();
obj2.clearWordBubble();
}
function setConversation(obj1, obj2)
{
obj1.conversation_partner = obj2;
obj2.conversation_partner = obj1;
obj1.conversation_index = 0;
obj2.conversation_index = 0;
var starter = null;
var finisher = null;
var candidates = conversationCandidates(obj1, obj2);
var convo = candidates[game.rnd.integerInRange(0, candidates.length-1)];
if ( convo['starter'] !== "" && convo['starter'] == obj1.sprite_group ) {
starter = obj1;
finisher = obj2;
} else if ( convo['starter'] !== "" && convo['starter'] == obj2.sprite_group ) {
starter = obj2;
finisher = obj1;
} else {
starter = obj1;
finisher = obj2;
}
obj1.current_conversation = convo;
obj2.current_conversation = convo;
starter.conversation_index = 0;
finisher.conversation_index = 1;
addState(starter, STATE_CONVERSING_YOURTURN);
starter.clearWordBubble(false);
finisher.clearWordBubble(false);
starter.enableWordBubble();
}