Закінчуємо гру Пінг-Понг

Тепер, після короткого вступу до потоки ми готові поміняти класи нашої гри в пінг – понг Давайте почнемо з класу PingPongGreenTable Нам не треба відображати білу точку по кліку миші – це було просто навчальний вправу для відображення координат покажчика миші Тому ми видалимо оголошення змінної point і рядки, які малюють білу точку з методу paintComponent () Також, в конструкторі більше не потрібен MouseListener, так як він тільки показує координати точкіС іншого боку, цей клас повинен реагувати на деякі кнопкіклавіатури (N – Для початку нової гри, S – Для подачі мяча і Q – Длявихода з гри) У цьому нам допоможе метод addKeyListener () Для того, щоб зробити наш код більш інкапсульованим, я перемістив виклики repaint () з класу PingPongGameEngine в клас PingPongGreenTable Тепер, коли знадобиться, PingPongGreenTable буде перемальовувати себе сам Також, я додав методи для зміни положення мяча, ракеткікомпьютера і для відображення повідомлень package screens

import javaxswingJPanel import javaxswingJFrame import javaxswingBoxLayout import javaxswingJLabel

import javaxswingWindowConstants

import javaawtDimension import javaawtContainer import javaawtGraphics import javaawtColor

import enginePingPongGameEngine

/**

* Цей клас малює зелений стіл для пінг-понгу,

куля, ракетки, відображає рахунок

*/

public class PingPongGreenTable extends JPanel

implements GameConstants{

private JLabel label

private int computerRacket_Y = COMPUTER_RACKET_Y_START

private int kidRacket_Y = KID_RACKET_Y_START

private int ballX = BALL_START_X

private int ballY = BALL_START_Y

Dimension preferredSize = new

Dimension(TABLE_WIDTH,TABLE_HEIGHT)

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

public Dimension getPreferredSize() {

return preferredSize

}

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

PingPongGameEngine gameEngine = new PingPongGameEngine(this)

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

addMouseMotionListener(gameEngine)

/ / Обробляємо події клавіатури

addKeyListener(gameEngine)

}

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

void addPaneltoFrame(Container container) {

containersetLayout(new BoxLayout(container,BoxLayoutY_AXIS))

containeradd(this)

label = new JLabel(

&quotPress N for a new game, S to serve or Q to quit&quot)

containeradd(label)

}

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

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

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

public void paintComponent(Graphics g) {

superpaintComponent(g)

/ / Намалювати зелений стіл gsetColor (ColorGREEN) gfillRect (0,0, TABLE_WIDTH, TABLE_HEIGHT)

/ / Намалювати праву ракетку gsetColor (Coloryellow) gfillRect (KID_RACKET_X, kidRacket_Y,

RACKET_WIDTH, RACKET_LENGTH)

/ / Намалювати ліву ракетку gsetColor (Colorblue) gfillRect (COMPUTER_RACKET_X, computerRacket_Y,

RACKET_WIDTH,RACKET_LENGTH)

/ / Намалювати мяч gsetColor (Colorred) gfillOval (ballX, ballY, 10,10)

/ / Намалювати білі лінії

gsetColor(Colorwhite) gdrawRect(10,10,300,200) gdrawLine(160,10,160,210)

/ / Встановити фокус на стіл, щоб

/ / Оброблювач клавіатури міг посилати команди столу

requestFocus()

}

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

public void setKidRacket_Y(int yCoordinate){

thiskidRacket_Y = yCoordinate

repaint()

}

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

public int getKidRacket_Y(){

return kidRacket_Y

}

/ / Встановити поточне положення ракетки компютера public void setComputerRacket_Y(int yCoordinate){

thiscomputerRacket_Y = yCoordinate

repaint()

}

/ / Встановити ігрове повідомлення

public void setMessageText(String text){

labelsetText(text)

repaint()

}

/ / Встановити позицію мячаpublic void setBallPosition(int xPos, int yPos){

ballX=xPos ballY=yPos repaint()

}

public static void main(String[] args) {

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

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

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

PingPongGreenTable table = new PingPongGreenTable()

tableaddPaneltoFrame(fgetContentPane())

/ / Встановити розмір вікна і зробити його видимим fsetBounds (0,0, TABLE_WIDTH +5, TABLE_HEIGHT +40) fsetVisible (true)

}

} Я додав кілька final змінних в інтерфейс GameConstants, і ви повинні здогадатися за їх іменами, для чого вони потрібніpackage screens

/**

* Цей інтерфейс містить всі константи, які використовуються у грі

*/

