Jump to content

Previous LSL Scripter would love some help!


teuclase
 Share

You are about to reply to a thread that has been inactive for 4563 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hello, world! *snickers*

I have recently rejoined SL after a bit of a hiatus; I unfortunately had to transfer to a new account as I've lost access to my previous one, and even if I got it restored my inventory would be missing due to it being a TSL account.

Anyways, I haven't LSL Scripted- or done any programming/coding/scripting, for that matter- in roughl 3-4 years. I'm trying to get back into it, and I figured LSL would be a great way to as I can immediately compile my codes into a visual result.

I've been working on a script, and have reached a bit of difficulty within it. What I'm trying to create is a script where an object is black; upon clicking, it's starts cycling through a rainbow; upon clicking again, it returns to black; and on another click, it resumes its rainbow cycling.

My issue is that, within the following code, the color changing can start just fine; however, due to the script being stuck in multiple while loops, it never allows me to touch it again to revert to black.

Here's the code:

//TRISTAN MAKE PRETTY COLOR CHANGING SCRIPT! YAYYY
//HI PERSON READING MY SCRIPT!

float red = 0.0;
float green = 1.0;
float blue = 0.0;
integer touched = FALSE;

default
{
    state_entry()
    {
        llSetColor(<0, 0, 0>, ALL_SIDES);
        llSetText("Touch to Start Color Cycle!", <1,1,1>, 1);
    }
    touch_start(integer detectednum)
    {
        if(touched == FALSE)
        {
           touched = TRUE;
           llSetText(" ", <1,1,1>, 0);
           llSetColor(<red, green, blue>, ALL_SIDES);
        }
        else
        {
            touched = FALSE;
            llSetColor(<0, 0, 0>, ALL_SIDES);
            llSetText("Touch to Start Color Cycle!", <1,1,1>, 1);
        }
        while(touched == TRUE)
        {
            //Becomes Red
            while(red < 1)
            {
                    red = (red + .01);
                    llSetColor(<red, green, blue>, ALL_SIDES);
                    llSleep(0.005);
            }
            while(green > 0)
            {
                green = (green - .01);
                llSetColor(<red, green, blue>, ALL_SIDES);
                llSleep(0.005);
            }
            //Becomes Pink
            while(blue < 1)
            {
                    blue = (blue + .01);
                    llSetColor(<red, green, blue>, ALL_SIDES);
                    llSleep(0.005);
            }
            //Becomes Blue
            while(red > 0)
            {
                red = (red - .01);
                llSetColor(<red, green, blue>, ALL_SIDES);
                llSleep(0.005);
            }
            //Becomes Teal
            while(green < 1)
            {
                    green = (green + .01);
                    llSetColor(<red, green, blue>, ALL_SIDES);
                    llSleep(0.005);
            }
            //becomes Green
            while(blue > 0)
            {
                blue = (blue - .01);
                llSetColor(<red, green, blue>, ALL_SIDES);
                llSleep(0.005);
            }
            //Cycles
        }
    } 
     
}

 Now, I know I could use timers and a function to make this script work, but that would require calculation of color changing times; and I'm not doing this for the sake of making a color changing object, but rather for the sake of refreshing my mind on LSL and programming logic in general.

What I'm looking for is a way that I could run what's in the while(touched == TRUE) loop, but still be able to use a touch_start to stop the loop at any time, not within a specific window of time.

Would you mind sharing any ideas on how I could go about this?

Thanks!

~Tristan Euclase

Link to comment
Share on other sites

 

touch_start() will be triggered when you click the object, but there's no way inside the event to see if the agent is still touching (holding the mouse button down), as all the llDetected* refer to the event when the touch started.

You might see touch event (http://wiki.secondlife.com/wiki/Touch), it is triggered as long as the mouse button is held down (meaning as soon as your script event handler returns, there's new touch() event in the queue), so you can use touch() event instead of of the while loop.

 

Link to comment
Share on other sites


LindaB Helendale wrote:

 

touch_start() will be triggered when you click the object, but there's no way inside the event to see if the agent is still touching (holding the mouse button down), as all the llDetected* refer to the event when the touch started.

You might see touch event (
), it is triggered as long as the mouse button is held down (meaning as soon as your script event handler returns, there's new touch() event in the queue), so you can use touch() event instead of of the while loop.

 

Hmm... wouldn't that make the color change only happen while you're holding down a click on the object? I'm looking moreso to have the color change triggered or stopped by clicking the object once.

Link to comment
Share on other sites


teuclase wrote:

Hmm... wouldn't that make the color change only happen while you're holding down a click on the object? I'm looking moreso to have the color change triggered or stopped by clicking the object once.

 

oh , I guess I didnt  read  well enough what you want *blushes* 

To interact with the script you need event loop (as new events wont interrupt the running event handler).  I can think of two ways, timer is one, as you said, other option is to have event handler for changed color ( see changed() event), each color change would trigger  new changed() event, so your while loop would be changed() event loop. When you click it, touch_start would go through and you could change the loop.

 EDIT: you could set the interval when  it can be interrupted by adjusting how many steps in your current sweep over rainbow is done in one changed() event.

 

Link to comment
Share on other sites

The most important thing in your code is that llSleep(0.005) is totally meaningless. You are asking the server to do something for 5 msec.That would require at least a 1msec system timer. It is very uncommon for a soft real-time system such as a SL server to implement a 1msec timer. Usually they have 100 msec timers. In which case the smallest timing window you can get is 200 msec. So the server simply substitutes 0.2 for your 0.005 anyways.

The least important thing is that your code is not going to work whatever the timing window is because llSleep() tells it to ignore all events including the touch event. To keep your program design you might want to do something like below. Your design however is a very mediocre to begin with. I'm sure you can come up with a better one.

//TRISTAN MADE A BAD SCRIPT! YAYYY
//HI PERSON READING MY SCRIPT!

float red = 0.0;
float green = 1.0;
float blue = 0.0;
integer touched = FALSE;

default
{
state_entry()
{
llSetColor(<0, 0, 0>, ALL_SIDES);
llSetText("Touch to Start Color Cycle!", <1,1,1>, 1);
}
touch_start(integer detectednum)
{
if(llGetObjectDesc() == "0")
{
llSetObjectDesc("1");
llSetText(" ", <1,1,1>, 0);
llSetColor(<red, green, blue>, ALL_SIDES);
}
else
{
llSetObjectDesc("0");
llSetColor(<0, 0, 0>, ALL_SIDES);
llSetText("Touch to Start Color Cycle!", <1,1,1>, 1);
}
while(touched == TRUE)
{
//Becomes Red
while(red < 1 && llGetObjectDesc() == "1")
{
red = (red + .01);
llSetColor(<red, green, blue>, ALL_SIDES);
llSleep(0.2);
}
while(green > 0 && llGetObjectDesc == "1")
{
green = (green - .01);
llSetColor(<red, green, blue>, ALL_SIDES);
llSleep(0.2);
}
//Becomes Pink
while(blue < 1 && llGetObjectDesc() == "1")
{
blue = (blue + .01);
llSetColor(<red, green, blue>, ALL_SIDES);
llSleep(0.2);
}
//Becomes Blue
while(red > 0 && llGetObjectDesc() == "1")
{
red = (red - .01);
llSetColor(<red, green, blue>, ALL_SIDES);
llSleep(0.2);
}
//Becomes Teal
while(green < 1 && llGetObjectDesc() == "1")
{
green = (green + .01);
llSetColor(<red, green, blue>, ALL_SIDES);
llSleep(0.2);
}
//becomes Green
while(blue > 0 && llGetObjectDesc() == "1")
{
blue = (blue - .01);
llSetColor(<red, green, blue>, ALL_SIDES);
llSleep(0.2);
}
//Cycles
}
}

}
Link to comment
Share on other sites

Huzzah! It has been done.

I do realize that some of my if arguments contain colors that are irrelevant for the transition, but I put them in there for the sake of clarity.

Any ideas for optimization besides removing said if arguments?

/*TRISTAN MAKES ABSOLUTELY HORRID SCRIPT AND PEOPLE MAKE FUN OF HIM FOR IT BY CHANGING THIS NOTE BECAUSE THEY MEANS! */float red = 1.0;float green = 0.0;float blue = 0.0;integer touched = FALSE;float color_increase(float increase){    increase = increase + .01;    return increase;}float color_decrease(float decrease){    decrease = decrease - .01;    return decrease;}default{    state_entry()    {        llSetColor(<0, 0, 0>, ALL_SIDES);        llSetText("Touch to Start Color Cycle!", <1,1,1>, 1);    }    touch_start(integer detectednum)    {        if(touched == FALSE)        {           touched = TRUE;           llSetText(" ", <1,1,1>, 0);           llSetColor(<red, green, blue>, ALL_SIDES);        }        else        {            touched = FALSE;            llSetColor(<0, 0, 0>, ALL_SIDES);            llSetText("Touch Again to Restart Color Cycle!", <1,1,1>, 1);        }    }    changed(integer changedint)    {        if(changedint == CHANGED_COLOR && touched == TRUE)        {            //Transition RED to RED-BLUE            if(red >= 1 && blue <= 1 && green <= 0)            {                blue = color_increase(blue);            }            //Transition RED-BLUE to BLUE            else if(red >= 0 && blue >= 1 && green <= 0)            {                red = color_decrease(red);            }            //Transition BLUE to BLUE-GREEN            else if (red <= 0 && blue >= 1 && green <= 1)            {                green = color_increase(green);            }            //Transition BLUE-GREEN to GREEN            else if (red <= 0 && blue >= 0 && green >= 1)            {                blue = color_decrease(blue);            }            //Transition GREEN to GREEN-RED            else if (red <= 1 && blue <= 0 && green >= 1)            {                red = color_increase(red);            }            //Transition GREEN-RED to RED            else if (red >= 1 && blue <= 0 && green >= 0)            {                green = color_decrease(green);            }            llSetColor(<red, green, blue>, ALL_SIDES);                 }    }}

 

Link to comment
Share on other sites

Why not try another approach to make it simple.
Put a rainbow texture on the prim and run this script:

// rolling texture when clicked, texture black out when not clicked, by Dora gustafson 2011

integer mode;
integer side = ALL_SIDES; // Prim face number
integer x_frames = 1;
integer y_frames = 1;
float start = 0.0;
float length = 0.0;
float rate = 0.05;  // frames/S

default
{
    state_entry()
    {
        mode = ANIM_ON | SMOOTH | LOOP;
        llSetTextureAnim( mode, side, x_frames, y_frames, start, length, rate );
    }
    touch_start(integer n)
    {
        llSetColor(< 1.0, 1.0, 1.0>, side);
        llSetText(" ", <1,1,1>, 0);
    }
    touch_end(integer n)
    {
        llSetColor(< 0.0, 0.0, 0.0>, side);
        llSetText("Touch to Start Color Cycle!", <1,1,1>, 1);
    }
}

 

Link to comment
Share on other sites

I could do that, yes, but that'd be a different visual effect, I'd have to account for the different faces needing different texture rotations to make it seamless, and I'd need a texture.

Furthermore, I made this script for mood lighting; in addition to llSetColor a script I just refined also sets the light color to floats <red, green, blue>.

Link to comment
Share on other sites

I got an idea when I read your post. I was about to use a timer but Linda's idea to use the changed() event is much better.

Here it comes:

vector Color = <0.0, 1.0, 0.0>;list Changes = [    <0.01, 0.0, 0.0>, <0.0, -0.01, 0.0>, <0.0, 0.0, 0.01>, <-0.01, 0.0, 0.0>,     <0.0, 0.01, 0.0>, <0.0, 0.0, -0.01>];integer Step = 0;integer MaxStep;integer isCYCLING = FALSE;default{    state_entry()    {        MaxStep = (Changes != []); // Faster llGetListLength()        llSetColor(ZERO_VECTOR, ALL_SIDES);    }    touch_start(integer total_number)    {        if (!isCYCLING)        {            isCYCLING = TRUE;            llSetColor(Color, ALL_SIDES);        }        else        {            isCYCLING = FALSE;            llSetColor(ZERO_VECTOR, ALL_SIDES);            llSetLinkPrimitiveParamsFast(LINK_THIS,                                         [PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 1.0, 10.0, 0.25]);        }    }        changed(integer change)    {        if ((change & CHANGED_COLOR) && (isCYCLING))        {            Color += llList2Vector(Changes, Step);            integer next_step = FALSE;            if (Color.x < 0.0) { Color.x = 0.0; next_step = TRUE; } // Red            else if (Color.x > 1.0) { Color.x = 1.0; next_step = TRUE; }            if (Color.y < 0.0) { Color.y = 0.0; next_step = TRUE; } // Green            else if (Color.y > 1.0) { Color.y = 1.0; next_step = TRUE; }            if (Color.z < 0.0) { Color.z = 0.0; next_step = TRUE; } // Blue            else if (Color.z > 1.0) { Color.z = 1.0; next_step = TRUE; }            llSetColor(Color, ALL_SIDES);            llSetLinkPrimitiveParamsFast(LINK_THIS,                                         [PRIM_POINT_LIGHT, TRUE, Color, 1.0, 10.0, 0.25]);            if (next_step)            {                Step = (Step + 1) % MaxStep;            }        }    }}

Compiled and tested in-world.

You talked about light so I added it already. Enjoy! ;)

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4563 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...