Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wykorzystanie zmiennej z jednej funkcji w innej
Forum PHP.pl > Forum > Po stronie przeglądarki
eFK
Witam serdecznie

Tworzę prostą grę opartą o js. Mam dwie funkcje js. Pierwsza odpowiada za wyświetlanie w randomowej kolejności elementów tablic. Druga sprawdza poprawność odpowiedzi i zlicza punkty. Pierwsza z nich jest regularnie odświeżana dzięki setInterval.

I teraz mój problem. Potrzebuję trzecią funkcję, która uzależni czas odświeżania w setInterwal od ilości punktów, a będzie odświeżana jak ta pierwsza. Niestety poza drugą z moich funkcji nie mogę użyć zmiennej z punktami, gdyż tak działa js (zmienne lokalne i globalne).

Czy jest jakiś sposób na obejście tego? Jak na razie moje poszukiwania nie przyniosły efektu, może ktoś mógłby mi coś poradzić. Jak trzeba to oczywiście kod funkcji również tutaj zamieszczę.
Comandeer
Możesz skorzystać z IIFE i zamknąć obydwie funkcji wewnątrz IIFE - wówczas uzyskasz własny scope (zakres), który nie wypłynie do globalnego, a może być współdzielony przez zamknięte w nim funkcje
eFK
Więc "bawię się" IIFE i domykaniem, próbując je poznać i zrozumieć, i chciałabym się dopytać o kilka rzeczy.
Mam taki, stworzony zupełnie bez większego celu, jedynie dla sprawdzenia jak działają niektóre elementy kod:

  1. <div id='points'></div>
  2. <div id='check'></div>
  3. <div id='try'></div>
  4. var all = function(globaldate){
  5.  
  6.  
  7. function a(p, o){
  8. document.getElementById('check').innerHTML = i = parseInt(p) + parseInt(o);}
  9.  
  10.  
  11. function b(){
  12. points = globaldate + 100;
  13. document.getElementById('points').innerHTML = points;}
  14.  
  15. document.getElementById('try').innerHTML ='<div onClick="a(1, 9)">clickclickclick</div>';
  16.  
  17. b();
  18.  
  19. }(document.getElementById('points').innerHTML)
  20.  
  21.  


Chcę połączyć tutaj funkcję a() z onClick, aby naciśnięcie na odpowiedni div ją wywoływało. Nie działa - wg. konsoli "a nie jest funkcją". Po pierwsze, nie mogę zrozumieć dlaczego w takim przypadku "a" nie jest rozumiane jako funkcja. I po drugie, czy da się to jakoś zrobić?
Comandeer
No bo [onclick], jako atrybut, zawsze szuka danej rzeczy w globalnym scope. Dlatego przypinanie zdarzeń najlepiej robić z poziomu JS. Ja bym to widział tak:
Kod
var try = document.getElementById('try');
try.innerHTML = 'clickclickclick';
try.onclick = function()
{
    a(1, 9);
};

Powinno zaskoczyć
eFK
Dzięki, to rzeczywiście bardzo ważna i potrzebna rzecz (tylko zamiast var try trzeba użyć var cokolwiek_innego :-))

