Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   Preview: Text Animations (https://forums.graalonline.com/forums/showthread.php?t=134260297)

adam 08-23-2010 03:19 PM

Preview: Text Animations
 
Some code to animate text on the screen prettily, This is just a prototype version though. It's not fully done yet.



PHP Code:

//NPC Created by Rogue Shadow (TCN)
//AIM: RogueTCN
//FORUM PM: adam
// Special messaging prototype 2

//#CLIENTSIDE

// Actions 
//   { "doFade" , time , value 0-1 }
//   { "doMove" , time , new x , new y }
//   { "doZoom" , time , value } - 0 doesn't seem to be a good value for zoom on the text, didn't test in opengl mode yet.
//   { "doDelay", time , value } delays by the specified amount of time.
//   { "NewText" , time , value } instantly changes text, the border sizes follow
// Planned Actions
//   { "doTextColor" , time , {red, green, blue} } - transition from current color to new one smoothly over time.
//   { "doBgColor" , time , {red, green, blue} } - transition from current color to new one smoothly over time. 
//   { "doOutlineColor" , time , {red, green, blue} } - transition from current color to new one smoothly over time.
//   { "doDestruct" } - yeah... almost forgot this feature. The text will go away soon (but not right away) after you delete it's variable
//                      But this will do it right, when added.

// While I'd love to add rotation, it is beyond difficult o.O and insanely complex, 
// unless the methods i've thought of are wrong.


function onCreated(){
  
this.join("personal_adam_anitext");
  
this.msg2 newText(this300screenwidth/3screenheight+10"This is some great Testing text."1nulltrue);
  
this.msg2.addActions( { {"doMove"2screenwidth/3,screenheight/3},{"doFade",2,1},{"doZoom"2,5}});
  
this.msg2.addActions( { {"doZoom"21} });
  
this.msg2.addActions( { {"doDelay"1}});
  
this.msg2.addActions( { {"NewText""I'm off now, cya."},{"doDelay"2} });
  
this.msg2.addActions( { {"doMove"1screenwidthscreenheight/3},{"doFade",2,0},{"doZoom"2,.1}});
  
this.msg2.addActions( {{ "doFade"11} ,{"doZoom"1.1}} );
  
this.msg2.addActions( {{"doMove"1screenwidth/3,screenheight/3}});
  
this.msg2.addActions( {{"doFade"50} ,  {"doZoom"51.5}, {"doDelay"10}});
  for (
temp.0temp.10temp.++ ){
    
this.msg2.addActions ( { {"doMove"2random(0,screenwidth-10),random(0,screenheight-10) },{"doFade"2random(.2,1)},{"doZoom"2random(.1,4)} } );
    
this.msg2.addActions ( {{"doFade".50}});this.msg2.addActions({{"NewText""Action: " temp.i+@" of 10"},{"doFade",.5,1}});
  }
  
this.msg2.start();


And the class.
PHP Code:

//#CLIENTSIDE

function newText(temp.scopetemp.start_itemp.xtemp.ytemp.texttemp.zoomFactortemp.textColortemp.useBackgroundtemp.bgColortemp.bgPaddingtemp.borderColortemp.borderThickness){
  
// Various Declarations to start with.
  
temp.= new TStaticVar(); // All contained in a single TStaticVar (which is basically a whole script within a script, there are other ways, but this one is fun too.)
  
temp.t.global = temp.scope// Saving the scope seems to make it easier to do things like, draw images, and access other things from within the script here.
  
temp.t.start_i temp.start_i// The index we start drawing from, incrementing until we're done drawing things.
  
temp.t.temp.xtemp.t.temp.y// x,y position of the top-left corner of the text. The actual image drawn will extend beyond this by the amount of temp.bgPadding and the borderThickness
  
temp.t.textColor = (temp.textColor != null) ? temp.textColor:{1,1,1}; temp.t.alpha 0// Default color white, alpha starts at 0 (suggesting Fading in whenever possible)
  
temp.t.layer 10*temp.start_i// layer 10 times the drawing index, to allow overlapping text rather than smooshing together text.
  
temp.t.font "Comic Sans MS"temp.t.style ""// Default font and style here.
  
temp.t.zoom = (temp.zoomFactor != null) ? temp.zoomFactor:1// default zoom of 1, or what you select.
  
temp.t.text temp.text// save that text
  
temp.t.width gettextwidth(temp.t.zoomtemp.t.font""temp.t.text); // initial width/height,   recalculated on zoom always
  
temp.t.height gettextheight(temp.t.zoomtemp.t.font"");
  
temp.t.queue = {};
  if (
temp.useBackground != null){    
    
temp.t.background useBackground;   // if were using the background
    
temp.t.bgPadding = (temp.bgPadding != null) ? temp.bgPadding:2// how far the background extends beyond the text itself
    
temp.t.borderThickness = (temp.borderThickness != null) ? temp.borderThickness:2// the thickness of the backgrounds outline
    
temp.t.bgColor = (temp.bgColor != null) ? temp.bgColor:{0,0,0}; // it's color, default black
    
temp.t.borderColor = (temp.borderColor != null) ? temp.borderColor:{1,1,1};
  }
  
  
temp.t.start = function () {
    
this.started true;
    
this.onUpdate();
  };
  
  
temp.t.stop = function () {
    
this.started false;
  };
  
  
temp.t.addActions = function ( temp.actions ) {
    
this.queue.addtemp.actions );
    
this.count++;
  };

  
temp.t.onUpdate = function () {
    if (!
this.started)return;
      for (
temp.actionthis.queue[0]){
        if (
temp.action[0in {"doZoom""doMove""doFade""doDelay"}){
          if (
this.(@temp.action[0])(temp.action))this.garbage.add(temp.action);
        }elseif(
temp.action[0] == "NewText"){
      
this.NewText(temp.action[1]); this.garbage.add(temp.action);
      }else 
this.garbage.add(temp.action);
    }


    for (
temp.gthis.garbage){
      for (
temp.0temp.this.queue[0].size(); temp.i++){
       if (
temp.g[0] == this.queue[0][temp.i][0]){
          
this.queue[0].delete(temp.i);
          break;
        }
      }
    }
    
this.garbage "";
    if (
this.queue[0].size() == && this.queue.size() > 0){
      
this.queue.delete(0);
      
//echo("Completed actions, moving to next set.");
    
}
    
this.draw();
    
//this.cancelevents("Update");
    
this.scheduleevent(0.05"Update"null);
  };

  
temp.t.doFade = function (action) {
    
temp.time temp.action[1];
    
temp.newAlpha temp.action[2];
    if (
this.fadeDist == null) {
      
this.fadeDist temp.newAlpha this.alpha;
      
this.fadeStep this.fadeDist/(temp.time*20);
    }
    if (
abs(temp.newAlpha this.alpha) <= this.fadeStep){
      
this.alpha temp.newAlpha;
    }else 
this.alpha += this.fadeStep;

    if (
this.alpha == temp.newAlpha){
      
this.fadeDist null;
      
this.fadeStep null;
      return 
true;
    }else return 
false;
  };

  
temp.t.doDelay = function (action) {
    
temp.time int(temp.action[1]*100)/100;
    if (
this.delayTime == null){
      
this.delayTime temp.time;
    }
    
this.delayTime -= .05;
    if (
this.delayTime <= 0){
      
this.delayTime null;
      return 
true;
    }else return 
false;
  };
  
  
temp.t.doZoom = function (action) {
    
temp.time int(temp.action[1]*100)/100;
    
temp.newZoom int(temp.action[2]*100)/100;
    if (
this.zoomDist == null) {
      
this.zoomDist temp.newZoom this.zoom;
      
this.zoomStep = (this.zoomDist*.05)/(temp.time);
    }
    if (
abs(temp.newZoom this.zoom) <= this.zoomStep){
      
this.zoom temp.newZoom;
    }else 
this.zoom += this.zoomStep;
    
    
this.NewText(this.text);
    if (
this.zoom == temp.newZoom){
      
this.zoomDist null;
      
this.zoomStep null;
      return 
true;
    }else return 
false;
  }; 
  
  
temp.t.doMove = function (action) {
    
temp.time int(temp.action[1]*100)/100;
    
temp.newx int(temp.action[2]);
    
temp.newy int(temp.action[3]);
    if (
this.moveStep == null){
      
temp.dx temp.newx this.x;
      
temp.dy temp.newy this.y;
      
temp.dist = (temp.dx^temp.dy ^2)^.5;
      
temp.addx = (temp.dx/temp.dist)*(temp.dist*.05/temp.time);
      
temp.addy = (temp.dy/temp.dist)*(temp.dist*.05/temp.time);
      
this.moveStep = {temp.addxtemp.addy};
    }

    if (
abs(temp.newx this.x) <= this.moveStep[0]){
      
this.temp.newx;
    }else 
this.+= this.moveStep[0];
    
    if (
abs(temp.newy this.y) <= this.moveStep[1]){
      
this.temp.newy;
    }else 
this.+= this.moveStep[1];
    
    if (
this.== temp.newx && this.== temp.newy){
      
this.moveStep null;
      return 
true;
    }else return 
false;
  };

  
temp.t.NewText = function (newText) {
    
this.text temp.newText;
    
this.width gettextwidth(this.zoomthis.font""this.text); 
    
this.height gettextheight(this.zoomthis.font"");
  };

  
temp.t.draw = function (){
    
temp.this.start_i;
    
with (this.global.findimg(temp.i)){
      
thiso.x;  thiso.y;
      
text thiso.text;
      
red thiso.textColor[0];  green thiso.textColor[1];  blue thiso.textColor[2];
      
zoom thiso.zoom;
      
font thiso.fontstyle thiso.style;
      
layer thiso.layer;
      
alpha thiso.alpha;
      
mode 1;
    }
    
temp.i++;
    if (!
this.background) return temp.i;
    
with (this.global.findimg(temp.i)){
      
temp.xx=thiso.x;temp.yy=thiso.y;temp.w=thiso.width;temp.h=thiso.height;temp.p=thiso.bgPadding;
      
polygon = {xx-p,yy-p,
                 
xx+w+p,yy-p,
                 
xx+w+p,yy+h+p,
                 
xx-p,yy+h+p};
      
temp.p2 temp.p+thiso.borderThickness;
      
temp.poly2 = {xx-p2,yy-p2,
                 
xx+w+p2,yy-p2,
                 
xx+w+p2,yy+h+p2,
                 
xx-p2,yy+h+p2};

                 
      
layer thiso.layer 1;
      
red thiso.bgColor[0]; green thiso.bgColor[1]; blue thiso.bgColor[2];
      
alpha thiso.alphamode 1;
    }
    
temp.i++;
    
with (this.global.findimg(temp.i)){
      
polygon temp.poly2;
      
layer thiso.layer -2;
      
red thiso.borderColor[0]; green thiso.borderColor[1]; blue thiso.borderColor[2];
      
alpha thiso.alphamode 1;
    }
    
temp.i++;
    
this.lasti temp.i;
    return 
temp.i;
  };
 
  return 
temp.t;



Soala 08-23-2010 03:24 PM

fun :D

adam 08-23-2010 03:25 PM

Hehe, reached the max text allowed in a post.

If you try it out, if you can, use opengl mode. It'll let the alpha work properly on the text at all zoom levels, and zooming will be much smoother.

Dnegel 08-23-2010 04:33 PM

Wow, it looks pretty nice. :D

adam 08-23-2010 07:00 PM

Large improvements already. :)

Fulg0reSama 08-23-2010 07:40 PM

this would work very nicely for some advanced NPC dialogue system.

adam 08-23-2010 07:54 PM

Live Demo: Testbed Server Weapon: Shared/AniTextDemo
Alternate Demo: Repeats player's chat, showing it on the bottom of the screen. Weapon: Public/adam/AniText
If somebody could try it in opengl mode, and with v6 and tell me how it performs that'd be great. Remember it's my birthday, do it.

Sorry no video this time, wasn't ready to do another one of those o.O
Still a few things to add, but just about every animation possible is added now.
The demo script wasn't meant to be pretty, just randomly animates everything possible. Although it is fun to watch. I suggest trying it out in opengl mode if you can, if you run V6 please let me know how it works too.

PHP Code:

//NPC Created by Rogue Shadow (TCN)
//AIM: RogueTCN
//FORUM PM: adam
// Special messaging prototype 4

//#CLIENTSIDE

// Actions format {"var", time, newvalue}
// string these blocks together for simultanous actions
// add them in succession for sequences.
// or any combination thereof
function onCreated(){
  
this.join("personal_adam_anitext");
  
sleep(.01);// class seems to need just a moment.
  
this.newText(this200screenwidth/3screenheight/3"Testing Text"true);
  
this.m.A( {{"alpha"11}} );
  
this.m.A( {{"delay"1}});
  for (
temp.i=0;temp.i<20;temp.i++){
    
this.m.A( {{"alpha",1,random(0,1)},{"x",1,random(0,screenwidth)},{"y",1,random(0,screenheight)},{"zoom",1,random(.1,5)},{"bgPadding",1,random(2,50)},{"outline",.5,random(1,50)},{"oBlue"1random(0,1)},{"oRed"1random(0,1)},{"oGreen",1,random(0,1)},{"tBlue"1random(0,1)},{"tRed"1random(0,1)},{"tGreen",1,random(0,1)},{"bBlue"1random(0,1)},{"bRed"1random(0,1)},{"bGreen",1,random(0,1)}});
  }
  
this.m.A( {{"alpha",1,1},{"x",1,screenwidth/2},{"y",1,screenheight/2},{"zoom",1,1},{"bgPadding",1,2},{"outline"11},{"tRed"11},{"tGreen",1,1},{"tBlue",1,1},{"bRed",1,0},{"bGreen",1,0},{"bBlue",1,0},{"oRed",1,1},{"oBlue",1,1},{"oGreen",1,1}});
  
this.m.start();


PHP Code:

//#CLIENTSIDE

function newText(temp.scopetemp.start_itemp.xtemp.ytemp.texttemp.useBackground){
  
// Various Declarations to start with.
  
temp.= new TStaticVar();
  
temp.t.global = temp.scope
  
temp.t.start_i temp.start_i;
  
temp.t.temp.xtemp.t.temp.y
  
temp.t.tRed 1temp.t.tGreen 1temp.t.tBlue 1;
  
temp.t.alpha 0;
  
temp.t.layer 10*temp.start_i
  
temp.t.font "Comic Sans MS"temp.t.style ""
  
temp.t.zoom 1
  
temp.t.text temp.text;
  
temp.t.width gettextwidth(temp.t.zoomtemp.t.font""temp.t.text); 
  
temp.t.height gettextheight(temp.t.zoomtemp.t.font"");
  
temp.t.delay true;
  
temp.t.animatable = {"delay","x","y","zoom","alpha","bgPadding","outline","tRed","tBlue","tGreen","bRed","bBlue","bGreen","oRed","oGreen","oBlue"};
  
temp.t.queue = {};
  if (
temp.useBackground != null){    
    
temp.t.background useBackground;  
    
temp.t.bgPadding 2
    
temp.t.outline 2
    
temp.t.bRed 0temp.t.bGreen 0temp.t.bBlue 0;
    
temp.t.oRed 1temp.t.oGreen 1temp.t.oBlue 1;
  }
  
  
temp.t.start = function () {
    
this.started true;
    
this.onUpdate();
  };
  
  
temp.t.stop = function () {
    
this.started false;
  };
  
  
temp.t.= function ( temp.actions ) {
    
this.queue.addtemp.actions );
    
this.count++;
  };

  
temp.t.onUpdate = function () {
    if (!
this.started)return;
    
    for (
temp.actionthis.queue[0]){
      if (
temp.action[0in {"NewText"}){
        if (
this.(@temp.action[0])(temp.action)){
          
this.queue[0].remove(temp.action);
        }
      }elseif(
temp.action[0in this.animatable){
        if (
this.doValue(temp.action)){
          
this.queue[0].remove(temp.action);
        }
      }else 
this.queue[0].remove(temp.action);
    }
    
    if (
this.queue[0].size() == && this.queue.size() > 0this.queue.delete(0);
    
this.draw();
    
this.scheduleevent(0.05"Update"null);
  };

  
temp.t.doValue = function (action) {
    
temp.value temp.action[0];
    
temp.time temp.action[1];
    
temp.newvalue temp.action[2];
    if (
temp.time == 0){
      
this.(@value) = temp.newvalue;
      return 
true;
    }
    if (
this.(@value).dist == null){
      
this.(@value).dist temp.newvalue this.(@value);
      
this.(@value).step this.(@value).dist / (temp.time*20);
    }
    if (
abs temp.newvalue this.(@value)) <= this.(@value).step){
      
this.(@value) = temp.newvalue;
    }else 
this.(@value) += this.(@value).step;
    
    if (
temp.value == "zoom")this.NewText({"NewText",this.text});
    
    if (
this.(@value) == temp.newvalue){
      
this.(@value).dist null;
      
this.(@value).step null;
      
this.delay true;
      return 
true;
    }else return 
false;
  };

  
temp.t.NewText = function (action) {
    
this.text temp.action[1];
    
this.width gettextwidth(this.zoomthis.font""this.text); 
    
this.height gettextheight(this.zoomthis.font"");
    return 
true;
  };

  
temp.t.draw = function (){
    
temp.this.start_i;
    
with (this.global.findimg(temp.i)){
      
thiso.x;  thiso.y;
      
text thiso.text;
      
red thiso.tRed;  green thiso.tGreen;  blue thiso.tBlue;
      
zoom thiso.zoom;
      
font thiso.fontstyle thiso.style;
      
layer thiso.layer;
      
alpha thiso.alpha;
      
mode 1;
    }
    
temp.i++;
    if (!
this.background) return temp.i;
    
with (this.global.findimg(temp.i)){
      
temp.xx=thiso.x;temp.yy=thiso.y;temp.w=thiso.width;temp.h=thiso.height;temp.p=thiso.bgPadding;
      
polygon = {xx-p,yy-p,
                 
xx+w+p,yy-p,
                 
xx+w+p,yy+h+p,
                 
xx-p,yy+h+p};
      
temp.p2 temp.p+thiso.outline;
      
temp.poly2 = {xx-p2,yy-p2,
                 
xx+w+p2,yy-p2,
                 
xx+w+p2,yy+h+p2,
                 
xx-p2,yy+h+p2};

                 
      
layer thiso.layer 1;
      
red thiso.bRed;  green thiso.bGreen;  blue thiso.bBlue;
      
alpha thiso.alphamode 1;
    }
    
temp.i++;
    
with (this.global.findimg(temp.i)){
      
polygon temp.poly2;
      
layer thiso.layer -2;
      
red thiso.oRed;  green thiso.oGreen;  blue thiso.oBlue;
      
alpha thiso.alphamode 1;
    }
    
temp.i++;
    
this.lasti temp.i;
    return 
temp.i;
  };
  
  return 
temp.t;



adam 08-24-2010 02:36 AM

Added the ability to use a fixed size background, and anchor the text anywhere within it, Top Middle Bottom, Left Middle Right. Although if you zoom the text and it goes bigger ... your fault.

Adding/polishing the ability to send an event trigger to the main script, since you don't really know exactly when things get done. You can queue a trigger to be sent, returning the object that sent it, and go from there.

adam 08-25-2010 03:08 AM

Anybody remember this? http://forums.graalonline.com/forums...54&postcount=1

I just added support for the tweening functions Robin used, made by some guy. Much improved. I'll work on another demo/video. Then I think I'll be done.

adam 08-25-2010 11:27 PM

I really need to make a new video :( Compared to the current version the video looks very bad.

You can now use the messages to get input from the player. An event is triggered when you click on a message, if you told the message to watch for clicks.

function onAnimationTrigger(trigger, object, param1) // so far param1 is only for the button the player clicked with. trigger is "Clicked" for being clicked. or whatever you told it to send with {"Trigger", <name>};

DrakilorP2P 08-26-2010 12:33 AM

Quote:

Originally Posted by adam (Post 1596671)
I really need to make a new video :( Compared to the current version the video looks very bad.

I'm looking forward to a new video if you decide to make one.

adam 08-26-2010 04:49 AM

Quote:

Originally Posted by DrakilorP2P (Post 1596677)
I'm looking forward to a new video if you decide to make one.

Dude... your on testbed RC constantly. Can't you come check it out when you see 40 updates of a script of mine?

lol

Either way, thanks, that helps motivate me.

DrakilorP2P 08-26-2010 08:12 PM

Quote:

Originally Posted by adam (Post 1596699)
Dude... your on testbed RC constantly. Can't you come check it out when you see 40 updates of a script of mine?

I'm a little lazy. ;)

Crow 08-26-2010 08:19 PM

Quote:

Originally Posted by DrakilorP2P (Post 1596821)
I'm a little lazy. ;)

Shh! Nobody would have noticed :redface:


All times are GMT +2. The time now is 11:34 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.