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, "width":0,
"x":320, "x":320,
"y":608 "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, "opacity":1,
"type":"objectgroup", "type":"objectgroup",
@@ -646,6 +665,32 @@
"width":0, "width":0,
"x":160, "x":160,
"y":512 "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, "opacity":1,
"type":"objectgroup", "type":"objectgroup",

View File

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

View File

@@ -37,6 +37,8 @@ STATE_RUNNINGTOLIGHT = 1 << 11;
STATE_RUNNINGTOREPORT = 1 << 12; STATE_RUNNINGTOREPORT = 1 << 12;
STATE_LOOKINGFORTARGET = 1 << 13; STATE_LOOKINGFORTARGET = 1 << 13;
STATE_STEALING = 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_AWARENESS = (STATE_UNAWARE | STATE_CONCERNED | STATE_ALERTED | STATE_LOSTHIM);
STATES_MOVEMENT = (STATE_MOVING | STATE_RUNNING); STATES_MOVEMENT = (STATE_MOVING | STATE_RUNNING);

View File

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

View File

@@ -299,7 +299,7 @@ GameState.prototype.update = function()
} }
this.staticSounds.forEach(_fix_audio_relative, this); this.staticSounds.forEach(_fix_audio_relative, this);
function _inner_collide(x) { function _player_collide(x) {
if ( x.collide_with_map == true ) { if ( x.collide_with_map == true ) {
for ( var ln in this.map_collision_layers ) { for ( var ln in this.map_collision_layers ) {
layer = this.map_collision_layers[ln]; 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(); this.updateShadowTexture();
if ( this.aiSprites.debug == false ) { if ( this.aiSprites.debug == false ) {

View File

@@ -353,3 +353,79 @@ function getRouteByName(name)
} }
throw("Could not locate path " + 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();
}