public interface GameConstants {

/ / Розміри столу

public final int TABLE_WIDTH =  320

public final int TABLE_HEIGHT = 220 public final int TABLE_TOP = 12 public final int TABLE_BOTTOM = 180

/ / Крок переміщення мяча в пікселяхpublic final int BALL_INCREMENT = 4

/ / Максимальні і мінімальні координати мяча public final int BALL_MIN_X = 1+ BALL_INCREMENT public final int BALL_MIN_Y = 1 + BALL_INCREMENT

public final int BALL_MAX_X = TABLE_WIDTH – BALL_INCREMENT

public final int BALL_MAX_Y = TABLE_HEIGHT – BALL_INCREMENT

/ / Початкові координати мяча

public final int BALL_START_X = TABLE_WIDTH/2

public final int BALL_START_Y = TABLE_HEIGHT/2

/ / Розміри, розташування і крок переміщення ракеток

public final int KID_RACKET_X = 300

public final int KID_RACKET_Y_START = 100

public final int COMPUTER_RACKET_X = 15

public final int COMPUTER_RACKET_Y_START = 100

public final int RACKET_INCREMENT = 2 public final int RACKET_LENGTH = 30 public final int RACKET_WIDTH = 5 public final int WINNING_SCORE = 21

/ / Сповільнити швидкі компютери – змініть це значення,

/ / Якщо знадобиться

public final int SLEEP_TIME = 10 / / Час в мілісекундах

}

Нижче я перерахував основні зміни, які зробив у класі PingPongGameEngine: ü  Удалил інтерфейс MouseListener і всі його методи, тому що ми більше не обробляємо кліки миші Всі рухи миші будуть оброблятися MouseMotionListenerü  Тепер цей клас реалізує інтерфейс Runnable, а вся логіка знаходиться в методі run () Подивіться на конструктор – там я створюю і запускаю новий потік Метод run () обробляє правила гри в кілька кроків, всі ці кроки запрограмовані всередині умови if (ballServed) Це скорочений варіант вираження if (ballServed == true)

ü  ласка, зверніть увагу на умова, яку встановлює значення змінної canBounce в першому кроці Залежно від цього виразу, значення змінної буде або true, або false

ü  Клас реалізує інтерфейс KeyListener, і метод keyPressed () перевіряє, яка кнопка була натиснута для початку / завершення гри, або подачі мяча Цей метод дозволяє обробляти як заголовні, так і маленькі букви, наприклад N і nü  Я додав кілька private методів: displayScore (), kidServe () і isBallOnTheTable () Вони оголошені приватними, тому що використовуються тільки всередині цього класу і інші класи навіть не підозрюють про їх існування Це приклад інкапсуляції в дії | ü  Деякі компютери настільки швидкі, що контролювати рух мяча стає важко Тому я забарився гру за допомогою методу Threadsleep () Статичний метод sleep () призупинить поточний потік на задане в конструкторі кількість міллісекундü  Щоб гра стала трохи веселіше, мяч тепер рухається по діагоналі після удару ракеткою дитини Тому змінюється не тільки X координата мяча, але і Ypackage engine

import javaawteventMouseMotionListener

import javaawteventMouseEvent import javaawteventKeyListener import javaawteventKeyEvent import screens*

/**

* Цей клас – обробник подій миші і клавіатури

* Розраховує рух мяча і ракеток, зміна їх координат

*/

