Повертаємося до графіки. Пінг-Понг

У розділах 5, 6 і 7 ми використовували деякі компоненти ізAWT і Swing бібліотек Тепер я покажу вам, як можна малювати і рухати такі постаті, як овали, прямокутники та лінії всередині вікна Також, ви дізнаєтеся, як обробляти події миші і клавіатури Щоб додати трохи веселощів в ці нудні теми, в цьому розділі ми будемо вивчати їх при створенні гри пінг – понг У ігребудут два учасники, я називаю їх дитина і компютерСтратегія

Давайте встановимо правила гри:

ü  Гра продовжується, поки один з гравців (дитина або компютер) не набере 21 очкоü  Ракетка дитини буде управлятися за допомогою мишіü  Рахунок гри буде відображатися в нижній частині окнаü  Нова гра починається при натисканні кнопки N на клавіатурі, Q –завершує гру і S – подає мяч ü  Подати мяч може тільки ребенокü  Для того, що виграти очко, мяч повинен потрапити в область завертікальной лінією ракетки, коли ракетка не блокує мяч

ü  Коли компютер відбиває мяч, мяч може рухатися толькогорізонтально вправоü  Якщо мяч стосується ракетки у верхній половині столу, він може рухатися тільки вліво і вгору Якщо мяч знаходився в нижнійчастини столу, він може рухатися тільки вниз і вліво

Повинно бути, ви думаєте, що написати таку програму дуже складно Хитрість у тому, щоб розбити складне завдання на кілька маленьких і простих завдань і зробити кожну з них окремо

Ця хитрість називається аналітичним мисленням і вона допомагає не тільки в програмуванні, але і в повсякденному житті Не турбуйтеся, якщо ви не можете досягти великої мети, розбийте її на маленькі і виконуйте окремо

Тому перша версія програми буде виконувати тільки деякі з правил – програма буде малювати стіл, переміщати ракетку і показувати координати кліків мишіВместо того, щоб говорити «Мій компютер не працює» (велика проблема), спробуйте подивитися, що саме не працює (знайдіть проблему трохи менше)

1 Чи підключений компютер крозетке (Так / ні)Так

2Когда я запускаю компютер, чи відображаються іконки на екрані (так / ні)Так

3 Чи можна переміщати мишу по екрану (так / ні) Ні

4 Чи правильно підключений кабель миші (так / ні) Ні

Просто підключіть кабель миші і компютер знову буде працювати Велика проблема вирішується всього лише підключенням кабелю мишіКодГра буде складатися з трьох класів:

ü  Клас PingPongGreenTable візьме на себе візуальну частину Втечение гри він буде відображати стіл, ракетки і мяч ü  Клас PingPongGameEngine, який вважатиме координати мяча і ракеток, починати і завершувати гру, подавати мяч Клас передаватиме поточні координати компонентів класу PingPongGreenTable, який буде перемальовуватись відповідно з даними ü  Інтерфейс GameConstants оголошуватиме все константи, які знадобляться в грі, наприклад довжину і ширину столу, початкові позиції ракеток і тд Ось як буде виглядати стіл для пінг – понгу:

Перша версія цієї гри буде робити тільки три речі:

Ø  Відображати зелений стіл для пінг – понгу

Ø  Відображати координати покажчика миші, коли ви клікаетеØ  Рухати ракетку дитини вгору і вниз Через дві сторінки ви зможете побачити наш клас PingPongGreenTable, який успадковується від класу JPanel з Swing Подивіться на цей код, поки читайте текст ніжеТак як наша програма повинна знати точні координати покажчика миші, конструктор PingPongGreenTable створюватиме обєкт класу – обробника подій PingPongGameEngine

Цей клас буде виконувати деякі дії, коли дитина клацає на кнопку миші або просто рухає її Метод addPaneltoFrame () створює текстовий елемент, який буде відображати координати миші

Цей розділ не аплет, тому замість методу paint (), використовується paintComponent () Цей метод може бути викликаний як JVM, коли потрібно перемалювати вікно, так і нашою програмою, за допомогою методу repaint () Так, ви прочитали правильно, метод repaint () усередині викликає paintComponent () і надає вашій класу доступ до обєкта Graphics, щоб ви змогли малювати всередині вікна Ми будемо викликати цей метод кожен раз після перерахунку координат ракеток або мяча для їх правильного відображення

Щоб намалювати ракетку, спочатку задайте колір, а потім заповніть їм прямокутник за допомогою методу fillRect () Цей метод повинен знати X і Y координати верхнього лівого кута прямокутника, а так само ширину і висоту в пікселях

Коло малюється за допомогою методу fillOval (), для цього треба знати координати центру овалу, його висоту і ширину Коли висота і ширина однакові, овал виглядає як коло