Niestety mam kolejny problem i po całej nocy szukania rozwiązania i tylko dwóch godzinach spania nie mam już pomysłu pod jakim hasłem szukać. Pełen kod mojego programu na ten moment wygląda tak:

  1. <!DOCTYPE html>
  2.  
  3. <meta charset="utf-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  5. <title>Koncentruj się</title>
  6. <meta content="gra, koncentracja" name="keywords">
  7. <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
  8.  
  9. /*arrays*/
  10. index=[0,1,2,3,4,6,7,8];
  11. colorus=["#000000","#800000","#0000FF","#008000","#FFFF00","#FF00FF","#808080","#FF0000","#FFE4E1"];
  12. desc=["czarny","brązowy","niebieski","zielony","żółty","fioletowy","szary","czerwony","różowy"];
  13.  
  14.  
  15. <style type="text/css">
  16. p{
  17. font-size:50px;
  18. font-weight:bold;
  19. text-transform:uppercase;}
  20.  
  21. .colourbox{
  22. width:150px;
  23. height:150px;
  24. border:1px solid black;
  25. text-align:center;
  26. float:left;
  27. margin:7px;}
  28.  
  29. </head>
  30. <div id="temp"></div>
  31. <div id="points"></div>
  32. <div id="mistakes"></div>
  33. <div id="cont"></div>
  34. <div id="boxes"></div>
  35.  
  36. var all = function(globaldate1){
  37.  
  38. /*function random array elements*/
  39.  
  40. function random(){
  41. function randarray(array){
  42. for(var i = 0; i < array.length; i++){
  43. var j = Math.floor(Math.random() * array.length);
  44. var temp = array[i];
  45. array[i] = array[j];
  46. array[j] = temp;
  47. }
  48. return array;
  49. }
  50.  
  51. /*random, showed colour & description*/
  52. var randindex=randarray(index);
  53. var randomdesc=randarray(desc);
  54. var randomcolour=randarray(colorus);
  55. var randescolour=randomcolour[randindex[0]];
  56.  
  57. document.getElementById("cont").innerHTML='<p style="color:'+randescolour+'">'+randomdesc[0]+'</p>';
  58.  
  59.  
  60. var x=1;
  61. var boxes=[];
  62. while(x<=7){
  63. boxes[x++]=['<div class="colourbox" style="background:'+randomcolour[x] +'"></div>'];}document.getElementById("boxes").innerHTML=boxes;
  64.  
  65. /* Tu jest problem, funkcja play nie otrzymuje koloru wybranego diva, ale jeden kolor dla wszystkich div, niezaleznie od tego na który się kliknie*/
  66. $("#boxes").on("click", ".colorbox", function () {
  67. play($(this).data("boxColor"), randescolour);
  68. });
  69. }
  70. random();
  71. /*end of function randarray*/
  72. /*function play and points*/
  73.  
  74. function play(choosecolor, randescolor){
  75. if(choosecolor==randescolor){
  76. if(document.getElementById('points').innerHTML===''){
  77. document.getElementById('points').innerHTML=100;}
  78. else{
  79. function points(allpoints){
  80. var addpoints=parseInt(allpoints)+100;
  81. document.getElementById('points').innerHTML=addpoints;
  82. }
  83. }
  84. points(document.getElementById('points').innerHTML);
  85. }
  86. else{
  87. if(document.getElementById('mistakes').innerHTML===''){
  88. document.getElementById('mistakes').innerHTML=1;}
  89. else{
  90. function mistakes(allmistakes){
  91. var addmistakes=parseInt(allmistakes)+1;
  92. document.getElementById('mistakes').innerHTML=addmistakes;
  93. }
  94. }
  95. mistakes(document.getElementById('mistakes').innerHTML);
  96. }
  97. random();
  98. }
  99.  
  100. }(document.getElementById("points").innerHTML)
  101.  
  102. setInterval("random();",time);
  103.  
  104.  
  105. </body>
  106. </html>


To jeszcze nie jest skończone, brakuje kilku ważnych opcji. Ale najpierw muszę rozwiązać problem z funkcją play(). Chodzi o to, że jako argumenty powinna otrzymywać kolor tła klikniętego diva (randomcolour[x], z czym właśnie jest problem) oraz kolor napisu (randescolour). Niestety argument funkcji nie jest połączony oddzielnie z każdym divem i dla każdego z nich przesyła taką samą wartość, co akurat nie jest dziwne i rozumiem dlaczego tak jest. Dlatego zamiast mieś inną wartość dla diva czerwonego, inną dla niebieskiego, zielonego itd., zawsze jest ona taka sama.
Rozwiązanie pewnie jest banalne, ale naprawdę nie wiem jak to zrobić ...
Comandeer
Wgl nie czaję tego kodu. Opisz dokładniej co chcesz uzyskać, bo u mnie wgl nic nie chce działać.
eFK
Chcę stworzyć prostą grę na koncentrację, polegająca na tym, że na ekranie pojawia się nazwa jakiegoś koloru, w innym kolorze, a gracz w ciągu kilku sekund musiał wybrać spośród znajdujących się poniżej kolorowych kwadratów taki kolor w jakim był napis, a nie jaki był napisany. Np. jeżeli na ekranie pojawiał ci się słowo "zielony", ale w czerwonym kolorze, trzeba wybrać czerwony kwadrat.

