Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [jQuery] Snake
Forum PHP.pl > Inne > Oceny
lord_t
W ramach ćwiczenia się w js i jQuery(wersja: 1.2.3) postanowiłem popełnić Snake'a, który w praktyce wygląda tak: SNAKE

Info:
-sterowanie na klawiszach W,S,A,D
-jestem świadom, że odznaczenie inputa sprawia, że gra nie działa.

Kody:

jQuery:
  1. <script type="text/javascript" src="jquery-1.2.3.min.js"></script>
  2. <script type="text/javascript">
  3. <!--
  4.  
  5. function Snake(nazwa_,rozmiarPlanszy_,szybkosc_,maxOwocow_)
  6. {
  7. /* Snake by Pawel 'lord_T' Maruszczyk
  8. * Silesia, July 2008, version 1.0
  9. * License MIT
  10. */
  11.  
  12. this.rozmiar=rozmiarPlanszy_;
  13. this.ileOwoc=0;
  14. this.maxOwoc=maxOwocow_|2;
  15. this.dlugosc=2; //glowa + ogon
  16. this.ogon=[];
  17. this.szybkosc=szybkosc_;
  18. this.nazwa=nazwa_;
  19. this.ruch=true;
  20. this.i;
  21. this.j;
  22. this.macierz;
  23. this.kierunek='down';//'up','right','left'
  24. this.niemozliwy='s';//kierunek niemozliwy do wybrania (ktory klawisz)
  25. var ths=this;
  26.  
  27. //aktualizacja ogona
  28. this.addTail=function(a,b)
  29. {
  30. this.ogon.unshift({i:a,j:b});
  31. if( (this.ogon.length+1) >this.dlugosc )
  32. {
  33. var usuniety=this.ogon.pop();
  34. $('#'+usuniety.i+'_'+usuniety.j).removeClass().addClass('pole');
  35. }
  36. }
  37.  
  38. //sprawdzanie kolizji glowy z ogonem i owocami
  39. this.checkCol/*isions*/=function(i,j)
  40. {
  41. var count=this.ogon.length;
  42. for(var k=1;k<count;++k)
  43. if(this.ogon[k].i==i && this.ogon[k].j==j){
  44. this.ruch=false;
  45. break;
  46. }
  47. if($('#'+i+'_'+j).hasClass('owoc')){
  48. ++this.dlugosc;
  49. --this.ileOwoc;
  50. $('#'+i+'_'+j).removeClass().addClass('glowa');
  51. }
  52. }
  53.  
  54. //kolorowanie glowy i sprawdzenie kolizji
  55. this.putHead=function(i,j)
  56. {
  57. $('#'+i+'_'+j).addClass('glowa');
  58. this.checkCol(i,j);
  59. this.i=i;
  60. this.j=j;
  61. }
  62.  
  63. //kolorowanie ogona
  64. this.moveTail=function()
  65. {
  66. for(var k=0;k<this.ogon.length;++k)
  67. $('#'+this.ogon[k].i+'_'+this.ogon[k].j).addClass('ogon');
  68. }
  69.  
  70. //ruch glowy w wybranym kierunku i aktualizacja ogona
  71. this.moveHead=function()
  72. {
  73. this.addTail(this.i,this.j);
  74. switch(ths.kierunek)
  75. {
  76. case 'down': ths.niemozliwy='w';++this.i;this.i%=this.rozmiar;break;
  77. case 'up' : ths.niemozliwy='s';this.i+=(this.rozmiar-1);this.i%=this.rozmiar;break;
  78. case 'left': ths.niemozliwy='d';this.j+=(this.rozmiar-1);this.j%=this.rozmiar;break;
  79. case 'right':ths.niemozliwy='a';++this.j;this.j%=this.rozmiar; break;
  80. }
  81. this.putHead(this.i,this.j);
  82. }
  83.  
  84. //wstawianie owocow na plansze
  85. this.putFruit=function()
  86. {
  87. if(this.ileOwoc<=this.maxOwoc){
  88. var losI=Math.floor(Math.random() * this.rozmiar);
  89. var losJ=Math.floor(Math.random() * this.rozmiar);
  90. var wolne=true;
  91.  
  92. if(this.i==losI && this.j==losJ) wolne=false;
  93. if(wolne){
  94. var count=this.ogon.length;
  95. for(var k=0;k<count;++k)
  96. if(this.ogon[k].i==losI && this.ogon[k].j==losJ){
  97. wolne=false;
  98. break;
  99. }
  100. }
  101. if(wolne){
  102. $('#'+losI+'_'+losJ).addClass('owoc');
  103. ++this.ileOwoc;
  104. }
  105. }
  106.  
  107. nastOwoc=Math.floor(Math.random())+8.5*ths.szybkosc;
  108. setTimeout(ths.nazwa+".putFruit()",nastOwoc);
  109. }
  110.  
  111. //petla czasu - rusza wezem
  112. this.timeLoop=function()
  113. {
  114. this.moveHead();
  115. this.moveTail();
  116. if(this.ruch)
  117. setTimeout(ths.nazwa+".timeLoop()",ths.szybkosc);
  118. else{
  119. $('.waz div').css('background','#ccc');
  120. $('.waz').after($('<div id="gameover">GAME OVER</div>'));
  121. }
  122. }
  123.  
  124. //przygotowanie planszy
  125. this.makeSnakesPlace=function()
  126. {
  127. n=this.rozmiar;
  128. this.macierz=new Array(n);
  129. var tabelaPola=$('<table class="waz"></table>');
  130. for(var i=0;i<this.rozmiar;++i)
  131. {
  132. this.macierz[i]=new Array(n);
  133. var wiersz=$('<tr></tr>');
  134. for(var j=0;j<this.rozmiar;++j)
  135. {
  136. this.macierz[i][j]=0;
  137. wiersz.append($('<td><div class="pole" id="'+i+'_'+j+'"></div></td>'));
  138. }
  139. tabelaPola.append(wiersz);
  140. }
  141. $('body').append(tabelaPola).append('<input style="width:0;color:white" type="text" id="czytnik"/>');
  142. $('#czytnik').focus();
  143.  
  144. $('#czytnik').keypress(function(e){
  145. $(this).val('');
  146. var key=String.fromCharCode(e.which);
  147. if(key!=ths.niemozliwy)
  148. switch(key){
  149. case 's':ths.kierunek='down'; break;
  150. case 'w':ths.kierunek='up'; break;
  151. case 'a':ths.kierunek='left'; break;
  152. case 'd':ths.kierunek='right'; break;
  153. }
  154. });
  155. this.putHead(0,2);
  156. this.putFruit();
  157. this.timeLoop();
  158. }//make
  159.  
  160. this.makeSnakesPlace();
  161. }//objekt snake
  162.  
  163. $('document').ready(function(){
  164. Waz=new Snake('Waz',10,300);
  165. });
  166. //-->


