NASZE SERWISY:    ANDROID   LINUX   MAEMO   SYMBIAN   WEBOS




Hosting sponsoruje:



GRIN3 - polskie fonty

Profesjonalne czcionki z polskimi znakami - czcionki.com

OpenMobile on Facebook


 

[Java] Game API czyli duszki w akcji

Odpowiednie forum do zadawania pytań dotyczących rozpoczęcia programowania.

[Java] Game API czyli duszki w akcji

Postprzez issa » 4 maja 2009, o 14:59

Napisałem trochę kodu wykorzystującego interfejs Runnable , jako alternatywę dla dziedziczenia po klasie Thread przy obsłudze wątków. Zadaniem kodu jest obsługa niezależnych wątków które umożliwią autonomiczną animację "duszków" w pionie i w poziomie , z punktem startowym , opóźnieniem (tu ustawione na zero) oraz kierunkiem ruchu podanym w konstruktorze. Rozgryzam powoli pakiet javax.microedition.lcdui.game , na razie nie za bardzo składa mi się w całość klasa TiledLayer , ale do w/w wystarczały klasy menadżera warstw (LayerManager) , duszka (Sprite) i płótna gry (GameCanvas) , a zastosowałem dwie klasy wewnętrzne w klasie Animacja która dziedziczy właśnie po klasie GameCanvas , jedna obsługująca ruch w poziomie , druga ruch w pionie. Kod jest dokładnie opisany , zmienne mają intuicyjne nazwy , może komuś się przyda przy rozwijaniu swojej wiedzy dotyczącej Javy. A niedługo wrzucę "Kółko i krzyżyk" napisane w Javie , wykorzystujące klasy Vector i Random z pakietu java.util.
Film (mp4) z działania programu i sama aplikacja jest pod adresem:

http://www.zshare.net/download/595810123e12eee6/

Kod:
Kod: Zaznacz cały

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.game.*;

public class Watki extends MIDlet implements CommandListener
{

private Animacja animacja;
private Display ekran;
public Watki()
   {
    Animacja animacja = new Animacja ();
    Command koniec = new Command ("Koniec" , Command.EXIT , 0);
 
    animacja.addCommand (koniec);
    animacja.setCommandListener (this);
    ekran = Display.getDisplay(this);
    ekran.setCurrent (animacja);

  }

public void startApp() {}
   
public void pauseApp() {}

public void destroyApp (boolean bezwarunkowo) {}

public void commandAction (Command polecenie , Displayable ekran)
      {
       if (polecenie.getCommandType () == Command.EXIT)
          {       
            notifyDestroyed();
          }

      }
}

//klasa Animacja dziedziczy z klasy GameCanvas
 
class Animacja extends GameCanvas

{
//konstruktor
   public Animacja ()
//*
wywolanie konstruktora klasy bazowej (czyli Canvas) , jeśli parametrem jest wartość logiczna true , zdarzenia obsługi klawiatury
dziedziczone z klasy Canvas nie będą obsługiwane , klasa GameCanvas posiada też własną metodę obsługi klawiatury
*//
     { super (true);
//ustawienie trybu pełnoekranowego
       setFullScreenMode (true);
//*
wczytywanie obrazków duszków i tła (też jest obiektem klasy Sprite) z zasobów (res) midletu , ponieważ ta operacja może
wygenerować wyjątek , jest zamknięta w bloku try ... catch
*//
       try
        {
         obrazekDuszka1 = Image.createImage ("/duszek1.png");
         obrazekDuszka2 = Image.createImage ("/duszek2.png");
         obrazekTla =     Image.createImage ("/tlo.png");
        }
       catch (Exception e) {}
// pobranie obiektu "wykreślacza"
       g_buforu = getGraphics();
// utworzenie menadżera warstw
       menadzer_warstw = new LayerManager();
// tworzymy 3 "duszki" z wczytanych wcześniej obrazków o podanych wymiarach
       duch1 = new Sprite ( obrazekDuszka1 , 30 ,30);
       duch2 = new Sprite ( obrazekDuszka2 , 30 ,30);
       tlo =   new Sprite ( obrazekTla , 968 , 640);
// ustawienie pozycji tła w odniesieniu do lewego górnego rogu wyświetlacza
       tlo.setPosition (0,0);
       
//*
dodanie do menadżera warstw każdego duszka z których każdy jest osobną warstwą. Warstwy należy nakładać w odpowiedniej kolejności ,
jeśli najpierw dodalibyśmy tło , duszki byłby rysowane pod tłem , czyli nie byłoby ich widać
*//       
       menadzer_warstw.append(duch1);
       menadzer_warstw.append(duch2);
       menadzer_warstw.append  (tlo);

//*
utworzenie wątków. Są to obiekty typu interfejsowego o nazwie watek_poziomy1 i watek_pionow1 , z parametrami przekazywanymi
do konstruktora , odpowiednio: obiekt duszka (klasy Sprite) , opoznienie , polożenie x,y oraz kierunek ruchu
*//
       Runnable watek_poziomy = new WatekPoziomy (duch1 ,0 , 10 , 20 , 1 );
       Runnable watek_pionowy = new WatekPionowy (duch2 ,0 , 50 , 10  , -1 );
// uruchomienie wątków
       new Thread (watek_poziomy).start();
       new Thread (watek_pionowy).start();
       
     }
     

//*
na rzecz obiektu menadzera warstw (klasy LayerManager) wywoływana jest metoda paint odrysowująca wszystkie elementy
, ale dopiero po wywołaniu metody flushGraphics , zawartość bufora jest "spłukiwana"/flush na ekran
*//
   public void paint (Graphics g)
     { 
       menadzer_warstw.paint (g,0,0);
       flushGraphics();
     }
// klasa wewnętrzna WatekPopziomy implementująca interfejs Runnable   
    class WatekPoziomy implements Runnable
    {
     public WatekPoziomy (Sprite poziomy_duch , int opoznienie , int x , int y , int dx)
      {
// inicjalizacja składowych klasy WatekPoziomy
       this.poziomy_duch = poziomy_duch;
       this.poziomy_opoznienie = opoznienie;
       this.poziomy_x = x;
       this.poziomy_dx = dx;
       poziomy_petla = 0;
// ustawienie duszka w porządanej pozycji
       poziomy_duch.setPosition (x,y);
      }
//*
metoda run która musi być zaimplementowana , ponieważ klasa implementuje interfejs Runnable
a która zdefiniuje nam działanie wątku
*//
      public void run()
         
           {
// petla będzie miała przebieg 5000
             while (poziomy_petla<5000)

              {
//*
metoda move przesuwa duszka. Jej argumentem nie są współrzędne ekranu , a wartość w pikselach  o jaką chce się przesunąć duszka w
stosunku do starej pozycji,
w tym wypadku jest on przesuwany co jeden piksel w lewo (-1) lub prawo (+1)
                poziomy_duch.move (poziomy_dx , 0);
// odmalowanie
                paint(g_buforu);
// jeśli duszek dojdzie do lewej krawędzi , zmienna opisująca kierunek ruchu przyjmie wartość +1
                if (poziomy_x<1) {poziomy_dx = +1;}
// a jeśli dojdzie do prawej , przyjmie -1
                if (poziomy_x>getWidth()-30) {poziomy_dx = -1;}

                poziomy_x = poziomy_x+poziomy_dx;
// usypianie wątku  (opóźnianie) , statyczna metoda sleep może wygenerować wyjątek , stąd blok try ... catch             
                 try
                  {
                   Thread.sleep (poziomy_opoznienie);
                  }
                  catch (Exception e)
                  {
                  }
               
              }
           }
// składowe klasy
     private Sprite poziomy_duch;
     private int poziomy_x;
     private int poziomy_opoznienie;
     private int poziomy_dx;
     private int poziomy_petla;
     }

//*
To druga klasa wewnętrzna , która jest odpowiedzialna za obsługę wątku pionowego , działanie analogiczne jak
klasy powyżej tylko w ciele metody run sprawdza dojście duszka do górnej i dolnej krawędzi ekranu
class WatekPionowy implements Runnable
*//
    {
     public WatekPionowy (Sprite pionowy_duch , int opoznienie , int x , int y ,int dy)
      {
       this.pionowy_duch = pionowy_duch;
       this.pionowy_opoznienie = opoznienie;
       this.pionowy_y = y;
       this.pionowy_dy = dy;
       pionowy_petla = 0;
       pionowy_duch.setPosition (x , y);
      }
      public void run()
         
           {
             while (pionowy_petla<5000)

              {  pionowy_duch.move (0 , pionowy_dy);
                 paint(g_buforu);
                 
                 if (pionowy_y<1) {pionowy_dy = +1;}
                 if (pionowy_y>getHeight()-30) {pionowy_dy = -1;}         
                 pionowy_y = pionowy_y+pionowy_dy;
                 try
                  {
                   Thread.sleep (pionowy_opoznienie);
                  }
                  catch (Exception e)
                  {
                  }
               
              }
           }
     private Sprite pionowy_duch;
     private int pionowy_y;
     private int pionowy_opoznienie;
     private int pionowy_dy;
     private int pionowy_petla;
     }
// składowe klasy zewnętrznej czyli Animacja
private LayerManager menadzer_warstw;
private Image obrazekDuszka1;
private Image obrazekDuszka2;
private Image obrazekTla;
private Sprite duch1;
private Sprite duch2;
private Sprite tlo;
private Graphics g_buforu;
}

issa
10%
10%
 
Posty: 49
Dołączył(a): 11 sierpnia 2006, o 20:13
    WindowsXPFirefox

Powrót do Od czego zacząć?

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość

cron