• Nie Znaleziono Wyników

Przykład aplikacji z animacją – symulacja kuli bilardowej

N/A
N/A
Protected

Academic year: 2021

Share "Przykład aplikacji z animacją – symulacja kuli bilardowej "

Copied!
4
0
0

Pełen tekst

(1)

Laboratorium z informatyki sem. II/ćw. 12 Wydział Transportu PW - 2020/21

Materiały do użytku wewnętrznego strona 1

I

NSTRUKCJA DO

Ć

WICZENIA

12

I

Przykład aplikacji z animacją – symulacja kuli bilardowej

1. Utwórz nowy projekt typu Java Class Library zapisz go w folderze roboczym pod nazwą Projekt12a. Dodaj do projektu klasę typu JFrame o nazwie Animacja1.

2. Ustal rozmiary ramki na 600×400 oraz kolor tła na żółty (metody setSize() i setBackground()), w tytule ramki wpisz animacja kuli bilardowej.

3. Do projektu dodaj nową zewnętrzną klasę Javy o nazwie Kula (Kliknij prawym przyciskiem myszy na nazwie projektu i wybierz z menu podręcznego polecenie New/Java Class; klasę Kula umieść w tym samym pakiecie co klasę Animacja1) W klasie Kula umieść poniższe deklaracje pól, oznaczających

kolor kuli, współrzędne położenia i średnicę kuli oraz składowe prędkości ruchu:

Color kolor;

int x = 0, y = 30, d = 20, dx = 3, dy = 5;

4. W klasie Kula dopisz konstruktor, tworzący kulę o danym położeniu i kolorze:

public Kula(int x0, int y0, Color k) { x = x0;

y = y0;

kolor = k;

}

5. Dopisz w klasie Kula metodę rysuj (), która na kanwie obiektu graficznego rysuje koło wpisane w kwadrat o lewym górnym wierzchołku (x, y) i boku d:

void rysuj(Graphics g){ // klasa Graphics wymaga importu g.setColor(kolor);

g.fillOval(x, y, d, d);

}

6. Dopisz w klasie Kula metodę przesuń (), zmieniającą położenie kuli o wektor (dx, dy) i zmieniającą kierunek ruchu, jeśli kula dotarła do brzegu okna:

void przesuń(int zakresX, int zakresY) { x += dx;

y += dy; // zmiana położenia – przesunięcie o (dx, dy) if (x >= zakresX - d || x <= 0) {

dx = -dx; } // odbicie od krawędzi okna – zmiana kierunku ruchu if (y >= zakresY - d || y <= 30) {

dy = -dy;}

}

7. Pod nagłówkiem klasy Animacja1 zadeklaruj obiekt K klasy Kula:

Kula K;

W konstruktorze klasy Animacja1 utwórz ten obiekt instrukcją:

K = new Kula(10,30, Color.red);

8. Utwórz w klasie Animacja1 metodę graficzną paint (), zawierającą instrukcje przesuwające kulę i rysujące jej nowe położenie:

public void paint(Graphics g) { super.paint(g);

g.clearRect(0, 0, getWidth(), getHeight());

K.przesuń(getWidth(), getHeight());

K.rysuj(g);

}

9. Uruchom aplikację; zaobserwuj zmianę położenia kuli przy zmianie rozmiarów okna.

10. UWAGA!! Jeśli obraz animacji zacznie migotać, należy całą grafikę rysować w buforze graficznym, a następnie utworzony obraz odrysować na kontekście graficznym g metodą drawImage. Należy postąpić według poniższych wskazówek:

1. Pod nagłówkiem klasy głównej zadeklaruj obiekt klasy Image oraz Graphics:

Image obraz;

Graphics bufor ; // obraz, bufor - posłużą do ilustracji graficznej

2. W konstruktorze klasy głównej utwórz obraz graficzny o rozmiarach ramki , a na zmienną bufor pobierz kontekst graficzny utworzonego obrazu:

obraz=createImage(getWidth(),getHeight());

bufor=obraz.getGraphics();

3. W treści metody paint wszystkie metody graficzne wywołaj wykorzystując obiekt graficzny bufor, zamieniając parametr g na bufor. A następnie odrysuj utworzony obraz utworzony w buforze i uruchom aplikację. Po zmianach metoda paint ma postać:

public void paint(Graphics g) { super.paint(bufor);

bufor.clearRect(0, 0, getWidth(), getHeight());

W.wychyl();

W.rysuj(bufor);

g.drawImage(obraz, 0, 0, this); }

(2)

Laboratorium z informatyki sem. II/ćw. 12 Wydział Transportu PW - 2020/21

Materiały do użytku wewnętrznego strona 2

II

Animacja ruchu kuli

1. W klasie Animacja1 zaimplementuj interfejs ActionListener - przed nawiasem rozpoczynającym definicję klasy

Animacja1 dopisz: implements ActionListener

2. Zaimportuj ten interfejs, a następnie lewym przyciskiem myszy kliknij ikonę żarówki po lewej stronie nagłówka klasy Animacja1 i wybierz polecenie Implement all abstract metods . Zostanie wygenerowana metoda

actionPerformed(), która automatycznie będzie się wykonywała, co czas określony przez obiekt klasy Timer (obiekt ten zostanie utworzony w punkcie 4) .

3. Usuń z metody actionPerformed(), instrukcję throw … wyrzucającą wyjątek i wpisz instrukcję, która co czas określony przez obiekt klasy Timer „przemalowuje” okno ramki naszej aplikacji

repaint();

4. Pod nagłówkiem klasy Animacja 1 zadeklaruj pole timer klasy Timer , posłuży ono do generowania zdarzeń w stałych odstępach czasu; zaimportuj klasę javax.swing.Timer, wybierając odpowiednią klasę w dialogu Fix Imports:

Timer timer = new Timer(10, this); //zegar tykający co 10 ms

5. Dopisz w konstruktorze klasy Animacja1

instrukcję, która uruchamiania zegara:

timer.start(); //uruchomienie zegara

6. Uruchom aplikację i zaobserwuj animację jako wynik obsługi zdarzeń zegara

III

Animacja wielu kul – zastosowanie tablicy dynamicznej typu ArrayList oraz interfejsu myszy

Zmodyfikujemy aplikację Animacja1 tak, aby symulować ruch wielu kul. Kolejna kula powstaje w miejscu wskazanym kursorem myszy. Wszystkie obiekty klasy Kula będą zapisywane na dynamicznej liście. Ruch każdej kuli jest niezależny od pozostałych, nie rozpatrujemy zderzeń a jedynie odbicia od brzegów okna.

1. Utwórz kopię projektu Projekt12a o nazwie Projekt12b (Kiliknij prawy przyciskiem myszy na nazwie projektu i wybierz polecenie copy; wybierz miejsce docelowe projektu i odpowiednio zmień jego nazwę). Zmień nazwę klasy głównej na Animacja2, następnie otwórz ją w edytorze NetBeans i zmień tytuł ramki na Animacja kul bilardowych – zastosowanie myszy. Klasę Animacja2 zmodyfikuj w opisany dalej sposób.

2. Pod nagłówkiem klasy Animacja2 zadeklaruj dynamiczną tablicę kul

List< Kula> LK = new ArrayList< >();

Zaimportuj klasy List i ArrayList z pakietu java.util.

3. W treści metody paint (), istniejące instrukcje przesuwania i rysowania kuli umieść w pętli, aby były wykonywane dla wszystkich kul:

for(Kula K : LK){

K. przesuń(getWidth(),getHeight());

K.rysuj(g);

}

4. Aby na ramce umożliwić tworzenie kul za pomocą myszy, doprowadź nagłówek klasy Animacja2 do postaci public class Animacja2 extends javax.swing.JFrame implements ActionListener, MouseListener Zaimportuj ten interfejs, utwórz wszystkie jego abstrakcyjne metody, usuń w nich instrukcje throw … wyrzucające wyjątek, a metodę mousePressed() uzupełnij do postaci:

public void mousePressed(MouseEvent e) { int x=e.getX(); int y=e.getY();

if (e.getButton() == MouseEvent.BUTTON1) {

K = new Kula(x, y, Color.red); // tworzenie kuli lewym przyciskiem myszy LK.add(K);

} else {

LK.clear(); } //usuwanie wszystkich kul prawym lub środkowym przyciskiem myszy }

5. W konstruktorze klasy Animacja2 usuń instrukcję tworzącą pojedynczą kulę oraz dopisz instrukcję dodającą nasłuch akcji:

addMouseListener(this);

6. Uruchom aplikację i sprawdź działanie przycisków myszy.

IV Przykład aplikacji z animacją - tworzenie obrazu wahadła

1. Utwórz nowy projekt typu Java Class Library pod nazwą Projekt12c i zapisz go w folderze roboczym; dodaj do niego klasę typu JFrame o nazwie Animacja3.

2. Wpisz tytuł ramki Animacja ruchu wahadła matematycznego i ustal jej rozmiary na 600×400,

3. Do projektu dodaj nową klasę Javy o nazwie Wahadło. W klasie Wahadło,

poniżej nagłówka klasy, dodaj następujące deklaracje zmiennych:

double t; // czas

double alfa0, alfa; // początkowy i bieżący kąt wychylenia double dt = 0.004; // przyrost czasu

int x0, y0; // współrzędne punktu zaczepienia wahadła

int d; // długość nitki

Color kolor; // kolor ciężarka

(3)

Laboratorium z informatyki sem. II/ćw. 12 Wydział Transportu PW - 2020/21

Materiały do użytku wewnętrznego strona 3

4. W klasie Wahadło utwórz konstruktor o sygnaturze Wahadło(int xp, int yp, int dl, Color k) i w jego treści wpisz instrukcje przypisujące odpowiednim polom wartości początkowe, podane jako parametry konstruktora:

public Wahadło(int xp, int yp, int dl, Color k){

x0=xp; y0=yp; d = dl; kolor = k;

}

5. W klasie Wahadło utwórz metodę rysuj(), która rysuje wahadło na kanwie obiektu graficznego:

void rysuj(Graphics g){

g.setColor(kolor);

int x=x0+(int)(d*Math.sin(alfa)); // x, y – współrzędne położenia ciężarka wahadła int y=y0+(int)(d*Math.cos(alfa));

g.drawLine(x0, y0, x,y); // linia od punktu x0, y0 do punktu x, y

g.fillOval(x-10, y-10, 20, 20); } // koło o średnicy 20, ze środkiem w punkcie x, y

6. Pod nagłówkiem klasy Animacja3 zadeklaruj obiekt W klasy Wahadło:

Wahadło W;

7. Na końcu konstruktora klasy dodaj instrukcję tworzącą obiekt klasy Wahadło i przypisującą go zmiennej W

W = new Wahadło(getWidth() / 2, 30, 250, Color.blue);

8. Utwórz w klasie Animacja3 klasę metodę graficzną paint(), zawierającą instrukcje rysujące tło i wahadło:

public void paint(Graphics g) { super.paint(g);

g.clearRect(0, 0, getWidth(), getHeight());

W.rysuj(g); }

9. Uruchom aplikację.

V

Symulacja ruchu wahadła

1. W klasie Wahadło dopisz metodę start(), która określa początkowy kąt wychylenia wahadła:

void start() { t=0;

alfa0 = alfa;

}

Następnie dopisz metodę wychyl(), zmieniającą kąt wychylenia w zależności od czasu i kąta początkowego:

void wychyl() { if (alfa0 != 0) {

t+=dt; // przyrost czasu o wartość dt

alfa=alfa0*Math.cos(Math.sqrt(981/d/0.0375)*t); //równanie wahadła matematycznego

}} // 0.0375 współczynnik zamiany pikseli na centymetry

Ponadto dopisz metodę zmień (), zmieniającą kąt wychylenia wahadła o wartość parametru da (w radianach) i zmieniającą długość nitki o wartość parametru dl (w pikselach):

void zmień(double da, int dl) { alfa = alfa + da; alfa0 = 0;

d += dl;

if (d<10) d=10; // minimalna długość nitki wynosi 10 }

2. W klasie Animacja3, na końcu metody konstruktora, dopisz instrukcje ustawienia początkowego wychylenia wahadła równego Π/3 i wywołania metody start()

W.zmień( Math.PI/3, 0 );

W.start();

3. Uruchom aplikację i zaobserwuj nowe położenie początkowe wahadła

4. W metodzie paint(), przed metodą rysującą wahadło, dodaj wywołanie metody zmieniającej jego położenie w czasie:

W.wychyl();

5. Uruchom aplikację; zaobserwuj zmianę położenia wahadła przy zmianie rozmiarów okna.

6. Aby zmiana położenia wahadła następowała automatycznie, w klasie Animacja3 zaimplementuj interfejs

ActionListener - przed nawiasem rozpoczynającym definicję klasy dopisz: implements ActionListener

7. Zaimportuj ten interfejs, a następnie lewym przyciskiem myszy kliknij ikonę żarówki po lewej stronie nagłówka klasy Animacja3 i wybierz polecenie Implement all abstract metods. Zostanie wygenerowana metoda

actionPerformed(), która automatycznie będzie się wykonywała, co czas określony przez obiekt klasy Timer (obiekt ten zostanie utworzony w punkcie 9) . Usuń z niej instrukcję throw … wyrzucającą wyjątek.

8. Wpisz treść metody actionPerformed(), która co czas określony przez obiekt klasy Timer „przemalowuje” ramkę:

repaint();

9. W klasie Animacja3 zadeklaruj pole timer klasy Timer , posłuży ono do generowania zdarzeń w stałych odstępach czasu; zaimportuj klasę javax.swing.Timer, wybierając odpowiednią klasę w dialogu Fix Imports:

Timer timer = new Timer(10, this); //zegar tykający co 10 ms

10. Dopisz w konstruktorze klasy Animacja3

instrukcję uruchamiającą zegar:

timer.start(); //uruchomienie zegara

(4)

Laboratorium z informatyki sem. II/ćw. 12 Wydział Transportu PW - 2020/21

Materiały do użytku wewnętrznego strona 4

11. Uruchom aplikację i zaobserwuj animację jako wynik obsługi zdarzeń zegara

Uwaga jeśli obraz animacji będzie migotał należy rysować grafikę w buforze graficznym i postąpić zgodnie ze wskazówkami zamieszczonymi w punkcie I.10 instrukcji

VI

Zmiana kąta wychylenia początkowego i długości nitki za pomocą klawiatury

1. Aby umożliwić zmiany kąta wychylenia wahadła i długości nitki za pomocą klawiszy strzałek ← → ↑ ↓, dodaj do nagłówka klasy Animacja3 kolejny interfejs o nazwie KeyListener. Doprowadź nagłówek tej klasy do postaci:

public class Animacja3 extends javax.swing.JFrame implements ActionListener, KeyListener . Zaimportuj ten interfejs, utwórz wszystkie jego abstrakcyjne metody, usuń w nich instrukcje throw wyrzucające wyjątek.

Metody keyPressed() i keyReleased()uzupełnij do postaci:

public void keyPressed(KeyEvent e) { int a = e.getKeyCode();

if (a == KeyEvent.VK_RIGHT) { W. zmień (0.05, 0); } // zmiana kąta wychylenia o 0.05 radiana if (a == KeyEvent.VK_LEFT) { W.zmień (-0.05, 0); }

if (a == KeyEvent.VK_UP) { W.zmień (0, -2); } // zmiana długości nitki o 2 piksele if (a == KeyEvent.VK_DOWN) { W.zmień (0, 2); }

}

public void keyReleased(KeyEvent e) {//uruchomienie wahadła po zwolnieniu przycisku int a = e.getKeyCode();

if (a == KeyEvent.VK_RIGHT || a == KeyEvent.VK_LEFT

|| a == KeyEvent.VK_UP || a == KeyEvent.VK_DOWN) { W.start();}

}

2. W metodzie konstruktora klasy Animacja3 usuń wywołania metod zmień() i start() i dodaj instrukcję umożliwiającą obsługę klawiatury i instrukcję dodającą nasłuch:

setFocusable(true);

addKeyListener(this);

3. Uruchom aplikację i sprawdź reakcję na klawisze strzałek.

4. Aby umożliwić zatrzymywanie wahadła za pomocą przycisku spacji, dopisz w klasie Wahadło metodę:

void stop() {

alfa0 = 0; alfa = 0;

}

5. Samodzielnie dopisz w metodzie keyPressed() odpowiednią instrukcję powodującą zatrzymanie wahadła po naciśnięciu klawisza spacji (VK_SPACE). Uruchom aplikację i sprawdź możliwość zatrzymywania wahadła.

Zadania do samodzielnego wykonania

1. Zmiana koloru kuli. Zmodyfikuj klasę Animacja1 tak, aby przy odbiciu kuli od krawędzi okna kolor kuli zmieniał się na losowy odcień czerwieni.

Wskazówka: W klasie Kula zadeklaruj pole służące do generowania liczb losowych (pamiętaj o imporcie klasy Random):

Random r = new Random();

W metodzie przesuń() dopisz w odpowiednim miejscu instrukcję zmieniającą wartość pola kolor:

kolor=new Color(r.nextInt(256), 0, 0);

2. Różne kolory kul. Zmodyfikuj klasę Animacja2 tak, aby każda nowa kula miała losowy kolor.

Wskazówka: Kolor nowej kuli może być losowany w klasie Animacja2, przed wywołaniem konstruktora klasy Kula

w metodzie mousePressed(). W klasie Animacja2 należy zadeklarować pole klasy Random (p.zadanie 1).

3. Losowe parametry wahadła. Zmodyfikuj Projekt12c tak, aby zamiast klawiszy strzałek użyć klawisza Enter (VK_ENTER) do uruchamiania wahadła o losowym wychyleniu początkowym.

Wskazówka: W klasie Animacja3 zmodyfikuj treść metody keyPressed() i keyReleased()– usuńwszystkie instrukcje dotyczące klawiszy strzałek. Przy wciśnięciu klawisza Enter zatrzymuj wahadło, przy zwolnieniu klawisza Enter

zmień kąt wychylenia na losową wartość z zakresu (-Π/3 , Π/3 ) i uruchom wahadło.

4. Wesoły bałwan. Utwórz nową aplikację z ruchomym bałwankiem, rysowanym na ramce za pomocą kilku elips, odcinka i prostokąta (jak na rysunku obok).

Bałwanek porusza się pionowo od środka dolnej krawędzi okna do połowy wysokości, po czym zawraca do dołu okna, gdzie rozpoczyna kolejny ruch do góry itd.

Wskazówka: Wzorując się na symulacji kuli bilardowej utwórz nową aplikację lub skopiuj Projekt12a i zmodyfikuj jego treść. W metodzie rysuj() wpisz instrukcje, które zamiast jednego koła pozwolą narysować złożoną figurę. Wybierz jeden punkt (x, y), będący punktem odniesienia dla rysowanych figur. Odpowiednio zmodyfikuj warunek zmiany kierunku ruchu.

Cytaty

Powiązane dokumenty

Dźwięk pukania sygnalizuje inne połączenie przychodzące podczas trwania rozmowy. Wskazy- wany jest numer lub imię osoby dzwoniącej, jeżeli włączona jest identyfikacja

Możesz po położeniu w ten sposób karty na stos Tła zagrać z ręki kolejną kartę na Tło (wykonując w ten sposób, opisaną w rozdziale Ogólne reguły, akcję nr 3: zagraj

Numer telefonu osoby dzwoniącej jest widoczny na wyświetlaczu. Bez wpisu do sieciowej książki telefonicznej i bez usługi Smart Call Block Jeżeli numer osoby dzwoniącej jest zapisany

Związki w zdaniu dzielą się na te, które tworzą grupę podmiotu i grupę orzeczenia.. Podmiot razem z określeniami to

Jeśli urządzenie zewnętrzne zostanie podłączone poprzez gniazdo SCART, TV automatycznie przełączy się na tryb AV.Podczas oglądania kanałów DTV (Mpeg4 H.264) lub w

Przy włączonej niani elektronicznej zapisany numer (wewnętrzny lub zewnętrzny) zostaje wywołany, gdy tylko w otoczeniu słuchawki zostanie przekroczony określony poziom hałasu.

Dodatkowo sterownik pozwala na kontrolę temperatury kotła, powrotu, temperatury obwodu centralnego ogrzewania (CO), temperatury ciepłej wody użytkowej (CWU), temperatury pokojowej

Przycisną´c przycisk „PROG” nadajnika, zapisanego już w pamięci odbiornika i trzyma´c przez 3 sekundy (czeka´c aż lampka kontrolna nadawania zamiga jeden raz). Po wykonaniu tej