Is there a glitch with "lerp"?

For questions about using Classic.

Post » Wed Aug 05, 2009 7:57 am

[quote="manontherun":1u7v19nn]quote. all the objects keep moving on, and on, and on.

at start of expandable menu click trigger once set pvariable moveto to .y+16, set pvariable oldy to .y. when menu is expanded lerp to pvariable moveto. when object reaches moveto stop the event. when menu is collapsed lerp to pvariable oldy when object reaches oldy stop event .[/quote:1u7v19nn]

Let me see if I got this straight... I start an event that says... When you select a menu... trigger once... set private variable to whatever Y + 16 would be. That's the math for that. So it'd be like, "Set Options private variable to Options.Y + 16"... and that'll work for every single individual one?

And then we do the lerp movement with .Y being the starting point, and the private variable being the end point? And we have to tell it to stop once it gets to that point? How, exactly? Would it matter since this is being done with "trigger once"?

And then, when cancelling back, we do the same thing over, but instead of adding on the Y coordinate, we subtract, right? Set the private variable to Options.Y - 16? Then do the lerp movement all over again?

I assume, since I KNOW this is going to indescriminately affect every single "Options" object, that we throw in a condition that only the options BELOW the selected menu, and are aligned in the same X coordinate will be pushed down like this?

But did I understand your directions right? I AM pretty dumb at this whole thing, so I'm just making sure I got it. ^_^;;; Just breakin' it down to simplify it for myself.
B
4
S
2
G
4
Posts: 164
Reputation: 1,878

Post » Wed Aug 05, 2009 8:17 am

i dont do good explanations so someone else might jump in. just make sure trigger once when setting the pvariables. the movement wont be triggered once. i said stop event because lerp will still run when it reaches destination but it wont go anywhere, i believe. might as well stop extra cpu use. but thats just out of habit. someone else will tell you if it saves anything worth extra conditions for. and you should put the ones you want to move when clicking button in different family and run events on family. you could do it with out family though. family might be easier for you.... again unless someone else jumps in with how to do with pvariable and for each ordered.
B
2
S
2
G
4
Posts: 259
Reputation: 1,968

Post » Wed Aug 05, 2009 4:11 pm

Seems like an okay idea, and I even tried doing it as a function, so it could be done universally with each and every menu item, but upon testing it out, it turns out that if I have it select every menu text BELOW the cursor, it DOES add to each one of their private variables individually, and ONLY for the ones below the cursor. However, trying to move Options by Options.Y + 32 glitches them all up. lerp wouldn't work, so I tried just setting their .Y to whatever their private variable is, and it sends every single Options object to, and I'm copying and pasting this, "-8.64691e+018".

So setting the private variable to itself.Y + 32 or whatever... that works fine, I checked it in debug, and every Options object below the cursor DOES have a unique variable that coresponds with its own Y position. Moving them at all, on the other hand, seems glitchy.
B
4
S
2
G
4
Posts: 164
Reputation: 1,878

Post » Wed Aug 05, 2009 5:05 pm

In fact... I don't think you can do lerp movement with a private variable at all. Even setting the private variable to a set number like 300 or something makes all of them screw up.
B
4
S
2
G
4
Posts: 164
Reputation: 1,878

Post » Thu Aug 06, 2009 2:47 pm

i can be arsed to read the entire wall of text that this thread is, but from skimming im pretty sure youve misunderstood what you yourself are trying to do

[quote:8gkw087h]Options: Set Y to lerp(.Y, Options.Y+16, 1 - 0.00001 ^ TimeDelta)[/quote:8gkw087h]

