Using SayAt function after walking [SOLVED]

Started by Revae, Sat 05/01/2013 09:12:32

Previous topic - Next topic

Revae

Weird thing I can't seem to get to work.  I have a character with a very tall hat, and due to this I'd like his text to appear lower than normal (so it's over his head, not his hat).  So I've been using SayAt for this, and it generally works fine... until now (dun dun dun).

The camera pans up to him in a window.  I have him say something from the window.  Camera pans down.  He moves Then walks left and speaks again.  Like this: 

Code: AGS

function room_FirstLoad(){

player.Walk(205, 1772, eBlock, eWalkableAreas);
player.Say("Feynman!  Come down!  It's important!");

int xpos7 = 0;
int ypos7 = 1035;
while (ypos7 > 125) {
  SetViewport(xpos7, ypos7);
  Wait(1);
  xpos7 = xpos7+5;
  ypos7 = ypos7-5;
}

cFeynman.Walk(1840, 688, eBlock, eWalkableAreas);
cFeynman.FaceCharacter(cPlayer, eBlock);
cFeynman.SayAt(cFeynman.x, cFeynman.y -350, 400,"I have a doorbell ya know!");
cFeynman.SayAt(cFeynman.x, cFeynman.y -350, 400,"I'll be right down...");
cFeynman.Walk(2044, 688, eBlock, eWalkableAreas);

while (ypos7 <= 1035){
  SetViewport(xpos7, ypos7);
  Wait(1);
  xpos7 = xpos7-5;
  ypos7 = ypos7+5;
}

cFeynman.x=1174;
cFeynman.y=1790;

cFeynman.Walk(550, 1780, eBlock, eWalkableAreas);

cFeynman.SayAt(cFeynman.x, cFeynman.y -350, 400,"Okay...");
cFeynman.SayAt(cFeynman.x, cFeynman.y -350, 400,"What did you want now?");
}


But when he says "Okay..." it's off screen somewhere instead of over his head.  I can't see where it's ending up so I can't really tell what's going on exactly.

Would changing his position with "cFeynman.x=1174;" and "cFeynman.y=1790;" affect this or maybe the camera pan?  I'm kinda at a loss.

Also:  Is there any way that I can have the position of his text permanently set instead of using SayAt every time?  It's not a big deal, but it'd be nice to know.  :P

Armageddon

Say at is a pretty bad way to do this, I'd suggest cutting his hat from all his sprites and making the hat it's own character that follows the player exactly. If it's a cutscene you could just make a new character that says it in the one scene?

Revae

It is a cutscene, but I'd rather not have to make a new character every time my camera moves on this guy.  But if there is no other way then I'm going to have to...  Just want to explore my options first.

Making the hat a separate character sounds crazy hard since my walk cycles and every other animation are relatively high frame-rate (by AGS standards).  I can easily see this causing problems.  I'd like to figure out a better system anyway because I may have to use it on other characters down the line, and having their speaking animations synced up to their hats/wings/whateveriuse doesn't sound too practical.

I'm trying to keep my frame count down as well (as much as possible) since hitting 30,000 is actually a concern, and rendering out 2 images for every frame of animation on certain characters could impact that.

I may still go with making it a new character if need be...  I've actually used objects for certain character animations too when it seems like the best way.  Thanks.

geork

Despite having been here for a while, I've never, ever used viewports before, so unfortunately I can't be much specific use. However, I'm guessing shifting it from the camera's original position has something to do with it...in the manual, under SayAt, it states:
QuoteNOTE: This function does not support Whole-Screen speech.
I'm guessing what you'd have to do is to add a Viewport factor when calling SayAt, something like:
Code: AGS
cFeynman.SayAt(cFeynman.x + GetVieportX(), cFeynman.y -350 + GetViewportY(), 400,"Okay..."); //Could be this...
cFeynman.SayAt(cFeynman.x - GetVieportX(), cFeynman.y -350 - GetViewportY(), 400,"What did you want now?");//Or this...

Again, take all this with a pinch of salt, it's perfectly possible that you have to take away the Viewport, not add it.
Unfortunately I'm in a bit of a rush, but I hope one of those solutions does it (again, apologies if it's a waste of time, I've never used Viewports before)

Khris

#4
Since character coordinates are room coordinates and SayAt seems to require screen coordinates, the viewport coords have to be subtracted.

I'd use an extender function:
Code: ags
void SayY(this Character*, String text) {
  int x = this.x - GetViewportX();
  int y = this.y - GetViewportY();
  if (this == cFeynman) y -= 350;
  this.SayAt(x, y, 400, text);
}


Now you can call: cFeynman.SayY("Okay...");

edit: corrected typo

Revae

@Khris

Using that I get a "SayY is not a public member of "Character"" error.

Khris

You have to import the function in the header of the script where you put it.
Specifically, add the function to the top of GlobalScript.asc, then add this line to GlobalScript.ash:
Code: ags
import void SayY(this Character*, String text);


If you've done it correctly and type "cFeynman." into a script, the auto-complete window should list SayY, along with the icon having a yellow arrow.

Revae

I thought I'd done that.  Maybe I just typo'd it or something.  I'll test it out again...

Revae

#8
Alright.  I think I've got exactly what I'm looking for now.  Here's what I did:

Code: AGS

void SayY(this Character*, int textHeight, String text){ //Text height declared for use on other characters
  int x = this.x - 200-GetViewportX(); //subtracting 200 as well because "SayAt" width messes with the
                                       //coordinates
  int y = this.y - GetViewportY();
  textHeight = y - textHeight;
  this.SayAt(x, textHeight, 400, text);
}

calling:
cFeynman.SayY(220,"Okay...");

Works pretty perfectly.  Didn't change it drastically from Khris' recommendation, but I should be able to use it whenever my characters heads don't match up with their sprite heights.

Thanks!  I appreciate it.

Edit: And I did typo the header file.  It says "import void SayY(this Character*, int textHeight, String text);" now...  In case anyone needs to know in the future.

SMF spam blocked by CleanTalk