css:
Kod
<style type="text/css">
/* <![CDATA[ */
div{
height:20px;
width:20px;
}

div.pole{
background:#217F25;
}

div.glowa{
background:yellow;
}

div.ogon{
background:red;
}

div.owoc{
background:blue;
}

table.waz,#gameover
{
margin:20px auto;
padding:0;
}

#gameover{
width:100px;
}

td,tr{
    padding:0;
    margin:0;
    border:0;
}
/* ]]> */
</style>


Trochę mi ten kod przycięło do lewej, no ale tak działa forum na tabulacje;) Ładniejszy w źródle strony:)
bim2
zamiast
$('#czytnik').keypress
daj
$('document').keypress
i powinno działac ;P
lord_t
$(document).key... pomogło, thx.

Jak zrobię kolejną wersję to tam już ową zmianę zamieszczę.

PS. Ja już myślę, że tu jakaś opinia o skypcie a tu psińco;p No ale dzięki:)
Szunaj85
Gierka nawet całkiem całkiem, ale według mnie:
- powinienneś dopracować grafikę
- Na końcu gry wyświetla się GAME OVER i tyle. Brakuje mi tu punktacji
.radex
Jest ok, ale nic specjalnego. Można powiedzieć, że sam silnik jest gotowy, ale to trzeba jakoś dokończyć, ładnie "opakować" tongue.gif

Na przykład dobrze by było zrobić, że jeśli input jest odznaczony (czyli jeśli nie jest bodajże focus), to stopuje grę winksmiley.jpg
Михаил_з_СССР
Gra bardzo fajna, oceniam na 8/10. Zamiast kolorowych kwadracików można by zastosować prostą grafikę z przezroczystym tłem (tułów poziomy/pionowy, skręt głowy węża w różne strony, ogon itp.).

#EDIT: Literówka.
tiraeth
Widzę kilka literówek w kodzie, np. ths.niemozliwy zamiast this.niemozliwy - to samo z ths.kierunek.

Ogólnie wężyk spoko smile.gif Wkurza tylko to focusowanie na pole tekstowe.
Crozin
@tiraeth: autor wcześniej zrobił
Kod
var ths=this;
Nie wiem w jakim celu, ale IMHO to nie literówka winksmiley.jpg
Babcia@Stefa
Kodu nie oceniam (nie mam czasu przeglądać), ale efekt mi się podoba - na pewno sam bym lepszego nie uzyskał winksmiley.jpg
Co do grafiki też fajna, chociaż nie wiem czy ktoś będzie w to grać (trochę nie praktyczne) ale mi się podoba winksmiley.jpg

8/10 - nic nie jest idealne, w kodzie wiedzę same polskie nazwy chociaż tylko zerknęłem na niego, nie sprawdzałem biggrin.gif