public class PingPongGameEngine implementsRunnable, MouseMotionListener, KeyListener, GameConstants{

private PingPongGreenTable table / / Посилання на стілprivate int kidRacket_Y = KID_RACKET_Y_START    private int computerRacket_Y=COMPUTER_RACKET_Y_START    private int kidScore    private int computerScore

private int ballX / / Координата X мяча private int ballY / / Координата Y мячаprivate boolean movingLeft = true    private boolean ballServed = false

/ / Значення вертикального пересування мяча в пікселяхprivate int verticalSlide

/ / Конструктор Містить посилання на обєкт столу

public PingPongGameEngine(PingPongGreenTable  greenTable){

table = greenTable

Thread worker = new Thread(this)

workerstart()

}

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

/ / (Деякі з них порожні, але повинні бути включені всі одно)

public void mouseDragged(MouseEvent e) {

}

public void mouseMoved(MouseEvent e) {

int mouse_Y = egetY()

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

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

/ / Інакше – опустити вниз

if (mouse_Y&ltkidRacket_Y &amp&amp kidRacket_Y&gtTABLE_TOP){

kidRacket_Y -= RACKET_INCREMENT

}elseif (kidRacket_Y &lt TABLE_BOTTOM) {

kidRacket_Y += RACKET_INCREMENT

}

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

tablesetKidRacket_Y(kidRacket_Y)

}

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

public void  keyPressed(KeyEvent e){

char key = egetKeyChar()

if (n == key || N == key){

startNewGame()

} elseif (q == key || Q == key){

endGame()

} elseif (s == key || S == key){

kidServe()

}

}

public void keyReleased(KeyEvent e){}

public void keyTyped(KeyEvent e){}

/ / Нова гру

public void startNewGame(){

computerScore=0

kidScore=0

tablesetMessageText(&quotScore Computer: 0  Kid: 0&quot)

kidServe()

}

/ / Закінчити гру public void endGame(){

Systemexit(0)

}

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

public void run(){

boolean canBounce=false

while (true) {

if(BallServed) {/ / якщо мяч рухається

/ / Крок 1 Мяч рухається вліво

if ( movingLeft &amp&amp ballX &gt BALL_MIN_X){

canBounce = (ballY &gt= computerRacket_Y &amp&amp

ballY &lt (computerRacket_Y + RACKET_LENGTH)true: false)

ballX-=BALL_INCREMENT

/ / Додати зміщення вгору або вниз до будь

/ / Рухам мяча вліво або вправо

ballY-=verticalSlide

tablesetBallPosition(ballX,ballY)

/ / Може відскочити

if (ballX &lt= COMPUTER_RACKET_X  &amp&amp canBounce){

movingLeft=false

}

}

/ / Крок 2 Мяч рухається вправо

if ( movingLeft &amp&amp ballX &lt= BALL_MAX_X){

canBounce = (ballY &gt= kidRacket_Y &amp&amp ballY &lt

(kidRacket_Y + RACKET_LENGTH)true:false)

ballX+=BALL_INCREMENT

tablesetBallPosition(ballX,ballY)

/ / Може відскочити

if (ballX &gt= KID_RACKET_X &amp&amp canBounce){

movingLeft=true

}

}

/ / Крок 3 Переміщати ракетку компютера вгору або вниз,

/ / Щоб блокувати мяч

if (computerRacket_Y &lt ballY

&amp&amp computerRacket_Y &lt TABLE_BOTTOM){

computerRacket_Y +=RACKET_INCREMENT

}else if (computerRacket_Y &gt TABLE_TOP){

computerRacket_Y -=RACKET_INCREMENT

}

tablesetComputerRacket_Y(computerRacket_Y)

/ / Крок 4 Призупинити

try {

Threadsleep(SLEEP_TIME)

} catch (InterruptedException e) {

eprintStackTrace()

}

/ / Крок 5 Оновити рахунок, якщо мячв зеленій області, але не рухається

if (isBallOnTheTable()){

if (ballX &gt BALL_MAX_X ){

computerScore++

displayScore()

}else if (ballX &lt BALL_MIN_X){

kidScore++

displayScore()

}

}

} / / Кінець if ballServed

} / / Кінець while

} / / Кінець run ()

/ / Подати з поточної позиції ракетки дитини

private void kidServe(){

ballServed = true

ballX = KID_RACKET_X-1

ballY=kidRacket_Y

if (ballY &gt TABLE_HEIGHT/2){

verticalSlide=-1

}else{

verticalSlide=1

}

tablesetBallPosition(ballX,ballY)

tablesetKidRacket_Y(kidRacket_Y)

}

private void displayScore(){

ballServed = false

if (computerScore ==WINNING_SCORE){

tablesetMessageText(&quotComputer won &quot + computerScore + &quot:&quot + kidScore)

}else if (kidScore ==WINNING_SCORE){

tablesetMessageText(&quotYou won &quot+ kidScore +

&quot:&quot + computerScore)

}else{

tablesetMessageText(&quotComputer:  &quot+ computerScore +

&quot Kid: &quot + kidScore)

}

}

/ / Перевірити, чи не перетнув мяч верхню або нижню межу столу

private boolean isBallOnTheTable(){

if (ballY &gt= BALL_MIN_Y &amp&amp ballY &lt= BALL_MAX_Y){

return true

}else {

}

}

}

return false

Вітаю Ви закінчили розробку вашої другої гри Скомпілюйте класи і грайте в неї Після того, як ви розберетеся в коді, спробуйте змінити його – я впевнений, у вас є ідеї, як зробити цю гру краще Якщо хочете продовжити програмувати гри, погляньте на Robocode – етапрограмміруемая гра, дозволяє вивчати Java, створюючи роботів:

http://robocodesourceforgenet/Open&ampca=daw-­‐prod-­‐robocodeПосібник з сокетам в Java:

http://wwworaclecom/technetwork/java/socket-­‐

140484html

Введення в потоки Java:

http://www-­‐106ibmcom/developerworks/edu/j-­‐dw-­‐

 javathread-­‐ihtmlКлас javaawtGraphics:

http://downloadoraclecom/javase/6/docs/api/java/awt/G

raphicshtml

 Практичні завдання1 Клас PingPongGameEngine встановлює координати білої точки за допомогою такого коду:

tablepointx = egetX()

Зробіть змінну point приватній в класі PingPongGreenTable і добавьтеpublic метод setPointCoordinates (int x, int y)

Використовуйте цей метод в классеPingPongGameEngine

2 У нашій грі пінг – понг є помилка: після того, як один з гравців виграв, все ще можна натиснути кнопку S і гра продовжиться Виправте цю помилку

 Практичні вправи для розумників і розумниць

1 Спробуйте поміняти значення RACKET_INCREMENT і BALL_INCREMENT Чим більше ці значення, тим швидше рухається мяч і ракетки Поміняйте код так, щоб користувач міг вибирати рівень від 1 до 10 Використовуйте обрані значення як коефіцієнт руху для мяча і ракеток

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

Джерело: 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>

*

*