Координата X у вікні збільшується зліва направо, координата Y зростає зверху вниз Припустимо, ширина ось цього прямокутника 100 пікселів, а висота – 70:

             Координати X і Y кутів прямокутника показані в дужках

Ще один цікавий метод – getPreferredSize () Для того, щоб встановити розміри столу, ми створимо екземпляр класу Dimension з Swing Віртуальній машині Java потрібно знати про розміри вікна, тому вона викликає метод getPreferredSize () обєкта

PingPongGreenTable Цей метод повертає обєкт Dimension, який ми створили в відповідності з розмірами нашого столу

Обидва класи PingPongGreenTable і PingPongGameEngine використовують деякі константи, які не змінюються Наприклад, у класі PingPongGreenTable використовується ширина і висота столу, а PingPongGameEngine повинен знати, на скільки пікселів рухати мяч-чим менше це значення, тим більш плавним буде рух

Зручно зберігати всі константи (змінні final) в інтерфейсі У нашій грі інтерфейс називається GameConstants Якщо в класі знадобляться ці значення, просто додайте implements GameConstants до оголошення класу і використовуйте будь-які змінні final з цього інтерфейсу так, як ніби вони задані в цьому ж класі Тому обидва класу PingPongGreenTable і PingPongGameEngine реалізують інтерфейс GameConstants

Якщо ви вирішите поміняти розмір столу, мяча або ракетки, єдине місце, де це потрібно буде зробити – інтерфейс GameConstants Давайте подивимося на код класу PingPongGreenTable і інтерфейс GameConstants

package screens

import javaxswingJPanel import javaxswingJFrame import javaxswingBoxLayout import javaxswingJLabel

import javaxswingWindowConstants

import javaawtPoint import javaawtDimension import javaawtContainer import javaawtGraphics import javaawtColor

import enginePingPongGameEngine

/**

Цей клас малює стіл для пінг-понгу і відображає координати точки, де користувач клікнув мишею

*/

publicclass PingPongGreenTable extends JPanel

implements GameConstants{ JLabel label

public Point point = new Point(0,0)

public int ComputerRacket_X =15

private int kidRacket_Y =KID_RACKET_Y_START

Dimension preferredSize= new Dimension(TABLE_WIDTH,TABLE_HEIGHT)

/ / Цей метод встановлює розмір

/ / Викликається віртуальної Java машиною

public Dimension getPreferredSize() {

return preferredSize

}

/ / Конструктор Створює обробник подій миші PingPongGreenTable () {

PingPongGameEngine gameEngine =new PingPongGameEngine(this)

/ / Обробляє кліки миші для відображення її координат

  addMouseListener(gameEngine)

/ / Обробляє руху миші для пересування ракеток

  addMouseMotionListener(gameEngine)

}

/ / Додати панель з JLabel у вікно

void addPaneltoFrame(Container container) {

containersetLayout(new BoxLayout(container, BoxLayoutY_AXIS))

containeradd(this)

label = new JLabel(&quotClick to see coordinates&quot)

containeradd(label)

}

/ / Перемалювати вікно Цей метод викликається віртуальної

/ / Машиною, коли потрібно оновити екран або

/ / Викликається метод repaint () з PingPointGameEngine publicvoid paintComponent (Graphics g) {

superpaintComponent(g)

gsetColor(ColorGREEN)

/ / Намалювати стіл gfillRect (0,0, TABLE_WIDTH, TABLE_HEIGHT) gsetColor (Coloryellow)

/ / Намалювати праву ракетку gfillRect (KID_RACKET_X_START, kidRacket_Y, 5,30) gsetColor (Colorblue)

/ / Намалювати ліву ракетку gfillRect (ComputerRacket_X, 100,5,30) gsetColor (Colorred)

gfillOval (25,110,10,10) / / Намалювати мяч

gsetColor(Colorwhite)

gdrawRect(10,10,300,200)

gdrawLine(160,10,160,210)

/ / Відобразити точку як маленький квадрат 2×2 пікселів

if (point = null) {

labelsetText(&quotCoordinates (x,y): &quot + pointx +

&quot, &quot + pointy)

gfillRect(pointx, pointy, 2, 2)

}

}

/ / Встановити поточне положення ракетки дитини

public void setKidRacket_Y(int xCoordinate){

thiskidRacket_Y = xCoordinate

}

/ / Повернути поточне положення ракетки дитини

public int getKidRacket_Y(int xCoordinate){

return kidRacket_Y

}

publicstaticvoid main(String[] args) {

/ / Створити екземпляр вікна

JFrame f = new JFrame(&quotPing Pong Green Table&quot)

/ / Переконатися, що вікно може бути закрите після натискання на

/ / Хрестик в кутку

fsetDefaultCloseOperation(WindowConstantsEXIT_ON_CLOSE) PingPongGreenTable table = new PingPongGreenTable() tableaddPaneltoFrame(fgetContentPane())

/ / Встановити розмір вікна і зробити його видимим

fpack()

fsetVisible(true)

}

}