Pozdrawiam, WebNuLL(Babcia@Stefa)
lord_t
Najpierw trochę odpowiem:
@tiraeth: to nie literówka;) ale fakt, że w wielu miejscach ths można było zastąpić this (co też zrobiłem). W jednym miejscu nie można ( $(document).keypress(function(e){...}), ponieważ tam this odwołuje się do document.
@Babcia@Stefa: a od kiedy angielskie nazewnictwo są wyznacznikiem dobrego kodu? Nazwy metod są po ang, bo wydaja mi się krótsze niż pol. odpowiedniki. Jeśli lepiej i łatwiej czyta Ci się kody pisane całkowicie po ang. to możesz sobie przetłumaczyć ten kod.

Wersja 1.1

Zmiany:
-wyrzucenie 'czytnika' (thx dla bima2)
-punktacja

Kod jQuery (wkleiłem jako php tylko dlatego, żeby były TABy;) )
  1. <?php ?>
  2. <script type="text/javascript">
  3. <!--
  4.  
  5. function Snake(nazwa_,rozmiarPlanszy_,szybkosc_,maxOwocow_)
  6. {
  7. /* Snake by Pawel 'lord_T' Maruszczyk
  8.  * Silesia, July 2008, version 1.1
  9.  * License MIT
  10.  */
  11.  
  12. this.rozmiar=rozmiarPlanszy_;
  13. this.ileOwoc=0;
  14. this.maxOwoc=maxOwocow_|2;
  15. this.dlugosc=2; //glowa + ogon
  16. this.ogon=[];
  17. this.szybkosc=szybkosc_;
  18. this.nazwa=nazwa_;
  19. this.ruch=true;
  20. this.i;
  21. this.j;
  22. this.macierz;
  23. this.kierunek='down';//'up','right','left'
  24. this.niemozliwy='s';//kierunek niemozliwy do wybrania (ktory klawisz)
  25. var ths=this;
  26.  
  27. //aktualizacja ogona
  28. this.addTail=function(a,b)
  29. {
  30. this.ogon.unshift({i:a,j:b});
  31. if( (this.ogon.length+1) >this.dlugosc )
  32. {
  33. var usuniety=this.ogon.pop();
  34. $('#'+usuniety.i+'_'+usuniety.j).removeClass().addClass('pole');
  35. }
  36. }
  37.  
  38. //sprawdzanie kolizji glowy z ogonem i owocami
  39. this.checkCol/*isions*/=function(i,j)
  40. {
  41. var count=this.ogon.length;
  42. for(var k=1;k<count;++k)
  43. if(this.ogon[k].i==i && this.ogon[k].j==j){
  44. this.ruch=false;
  45. break;
  46. }
  47. if($('#'+i+'_'+j).hasClass('owoc')){
  48. ++this.dlugosc;
  49. --this.ileOwoc;
  50. $('#'+i+'_'+j).removeClass().addClass('glowa');
  51. }
  52. }
  53.  
  54. //kolorowanie glowy i sprawdzenie kolizji
  55. this.putHead=function(i,j)
  56. {
  57. $('#'+i+'_'+j).addClass('glowa');
  58. this.checkCol(i,j);
  59. this.i=i;
  60. this.j=j;
  61. }
  62.  
  63. //kolorowanie ogona
  64. this.moveTail=function()
  65. {
  66. for(var k=0;k<this.ogon.length;++k)
  67. $('#'+this.ogon[k].i+'_'+this.ogon[k].j).addClass('ogon');
  68. }
  69.  
  70. //ruch glowy w wybranym kierunku i aktualizacja ogona
  71. this.moveHead=function()
  72. {
  73. this.addTail(this.i,this.j);
  74. switch(this.kierunek)
  75. {
  76. case 'down': this.niemozliwy='w';++this.i;this.i%=this.rozmiar;break;
  77. case 'up' : this.niemozliwy='s';this.i+=(this.rozmiar-1);this.i%=this.rozmiar;break;
  78. case 'left': this.niemozliwy='d';this.j+=(this.rozmiar-1);this.j%=this.rozmiar;break;
  79. case 'right':this.niemozliwy='a';++this.j;this.j%=this.rozmiar; break;
  80. }
  81. this.putHead(this.i,this.j);
  82. }
  83.  
  84. //wstawianie owocow na plansze
  85. this.putFruit=function()
  86. {
  87. if(this.ileOwoc<=this.maxOwoc){
  88. var losI=Math.floor(Math.random() * this.rozmiar);
  89. var losJ=Math.floor(Math.random() * this.rozmiar);
  90. var wolne=true;
  91.  
  92. if(this.i==losI && this.j==losJ) wolne=false;
  93. if(wolne){
  94. var count=this.ogon.length;
  95. for(var k=0;k<count;++k)
  96. if(this.ogon[k].i==losI && this.ogon[k].j==losJ){
  97. wolne=false;
  98. break;
  99. }
  100. }
  101. if(wolne){
  102. $('#'+losI+'_'+losJ).addClass('owoc');
  103. ++this.ileOwoc;
  104. }
  105. }
  106.  
  107. nastOwoc=Math.floor(Math.random())+8.5*this.szybkosc;
  108. setTimeout(this.nazwa+".putFruit()",nastOwoc);
  109. }
  110.  
  111. //petla czasu - rusza wezem
  112. this.timeLoop=function()
  113. {
  114. this.moveHead();
  115. this.moveTail();
  116. if(this.ruch)
  117. setTimeout(this.nazwa+".timeLoop()",this.szybkosc);
  118. else{
  119. $('.waz div').css('background','#ccc');
  120. $('.waz').after($('<div id="gameover">KONIEC GRY<br />Zdobyte punkty: '+Math.round((1+(this.rozmiar*this.rozmiar))/20*this.dlugosc)+'</div>'));// ((1+r*r)*n/2)/10=suma c.arytm/10
  121. }
  122. }
  123.  
  124. //przygotowanie planszy
  125. this.makeSnakesPlace=function()
  126. {
  127. n=this.rozmiar;
  128. this.macierz=new Array(n);
  129. var tabelaPola=$('<table class="waz"></table>');
  130. for(var i=0;i<this.rozmiar;++i)
  131. {
  132. this.macierz[i]=new Array(n);
  133. var wiersz=$('<tr></tr>');
  134. for(var j=0;j<this.rozmiar;++j)
  135. {
  136. this.macierz[i][j]=0;
  137. wiersz.append($('<td><div class="pole" id="'+i+'_'+j+'"></div></td>'));
  138. }
  139. tabelaPola.append(wiersz);
  140. }
  141. $('body').append(tabelaPola);
  142.  
  143. $(document).keypress(function(e){
  144. $(this).val('');
  145. var key=String.fromCharCode(e.which);
  146. if(key!=ths.niemozliwy)
  147. switch(key){
  148. case 's':ths.kierunek='down'; break;
  149. case 'w':ths.kierunek='up'; break;
  150. case 'a':ths.kierunek='left'; break;
  151. case 'd':ths.kierunek='right'; break;
  152. }
  153. });
  154. this.putHead(0,2);
  155. this.putFruit();
  156. this.timeLoop();
  157. }//make
  158.  
  159. this.makeSnakesPlace();
  160. }//objekt snake
  161.  
  162. $('document').ready(function(){
  163. Waz=new Snake('Waz',10,300);
  164. });
  165. //-->
  166. </script><?php ?>


