Avatar billede gotcha Nybegynder
12. december 2000 - 15:45 Der er 9 kommentarer og
1 løsning

Følg musen!!!

At få en besked til at følge musen
Ideen

I dette tilfælde ønsker vi at konstruere en besked, der viser en meddelelse efterfulgt af vores filstørrelse. Denne besked udnytter vi således, at hver bestanddel i denne tildeles unikke egenskaber i stedet for blot at bevæge hele beskeden, hvilket ikke ville se ønskværdigt ud. Dernæst skal beskeden følge efter musen, således at hver bestanddel har en fast position (afhængigt af musens position), som den bevæger sig mod.
Metoden

Efter at have fastlagt vores ide er det hensigtsmæssigt at skitsere en grov metode, der har til formål at bringe struktur i vores arbejde. Det er ikke hensigtsmæssigt at gå i gang med selve skabelsen af filen førend man har gjort sig klart, hvordan man har tænkt sig at gribe problemstillingen an. Hvis man alligevel går i gang med at bygge filen uden denne struktur, ender man højst sandsynligt med en masse unødvendige bestanddele og en del spildtid, fordi man simpelthen søger efter en løsning uden at have gjort sig klart, hvad løsningen egentlig indebærer. Derfor, med henblik på forrige afsnit, kan vi groft skitsere metoden således:

1) Konstruer beskeden
2) Opret de nødvendige variable
3) Tildel hver bestanddel af beskeden unikke egenskaber
4) Placer disse afhængigt af afstanden til den forrige
5) Gentag forrige trin

Fundamentet

Ifølge vores grove metode viser det sig, at vi først har brug for at konstruere en besked, som vi vil kalde for myText. Denne skal som sagt bestå af en meddelelse efterfulgt af vores filstørrelse, hvorfor vi har følgende:

myText = \"NOW LOADING \"+Math.floor((_root.getBytesTotal())/1000)+\" KB...\";

I dette tilfælde er vores meddelelse altså “NOW LOADING”, hvor vi indsætter citattegn omkring denne, da det jo er en tekststreng. Størrelsen af vores fil kommer ved at bruge metoden anyMovieClip.getBytesTotal. Hvis vi ændrer anyMovieClip til _root returneres størrelsen af vores samlede fil i bytes, hvorfor vi altså skriver _root.getBytesTotal. Som sagt er den returnerede værdi i bytes, men vi ønsker at vise den i kilobytes. Grunden til at vi dividerer med 1000 er, at kilo blot betyder 1000 (for eksempel er en kilometer jo 1000 meter!). Desuden ønsker vi at afrunde denne værdi til det heltal, som er mindre eller lig med værdien, hvorfor vi skriver Math.floor. Endelig tilføjer vi den korrekte endelse til vores besked, hvor denne skal være i samme mål som vores tal.

Da vi nu har konstrueret vores besked har vi ifølge vores grove metode brug for at oprette de nødvendige variable. Med henblik på vores ide og overvejelser i denne sammenhæng kommer vi frem til følgende variable:

1) Variable, der bruges til at beskrive en bestanddels bevægelse mod den fastlagte position
2) En variabel, der angiver afstanden mellem to bestanddele
3) Variable, der angiver udgangspositioner for vores besked
4) En variabel, der fungerer som en tæller til vores løkker
5) En variabel, der holder styr på alle bestanddele
6) En variabel, der returnerer antallet af alle bestanddele

 
Ud fra dette konstruerer vi følgende, der følger ovennævnte rækkefølge:

myRatio = 5;
myFriction = 1.75;
letterSpace = 12;
startX = 225;
startY = 300;
i = 1;
myTrails = new Array();
myLength = myText.length;

Som nævnt har vi tænkt os at dele vores besked op i mindre bestanddele. Til dette formål har vi brug for et movie clip, ud fra hvilken disse bliver konstrueret. Derfor vedhæftes itemMaster til roden af vores fil. Dette gøres med følgende udtryk (dette udtryk fungerer kun, hvis navnet itemMaster er angivet under Symbol Linkage Properties for itemMaster), hvor vi sørger for at dybden er unik således at der ikke opstår konflikter:

_root.attachMovie( \"itemMaster\", \"itemMaster\", 10000 );

Endelig har vi brug for en løkke, der deler vores besked op og tilføjer de nødvendige variable til den enkelte bestanddel:

for (i; i<=myLength; i++) {
    duplicateMovieClip (\"itemMaster\", \"trail\"+i, i);
    myTrails[i] = _root[\"trail\"+i];
    myTrails[i]._x = startX+i*letterSpace;
    myTrails[i]._y = startY;
    myTrails[i].myChar = myText.charAt(i-1);
    myTrails[i].xPos = myTrails[i]._x;
    myTrails[i].yPos = myTrails[i]._y;
}

Som det fremgår af ovenstående bruger vi variablen i til at holde styr på denne løkke, som ender, når i ikke længere er mindre eller lig med længden af vores besked. Denne længde er det samme som antallet af bestanddele i vores besked, så handlingerne bliver altså udført for hver bestanddel. Det første vi gør, er at tage en kopi af itemMaster. Denne kopi bliver tildelt navnet ”trail” + i, således at den første bestanddel kommer til at hedde trail1, den anden trail2 etc., hvor dybden er i:

duplicateMovieClip (\"itemMaster\", \"trail\"+i, i);

Det næste trin er at tilføje hver bestanddel til vores array, hvorefter vi fastlægger en individuel vandret og lodret position til disse. Her er den vandrette position vores startposition plus vores tæller gange mellemrummet mellem hver bestanddel, mens den lodrette selvfølgelig blot er den samme som vores startposition, da vi jo ønsker at opstille vores besked på en vandret linie:

myTrails[i] = _root[\"trail\"+i];
myTrails[i]._x = startX+i*letterSpace;
myTrails[i]._y = startY;

Hvis vi kigger på itemMaster, som vores bestanddele jo er konstrueret ud fra, ser vi, at der kun er et enkelt tekstfelt med navnet myChar. Denne opbygning gør sig også gældende for alle vores bestanddele, så hvis vi nu for alle bestanddele i vores besked myText tildeler tekstfeltet myChar den tilhørende bestanddel i variablen myText, har vi altså så at sige taget variablen myText og gjort den til noget vi kan bevæge. Dette gøres via dette:

myTrails[i].myChar = myText.charAt(i-1);
 
Dette udtryk tager og tildeler variablen myChar inde i den korrekte bestanddel det tilhørende bogstav. Grunden til at vi tager det forrige bogstav er, at metoden String.charAt har en udgangsværdi på 0, mens vi i vores løkke starter med en udgangsværdi på 1 (værdien af variablen i). For at kompensere for dette trækker vi blot 1 fra i. Det sidste trin er at oprette to variable xPos og yPos i hver bestanddel, der udgør hhv. den vandrette og lodrette position for bestanddelen:

myTrails[i].xPos = myTrails[i]._x;
myTrails[i].yPos = myTrails[i]._y;

Alt dette befinder sig i den første frame, der altså repræsenter vores fundament.
Friktion

Når vi atter en gang betragter vores grove metode, viser det sig, at det næste skridt er at placere hver bestanddel afhængigt af afstanden til den forrige. I denne sammenhæng bliver vi nødt til at kigge på begrebet friktion. Normalt forstås der ved friktion en fysisk gnidning, men i denne sammenhæng blot at vi gerne vil bremse en bestanddel op indtil den når den position, som den bevæger sig mod. Hvis man forestiller sig en person på en cykel, der cykler hen langs en vej og pludselig holder op med at cykle, vil personen på et tidspunkt stå stille, da der er tale om en gnidning. Dernæst noterer vi stedet, hvor personen holdt op med at cykle og stoppede. Hertil bemærker vi, at personen bevægede sig hurtigere jo større afstanden er til stedet, hvor personen stoppede.

I vores tilfælde kender vi både det nuværende sted og stedet, hvor vi vil hen. Vores hastighed beskriver vi åbenbart ved at tage afstanden mellem disse to og dele den med en konstant. Dette lagrer vi i en variabel; vores næste position er så vores nuværende position plus denne variabel. Jo større denne variabel er, og dermed vores afstand, jo større bliver vores hastighed altså. Dette udføres både i vandret og lodret plan. For at belyse dette betragter vi en bestanddel, der nærmer sig en fastlagt position (her er vi kun interesseret i vandret plan, da det som sagt er nøjagtig den samme logik, der gør sig gældende i lodret plan). Hvis vi siger, at vores nuværende position er 0 og vi vil frem til 100, får vi følgende tabel, hvor konstanten er den tidligere nævnte myFriction med en værdi på 2, den nuværende position er x, afstanden a, hastigheden v og den næste position y:

x    0    50    75    87,5
a    100    50    25    12,5
v    50    25    12,5    6,25
y    50    75    87,5    93,75

Som det fremgår af ovenstående tabel, starter vi ud med at bevæge os hurtigt, hvilket efterhånden aftager. Dette bekræfter altså at vi tager afstanden (100-x), deler den med en konstant, lagrer dette i en variabel (i dette tilfælde v) og beregner en ny position (x+v). Ud fra dette ser vi desuden, at jo større konstanten er, desto langsommere bevæger vi os (hastigheden v bliver mindre). Man kunne undre sig over det tilfælde, hvor x er større end der, hvor vi vil hen. Dette viser sig dog at ligge i selve udtrykket, idet at vores hastighed v bliver negativ; vi nærmer os altså stadig vores mål.

Endelig ønsker vi at opnå en svingning frem og tilbage, hvilket fremkommer ved at ændre på den måde vi beregner hastigheden v. Her tager vi den forrige værdi af hastighed v plus 100-x, hvilket vi deler med en ny konstant myRatio. Dette deles yderligere med den tidligere omtalte variabel myFriction. Herved opnår vi, at selvom afstanden er 0, vil vi alligevel bevæge os enten frem eller tilbage i forhold til hvor vi vil hen. pga. den forrige hastighed. Hvis vi omsætter denne logik til kode, kommer vi frem til følgende:

i = 1;
for (i; i<=myLength; i++) {
    if (i == 1) {
        trail1.speedX = (myTrails[i].speedX+(_xmouse+letterSpace-myTrails[i].xPos)/myRatio)/myFriction;
        trail1.speedY = (myTrails[i].speedY+(_ymouse-myTrails[i].yPos)/myRatio)/myFriction;
        trail1.xPos = myTrails[i].xPos+myTrails[i].speedX;
        trail1.yPos = myTrails[i].yPos+myTrails[i].speedY;
    } else {
        myTrails[i].speedX = (myTrails[i].speedX+(myTrails[i-1].xPos+letterSpace-         
        myTrails[i].xPos)/myRatio)/myFriction;
        myTrails[i].speedY = (myTrails[i].speedY+(myTrails[i-1].yPos-myTrails[i].yPos)/myRatio)/myFriction;
        myTrails[i].xPos = myTrails[i].xPos+myTrails[i].speedX;
        myTrails[i].yPos = myTrails[i].yPos+myTrails[i].speedY;
    }
    myTrails[i]._x = myTrails[i].xPos;
    myTrails[i]._y = myTrails[i].yPos;
}

Det første vi gør er at sætte vores tæller i til 1, da vi ønsker at bruge den igen. Dernæst har vi en løkke, der sikrer, at vores instruktioner bliver udført for hver bestanddel. Disse kan opdeles i to tilfælde. I det første er i lig med 1, hvor vi tager afstanden til musen snarere end afstanden til den forrige bestanddel (denne findes jo heller ikke).  Her lagrer vi først en variabel speedX, der følger den nævnte logik (denne variabel svarer til v), i den første bestanddel. Vi tager altså den forrige værdi af speedX, afstanden mellem musen plus afstanden mellem to bestanddele (hvor vi vil hen) og lægger disse sammen. Dernæst deles først med myRatio og siden myFriction. Når vi betragter vores udtryk ser vi desuden, at disse to variable skal være større end 1 for at opnå den ønskede virkning. Hvis vi f.eks. lader myFriction være 0,5 er det jo det samme som at gange med 2; vi kommer dermed til at bevæge os længere og længere væk (man kan dog godt lade myRatio være mindre end 1 eller i nærheden af 1, men det giver relativt store udsving, hvilket ikke er ønskværdigt). Herefter beregner vi den næste position xPos, der er den nuværende position plus den beregnede hastighed speedX. Som sagt er logikken ens både i vandret og lodret plan, hvorfor vi skriver nøjagtig det samme med den eneste forskel, at det vandrette plan er ændret til lodret. Endelig ser vi på de tilfælde, hvor i ikke er lig med 1 og finder, at logikken er fuldstændig den samme bortset fra, at vi tager afstanden til den forrige bestanddel og ikke musen. Tilbage er der blot at placere hver bestanddel ifølge disse beregninger, hvilket de sidste to linier gør. 

Disse instruktioner befinder sig i den anden frame, mens vi finder følgende i den tredje og sidste frame:

gotoAndPlay (_currentframe-1);   

Dette er blot en anden form for løkke (frame-baseret), hvor vi hele tiden går tilbage til frame 2 (den forrige).
Opsummering

Vi har med det ovenstående taget en variabel og fået den til at bevæge sig efter musen. Under konstruktionen af filen har vi desuden omtalt begrebet friktion, der rummer interessante aspekter. Disse kunne eksempelvis være en ændring af størrelse i stedet for placering, lade en billedserie placere sig afhængigt af friktionen m.m.


Ovenstående skulle være første kapitel til et hæfte, men det bliver alligevel ikke til noget. Håber I synes om det ;O)
Avatar billede allandk Nybegynder
12. december 2000 - 15:56 #1
Hvorfor bliver det ikke til noget?

Og hvorfor smider du det herud.

ab :)
Avatar billede tommyf Nybegynder
12. december 2000 - 16:09 #2
Fy for pokker, jeg troede det var et spørgsmål. Var sgu lige ved at få et hjertestop ;-)
Avatar billede gotcha Nybegynder
12. december 2000 - 16:44 #3
Redaktøren mente, at redigeringsarbejdet ville blive for stort (ovenstående er uden rettelser, tilføjelser m.v.) :o(

Hvis jeg ikke offentliggjorde det, ville det bare ligge på min egen computer, så hvorfor ikke give skidtet fri (forhåbentlig lærer folk noget af det)?

Avatar billede tommyf Nybegynder
12. december 2000 - 16:48 #4
Det er da nogle pæne eksempler du har lavet på din side :)
Avatar billede gotcha Nybegynder
12. december 2000 - 16:55 #5
De er meget gamle; jeg har lavet en bunke nye, der er meget mere interessante. Tak for det ;o)

Avatar billede gotcha Nybegynder
12. december 2000 - 17:07 #7
Hvis I forresten har nogle ideer mht. bevægelse eller lign., vil jeg meget gerne høre dem!

Den næste fil bliver noget med at have en besked, hvor hvert bogstav bliver skrevet med et fast tidsrum (måske en lille vilkårlig afvigelse). I mellemtiden udspringer der kopier ud fra hvert bogstav, der er ens. Disse udfører så en slags bevægelse (jeg har endnu ikke besluttet hvilken). Man kunne også lade dem have vilkårlige farver?

Har I nogle forslag?
Avatar billede sun Nybegynder
02. januar 2001 - 16:57 #8
jeg syndes det er godt hvis man har lave noget andre kan bruge, at man skriver det så hvis folk søger efter det kan de få svar.

Men husk at lukke det med at svare på det selv!
Avatar billede gotcha Nybegynder
24. august 2004 - 08:44 #9
Vil jeg så langt om længe gøre :)
Avatar billede musicchart.dk Nybegynder
28. juni 2005 - 19:57 #10
Over 3½ år om at lukke et spørgsmål, så har man også set det med :o)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester