Guest User

Untitled

a guest
Jun 24th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.85 KB | None | 0 0
  1. import java.awt.*;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import java.io.IOException;
  5. import java.net.URL;
  6. import java.util.*;
  7. import javax.swing.*;
  8. import javax.sound.sampled.*;
  9.  
  10.  
  11. public class GUI extends JFrame implements ActionListener {
  12.  
  13. /**
  14. * Her ligger spillebrikkene
  15. */
  16. private ImagePanel hovedPanel;
  17. /**
  18. * Viser tid og poeng nederst
  19. */
  20. private JPanel statusPanel;
  21. /**
  22. * 'Nytt spill' knapp og størrelsesvalg
  23. */
  24. private JPanel kontrollPanel;
  25. /**
  26. * Knapper for å starte nytt spill
  27. */
  28. private JButton nytt, igjen;
  29. /**
  30. * Størrelsesvalg
  31. */
  32. private JRadioButton small, medium, large, xlarge;
  33. /**
  34. * Vise tid og antall brikker
  35. */
  36. private JLabel antall, tid;
  37. /**
  38. * For å finne X og Y til knappen som ble trykket
  39. */
  40. private Map<Object, Integer> xMap;
  41. private Map<Object, Integer> yMap;
  42. /**
  43. * Liste over alle aktive brikker
  44. */
  45. private ArrayList<GUIBrikke> brikker;
  46. /**
  47. * Referanse til spillet
  48. */
  49. private ISpill spill;
  50. /**
  51. * Vekker oss hvert halve sekund
  52. */
  53. private javax.swing.Timer timer;
  54.  
  55. /**
  56. * Katalog hvor GUI-en leter etter bilder (relativt til hvor klassefilene ligger)
  57. */
  58. public static String bildeSti = "images/";
  59.  
  60. /**
  61. * Oppretter en ny spill-GUI
  62. * @param spill Spillet som skal kontrolleres
  63. */
  64. public GUI(ISpill spill) {
  65. super("Memo");
  66.  
  67. this.spill = spill;
  68. timer = new javax.swing.Timer(500, this); // vekk oss hvert 500 millisekund
  69.  
  70. kontrollPanel = new JPanel();
  71. hovedPanel = new ImagePanel(bildeSti + "bakgrunn.jpg");
  72. statusPanel = new JPanel();
  73.  
  74. add(kontrollPanel, BorderLayout.NORTH);
  75. add(hovedPanel,BorderLayout.CENTER);
  76. add(statusPanel, BorderLayout.SOUTH);
  77.  
  78. nytt = new JButton("Nytt Spill");
  79. nytt.addActionListener(this);
  80. small = new JRadioButton("S", false);
  81. medium = new JRadioButton("M", true);
  82. large = new JRadioButton("L", false);
  83. xlarge = new JRadioButton("XL", false);
  84.  
  85. ButtonGroup g = new ButtonGroup();
  86. g.add(small);
  87. g.add(medium);
  88. g.add(large);
  89. g.add(xlarge);
  90.  
  91. kontrollPanel.add(nytt);
  92. kontrollPanel.add(new JLabel("Brettstørrelse:"));
  93. kontrollPanel.add(small);
  94. kontrollPanel.add(medium);
  95. kontrollPanel.add(large);
  96. kontrollPanel.add(xlarge);
  97.  
  98. antall = new JLabel("Brikker: 0");
  99. tid = new JLabel("Tid: 0:00");
  100. statusPanel.add(antall);
  101. statusPanel.add(tid);
  102.  
  103. lagBrett(spill.nyttSpill(Vanskelighet.MEDIUM));
  104.  
  105. pack();
  106. setVisible(true);
  107. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  108.  
  109.  
  110.  
  111. }
  112.  
  113. /**
  114. * Lager et nytt spillbrett på hovedpanelet
  115. *
  116. * @param brett En 2D-tabell med brikker
  117. */
  118. private void lagBrett(ITabell2D<IBrikke> brett) {
  119. xMap = new HashMap<Object, Integer>();
  120. yMap = new HashMap<Object, Integer>();
  121. brikker = new ArrayList<GUIBrikke>();
  122. hovedPanel.removeAll();
  123. hovedPanel.setLayout(new GridLayout(brett.høyde(), brett.bredde()));
  124. for(int x = 0; x < brett.bredde(); x++)
  125. for(int y = 0; y < brett.høyde(); y++) {
  126. JPanel p = new JPanel();
  127. GUIBrikke b = new GUIBrikke(brett.hent(x, y), "bakside.jpg");
  128. brikker.add(b);
  129. b.addActionListener(this);
  130. p.add(b);
  131. p.setOpaque(false);
  132. hovedPanel.add(p);
  133. xMap.put(b, x);
  134. yMap.put(b, y);
  135. }
  136. timer.start();
  137. hovedPanel.settBilde(bildeSti + spill.bakgrunnsBilde());
  138. pack();
  139. }
  140.  
  141. /**
  142. * Går gjennom og oppdaterer grafikken til alle brikkene, og viser oppdatert informasjon i displayet
  143. */
  144. private void oppdater() {
  145. boolean delay = false;
  146. for(GUIBrikke b : brikker)
  147. delay |= b.oppdater();
  148. if(delay)
  149. timer.start();
  150. antall.setText(String.format("Brikker: %d", spill.antall()));
  151. tid.setText(String.format("Tid: %d:%02d", spill.tid()/60, spill.tid()%60));
  152. hovedPanel.settBilde(bildeSti + spill.bakgrunnsBilde());
  153.  
  154. }
  155. /**
  156. * Denne blir kalt av Java hver gang brukeren trykker på en knapp, eller hver gang
  157. * timer-signalet avfyres.
  158. *
  159. * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
  160. */
  161. @Override
  162. public void actionPerformed(ActionEvent e) {
  163. if(e.getSource() == nytt || e.getSource() == igjen) {
  164. Vanskelighet v = Vanskelighet.MEDIUM;
  165. if(small.isSelected())
  166. v = Vanskelighet.SMALL;
  167. else if(medium.isSelected())
  168. v = Vanskelighet.MEDIUM;
  169. else if(large.isSelected())
  170. v = Vanskelighet.LARGE;
  171. else if(xlarge.isSelected())
  172. v = Vanskelighet.XLARGE;
  173. lagBrett(spill.nyttSpill(v));
  174. }
  175. else if(e.getSource() == timer) {
  176. //timer.stop();
  177. oppdater();
  178. }
  179. else {
  180. int x = xMap.get(e.getSource());
  181. int y = yMap.get(e.getSource());
  182.  
  183. if(spill.velg(x, y))
  184. oppdater();
  185. else
  186. vunnet();
  187. }
  188. }
  189.  
  190. /**
  191. * Vis vinnertekst og be brukeren spille en gang til
  192. */
  193. private void vunnet() {
  194. hovedPanel.settBilde(bildeSti + spill.bakgrunnsBilde());
  195. hovedPanel.removeAll();
  196. hovedPanel.setLayout(new GridLayout(4,1));
  197. JPanel p = new JPanel();
  198. p.setOpaque(false);
  199. igjen = new JButton("En gang til?");
  200. igjen.addActionListener(this);
  201. igjen.setOpaque(false);
  202. p.add(igjen);
  203. JLabel l = new JLabel(spill.sluttTekst());
  204. l.setHorizontalAlignment(SwingConstants.CENTER);
  205. l.setForeground(Color.WHITE);
  206. l.setOpaque(false);
  207. JPanel p1 = new JPanel();
  208. p1.setOpaque(false);
  209. JPanel p2 = new JPanel();
  210. p2.setOpaque(false);
  211. hovedPanel.add(p1);
  212. hovedPanel.add(l);
  213. hovedPanel.add(p);
  214. hovedPanel.add(p2);
  215. timer.stop();
  216. validate();
  217. }
  218.  
  219. }
  220. class ImagePanel extends JPanel {
  221.  
  222. private Image img;
  223. private String imgNavn;
  224. private int w;
  225. private int h;
  226.  
  227. public ImagePanel(String bilde) {
  228. super();
  229. settBilde(bilde);
  230. Dimension size = new Dimension(w, h);
  231. setSize(size);
  232. }
  233. public void settBilde(String bilde) {
  234. if(!bilde.equals(imgNavn)) {
  235. System.out.println(bilde);
  236. img = new ImageIcon(getClass().getResource(bilde)).getImage();
  237. w = img.getWidth(null);
  238. h = img.getHeight(null);
  239. imgNavn = bilde;
  240. validate();
  241. }
  242. }
  243.  
  244. public void paintComponent(Graphics g) {
  245. int gw = this.getWidth();
  246. int gh = this.getHeight();
  247. int iw = w;
  248. int ih = h;
  249. int ix = 0, iy = 0;
  250. if(iw-gw > 20 || ih-gh > 20) {
  251. if((double)gw/gh > (double)iw/ih) {
  252. ih = (int)((double)iw*(double)gh/(double)gw);
  253. iy = (h-ih)/2;
  254. }
  255. else {
  256. iw = (int)((double)ih*(double)gw/(double)gh);
  257. ix = (w-iw)/2;
  258. }
  259. }
  260. else {
  261. if(iw > gw) {
  262. ix = (gw-iw)/2;
  263. iw = gw;
  264. }
  265. if(ih > gh) {
  266. iy = (gh-ih)/2;
  267. ih = gh;
  268. }
  269. }
  270. g.drawImage(img, 0, 0, gw-1, gh-1, ix, iy, iw-1, ih-1, null);
  271. }
  272.  
  273. }
  274.  
  275.  
  276. ----------------------------------------------------------------------------
  277. import java.awt.Insets;
  278.  
  279. import javax.swing.ImageIcon;
  280. import javax.swing.JButton;
  281.  
  282.  
  283. public class GUIBrikke extends JButton {
  284. private static final long serialVersionUID = -7919110561211386669L;
  285. private ImageIcon åpen;
  286. private ImageIcon lukket;
  287. IBrikke brikke;
  288.  
  289. public GUIBrikke(IBrikke brikke, String lukketBilde) {
  290. super();
  291. this.brikke = brikke;
  292. setContentAreaFilled(false);
  293. åpen = new ImageIcon(getClass().getResource(GUI.bildeSti + brikke.bilde()));
  294. lukket = new ImageIcon(getClass().getResource(GUI.bildeSti + lukketBilde));
  295. oppdater();
  296. setMargin(new Insets(0,0,0,0));
  297. }
  298. public boolean oppdater() {
  299. if(isVisible()) {
  300. if(brikke.erÅpen())
  301. setIcon(åpen);
  302. else
  303. setIcon(lukket);
  304.  
  305. if(!isEnabled())
  306. setVisible(false);
  307.  
  308. if(!brikke.erAktiv()) {
  309. setEnabled(false);
  310. this.setDisabledIcon(åpen);
  311. return true;
  312. }
  313. }
  314. return false;
  315. }
  316. }
  317. ----------------------------------------------------------------------------
  318. /**
  319. * Kontrakt for spillbrikker.
  320. *
  321. * GUI-en bruker en del av metodene under for å finne ut hvordan brikken skal
  322. * tegnes; resten vil være nyttig i resten av spillimplementasjonen.
  323. *
  324.  
  325. */
  326. public interface IBrikke {
  327.  
  328. /**
  329. * @return True om brikken er 'åpen' (viser bildet sitt)
  330. */
  331. public abstract boolean erÅpen();
  332.  
  333. /**
  334. * @return True om brikken ikke er fjernet fra spillet
  335. */
  336. public abstract boolean erAktiv();
  337.  
  338. /**
  339. * Setter brikken til å være lukket. (=> erÅpen() == false)
  340. */
  341. public abstract void lukk();
  342.  
  343. /**
  344. * Setter brikken til å være åpen. (=> erÅpen() == true)
  345. */
  346. public abstract void åpne();
  347.  
  348. /**
  349. * Setter brikken til å være fjernet. (=> erAktiv == false)
  350. */
  351. public abstract void fjern();
  352.  
  353. /**
  354. * Bilde (PNG, JPG, GIF, ...) for brikken. Bør være 75x100 piksler stort.
  355. *
  356. * @return Navn på billedfil som viser brikkens bilde (i åpen tilstand).
  357. */
  358. public abstract String bilde();
  359.  
  360. /**
  361. * @param b Brikke vi skal sammenlikne med
  362. * @return True om brikken representerer samme symbol som 'b'
  363. */
  364. public abstract boolean erLik(IBrikke b);
  365.  
  366. /**
  367. * @return Brikkens symbol (to brikker er like om getId() gir like strenger)
  368. */
  369. public abstract String getId();
  370.  
  371. }
  372.  
  373.  
  374. ----------------------------------------------------------------------------
  375.  
  376.  
  377. /**
  378. * Interface for todimensjonale tabeller.
  379.  
  380. * @param <E> Typen til elementene
  381. */
  382. public interface ITabell2D<E> {
  383. /**
  384. * @param x X-posisjon
  385. * @param y Y-posisjon
  386. * @return Elementet på posisjon (x, y)
  387. */
  388. public abstract E hent(int x, int y);
  389.  
  390. /**
  391. * @param x X-posisjon
  392. * @param y Y-posisjon
  393. * @param e Element som skal settes inn på posisjon (x, y)
  394. */
  395. public abstract void sett(int x, int y, E e);
  396.  
  397. /**
  398. * @return Høyde til tabellen (høyeste lovlige X-posisjon + 1)
  399. */
  400. public abstract int høyde();
  401.  
  402. /**
  403. * @return Bredden til tabellen (høyeste lovlige Y-posisjon + 1)
  404. */
  405. public abstract int bredde();
  406.  
  407. /**
  408. * @return En kopi av tabellen, med de samme elementene
  409. */
  410. public abstract ITabell2D<E> clone();
  411. }
  412.  
  413.  
  414. ----------------------------------------------------------------------------
  415.  
  416.  
  417. /**
  418. * Denne enum-klassen definerer fire konstanter: SMALL, MEDIUM, LARGE, XLARGE.
  419. * @author anya
  420. *
  421. */
  422.  
  423. public enum Vanskelighet {
  424. SMALL,
  425. MEDIUM,
  426. LARGE,
  427. XLARGE;
  428.  
  429. /**
  430. * @return Bredden til et brett med denne vanskeligheten
  431. */
  432. public int bredde() {
  433. switch(this) {
  434. case SMALL:
  435. return 6;
  436. case MEDIUM:
  437. return 7;
  438. case LARGE:
  439. return 8;
  440. case XLARGE:
  441. return 9;
  442. }
  443. return 0;
  444. }
  445.  
  446. /**
  447. * @return Høyden til et brett med denne vanskeligheten
  448. */
  449. public int høyde() {
  450. switch(this) {
  451. case SMALL:
  452. return 3;
  453. case MEDIUM:
  454. return 4;
  455. case LARGE:
  456. return 5;
  457. case XLARGE:
  458. return 6;
  459. }
  460. return 0;
  461. }
  462.  
  463. /**
  464. * @return Antall brikker på et brett med denne vanskeligheten
  465. */
  466. public int antall() {
  467. return bredde() * høyde();
  468. }
  469. }
  470.  
  471.  
  472. ----------------------------------------------------------------------------
  473.  
  474. /**
  475. * Kontrakt for memory-spill. GUI-klassen forventer å få et objekt av denne
  476. * typen, som tar hånd om spillmekanikken. Alle metodene under blir kalt fra GUI
  477. * basert på forskjellige hendelser -- som at brukeren trykker på en knapp, for
  478. * eksempel.
  479. *
  480. public interface ISpill {
  481. /**
  482. * Kalles når brukeren vil starte et nytt spill.
  483. *
  484. * @param v
  485. * Vanskelighet -- beskriver bredde og høyde på brettet
  486. * @return Et nytt brett med brikker utplassert.
  487. */
  488. public abstract ITabell2D<IBrikke> nyttSpill(Vanskelighet v);
  489.  
  490. /**
  491. * Kalles når brukeren trykker på en brikke.
  492. *
  493. * 'x' og 'y' er alltid innenfor grensene på det sist returnerte spillbrettet.
  494. *
  495. * @param x
  496. * X-posisjon til brikken
  497. * @param y
  498. * Y-posisjon til brikken
  499. * @return True hvis spillet fremdeles pågår, false hvis spillet nå er
  500. * avsluttet (vunnet)
  501. */
  502. public abstract boolean velg(int x, int y);
  503.  
  504. /**
  505. * Kalles for hvert trekk
  506. *
  507. * @return Antall brikker som er igjen på brettet, for visning i display
  508. */
  509. public abstract int antall();
  510.  
  511. /**
  512. * Kalles med jevne mellomrom
  513. *
  514. * @return Antall sekunder spillet har pågått
  515. */
  516. public abstract int tid();
  517.  
  518. /**
  519. * Kalles for hver trekk. Kan brukes til f.eks. å vise et annet bilde når
  520. * brukeren har vunnet.
  521. *
  522. * @return Filnavn på bakgrunnsbilde
  523. */
  524. public abstract String bakgrunnsBilde();
  525.  
  526. /**
  527. * Kalles etter at velg() returnerer false.
  528. *
  529. * @return En tekst som skal vises når brukeren har vunnet.
  530. */
  531. public abstract String sluttTekst();
  532.  
  533. }
  534.  
  535.  
  536. -------------------------------------------------------------------
  537.  
  538. import java.io.IOException;
  539. import java.util.HashMap;
  540.  
  541. import javax.sound.sampled.AudioInputStream;
  542. import javax.sound.sampled.AudioSystem;
  543. import javax.sound.sampled.Clip;
  544. import javax.sound.sampled.LineUnavailableException;
  545. import javax.sound.sampled.UnsupportedAudioFileException;
  546.  
  547.  
  548. public class LydSpiller {
  549. private static HashMap<String, Clip> clips = new HashMap<String,Clip>();
  550.  
  551. public static String lydSti = "sounds/";
  552.  
  553. /**
  554. * @param lyd Navn på lydfilen som skal spilles av (leter i <code>lydSti</code> underkatalogen)
  555. */
  556. public static void spillLyd(String lyd) {
  557. if(!clips.containsKey(lyd)) {
  558. try {
  559. AudioInputStream ais = AudioSystem.getAudioInputStream(LydSpiller.class.getResource(lydSti + lyd));
  560. Clip clip = AudioSystem.getClip();
  561. clip.open(ais);
  562. clips.put(lyd, clip);
  563. }
  564. catch(IOException e) {
  565. e.printStackTrace();
  566. }
  567. catch (UnsupportedAudioFileException e) {
  568. e.printStackTrace();
  569. } catch (LineUnavailableException e) {
  570. // TODO Auto-generated catch block
  571. e.printStackTrace();
  572. }
  573. }
  574. Clip c = clips.get(lyd);
  575.  
  576. c.setFramePosition(0);
  577. c.start();
  578.  
  579.  
  580. }
  581. }
  582. -----------------------------------------------------------------------------------
  583.  
  584.  
  585. /**
  586. * Tilstander for Brikke-klassen.
  587. */
  588.  
  589. public enum Tilstand {LUKKET, ÅPEN, FJERNET}
  590.  
  591. -----------------------------------------------------------------------------------
Add Comment
Please, Sign In to add comment