Kod css
  1. <style type="text/css">
  2. /* <![CDATA[ */
  3. div{
  4. height:20px;
  5. width:20px;
  6. }
  7.  
  8. div.pole{
  9. background:#217F25;
  10. }
  11.  
  12. div.glowa{
  13. background:yellow;
  14. }
  15.  
  16. div.ogon{
  17. background:red;
  18. }
  19.  
  20. div.owoc{
  21. background:blue;
  22. }
  23.  
  24. table.waz,#gameover
  25. {
  26. margin:20px auto;
  27. padding:0;
  28. }
  29.  
  30. #gameover{
  31. width:200px;
  32. text-align:center;
  33. }
  34.  
  35. td,tr{
  36. padding:0;
  37. margin:0;
  38. border:0;
  39. }
  40. /* ]]> */
vokiel
Sterowanie w Operze wreszcie działa, aż się skusiłem zagrać winksmiley.jpg
Kod
KONIEC GRY
Zdobyte punkty: 283


Dobra robota smile.gif
snovvy
Straciłem na tej grze około 10 min tongue.gif świetna sprawa :-) gra się przyjemnie :-) Kodu niestety nie ocenie bo na JS nie znam wstydnis.gif
lord_t
Wersja 1.2
Wersja 1.3
Wersja 1.4

Zmiany (1.2):
-sterowanie przeniesione z W,S,A,D na strzałki,
-wąż i owoce w postaci graficznej

Zmiany (1.3):
-buforowanie wszystkich pól
-zwiększenie hermetycznosci