1) trzy tablice z początku kodu przechowują nazwy kolorów, ich odpowiedniki w systemie HEX oraz liczby 0-1, co jest potrzebne do mieszania kolejności elementów w tych tablicach i zabezpiecza przed powtarzaniem się ich.
2) zmienna randescolour to randomowy kolor HEX przypisany jako color do wyświetlonej nazwy koloru, a randomdesc[0] to randomowa nazwa koloru - na ekranie powinna pojawić się randomowa nazwa koloru z tablicy desc w randomowym kolorze
3) dzięki pętli while i przypisaniu tych div do tablicy, wyświetlam <div class="colourbox" style='background:(randomowy HEX)"><div>. Robię tak, aby nie zajmować się każdym div oddzielnie, aby każdy miał inny kolor tła i po odświeżeniu zmieniały swoją kolejność.

Tutaj też rozpoczyna się problem. Gdyż po naciśnięciu na wybrany div do funkcji play powinny iść dwie wartości: kolor tła kliknietego diva (zmienna randomcolor[x]) oraz kolor wyświetlonej nazwy koloru (randescolor). Problem dotyczy pierwszej wartości: niezależnie na który div się naciśnie do funkcji play idzie taki sam randomcolor[x] (prawdopodobnie ostatnia wartość z pomieszanej tablicy z kolorami HEX).

4) funkcja play porównuje randomcolor[x] z randescolor, przydziela punkty i odświeża funkcję randarray, aby można było grac dalej.

To jeszcze nie jest skończony projekt. Dalej ma być jeszcze np. powiązanie prędkości setInterval z ilością punktów (im więcej tym szybciej), zmniejszanie/zwiększanie ilości dostępnych kolorów w zależności od ilości punktów (dlatego np. ilość punktów potrzebuję w najbardziej zewnętrznej, samo wykonującej się funkcji) , czy koniec gry w wypadku zbyt dużej ilości pomyłek.

Ciekawe czy komuś będzie się to chciało czytać :-D
tzm
Cytat(Comandeer @ 1.06.2015, 20:45:31 ) *
Wgl nie czaję tego kodu. Opisz dokładniej co chcesz uzyskać, bo u mnie wgl nic nie chce działać.


Mam Ci dopisać komentarze? Stary czytam Twojego bloga czasem.. i kompromitujesz się takimi hasłami. Przeczytałeś to chociaż? Czy problemy z myśleniem?
Comandeer
@tzm cieszę się, że znów wnosisz bardzo dużo do tematu. Brawo, kolejny raz udało Ci się mi dowalić. Nie wiem czy pomaga Ci to podbudować Twoje ego, ale jeśli tak to cieszę się, że mogę Ci pomóc. Zawsze wróżono mi karierę psychologa.

Co do tematu: proponuję wyjść od czegoś takiego - http://jsfiddle.net/Comandeer/hgpkvxa3/ Czyli w sumie główna zmiana w stosunku do Twojego kodu to zapisywanie koloru jako atrybut boksu. Wówczas można go z powodzeniem wyciągnąć przy samym kliku.

W Twoim kodzie w tym miejscu nie wiadomo skąd się bierze ten atrybut:
Kod
$("#boxes").on("click", ".colorbox", function () {
    play($(this).data("boxColor"), randescolour);
});

Bo nie widzę, żeby boksy gdziekolwiek miały przypisywany atrybut [data-boxColor]
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.