I'm an LSL begginer, help me for my first step
|
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
|
03-17-2005 07:37
Hello there,
Though I'd not experienced any program languages, I made up my mind to try LSL. I've ever customized some scripts a bit, but this is my first step as entirely making up.
First, I'd have liked to do the following.
Rezzing an object, I touching it once, it moving above 1m. And I touching it again, it moving down 1m, that is, it returnning.
I put down the following script.
////////////////////////////////////////////// vector base_pos; vector up_pos = <0,0,1>; vector down_pos = <0,0,-1>;
default { state_entry() { base_pos = llGetPos(); } touch_start(integer total_number) { llSetPos(base_pos + up_pos); state down; } } state down { state_entry() { base_pos = llGetPos(); } touch_start(integer total_number) { llSetPos(base_pos + down_pos); state default; } } //////////////////////////////////////////////
This worked, but I have a problem. I copying this object to another position and touching the copy one ,it moving to where the original one was supposed to move to. Though I guess it should be initialized the position whenever I touch it, I have no clue. Anyone, plz help me.
And for the next step, I'd like to move it by the local z axis. I'll appreciate your any suggestion.
Thanks.
|
Jillian Callahan
Rotary-winged Neko Girl
Join date: 24 Jun 2004
Posts: 3,766
|
03-17-2005 08:25
The easiest way to get predictable results is to have the script reset istelf when the object rezzes. In both states, put the following: on_rez(integer n) { llResetScript(); }
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
03-17-2005 12:08
Welcome to Second Life! This is the easiest way to do what you want: integer on = FALSE;
touch_start(integer total_number) { if(on) { llSetPos(llGetPos() + (<0,0,1> * llGetRot())); on = FALSE; } else { llSetPos(llGetPos() - (<0,0,1> * llGetRot())); on = TRUE; } } Now, let me try to break down how that works: - First we declare integer "on" to define whether we want to move up or down. - When we touch, we just use that to see which way to go. - Then we move to llGetPos() (where we are now) plus or minus this: (<0,0,1> * llGetRot())We're multiplying a vector times a rotation. Rotations are in quaternions, but it's easy to remember for now that when you multiply a vector times llGetRot(), it puts the vector in the local frame of the object. In future, I would suggest you try the Wiki as well: http://secondlife.com/badgeo/wakka.php?wakka=HomePage
_____________________
---
|
Racer Plisskin
Rezerator
Join date: 2 Jan 2005
Posts: 147
|
03-17-2005 16:48
Hi Seagel,
The reason your object jumps back to it's starting position is that you are setting that particular position in 'state_entry'. As long as the script is not reset, that value is acting like a constant so you kept 'snapping back' to it in all future 'event' cycles.
The example code Jeffrey posted resolves that issue by requesting a fresh location vector from the game engin before calculating each move. His version of the code also removes the need for a second state to be created as you had written it. The llGetRot() function call he added in isn't really needed for a simple application to move a prim up and down when touched. When you start working on moving and rotating objects at the same time is when this becomes necessary.
Racer P.
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
03-17-2005 17:28
Thanks for the added clarification, Racer. This is why I added the llGetRot segment: From: Seagel Neville And for the next step, I'd like to move it by the local z axis. I'll appreciate your any suggestion.
_____________________
---
|
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
|
Thank you!
03-18-2005 06:51
Hi, all, thanks a lot.
Jillian, It worked well when I rezzed the object from inventory. Though it didn't work when I copied it on the ground, I got "on_rez" event. I should like to thank you for your useful advice.
p.s. Sorry for telling late, but thank you for your updating Mielikki MK4. It's awesome!
Jeffrey, I always see your name and articles on several forums. You must be an expert. Thanks for your suggestion. Now I'm learning "llGetRot" at the Wiki. It is still too hard for me to udnerstand what you described, but let me ask you farther if I would take it clearly. Thanks.
Racer, I got what you said in the first paragraph and I knew it even if obscurely. And I had Jillian solve it. Jeffrey's example code is still too hard for me, but I will take it also through your informative guide. Thanks.
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
03-18-2005 07:18
Jeffrey, no offense, but wouldn't it be better to use states rather than a global flag like that? I'm not sure what impact it has on the server, but using global flags instead of states is one of my pet peeves  Something like: default { state_entry() { //If you want to start in the up state, uncomment the following line //state going_up; //If you want to start in the down state, uncomment the following line //state going_down; } } state going_up { touch_start(integer total_number) { llSetPos(llGetPos() + (<0,0,1> * llGetRot())); state going_down; } } state going_down { touch_start(integer total_number) { llSetPos(llGetPos() - (<0,0,1> * llGetRot())); state going_up; } }
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
03-18-2005 07:27
I've seen the discussion about states and globals before, but I have to say I don't fully understand it. Why are global variables bad? Why are states better? That seems to be Eggy's assertion, and it is entirely possible he's 100% correct. Is there a counter argument? I must admit I use a mixture of such things,  is that the worst of all worlds?
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
03-18-2005 09:12
I'm not a fundamentalist. Global variables aren't inherently bad. Sometimes they are the only way to go - for instance, sharing information between event handlers. The thing about this is that Jeffrey is using a global boolean, which is perfectly fine in such a simple example but can lead to spaghetti code if you make extensive use of it in a larger project. If that boolean is program state that more than one event handler needs to be aware of, well, you're going to have to use an IF-ELSE in each and every event handler. If you have more than one such boolean, it gets even messier. Now you have a whole truth table of possibilities to consider 1 - Both are true 2 - First is true, second is false 3 - Second is true, first is false 4 - Both are false Of course, you may not be aware that all these cases exist, and forget to check all of them, or maybe it won't even seem to make sense to check for them since they are never supposed to happen. This leaves your code's behavior undefined in the face of those things you didn't check. That's the source of bugs. For instance, you may want those two variables to be mutually exclusive. With states, you can be sure that they are mutually exclusive, since a program cannot be in two different states at once. With global variables, you leave your code wide open to buggery: anything, anywhere in the code, can manipulate those variables and put your program in an inconsistent state. Do you trust yourself not to make such mistakes? Wouldn't it be better to always keep things separate? The defense rests 
|
Lance LeFay
is a Thug
Join date: 1 May 2003
Posts: 1,488
|
03-18-2005 09:26
In my experience, states are unreliable.
Plus they add lines to your code >_>
_____________________
"Hoochie Hair is high on my list" - Andrew Linden "Adorable is 'they pay me to say you are cute'" -Barnesworth Anubis
|
Malachi Petunia
Gentle Miscreant
Join date: 21 Sep 2003
Posts: 3,414
|
03-18-2005 09:51
I tend to read "state" as "named collection of event handlers" which I think is more accurate than the connotations that the CompSci term "state" has. Keeping in mind the caveats of growing complexity that Eggy mentioned above, if you have simple scripts like an up-down toggle, using a global boolean reduces code overhead and LSL state change overhead (small, but existant). Not all scripts need get more complex; I have a handful of 5 liners that are often handy. Finally, just for pedantism sake, the relative moveTo example given above is technically correct. However, due to rounding errors in movements and angle computations, a prim scripted like that will often "drift" if used repeatedly over time. So, depending on how you intend to use it, your original approach of storing a start point and returning to it might be more appropriate. A pattern I find myself often using is: initialize() { // return all global variables and LSL conditions to the way I want to start // sometimes llResetScript() can't do non-static initialization - for example startPos = llGetPos(); ownerKey = llGetOwner(); .. }
default { on_rez(integer n) { initialize(); }
state_entry() { initialize(); } }
Which after typing in found was already in the LSL Wiki.
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
03-18-2005 10:18
Yup. Also from the wiki, an interesting tidbit about states:
States vs. Global variables
A state and a set of global variables can serve the same purpose, and each can be expressed in terms of the other. In general, you should prefer the use of states over global variables since states allow you to immediately assume script state without making comparisons. The less comparisons a script makes, the more regular code statements it can run.
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
03-18-2005 10:52
Thanks Eggy. I didn't mean to imply you were a fundamentalist, it's something I've been wondering about for a while and you just posted something at the right (or maybe wrong) moment.
I do use states for somethings, and I can't imagine *not* using them. I can't imagine not using globals in most scripts too however, too many times something needs sharing outside of an event.
Increasing complexity is always an interesting call... I can read things jumping around to states, function calls and the like, but the less of them I have to read the easier I find it to follow I must admit. Senility and stupidity catching up with me I guess!
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
03-18-2005 14:55
Oh, and on why I didn't just use a state... States Are The Devil!Actually, I just felt like using a global. Globals are also easier to learn for a beginner. I love states in general.  And, expert? I think the jury's out on that one... 
_____________________
---
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
03-18-2005 16:17
Heh, Jeffrey, you're not an expert, you're a god  Anyone who can code BVH/3DS importers is good enough for me 
|
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
|
Anything wrong?
03-18-2005 21:00
Hello there, Though I couldn't keep up with those discussions, I tried the both scripts, Jeffrey's one and Eggy's one. Oh, I realized that I needed at least one state on the script.  I didn't know such a thing. So I wrote Jeffrey's one like following. integer on = FALSE;
default { touch_start(integer total_number) { if(on) { llSetPos(llGetPos() + (<0,0,1> * llGetRot())); on = FALSE; } else { llSetPos(llGetPos() - (<0,0,1> * llGetRot())); on = TRUE; } } }
I thought the both is just difference between the way of wrighting. Eggy's one moved as expected, but Jeffrey's one moved down a half meter first just touching it after beeing rezzed. hmm... 
|
Jack Lambert
Registered User
Join date: 4 Jun 2004
Posts: 265
|
03-19-2005 00:40
From: Jeffrey Gomez Welcome to Second Life! This is the easiest way to do what you want: integer on = FALSE;
...
on = FALSE;
All the Kool Kids are using on = !on;
You want it to be cool, right?  So you can take it off some sweet jumps. --Jack Lambert
_____________________
---------------------------- Taunt you with a tree filled lot? hahahahahahaha. Griefer trees! Good lord you're a drama queen. Poor poor put upon you.
-Chip Midnight
|
gene Poole
"Foolish humans!"
Join date: 16 Jun 2004
Posts: 324
|
03-20-2005 21:08
From: Jack Lambert All the Kool Kids are using on = !on;
You want it to be cool, right?  So you can take it off some sweet jumps. --Jack Lambert Pffft, binary-NOT is so 90s... retro is the thang, and the cool kids are now using "on = 1 - on;" again (erm... make sure 'on' never starts above 1 or below 0). Take that off some sweet jumps, mang! Anyway, Seagel, you might want to give this page a look: http://secondlife.com/badgeo/wakka.php?wakka=CrashCourse
|
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
|
03-21-2005 21:34
Thank you, Jack and gene. But I seemed not understand you at all. I wish I were a Kool kid... I thought you had me write the following. integer on;
default { touch_start(integer total_number) { if(on) { llSetPos(llGetPos() + (<0,0,1> * llGetRot())); on = !on; } else { llSetPos(llGetPos() - (<0,0,1> * llGetRot())); on = on; } } } Touching it once, it moving down a half meter, and it never moving again... Sad...(BTW Why aren't there Sad and Cry Smiles...oops the rhetorical inconsistency?)
|
Jeffrey Gomez
Cubed™
Join date: 11 Jun 2004
Posts: 3,522
|
03-21-2005 23:04
Stick with: integer on;
default { touch_start(integer total_number) { if(on) { llSetPos(llGetPos() + (<0,0,1> * llGetRot())); on = !on; } else { llSetPos(llGetPos() - (<0,0,1> * llGetRot())); on = !on; } } } Or: integer on;
default { touch_start(integer total_number) { if(on) { llSetPos(llGetPos() + (<0,0,1> * llGetRot())); on = FALSE; } else { llSetPos(llGetPos() - (<0,0,1> * llGetRot())); on = TRUE; } } } When you say on = !on; you are reversing what "on" is. If on is TRUE, it becomes FALSE... if FALSE, TRUE. So you would want both to be !on, or just write it with TRUE and FALSE.
_____________________
---
|
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
|
03-21-2005 23:38
From: Jeffrey Gomez When you say on = !on; you are reversing what "on" is. If on is TRUE, it becomes FALSE... if FALSE, TRUE.
So you would want both to be !on, or just write it with TRUE and FALSE. Good God! I got it. Thank you Jeffrey again. 
|
Catherine Omega
Geometry Ninja
Join date: 10 Jan 2003
Posts: 2,053
|
03-22-2005 07:16
Honestly, just sticking with TRUE or FALSE is probably going to be a lot simpler and make your code a lot more readable for you. 
|
Seagel Neville
Far East User
Join date: 2 Jan 2005
Posts: 1,476
|
Roger
03-22-2005 21:06
Thanks, Catherine. I've decided to use TRUE and FALSE. I gave up beeing a Kool kid 
|
Jon Marlin
Builder, Coder, RL & SL
Join date: 10 Mar 2005
Posts: 297
|
03-23-2005 05:17
From: Seagel Neville Thanks, Catherine. I've decided to use TRUE and FALSE. I gave up beeing a Kool kid  As a professional software developer, I can tell you this is a much better solution. Writing maintainable code is probably the most important part of writing "good" code. Using a lot of what-seem-to-be cool tricks to impress your friends typically lead to a lot of head scratching six months later when you (or someone else) looks at the code again. Later, Jon
|