Zmiany (1.4):
-usunięcie niejawnego eval() z setTimeout()
-uproszczenie związane z klasą css

  1. <script type="text/javascript" src="jquery-1.4.1.min.js"></script>
  2. <script type="text/javascript">
  3. <!--
  4.  
  5. function Snake(nazwa,rozmiar/*planszy*/,szybkosc,maxOwocow)
  6. {
  7. /* Snake by Pawel 'lord_T' Maruszczyk
  8. * Silesia, February 2010, version 1.4
  9. * License MIT
  10. */
  11.  
  12. var ileOwoc=0;
  13. var maxOwoc=(maxOwocow-1||2);
  14. var dlugosc=2; //glowa + ogon
  15. var ogon=[];
  16. var ruch=true;
  17. var i;
  18. var j;
  19. var macierz;
  20. var ths=this;
  21.  
  22. this.kierunek='d';//'u','r','l'
  23. this.niemozliwy=40;//w dol - kierunek niemozliwy do wybrania (kod klawisza)
  24.  
  25.  
  26. //aktualizacja ogona
  27. this.addTail=function(a,b){
  28.  
  29. var tmpK=null;
  30. if(ogon[0])
  31. switch(ogon[0].uklad.p){
  32. case 'l': tmpK='r'; break;
  33. case 'r': tmpK='l'; break;
  34. case 'u': tmpK='d'; break;
  35. default: tmpK='u';
  36. }
  37.  
  38. ogon.unshift({i:a, j:b, uklad:{p/*oczatek*/:this.kierunek, k/*oniec*/:tmpK} });
  39.  
  40. if( (ogon.length+1) >dlugosc ){
  41. var usuniety=ogon.pop();
  42. macierz[usuniety.i][usuniety.j].removeClass();
  43. }
  44. }
  45.  
  46. //sprawdzanie kolizji glowy z ogonem i owocami
  47. this.checkCol/*isions*/=function(i,j){
  48.  
  49. var count=ogon.length;
  50. for(var k=1;k<count;++k)
  51. if(ogon[k].i==i && ogon[k].j==j){
  52. ruch=false;
  53. break;
  54. }
  55.  
  56. if(macierz[i][j].hasClass('owoc')){
  57. ++dlugosc;
  58. --ileOwoc;
  59. macierz[i][j].removeClass().addClass('glowa'+this.kierunek);
  60. }
  61. }
  62.  
  63. //kolorowanie glowy i sprawdzenie kolizji
  64. this.putHead=function(a,b){
  65.  
  66. macierz[a][b].addClass('glowa'+this.kierunek);
  67. this.checkCol(a,b);
  68. i=a;
  69. j=b;
  70. }
  71.  
  72. //kolorowanie ogona
  73. this.moveTail=function(){
  74.  
  75. for(var k=0;k<ogon.length;++k)
  76. {
  77. //budowanie nazwy klasy
  78. var tmp='ogon'+ogon[k].uklad.p;
  79.  
  80. if(k<ogon.length-1)
  81. tmp+= ogon[k].uklad.k;
  82.  
  83. macierz[ogon[k].i][ogon[k].j].removeClass().addClass(tmp);
  84. }
  85. }
  86.  
  87. //ruch glowy w wybranym kierunku i aktualizacja ogona
  88. this.moveHead=function(){
  89.  
  90. this.addTail(i,j);
  91. switch(this.kierunek){
  92. case 'd': this.niemozliwy=38; ++i; i%=rozmiar;break;
  93. case 'u': this.niemozliwy=40; i+=(rozmiar-1); i%=rozmiar;break;
  94. case 'l': this.niemozliwy=39; j+=(rozmiar-1); j%=rozmiar;break;
  95. case 'r': this.niemozliwy=37; ++j; j%=rozmiar; break;
  96. }
  97. this.putHead(i,j);
  98. }
  99.  
  100. //wstawianie owocow na plansze
  101. this.putFruit=function(){
  102.  
  103. if(ileOwoc <= maxOwoc){
  104. var losI=Math.floor(Math.random() * rozmiar);
  105. var losJ=Math.floor(Math.random() * rozmiar);
  106. var wolne=true;
  107.  
  108. if(i==losI && j==losJ) wolne=false;
  109.  
  110. if(wolne){
  111. var count=ogon.length;
  112. for(var k=0;k<count;++k)
  113. if(ogon[k].i==losI && ogon[k].j==losJ){
  114. wolne=false;
  115. break;
  116. }
  117. }
  118.  
  119. if(wolne){
  120. macierz[losI][losJ].addClass('owoc');
  121. ++ileOwoc;
  122. }
  123. }
  124.  
  125. nastOwoc=Math.floor(Math.random())+8.5*szybkosc;
  126. setTimeout(ths.putFruit,nastOwoc);
  127. }
  128.  
  129. //petla czasu - rusza wezem
  130. this.timeLoop=function(){
  131.  
  132. ths.moveHead();
  133. ths.moveTail();
  134. if(ruch)
  135. setTimeout(ths.timeLoop,szybkosc);
  136. else{
  137. $('#waz div').css('background','#ccc');
  138. $('#waz').after($('<div id="gameover">KONIEC GRY<br />Zdobyte punkty: '+Math.round((1+(rozmiar*rozmiar))/20*dlugosc)+'<input type="button" value="Nowa gra" onclick="window.location.reload()"></div>'));// ((1+r*r)*n/2)/10=suma c.arytm/10
  139. }
  140. }
  141.  
  142. //przygotowanie planszy
  143. this.makeSnakesPlace=function(){
  144.  
  145. macierz=new Array(rozmiar);
  146. var tabelaPola=$('<table id="waz"></table>');
  147. for(var i=0;i<rozmiar;++i){
  148. macierz[i]=new Array(rozmiar);
  149. var wiersz=$('<tr>');
  150. for(var j=0;j<rozmiar;++j){
  151. macierz[i][j]=$('<div>').appendTo($('<td>').appendTo(wiersz));
  152. }
  153.  
  154. tabelaPola.append(wiersz);
  155. }
  156.  
  157. $('body').append(tabelaPola);
  158.  
  159. $(document).keydown(function(e){
  160. var key=(e||window.event).keyCode;
  161. if(key!=ths.niemozliwy)
  162. switch(key){
  163. case 40:ths.kierunek='d'; break;
  164. case 38:ths.kierunek='u'; break;
  165. case 37:ths.kierunek='l'; break;
  166. case 39:ths.kierunek='r'; break;
  167. }
  168. });
  169.  
  170. this.putHead(0,2);
  171. this.putFruit();
  172. this.timeLoop();
  173.  
  174. }//make
  175.  
  176. this.makeSnakesPlace();
  177. }//objekt snake
  178.  
  179. $('document').ready(function(){
  180. Waz=new Snake('Waz',10,300);
  181. });
  182. //-->
  183.  
  184. <style type="text/css">
  185. /* <![CDATA[ */
  186. div{
  187. height:20px;
  188. width:20px;
  189. }
  190.  
  191. div.owoc{background-image:url('fruit.png');}
  192.  
  193. div.glowar{background-image:url('head-r.png');}
  194. div.glowal{background-image:url('head-l.png');}
  195. div.glowad{background-image:url('head-d.png');}
  196. div.glowau{background-image:url('head-u.png');}
  197.  
  198. div.ogonl{background-image:url('tail-l.png');}
  199. div.ogonr{background-image:url('tail-r.png');}
  200. div.ogonu{background-image:url('tail-u.png');}
  201. div.ogond{background-image:url('tail-d.png');}
  202.  
  203. div.ogonll,
  204. div.ogonrr,
  205. div.ogonrl,
  206. div.ogonlr{background-image:url('r-l.png');}
  207.  
  208. div.ogonud,
  209. div.ogonuu,
  210. div.ogondd,
  211. div.ogondu{background-image:url('u-d.png');}
  212.  
  213. div.ogonru,
  214. div.ogonur{background-image:url('u-r.png');}
  215.  
  216. div.ogonlu,
  217. div.ogonul{background-image:url('u-l.png');}
  218.  
  219. div.ogonrd,
  220. div.ogondr{background-image:url('d-r.png');}
  221.  
  222. div.ogonld,
  223. div.ogondl{background-image:url('d-l.png');}
  224.  
  225. table#waz,#gameover{
  226. margin:20px auto;
  227. padding:0;
  228. border-spacing:0px;
  229. }
  230.  
  231. table#waz div{
  232. background-color:#217F25;
  233. }
  234.  
  235. #gameover{
  236. width:200px;
  237. text-align:center;
  238. }
  239.  
  240. td,tr{
  241. padding:0;
  242. margin:0;
  243. border:0;
  244. }
  245.  
  246. input{margin:10px;}
  247. /* ]]> */