this equation doesnt need lerp, infact i have no idea why your using it. all its doing is setting the y position of watever.y, to a position somewhere in between its current y position and options y position +16. the value your using as the "t" value makes no sense. its a number that is never changing except for what time delta is so in short, your lerp targets are always moving, so your objects will continually move. (is options moving aswell?) what you should be doing is storing the initial y position for each object in a variable, called intY, and then the point which you wish it to get to (options.y + 16?) in another value like tgtY DO NOT CONTINUALLY UPDATE THESE, THEY ONLY NEED TO BE SET ONCE, LIKE AT START OF LAYOUT. then u use those two variable for each objects lerp coordinates, and then a third one for the t value so something like lerp('intY','tgtY','t')
u modify t in actions completely unrelated, by adding or subtracting small increments (0.01) from it until it reaches 1 or 0, then u stop.

you wont have to do all this for each object because you could put each one in a family with all these variables, and only control them when those object meet current conditions.

if you want the movement to smoothly accelerate and then smoothly decelerate, you "cosp" inplace of "lerp"
B
52
S
7
G
6
Posts: 1,945
Reputation: 7,610

Post » Thu Aug 06, 2009 10:56 pm

"Wallt of text"? ...

Anyhow, when you mention "t" being 1, I have to admit, I'm sort of copying how I saw lerp done before in other .caps, and thought, "Wow, this has a cool, neat motion from one object to another. PERFECT for my little pause menu thingy! How do I do this?"

Secondly, when I tried creating an internal value for the "Objects" menus to move to, like mano suggested, as I mentioned, the objects couldn't move to that Y position. If I told them their Y destination was their own internal value, they would glithc up and move to that -8.34534whatever-e coordinate that I mentioned in a previous post.

However, if there's a problem with whatever you're referring to as "t" being 1, I'd have no idea what that problem would cause. All I could really get was that you type out, lerp(current position, destination, 1, - time you want this movement done in ^ TimeDelta).

Also, I didn't know about cosp. That's pretty cool. ^^ Unfortunately, when trying it out, it seems to drop the FPS down a bit.
B
4
S
2
G
4
Posts: 164
Reputation: 1,878

Post » Mon Aug 10, 2009 8:33 am

after trying it out myself its more complicated then it seems. not the lerp part just getting each option to expand correctly every sub level in few events. but jfyi you can however try putting all your menus in two families and using for each family1 ordered by ascending family1.y. and family2.y > family1.y set abovedistance pv to dist(0,.y,0,family1) this will give you the distance for the closest text object thats above each text if there are none it will be 0. to get the distance of closest object below do for each family1 ordered by descending family1.y. and family2.y < family1.y set belowdistance pv to dist(0,.y,0,family1). probably hard to get without screenshot or cap but... anyway, you may be able to toy with that to push your text up/down. but i think it would just be easiest to just make containers of each stacked menu group and do lerp events with those.

the condition lerp(.y,'mytargety', 0.20) works fine for me. just to move the text. and btw u might want to change that ^ timedelta to * 100* timedelta. 0.00001 ^ timedelta is like not even moving for a year. might even be causing an error. hope thats somewhat useful. gl
B
2
S
2
G
4
Posts: 259
Reputation: 1,968

Post » Mon Aug 10, 2009 3:47 pm

EDIT: see next post:
Spriter Dev
B
88
S
21
G
12
Posts: 3,240
Reputation: 16,486

Post » Mon Aug 10, 2009 10:17 pm

ok, so here's an example with the FontSprite object: At least try the exe:)
even if the original poster doesn't want to use it, this will explain some of the things you can do with it, and how to do them. hope it helps someone

