Conversations
by Levi · in Torque Game Builder · 09/13/2007 (3:06 pm) · 3 replies
I have a question about conversations/dialogs. I've been thinking about how to impliment a dialog engine.
To me, it would make sense to put the conversations in a structured data file. XML maybe? Obviously, I don't want dialog spread thoughout the script source.
has anyone impliment this sort of thing before? Also, does anyone have suggested approaches to pushing the conversations to the screen? I'd like to make it as generic as possible.
Thanks.
To me, it would make sense to put the conversations in a structured data file. XML maybe? Obviously, I don't want dialog spread thoughout the script source.
has anyone impliment this sort of thing before? Also, does anyone have suggested approaches to pushing the conversations to the screen? I'd like to make it as generic as possible.
Thanks.
About the author
#2
You can download the project (source included) here:
FindingKeepers_WIN.zip
It has a full cutscene engine in there -- check out cutscene.cs
Apologies for the ugliness -- it was all done for a 2 week speed game coding contest.
--clint
09/14/2007 (7:23 am)
I recently did this with arrays, and storing all of the data in a big script file. Not the prettiest thing in the world, but simple to understand.You can download the project (source included) here:
FindingKeepers_WIN.zip
It has a full cutscene engine in there -- check out cutscene.cs
Apologies for the ugliness -- it was all done for a 2 week speed game coding contest.
--clint
#3
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=9031
I also have a script that will give you that typewriter affect for you text as well:
Typewriter.cs
level.xml
I used level.xml to test the reading and writing of the XML Doc.
09/18/2007 (5:30 pm)
Here's a resource that parses XML Docs:www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=9031
I also have a script that will give you that typewriter affect for you text as well:
Typewriter.cs
new t2dImageMapDatablock(TextBox)
{
imageMode = "full";
imageName = "~/data/images/TextBox";
};
new AudioProfile( LetterClick )
{
filename = "~/data/audio/click.wav";
description = "AudioNonLooping";
preload = true;
};
datablock t2dSceneObjectDatablock(BulletLabelDatablock)
{
class = "BulletLabel"; // associate this datablock with the namespace
txtPos = 1;
delay = 30;
MaxLength = 500;
};
function BulletLabel::CreateLabel(%this)
{
%Box = new t2dStaticSprite() {
scenegraph = SceneWindow2D.getSceneGraph();
ImageMap = TextBox;
};
%this.Box=%box;
%BulletText = new t2dTextObject() {
scenegraph = SceneWindow2D.getSceneGraph();
size = "48.025 31.000";
font = "Arial Black";
textAlign = "Left";
wordWrap = "1";
hideOverflow = "1";
lineHeight = "3";
aspectRatio = "1";
lineSpacing = "0";
characterSpacing = "0";
autoSize = "0";
fontSizes = "80";
textColor = "1 1 1 1";
// textColor = "0 0.0313726 1 1";
hideOverlap = "0";
};
%this.BulletText=%BulletText;
}
function BulletLabel::DisplayLabel(%this,%ShowText,%X,%Y)
{
%this.StartAfterPause(0,%ShowText,%X,%Y);//0 is false
}
function BulletLabel::StartAfterPause(%this,%pause,%ShowText,%X,%Y)
{
if (!IsObject(%this.BulletText)) %this.CreateLabel();
%this.text=%ShowText;//store for use in ArrowGroup::PlayInOrder
%ShowText=%ShowText @ %this.CopyString("*",%this.MaxLength-strLen(%ShowText));
%this.PositionBoxAndText(strlen(%ShowText),%X,%Y);
if (!%pause) %this.BulletLetter(%ShowText);
}
function BulletLabel::CopyString(%this,%xStr,%xCnt)
{
for(%X=0;%X<%xCnt;%X++)
%MakeStr=%MakeStr @ %xStr;
return %MakeStr;
}
function BulletLabel::BulletLetter(%this,%ThisText)
{
if (getSubStr(%ThisText,%this.txtPos-1,1)!$= "*")
{
%this.BulletText.text=getSubStr(%ThisText,0,%this.txtPos)@"|" ;
if (getSubStr(%ThisText,%this.txtPos-1,1) !$= " ") alxPlay(LetterClick);
%this.txtPos++;
if (%this.txtPos<strlen(%ThisText)+1)
%this.LabelEvent=%this.Schedule(%this.delay,"BulletLetter",%ThisText);
else %this.BulletText.text=getSubStr(%ThisText,0,%this.txtPos);//remove cursor line when finished
}
}
function BulletLabel::PositionBoxAndText(%this,%Length,%X,%Y)
{
%this.BulletText.position = %X SPC %Y;
%width=%Length*1.4;
%this.Box.size = %width SPC %this.BulletText.LineHeight+2;
%this.Box.Position = %X SPC %Y-4;
}
function BulletLabel::SafeDelete(%this)
{
%this.BulletText.safeDelete();
%this.Box.safeDelete();
Cancel(%this.LabelEvent);
Cancel(%this.PauseEvent);
%this.Delete();
}
////////////////////////////////////LabelGroup Class: manage all BulletLabel objects/////////////////////////////////////
datablock t2dSceneObjectDatablock(LabelGroupDatablock)
{
class = "LabelGroup"; // associate this datablock with the namespace
LineCnt = 0;
PauseLines = 0;//default is 0 false -no pausing between lines
};
function LabelGroup::NewLine(%this,%ShowText,%X,%Y)
{
%Label = new t2dStaticSprite()
{scenegraph = SceneWindow2D.getSceneGraph();
config = "BulletLabelDatablock";};
%this.Line[%this.LineCnt]=%Label;//store each Line in an array to be used later, such as in SafeDelete()
%this.LineCnt++;
%Label.PauseTime=%Label.delay * strLen(%ShowText);
if (!%this.PauseLines) %Label.DisplayLabel(%ShowText,%X,%Y);
else if (%this.LineCnt < %this.PauseLines) %Label.DisplayLabel(%ShowText,%X,%Y);
else {
%Label.StartAfterPause(1,%ShowText,%X,%Y);//1 is true
for(%X=0;%X<%this.LineCnt-1;%X++)
%totpause += %this.Line[%X].PauseTime;
%Label.PauseEvent[%this.LineCnt-1]=%this.schedule(%totPause,"PlayInOrder",%Label);
}
}
function LabelGroup::PlayInOrder(%this,%Label)
{
%Label.BulletLetter(%Label.text);
}
function LabelGroup::SafeDelete(%this)
{
for(%X=0;%X<%this.LineCnt;%X++)
if (IsObject(%this.Line[%X])) %this.Line[%X].safedelete();
%this.Delete();
}
function typeWriterTextObject::onAdd(%this)
{
%this.CompleteText = "";
%this.TextSpeed = 0.5;
}
function typeWriterTextObject::onTimer(%this)
{
%this.text = %this.text @ getSubStr(%this.CompleteText, strlen(%this.text), 1);
// uncomment below for sound
// playSound(typeWriterAudio);
}
function typeWriterTextObject::WriteText(%this, %string, %time)
{
%this.setTimerOff();
%this.setVisible(false);
%this.CompleteText = "";
%this.text = "";
if(%string !$= "")
{
%this.CompleteText = %string;
}
if(%time !$= "")
{
%this.TextSpeed = %time;
}
%this.setVisible(true);
%this.setTimerOn(%this.TextSpeed * 1000);
}
function TestLabels()
{
// Create a new XML document.
%pXml = new xmlDoc();
echo("Started new Doc");
// Load and parse XML file.
if(!%pXml.loadFile("POSGame/gameScripts/level.xml"))
{
echo("Failed to load level.xml!");
return;
}
// Push the first child element named "invagersgame" onto the XML document stack.
if(!%pXml.pushFirstChildElement("greatdialog"))
{
// The XML file is in the wrong format.
echo("Failed to load invaders game.");
return;
}
/*$BLabel = new t2dTextObject()
{scenegraph = SceneWindow2D.getSceneGraph();
name = "textBox";
class = "typeWriterTextObject";
size = "48.025 31.000";
Position = "10.000 40.000";
font = "Arial Black";
textAlign = "Left";
wordWrap = "1";
hideOverflow = "1";
lineHeight = "3";
aspectRatio = "1";
lineSpacing = "0";
characterSpacing = "0";
autoSize = "0";
fontSizes = "80";
textColor = "1 1 1 1";
// textColor = "0 0.0313726 1 1";
hideOverlap = "0";
};*/
//$Blabel.PauseLines =1;//0=false 1=true
texter.WriteText(%pXml.getText(),0.01);
//$BLabel.NewLine("Second line HA HA",-20, 15);
//$BLabel.NewLine("Third line wow...",-20, 20);
}level.xml
<?xml version="1.0" encoding="utf-8"?> <greatdialog>Presently this resource only implements the bare minimum functions needed to parse XML files in.</greatdialog>
I used level.xml to test the reading and writing of the XML Doc.
Associate Phillip O'Shea
Violent Tulip
It is a pretty basic concept and I don't think it would take a great amount of time to implement nicely, however.