HAD - hlavni.java
  1 package had;
  2 import java.applet.Applet;
  3 import java.awt.Color;
  4 import java.awt.Graphics;
  5 import java.awt.Image;
  6 import java.awt.event.KeyEvent;
  7 import java.awt.event.KeyListener;
  8 import java.io.DataInputStream;
  9 import java.io.DataOutputStream;
 10 import java.io.File;
 11 import java.io.FileInputStream;
 12 import java.io.FileOutputStream;
 13 import java.io.IOException;
 14 
 15 public class hlavni extends Applet  //nakonec jsem to nechal cely v AWT
 16                     implements KeyListener {
 17   
 18     /** HRA HAD
 19      *  @author Marek Aufart
 20      *   ---webova edice---, zdrojovy kod pro Vasi inspiraci, nicmene TUTO PRACI NESMITE VYDAVAT ZA SVOU!
 21      *
 22      *  pole x, uloziste souradnic hada x, max. delka hada 300
 23      *  pole y, uloziste souradnic tela y, max. delka hada 300
 24      */
 25      int x[] = new int[300]; 
 26      int y[] = new int[300];
 27      /** popis jednotlivych vlastnosti hada ( promennych ) a hodnot, kterych mohou nabyvat 
 28       *  smer 0..nahoru, 1..doleva, 2..doprava, 3..dolu
 29       *  delka 5 a vice (do limitu velikosti pole)
 30       *  zpozdeni 100ms - 10ms
 31       *  l pocet kroku hada, roste pri kazdem pohybu hada, 0 a vic
 32       *  sebrano pocet vsech sebranych bodu, 0 a vic
 33       *  bodu pocet ziskanych bodu (roste podle toho jake body had sezere), 0 a vic
 34       *  bodx, body vychozi poloha prvniho bodu, potom se uz generuje nahodne, 1..39, 1..29 
 35       *  extrabodx, extrabody promenne pro souradnice ExtraBodu, generuji se nahodne, 1..39, 1..29
 36       *  ttlb promenna do ktere se uklada cas jak dlouho se da jeste ExtraBod sezrat, kazdym krokem hada se dekrementuje az do 0, 50..0
 37       *  info uloziste zprav pro hrace - napr. ze zlomil rekord (pouzije se az na konci programu)
 38       *  sezral informace pro autopilota
 39       *  konec informace pro metodu paint(g), jestli nema vykreslit vysledky
 40       *  autopilot indikace zapnuti autopilota
 41       */ 
 42      int smer = 0, delka = 5, zpozdeni = 140; 
 43      int l=0, sebrano=0, bodu=0;
 44      int bodX=17, bodY=19;
 45      int extraBodX, extraBodY, ttlb;
 46      boolean sezral = false, konec = false, autopilot = false, zmacknuto = false;
 47      String info;
 48      
 49  /////////////////////////////////////////////////////////////////////////////
 50      
 51     public void zmacknuto(KeyEvent evt) {
 52         switch (evt.getKeyCode()){
 53             case KeyEvent.VK_UP: smer = 0; zmacknuto=true; //nahoru
 54                 break;
 55             case KeyEvent.VK_LEFT: smer = 1; zmacknuto=true;  //vlevo
 56                 break;
 57             case KeyEvent.VK_RIGHT: smer = 2; zmacknuto=true;  //vpravo
 58                 break;               
 59             case KeyEvent.VK_DOWN: smer = 3; zmacknuto=true;  //dolu
 60                 break;    
 61             case KeyEvent.VK_SPACE: if (autopilot) { autopilot=false; } else { autopilot = true; }   
 62         }
 63     }
 64      
 65     public void keyPressed( KeyEvent e ) {
 66         zmacknuto(e); 
 67     }
 68    public void keyReleased( KeyEvent e ) { }
 69    public void keyTyped( KeyEvent e ) { }
 70     
 71     public void inicializace() {
 72         /** vytvori startovniho hada
 73          *  naplni souradnice hada (zhruba doprostred plochy)
 74          *  --nevraci zadnou navratovou hodnotu
 75          */
 76       int i = 0;
 77       for(int j=13; j<=17; j++) {
 78           x[i]=20;
 79           y[i]=j;
 80           i++;
 81       }
 82     }
 83      
 84     public void dejBod() {
 85         /** vybere nahodne souradnice pro bod
 86          * (nikdy ne primo u kraje)
 87          *  --nevraci zadnou navratovou hodnotu
 88          */
 89        bodX=1+(int)(Math.random()*38);
 90        bodY=1+(int)(Math.random()*28);
 91     }
 92      
 93     public boolean sezralBod() {
 94         /** zjistuje, jestli se souradnice hlavy nekryji se souradnicemi bodu
 95          * @return vraci boolean - sezral/nesezral bod
 96          */
 97        boolean narazil = false;
 98        if (x[0]==bodX && y[0]==bodY) narazil = true;
 99        return narazil;
100     }
101     
102     public void dejExtraBod() {
103          /** vybere nahodne souradnice pro ExtraBod
104          * (nikdy ne primo u kraje) a da vic sanci hadovi (i kdyz ho nesezere na prvnim miste)
105          * nastavi dobu na jak dlouho bude bod aktivni (TimeToLiveBodu:)
106          *  --nevraci zadnou navratovou hodnotu
107          */
108        extraBodX=1+(int)(Math.random()*38);
109        extraBodY=1+(int)(Math.random()*28); 
110        ttlb=50;
111     }
112     
113     public boolean sezralExtraBod() {
114          /** zjistuje, jestli se souradnice hlavy nekryji se souradnicemi ExtraBodu
115          * @return vraci boolean - sezral/nesezral ExtraBod
116          */
117        boolean narazil = false;
118        if (x[0]==extraBodX && y[0]==extraBodY) narazil = true;
119        return narazil;
120     }
121     
122     public void projdiStenou() {
123          /** zjistuje, jestli hlava hada nenarazila na stenu 
124          *  pokud jo, tak přesune hadovu hlavu na druhou stranu plochy
125          *   -- nevraci zadnou navratovou hodnotu
126          */
127           if (y[0]<=0 && smer==0) y[0]=29;
128           if (y[0]>=29 && smer==3) y[0]=0;
129           if (x[0]<=0 && smer==1) x[0]=39;
130           if (x[0]>=39 && smer==2) x[0]=0; 
131     }
132     
133     public boolean isNarazil() {
134         /** porovna souradnice hlavy s kazdou jinou casti tela hada
135          *  tim zjistuje, jestli had nenarazil sam do sebe
136          * @return vraci boolean - narazil/nenarazil do sebe
137          */
138         boolean narazil= false;
139         for (int i=1; i<x.length-1;i++) {
140             if ((x[0] == x[i]) && (y[0] == y[i])) {
141               narazil = true;
142             }
143         }
144         return narazil;
145     }
146     
147     public void posun() {
148         /** posouva hada
149          *  1.prekresli kazdy bod teda na souradnice predchoziho
150          *  2.prepise u polohu hlavy, ta se potom dokresli na spravne misto
151          *  podle aktualniho smeru pohybu hada
152          *  -- nevraci zadnou navratovou hodnotu
153          */
154           //1.
155           for(int j=delka; j>=1; j--) {
156               x[j]=x[j-1];
157               y[j]=y[j-1];
158           }
159           //2.
160           switch(smer) {
161               case(0): y[0]=y[0]-1; 
162                        break;
163               case(1): x[0]=x[0]-1; 
164                        break;
165               case(2): x[0]=x[0]+1; 
166                        break;
167               case(3): y[0]=y[0]+1; 
168                        break;
169           }       
170     }
171     
172      public void zrychli() {
173          /** zmensi zpozdeni v zavisloti na poctu bodu
174          *   tim zrychli pohyb hada (nenecha ale zpozdeni klesnout pod 10ms)
175          *  --nevraci zadnou navratovou hodnotu
176          */
177           if (zpozdeni > 10) {
178             int zmena;
179             if (bodu<8) {
180                 zmena = 5;
181             } else {
182                 zmena = 2;
183             }
184             zpozdeni = zpozdeni - zmena;
185           }
186     }
187  
188     public void vykresli(Graphics g) {
189             /** vykreslovani jednotlivych grafickych casti appletu
190              *  blizsi vysvestleni primo u danych radku
191              *  rozmery plochy jsou 40x30, vysledne meritko pro zobrazovani 5:1
192              *  tato metoda pouziva trodu Graphics a nevraci zadnou navratovou hodnotu
193              */
194             //vycisteni platna
195             g.clearRect(0,0,500,150);            
196             //vykresleni ramecku
197             g.drawRect(0,0,200,150);              
198             //vykresleni bodu
199             g.setColor(Color.BLUE);
200             g.fillRect(5*bodX+1,5*bodY+1,3,3);
201             g.setColor(Color.BLACK);
202             //vykresleni extrabodu
203             if (ttlb>0) {
204               g.setColor(Color.RED);
205               g.fillRect(5*extraBodX,5*extraBodY,5,5);
206               g.setColor(Color.BLACK);
207             }
208             //--zaverecne vykreslovani hada
209             // - hlava
210             g.fillRect(5*x[0],5*y[0],6,6);
211             // - telo  
212             for(int k=1; k<=delka; k++) {
213                 g.drawRect(5*x[k],5*y[k],5,5);  
214             }
215        
216     }
217     
218       public void vykresliStav(Graphics g) {
219           /** vykresluje informace o hre
220            *  (v prave casti appletu)
221            *  -- nevraci zadnou navratovou hodnotu
222            */
223             g.drawString("Hra HAD",220,15);
224             g.drawString("bodu: "+bodu,220,40);
225             g.drawString("delka: "+delka,220,60);
226             if (autopilot) {
227                 g.setColor(Color.red);
228                 g.drawString("AUTOPILOT",220,100);
229                 g.setColor(Color.black);
230             }
231             g.drawString("Semestralni prace Y36ALG: Marek Aufart, FEL CVUT 2007",10,170);
232     }
233     
234       public void autopilot() {
235          /** samo-ovladani hada, zere primarne extraBody (sek.body)
236           *  casem ale narazi sam do sebe, uzivatel muze hada ovladat i pri zapnutem autopilotovi
237           *  moc chytrej taky neni, je to jen doplnek hry
238           *  -- nevraci zadnou navratovou hodnotu
239           */           
240            if (ttlb>0) {
241                 //primarne jde po extraBodech
242                 if (y[0]==extraBodY && x[0]>extraBodX && smer!=2 && zmacknuto==false) {
243                     smer = 1;
244                 }
245                 if (y[0]==extraBodY && x[0]<extraBodX && smer!=1 && zmacknuto==false) {
246                     smer = 2;
247                 }
248                 if (sezral) {
249                     if (smer!=3) smer = 0; else smer=3;
250                     sezral = false;
251                 }  
252            } else {
253                 //kdyz neni extraBod, tak jde po normalnim bodu
254                 if (y[0]==bodY && x[0]>bodX && smer!=2 && zmacknuto==false) {
255                     smer = 1;
256                 }
257                 if (y[0]==bodY && x[0]<bodX && smer!=1 && zmacknuto==false) {
258                     smer = 2;
259                 }
260                 if (sezral) {
261                     if (smer!=3) smer = 0; else smer=3;
262                     sezral = false;
263                 }
264            } 
265            zmacknuto=false;
266       }
267         
268      public void ukonceni(Graphics g) {
269         /** vypise ukoncovaci info pro uzivatele a zavola ulozeni
270          *  -- nevraci zadnou navratovou hodnotu
271          */
272         vykresli(g);
273          try {
274             Thread.sleep(1000);
275           } catch (InterruptedException ex) {
276             System.out.println("smula, zkuste znovu");
277           }  
278          
279         g.clearRect(0,0,201,151);
280         g.drawString("Je po hre",80,60);
281         g.drawString("Dosahli jste "+bodu+" bodu, blahopreji:-)",80,80);
282        // g.drawString(info,80,100);        
283     
284     }
285      
286       public int nactiVysledek() {
287          /** otevre soubor a nacte z nej cislo,
288           *  to jen vejvyssi dosud dosazeny vysledek, pokud soubor neexistuje,
289           *  dosadi za nejvyssi vysledek 0
290           * @return vraci int - nejlepsi dosud dosazeny vysledek
291           */    
292           int  bestVysledek = 0;
293           File soubor = new File("vysledek.dat");
294           if (soubor.exists() && soubor.canRead()) {
295             try {
296              DataInputStream souborVysledek = new DataInputStream(new FileInputStream("vysledek.dat"));
297              bestVysledek = souborVysledek.readInt();
298              souborVysledek.close();
299             } catch (IOException e) {
300              System.out.println("smula, chyba nacitani souboru s vysledky");
301             }
302           } else
303               showStatus("Soubor s vysledky nenalezen, ale nevadi.");
304         return bestVysledek;
305       } 
306       
307        public void ulozVysledek(int vysledek) {
308          /** otevre soubor a ulozi do nej vysledek,
309           *  ten je metode predan, jako parametr
310           * @param parametrem je nejvyssi vysledek - cislo, ktere metoda ulozi
311           *  -- nevraci zadnou navratovou hodnotu
312           */   
313            try {
314              File soubor = new File("vysledek.dat");
315              if (soubor.canWrite() || soubor.createNewFile() ) {           
316                  DataOutputStream souborVysledekZ = new DataOutputStream( new FileOutputStream("vysledek.dat"));
317                  souborVysledekZ.writeInt(vysledek);
318                  souborVysledekZ.close();
319                  showStatus("Vysledek uspesne ulozen.");
320               } else {
321                  showStatus("Vysledek nemuze byt ulozen, ale nevadi.");
322               }  
323             } catch (IOException e) {
324              System.out.println("smula, chyba ukladani souboru s vysledky");
325             }
326            
327       } 
328         
329        public void vyhodnoceni() {
330            /** zjisti, jestli nahrany pocet bodu je vyssi nez ulozeny pocet bodu
331             *  zapise do informace pro hrace, popr. ulozi vysledek
332             *  -- vraci boolean - ne/neni nejlepsi vysledek
333             */
334            int bestVysledek = nactiVysledek(); 
335            if (bodu > bestVysledek) {
336               info = "Prekonali jste rekord o "+ (bodu-bestVysledek) + " bodu.";
337               ulozVysledek(bodu);
338            } else {
339               info = "Rekord je stale "+ bestVysledek +" bodu.";  
340            }
341        }
342        //ridici vlakno
343         Thread kresleni = new Thread() {
344         public void run() {           
345            for (;;) {
346                
347               try {
348               //----zpozdeni------
349                 Thread.sleep(zpozdeni);
350               } catch (InterruptedException ex) {
351                 System.out.println("smula, zkuste znovu");
352               }    
353               
354               // extra body
355                 if (delka % 5 == 0 && bodu > 0 && ttlb==0) {
356                  dejExtraBod();
357                 }
358                if (isNarazil()) {
359                 // System.out.println("Je po hre - x "+x[0]+" y "+y[0]+" smer "+smer);
360                  break;
361                  }
362               
363               
364               if (sezralBod()) {
365                 bodu=bodu+1;
366                 delka=delka+1;
367                 dejBod();
368                 zrychli();
369                 sezral = true;
370             }
371             
372             if (ttlb>0 && sezralExtraBod()) {
373                 bodu=bodu+5;
374                 delka=delka+1;
375                 ttlb=0;
376                 zrychli();
377                 sezral = true;
378             }
379             
380            if (autopilot) autopilot(); //samostatny pohyb a prodluzovani hada - pro zkusebni ucely
381             
382             posun();         
383             projdiStenou();  
384             l++;    //pocitadlo kroku hada, inkrementace           
385             if (ttlb>=1) { 
386                 ttlb=ttlb-1; //odecet casu ExtraBodu
387             }
388             if (x[299] != 0) break; //aby nepreteklo pole souradnic hada
389               
390                repaint();
391            } //konec opakovani
392           //   vyhodnoceni(); 
393              konec=true;
394              repaint();
395             }
396         };
397 
398 ////////////////////////////////////////////////////////////////////////////////       
399        
400     public void init() {
401       setFocusable(true);
402       enableInputMethods(true);
403       addKeyListener( this );
404       inicializace();
405       requestFocus();
406     }        
407        
408     public void start() {       
409         kresleni.start(); //start ridiciho vlakna
410     }
411     
412     public void paint(Graphics g) {
413             if (l<2) showStatus("HAD: autopilota zapnete/vypnete mezernikem"); 
414             vykresli(g);
415             vykresliStav(g);
416 
417             if (konec) {
418               ukonceni(g);    
419               showStatus("Je po hre.");
420             }
421     }
422 
423 }