[color=#FF0000:l8egaw9v]try the exe first, so you know what the events you're looking at are for, and what they will do in the end.[/color:l8egaw9v]
[size=80:l8egaw9v]I only made it work with first and second options, and once you open the option, you can't do anything else. though, as you will see, adding new options only requires you to add one small event, and no guesswork as to how tall all the text for the submenu is[/size:l8egaw9v]

look through the cap a little, to get a basic idea of what's going on before reading the tutorial
after each screenshot, I will break down the actions one by one, so don't let them overwhelm you.

EXE
CAP
link to plugin
also, before we get started, don't be intimidated by the long post, it's actually only four main events, and I broke down each step really far since most people have never used this plugin:


how it works:

ok, in the start of layout, you choose your sprite, and set up which characters are which,
basically you tell it which frames of the sprite animation have which letters.
[size=78:l8egaw9v]it's not as confusing as it looks in the screenshot, basically I'm giving a range of characters like 'a' through 'z', and saying these letters start of frame 33,
the letters are stored in a sprite animation,
frame 33 is 'a', frame 34 is 'b', frame 35 is 'c', etc. if you have questions, look at the cap later, don't let this part worry you for now. it's really quite simple when you try it for yourself[/size:l8egaw9v]

you'll notice that the last line contains our whole menu, if you've never used the newline expression before, it's like pressing enter, so

[code:l8egaw9v]"first"&newline&"second"&newline&"third"&newline&"fourth"&newline&"fifth"[/code:l8egaw9v]

will type on the screen:
[code:l8egaw9v]first
second
third
fourth
fifth
[/code:l8egaw9v]



you can ignore the actions in the brackets, that's setting up a new fontsprite the same way as the first, if you are familiar with the 'function' object, you'll only need those actions once

so it goes like this,

[code:l8egaw9v]On Left Clicked on sprite[/code:l8egaw9v]

each letter is a sprite, so that means if the player clicks on any letter
this event triggers


[code:l8egaw9v]Pick Current Word[/code:l8egaw9v]

this takes that sprite, and goes back to the fontobject
now it's picked every sprite that makes up the word that the sprite was a part of
so if you click on the sprite for "i" in the word "first"
it picks every sprite that makes up the word "first"


[code:l8egaw9v]SpriteFont.CurrentWord Equal to "first"[/code:l8egaw9v]

here's where the magic happens
if the word they clicked on (the 'CurrentWord') is equal to "first", this event will trigger

you then create a SpriteFont2 object (just another spritefont, for the submenu)
I created it at
x= spritefont.phraseleft (the left edge of the all the letters) +30 (for an indent)
and
y = Sprite.Top+spritefont.newlineheight

remember, when we picked Current Word, we picked the sprites that make up that word,
spritefont ignores hotspots, so 'newlineheight' measures from the top of the letter sprite (the sprites that make up the word we clicked on),
so sprite.top+newlineheight, is where it would be writing the next line if you weren't doing a weird menu thing,
this means that your submenu (we just created, SpriteFont2) is positioned exactly as if you had just put a regular newline after the word you clicked on, with no guesswork

then those actions in brackets, are the same setup things we did for the original menu

the Showtext again, this time with SpriteFont2 with all our submenu option separated again by Newlines



[code:l8egaw9v]SpriteFont:Set private variable "option" to spritefont.WordPositionInPhrase[/code:l8egaw9v]

we make a private variable called option, to keep track of what the player clicked on. as you'll see, you won't need a different event for each option from here on out

WordPositionInPhrase is just that

[code:l8egaw9v]"hello, how are you?"[/code:l8egaw9v]

so the WordPositionInPhrase for "hello" is 0, "how" is 1, "are" is 2, etc...

you are setting the private variable "option", to this number, so you can remember which word you clicked on for later, this will make sense in a minute


[code:l8egaw9v]SpriteFont:Set private variable "submenuopen" to "yes"[/code:l8egaw9v]

the default is set to "no", so we can use this later to see if the submenu is open or not


[code:l8egaw9v]SpriteFont2:For Each Character
Sprite:Set opacity to 0[/code:l8egaw9v]

I did this so the submenu is invisible until we've made space for it



[code:l8egaw9v]"submenuopen" equal to "yes"

trigger once[/code:l8egaw9v]
once the menu is open, we want to do this one time


[code:l8egaw9v]SpriteFont:for each character

SpriteFont:Private Variable "option" less than SpriteFont.WordPositionInPhrase[/code:l8egaw9v]
Remember how we set "option" to the word number earlier?
now every letter that is in a word AFTER that original option, will trigger this event
so we set in each letter/sprite:
a private variable:
[code:l8egaw9v]StartHeight = .y (the current y position)[/code:l8egaw9v]

(where it is now, the beginning of the scrolling)


[code:l8egaw9v]EndHeight = StartHeight + SpriteFont2.PhraseHeight + 7[/code:l8egaw9v]

and we want it to end at the end of our submenu

PhraseHeight calculates the distance from the top pixel of the highest word in the phrase, to the lowest pixel at the bottom of the phrase, so this is how big, vertically, the submenu is.
why +7?
because as I said before, spritefont ignores hotspots, so this is to compensate
you can just do this by trial and error, or by checking the position of the sprite hotspot in the sprite editor

almost home...

once again

[code:l8egaw9v]SpriteFont:private variable SubmenuOpen equal to "yes"?
For Each Word
Value of "option" less than WordPositionInPhrase?[/code:l8egaw9v]

these are the same as in the last step
if the submenu is open, check each word and see if it comes after the wordnumber of the option that was clicked on, if so, we need to scroll it


now
[code:l8egaw9v]Sprite.Value('EndHeight') greater than .y?[/code:l8egaw9v]
if so, the sprites haven't scrolled down enough
so
I made a counter to use with lerp to move the sprites

it's a private variable in FontSprite2 called 'counter'
it starts at 0


[code:l8egaw9v]SpriteFont2('Counter') : Add 0.5 * timedelta[/code:l8egaw9v], this will add a tiny number to 'counter',

that will vary based on framerate, to make sure it moves at the same speed on any computer, regardless of slowdown,
if you don't care about slow down, you could have just put 'Add 0.1'


[code:l8egaw9v]Set Y to lerp(('StartHeight'),('EndHeight'),SpriteFont2('counter'))[/code:l8egaw9v]

quazi explained how lerp works, a number between 0 and 1, takes you from the first number to the second number, we set startheight and endheight variables for each sprite(each letter), to take it from where it was to where it was + the height of the submenu

now we've taken care of scrolling the sprites, and stopping the sprites,
because if they've gotten to the end, then the event:[code:l8egaw9v]Sprite.Value('EndHeight') greater than .y?[/code:l8egaw9v] won't be true anymore, so they will stop scrolling

all that's left now is making the submenu not invisible anymore when we're done scrolling


[code:l8egaw9v]Sprite.Value('EndHeight') less than or equal to .y?[/code:l8egaw9v]

this will be true when the sprites reach their final destination after they are done scrolling where they need to be...
it's opposite of the last event, so you could have also just used "else"


[code:l8egaw9v]SpriteFont2:for each character[/code:l8egaw9v]

remember, spritefont2 is the submenu, so now this will pick each sprite in those words one at a time


[code:l8egaw9v]SpriteFont2:Opacity less than 100[/code:l8egaw9v]

remember we set it to opacity to 0?


[code:l8egaw9v]Sprite: Set opacity to .opacity + (50*timedelta)[/code:l8egaw9v]

again, if you don't care that it goes at the exact same speed during slow down, you could have just put opacity +1
since this will keep being true until it's no longer transparent at all (opacity = 100), it gives you a nice slow fade in for the the sub menu...


as you can see, using this method, you don't have to keep guessing how much distance there is for different menus, or setup many objects for each word, and even though it's alot to take in the first time you use the spritefont object
it has a very simple logic to it, once you get over the initial learning curve

if you use functions with this example, the code could be drastically reduced
you could have also used "else", and a private variable to show whether it was a menu, or a submenu instead of a second spritefont object to reduce it further
Spriter Dev
B
88
S
21
G
12
Posts: 3,240
Reputation: 16,486

Previous

Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 13 guests