Тепер подивимося на інтерфейс GameConstants Всі значення змінних в пікселях У назвах final змінних використовуйте великі літери:

package screens

public interface GameConstants {

public final int TABLE_WIDTH =  320

public final int TABLE_HEIGHT = 220

public final int KID_RACKET_Y_START = 100 public final int KID_RACKET_X_START = 300 public final int TABLE_TOP = 12

public final int TABLE_BOTTOM = 180

public final int RACKET_INCREMENT = 4

}

Запущена програма не зможе поміняти значення цих змінних, тому що вони оголошені як final Але, якщо ви вирішите поміняти, наприклад, розмір столу, досить змінити значення TABLE_WIDTH

і TABLE_HEIGHT і перекомпілювати інтерфейс GameConstants

Рішення в цій грі бере клас PingPongGameEngine, которийреалізует 2 інтерфейсу, повязаних з подіями миші

MouseListener буде використовуватися в методі mousePressed () На кожне натискання миші цей метод буде малювати маленьку білу точку на столі і відображати її координати Чесно кажучи, в нашій грі цей код марний, але він покаже простий спосіб дістати з обєкта MouseEvent координати миші, які були передані JVM

Метод mousePressed () передає координати натиснутою кнопки миші змінної point Після того, як координати передані, цей метод просить віртуальну машину перемалювати столMouseMotionListener відстежує рух миші над столом, а метод mouseMoved () використовуватиметься для переміщення ракетки дитини вниз або вгору

Метод mouseMoved () вважає наступну позицію ракетки гравця Якщо покажчик миші знаходиться над ракеткою (координата Y миші менше, ніж координата Y ракетки), то цей метод гарантує, що ракетка НЕ вийде за межі столаКогда конструктор PingPongGreenTable створює обєкт класу PingPongGameEngine, він передає в нього посилання обєкта столу (ключове слово this означає посилання на область памяті з обєктом PingPongGreenTable) Тепер, PingPongGameEngine може «розмовляти» зі столом, наприклад, встановлювати нові

координати мяча або перемалювати стіл, коли потрібно Якщо ця частина не зовсім зрозуміла, перечитайте розділ глави 6 про передачу даних між класами

У нашій грі ракетки переміщаються вертикально по 4 пікселя, як ми задали в інтерфейсі GameConstants (клас PingPongGameEngine реалізує цей інтерфейс) Наприклад, наступний рядок забирає 4 від значення змінної kidRacket_Y: kidRacket_Y – = RACKET_INCREMENT

Наприклад, якщо координата Y ракетки була 100, після цього рядка кодаона стає рівною 96 і ракетка повинна піднятися вгору Той же результат можна отримати таким виразом: kidRacket_Y = kidRacket_Y – RACKET_INCREMENT

Якщо ви памятаєте, ми говорили про різні способи змінити значення змінної в Главі 3

Далі – клас PingPongGameEngine

package engine

import javaawteventMouseEvent

import javaawteventMouseListener

import javaawteventMouseMotionListener

import screens*

public class PingPongGameEngine  implements

MouseListener, MouseMotionListener, GameConstants{ PingPongGreenTable table

public int kidRacket_Y = KID_RACKET_Y_START

/ / Конструктор Містить посилання на обєкт столу public PingPongGameEngine(PingPongGreenTable  greenTable){

table = greenTable

}

/ / Обовязкові методи з інтерфейсу MouseListener

public void  mousePressed(MouseEvent e) {

/ / Взяти X і Y координати покажчика миші

/ / І встановити їх білої точці на столі

tablepointx = egetX()

tablepointy = egetY()

/ / Всередині викликає метод paintComponent () і оновлює вікно

tablerepaint()

}

public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) {}

/ / Обовязкові методи з інтерфейсу MouseMotionListener

public void mouseDragged(MouseEvent e) {}

public void  mouseMoved(MouseEvent e) {

int mouse_Y = egetY()

/ / Якщо миша знаходиться вище ракетки дитини

/ / І не виходить за межі столу –

/ / Пересунути її вгору, в іншому випадку – опустити вниз

if (mouse_Y &lt kidRacket_Y &amp&amp kidRacket_Y &gt TABLE_TOP){

kidRacket_Y -= RACKET_INCREMENT

}else if (kidRacket_Y &lt TABLE_BOTTOM) {

kidRacket_Y += RACKET_INCREMENT

}

/ / Встановити нове положення ракетки

tablesetKidRacket_Y(kidRacket_Y)     tablerepaint()

}

}

Джерело: Java Programming for Kids, Parents and Grandparents by Yakov Fain

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*