zegarek84
ogólnie dobrze napisana aplikacja - na głębsze przejżenie kodu nie mam czasu i tylko ogólne uwagi winksmiley.jpg
Cytat(lord_t @ 11.08.2008, 23:21:24 ) *
Najpierw trochę odpowiem:
@tiraeth: to nie literówka;) ale fakt, że w wielu miejscach ths można było zastąpić this (co też zrobiłem). W jednym miejscu nie można ( $(document).keypress(function(e){...}), ponieważ tam this odwołuje się do document.

tak, zmienne prywatne i zasięg - tu ok, ale skoro już takie obtymalizacje i mała "hermetyzacja" kodu to dlaczego używasz eval?? - w ostatniej wersji też jest:
Cytat
Kod
setTimeout(this.nazwa+".timeLoop()",this.szybkosc);

i w powyższym właśnie jest eval winksmiley.jpg - a wszystko obchodzisz odwołując się do zmiennej globalnej window.Waz...
podczas gdy zwróć uwagę i wklej w pasku adresu poniższy kod i zauważ, że też będzie działał:
Kod
java script:var a={b:function(){alert('ggg')},c:function(){setTimeout(this.b,1000);}};a.c();void(0);


i jeszcze jedna mała uwaga - trochu nie mam czasu analizować kod ale tak na szybko patrząc na metody to chyba nie buforujesz uchwytu do elementów do których się da tylko za każdym razem ich szukasz w DOM??
np. w tej metodzie (tak na szybko nie zauważyłem buforowania uchwytów a i nie zwróciłem głębiej uwagi na logikę gry czy akurat tu da się zbuforować uchwyty):
Kod
this.putHead=function(i,j)
    {
    $('#'+i+'_'+j).addClass('glowa'+this.kierunek);
    this.checkCol(i,j);
    this.i=i;
    this.j=j;
    }

a i nie wiem z jakiego edytora korzystasz więc czy te kreski, że to zmienne prywatne to nie wnikam... ale od razu napiszę jedną uwagę - zmienna prywatna może mieć tą samą nazwę (identyczną) jakby co jak zmienna publiczna i też definiując zmienne w argumentach funkcji danych zmiennych prywatnych nie trzeba definiować (chyba, że sprawdzasz czy jest podany argument) - i tu taki mały teścik:
Kod
java script:function test(){var a=2;this.a=3;this.a1=function(){return a;};this.a2=function(){return this.a;}};b=new test();alert(b.a1());alert(b.a2());void(0)


ps. javascript w tych kodach ma być razem jak będziesz wklejał do paska adresu winksmiley.jpg

EDIT.
ps. zaktualizuj sobie link do gry w temacie z Twoją ofertą do gry gdyż tam nie działa link winksmiley.jpg
lord_t
Dzięki za konstruktywny komentarz - Twoje rady uwzględniłem, a teraz kilka słów polemiki odnośnie eval(): Przedstawiony przez Ciebie kod nie działa w przypadku, gdy klasę tworzysz przy użyciu function(){}. Chętnie dowiem się jak to zrobić bez eval, może masz jakiś pomysłsmile.gif

Updejtowany kod w poście powyżej (+ link do wersji 1.3).
zegarek84
teraz jadę w pociągu i deczo się "znieczuliłem winksmiley.jpg" ale udało się - tzn lekkich problemów nastręczyła mi metoda timeLoop (okazuje się, że przy kompilacji do pamięci interpretera zachodziła mała rozbieżność - nie wiem czemu a że jestem deczko znieczulony to nie będę dokładniej szukał - w każdym bądź razie tam musiałem też this zastąpić nie tylko w setTimeout)...

a i nie chce mi się analizować (teraz znowu się drzemne ;p), ale chyba dało by się jeszcze kilka uchwytów do DOM zbuforować...

a i nie musiałeś co chwila pisać var - jeśli masz pod rząd to mogłeś oddzielać przecinkiem... działający kod z setTimeout bez eval pod mozillą i operą:

________
EDIT

usunąłem tego html'a bo rozwalał stronę a jest podane już rozwiązanie u lord_t

PS. down
nie czepiałem się kodu ;p - tylko pisałem, że tak można winksmiley.jpg - podobnie jak z eval - już nie chodzi o to, że wszyscy piszą, iż jest niebezpieczny, chodziło o to, że przede wszystkim bardzo ogranicza gdyż:
- kod musi być zinterpretowany po raz kolejny i jego interpretacja jest znacznie wolniejsza...
- odwoływać się można w nim tylko do zmiennych globalnych będących w obiekcie window - co nie sprzyja hermetyzacji kodu winksmiley.jpg

podobnie z buforowaniem chodziło mi tez o to, że to jest wtedy szybsze - w sumie tu nie było potrzeby ale... winksmiley.jpg

pozdro winksmiley.jpg
lord_t
eval: bingo!

Uważam, że nie ma sensu już nic buforować - pozostały tylko odwołania na początku (budowanie planszy- wcale nie musi iść jakoś ekstra szybko) i na końcu (nie ma sensu - dwa jednorazowo wywoływane odwołania).

var nie skrócę, bo nie lubię jak mi się ktoś czepia formatowania kodu;] A ponadto tak jest przejrzyściej.

P.S. Kod poprawiłem dwa moje posty wstecz. Wersja online.
ShadowD
318, nie było już za bardzo gdzie się zmieścić, powiększ mapę. haha.gif

Może możliwość stawiania jakiś kamieni na środku, jakiś edytorem mapy, takie marzenia, ogólnie 9/10 - SUPER! haha.gif
lord_t
Wersja 1.5

Zmiany (1.5):
-grafika (w pełnym tego słowa znaczeniu)
-pauza (spacja)
-Snake() zwraca uchwyt do gry
-preload obrazów(owoce, części węża)
-restartowanie (bez odświeżania strony)

P.S. Byłbym wdzięczny na sprawdzenie wyglądu w IE7 i ewentualnie jakiś zrzut ekranu w przypadku błędu.
P.S.2. @ShadowD: jeśli rozwinę to pomyślę nad tymi przeszkodami:)

  1. <script type="text/javascript" src="jquery-1.4.1.min.js"></script>
  2. <script type="text/javascript" src="DD_belatedPNG.js"></script>
  3. <script type="text/javascript">
  4. <!--
  5.  
  6. function Snake(rozmiar/*planszy*/,szybkosc,maxOwocow)
  7. {
  8. /* Snake by Pawel 'lord_T' Maruszczyk
  9. * Silesia, February 2010, version 1.5
  10. * License MIT
  11. */
  12.  
  13. var ileOwoc;
  14. var maxOwoc;
  15. var dlugosc;
  16. var ogon;
  17. var ruch;
  18. var i;
  19. var j;
  20. var macierz;
  21. var kierunek;
  22. var niemozliwy;
  23. var rama;
  24. var stOwoce; //st = setTimout
  25. var stRuch;
  26. var pauza;
  27. var padding;
  28.  
  29. //ustawienie parametrow poczatkowych
  30. var setParams=function(){
  31.  
  32. ileOwoc=0;
  33. maxOwoc=(maxOwocow||3);
  34. dlugosc=2;//glowa + ogon
  35. ogon=[];
  36. ruch=true;
  37. kierunek='d';//'u','r','l'
  38. niemozliwy=40;//w dol - kierunek niemozliwy do wybrania (kod klawisza)
  39. padding=Math.floor((rozmiar-1)/2)*20;
  40. }
  41.  
  42.  
  43. //aktualizacja ogona
  44. var addTail=function(a,b){
  45.  
  46. var tmpK=null;
  47. if(ogon[0])
  48. switch(ogon[0].uklad.p){
  49. case 'l': tmpK='r'; break;
  50. case 'r': tmpK='l'; break;
  51. case 'u': tmpK='d'; break;
  52. default: tmpK='u';
  53. }
  54.  
  55. ogon.unshift({i:a, j:b, uklad:{p/*oczatek*/:kierunek, k/*oniec*/:tmpK} });
  56.  
  57. if( (ogon.length+1) >dlugosc ){
  58. var usuniety=ogon.pop();
  59. macierz[usuniety.i][usuniety.j].removeClass();
  60. }
  61. }
  62.  
  63. //sprawdzanie kolizji glowy z ogonem i owocami
  64. var checkCol/*isions*/=function(i,j){
  65.  
  66. var count=ogon.length;
  67. for(var k=1;k<count;++k)
  68. if(ogon[k].i==i && ogon[k].j==j){
  69. ruch=false;
  70. break;
  71. }
  72.  
  73. if(macierz[i][j].hasClass('owoc')){
  74. ++dlugosc;
  75. --ileOwoc;
  76. macierz[i][j].removeClass().addClass('glowa'+kierunek);
  77. }
  78. }
  79.  
  80. //kolorowanie glowy i sprawdzenie kolizji
  81. var putHead=function(a,b){
  82.  
  83. macierz[a][b].addClass('glowa'+kierunek);
  84. checkCol(a,b);
  85. i=a;
  86. j=b;
  87. }
  88.  
  89. //kolorowanie ogona
  90. var moveTail=function(){
  91.  
  92. for(var k=0;k<ogon.length;++k)
  93. {
  94. //budowanie nazwy klasy
  95. var tmp='ogon'+ogon[k].uklad.p;
  96.  
  97. if(k<ogon.length-1)
  98. tmp+= ogon[k].uklad.k;
  99.  
  100. macierz[ogon[k].i][ogon[k].j].removeClass().addClass(tmp);
  101. }
  102. }
  103.  
  104. //ruch glowy w wybranym kierunku i aktualizacja ogona
  105. var moveHead=function(){
  106.  
  107. addTail(i,j);
  108. switch(kierunek){
  109. case 'd': niemozliwy=38; ++i; i%=rozmiar;break;
  110. case 'u': niemozliwy=40; i+=(rozmiar-1); i%=rozmiar;break;
  111. case 'l': niemozliwy=39; j+=(rozmiar-1); j%=rozmiar;break;
  112. case 'r': niemozliwy=37; ++j; j%=rozmiar; break;
  113. }
  114. putHead(i,j);
  115. }
  116.  
  117. //wstawianie owocow na plansze
  118. var putFruit=function(){
  119.  
  120. if(ileOwoc < maxOwoc){
  121. var losI=Math.floor(Math.random() * rozmiar);
  122. var losJ=Math.floor(Math.random() * rozmiar);
  123. var wolne=true;
  124.  
  125. if(i==losI && j==losJ) wolne=false;
  126.  
  127. if(wolne){
  128. var count=ogon.length;
  129. for(var k=0;k<count;++k)
  130. if(ogon[k].i==losI && ogon[k].j==losJ){
  131. wolne=false;
  132. break;
  133. }
  134. }
  135.  
  136. if(wolne && !macierz[losI][losJ].hasClass('owoc') ){
  137. macierz[losI][losJ].addClass('owoc owoc'+Math.floor(Math.random()*3));
  138. ++ileOwoc;
  139. }
  140.  
  141. }
  142.  
  143. var nastOwoc=Math.floor(Math.random())+8.5*szybkosc;
  144. stOwoce=setTimeout(putFruit,nastOwoc);
  145. }
  146.  
  147. //petla czasu - rusza wezem
  148. var timeLoop=function(){
  149.  
  150. moveHead();
  151. moveTail();
  152. if(ruch)
  153. stRuch=setTimeout(timeLoop,szybkosc);
  154. else{
  155. var rest=$('<div>Nowa gra</div>').click(function(){makeSnakesPlace(1);});
  156. var govr=$('<div id="gameover">KONIEC GRY<br>Zdobyte punkty: '+Math.round((1+(rozmiar*rozmiar))/20*dlugosc)+'</div>');
  157. govr.width(rozmiar*20).height(rozmiar*20-padding).css('padding-top',padding).append(rest);
  158.  
  159. $('table#waz').replaceWith(govr);
  160. }
  161. }
  162.  
  163. //wlacza/wylacza pauze
  164. var togglePause=function(){
  165.  
  166. if(stRuch!=null && ruch){
  167. clearTimeout(stOwoce);
  168. clearTimeout(stRuch);
  169. stRuch=null;
  170. pauza.css({display:'block',zIndex:1001});
  171. }
  172. else{
  173. putFruit();
  174. timeLoop();
  175. pauza.css({display:'none',zIndex:0});
  176. }
  177. }
  178.  
  179. //wczytuje do pamieci wszystkie obrazki i wspomaga png w IE
  180. var preloadImages=function(){
  181.  
  182. var klasy=['owoc0','owoc1','owoc2','glowar','glowal','glowad','glowau','ogonr','ogonl','ogond','ogonu','ogonlr','ogondu','ogonur','ogonul','ogondl','ogondr'];
  183. for(var p in klasy)
  184. $('body').append($('<div class="cache">').addClass(klasy[p]));
  185.  
  186. //tylko IE
  187. if($.browser.msie){
  188. DD_belatedPNG.fix('div#t, div#b,div#l, div#r,div#tl,div#tr,div#bl,div#br');
  189.  
  190. var png=['div.owoc0','div.owoc1','div.owoc2','div.glowar','div.glowal','div.glowad','div.glowau','div.ogonl','div.ogonr','div.ogonu','div.ogond','div.ogonll', 'div.ogonrr','div.ogonrl','div.ogonlr','div.ogonud','div.ogonuu','div.ogondd','div.ogondu','div.ogonru','div.ogonur','div.ogonlu','div.ogonul','div.ogonrd', 'div.ogondr','div.ogonld','div.ogondl'];
  191.  
  192. for(var i=0;i<document.styleSheets.length;++i){
  193. var css=document.styleSheets[i].rules;
  194.  
  195. if (document.styleSheets[i].title=="waz"){
  196. for(var j=0;j<css.length && png.length>0;++j){
  197. var r=css[j];
  198.  
  199. for(var k=0;k<png.length;++k){
  200. if(r.selectorText.toLowerCase()==png[k]){
  201.  
  202. var src=r.style.backgroundImage.toString();
  203. src=src.substring(4,src.lastIndexOf(')'))
  204.  
  205. r.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"',sizingMethod='crop');";
  206. r.style.background='none';
  207.  
  208. png.splice(k,1);
  209. k=100;//zakonczy biezaca petle
  210. }
  211. }
  212. }
  213.  
  214. break;
  215. }
  216. }
  217. }
  218. }
  219.  
  220. //przygotowanie planszy
  221. var makeSnakesPlace=function(restart){
  222.  
  223. setParams();
  224.  
  225. macierz=new Array(rozmiar);
  226. var tabelaPola=$('<table id="waz"></table>');
  227. for(var i=0;i<rozmiar;++i){
  228. macierz[i]=new Array(rozmiar);
  229. var wiersz=$('<tr>');
  230. for(var j=0;j<rozmiar;++j){
  231. macierz[i][j]=$('<div>').appendTo($('<td>').appendTo(wiersz));
  232. }
  233.  
  234. tabelaPola.append(wiersz);
  235. }
  236.  
  237.  
  238. if(restart)
  239. rama.find('#gameover').replaceWith(tabelaPola);
  240. else{
  241. //budowa obramowania i pauzy
  242. var szerokosc=rozmiar*20;
  243. pauza =$('<div id="pause"><div style="padding-top:'+padding+'px">PAUZA</div></div>').css({width:szerokosc,height:szerokosc,opacity:'0.7'});
  244. var boki =$('<div id="b"></div><div id="t"></div>').width(szerokosc);
  245. var brzegi=$('<div id="r"></div><div id="l"></div>').height(szerokosc);
  246. rama =$('<div id="rama"><div id="tl"></div><div id="tr"></div><div id="bl"></div><div id="br"></div></div>');
  247. rama.width(szerokosc+20).height(szerokosc+20).append(pauza).append(boki).append(brzegi).append(tabelaPola);
  248.  
  249. $('body').append(rama);
  250. }
  251.  
  252. $(document).keydown(function(e){
  253. var key=(e||window.event).keyCode;
  254. if(key==32)
  255. togglePause(); //pauzowanie na spacji
  256. else if(key!=niemozliwy && stRuch!=null)
  257. switch(key){
  258. case 40:kierunek='d'; break;
  259. case 38:kierunek='u'; break;
  260. case 37:kierunek='l'; break;
  261. case 39:kierunek='r'; break;
  262. }
  263. });
  264.  
  265. putHead(0,2);
  266. putFruit();
  267. timeLoop();
  268.  
  269. return rama;//uchwyt do weza
  270. }//make
  271.  
  272. preloadImages();
  273. return makeSnakesPlace();
  274. }//objekt snake
  275.  
  276. $('document').ready(function(){
  277. var waz=Snake(12,230);
  278. //$('#srodek').prepend(waz); //przykład wklejenia węża w div o id "srodek"
  279.  
  280. });
  281.  
  282.  
  283. //-->
  284.  
  285.  
  286.  
  287. <style type="text/css" title="waz">
  288. /* <![CDATA[ */
  289.  
  290. /*css dostępny pod linkiem z grą - forum nie pozwoliło mi dać tak długiego postu, więc wyciąłem. */
darko
Kozackie! smile.gif Tylko brakuje mi liczenia punktów za zebrane owoce. Ale i tak jestem pod wrażeniem.
koderrr
swietne !

przydalaby sie jedynie lista graczy z najlepszymi wynikami
thomson89
Świetna gierka, a i postępy znakomite. Jak patrzę na pierwszą wersję i ostatnią, jestem pod zachwytem.

Przydałaby się jeszcze większa mapka i możliwość dopasowania szybkości węża...

frytek92
Naprawdę super jeszcze lepiej by było jak bym widział wynik oraz by były bonusy na czas haha.gif ale i tak jest super chyba.

Twoja gra zmobilizuje mnie żeby douczyć się jQuery tongue.gif

Ocena : 9/10
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.