Многопоточные Явские прыгающие мячи апплета

Я пытаюсь создать Явский апплет, который заставляет несколько шаров отскочить в окне апплета, каждом с его собственной нитью. С кодом ниже всех шаров оттянуты, но только первые шаги. Что я делаю неправильно?

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static java.awt.Color.*;

public class BouncingBalls extends Applet implements Runnable {

    List ballList = new ArrayList();//holds Ball objects

    Color[] colors = new Color[]{BLACK, GRAY, WHITE, PINK, RED, ORANGE, YELLOW,
            GREEN, BLUE, CYAN};//array holding available colors

    static int width, height;//variables for applet dimensions

    int ballCount;//number of balls to be created, set by html parameter

    Random random = new Random();//random number generator


    public void init() {

       //get window dimensions
        width = getSize().width;
        height = getSize().height;

        //get number of balls from html
        String ballCountString = this.getParameter("ballCount");

        try {
            ballCount = Integer.parseInt(ballCountString);
        } catch (NumberFormatException e) {
            ballCount = 10;//set to 10 by default
        }

        for (int i = 0; i < ballCount; i++) {

           //randomly assign ballDiameter between 1 and 20
            int ballDiameter = random.nextInt(20) + 1;

           //create and add balls to ballList
            ballList.add(new Ball(
                    random.nextInt(width - ballDiameter),//set x coordinate
                    random.nextInt(height - ballDiameter),//set y coordinate
                    ballDiameter,//set ballDiameter
                    random.nextInt(ballDiameter) + 1,//deltaX <= ballDiameter
                    random.nextInt(ballDiameter) + 1,//deltaY <= ballDiameter
                    colors[i % 10]//use remainder to choose colors[] element
                    )
            );

        }//end for

    }//end init


    public void start() {

        for (Ball ball: ballList) {

            Thread t;
            t = new Thread(this);
            t.start();

        }//end for

    }//end start


    public void run() {

        for (Ball ball : ballList) {

           //infinite loop: ball moves until applet is closed
            while (true) {

                ball.move();

                repaint();//call paint method to draw circle in new location

               //set ball repaint delay using Thread sleep method
                try {
                    Thread.sleep(20);//wait 20 msec before continuing
                } catch (InterruptedException e) {
                    return;
                }

            }//end while

        }//end for

    }//end run

    public void paint(Graphics g) {

        super.paint(g);

        for (Ball ball : ballList) {

           //set current color
            g.setColor(ball.ballColor);

           //draw filled oval using current x and y coordinates and diameter
            g.fillOval(ball.x, ball.y, ball.diameter, ball.diameter);

        }//end for

    }//end paint
}

class Ball {

    int x, y,//coordinates of upper-left corner of circle
        diameter,//circle diameter
        deltaX, deltaY;//number of pixels ball moves each time it's repainted
    Color ballColor;


    public Ball(int x, int y, int diameter, int deltaX, int deltaY,
                Color ballColor) {

        this.x = x;
        this.y = y;
        this.diameter = diameter;
        this.deltaX = deltaX;
        this.deltaY = deltaY;
        this.ballColor = ballColor;

    }//end Ball constructor


    public void move() {

       //update x and y coordinates using delta values
        x += deltaX;
        y += deltaY;

       //reverse x direction when ball reaches boundary
        if (x >= BouncingBalls.width - diameter || x <= 0){
            deltaX = -deltaX;
        }//end if

       //reverse y direction when ball reaches boundary
        if (y >= BouncingBalls.height - diameter || y <= 0) {
            deltaY = -deltaY;
        }//end if

    }//end move

}//end BouncingBalls
1
nl ja de

1 ответы

Ваш , в то время как (верный) должен быть вне для петли. Это сидит на первом мяче, отбитом от iterator.

Однако можно хотеть пробежаться логику для одного шара за нить. Это на самом деле, кажется, создает количество N нитей (N быть количеством шаров), в который каждая нить переместит все шары вместо всего один.

Отредактируйте, чтобы обратиться к моему второму пункту:

Скажем, у вас есть 10 шаров. Вы начинаете 10 нитей, и каждая нить повторяет по всем шарам.

Например:

Thread 1:
public void run(){
   for(Ball b : ballList){
      b.move();
      b.repaint();
   }
}

Thread 2:
public void run(){
   for(Ball b : ballList){
      b.move();
      b.repaint();
   }
}

Thread N:
public void run(){
   for(Ball b : ballList){
      b.move();
      b.repaint();
   }
}

Это сделано, потому что вы создаете нити с тем же самым это случай работоспособного, которое повторяет по каждому шару.

 public void start() {

        for (Ball ball: ballList) {

            Thread t;
            t = new Thread(this);
            t.start();

        }//end for

    }//end start

Таким образом, я думал бы, если каждый шар, как предполагается, перемещает 1 единицу каждые 20 миллисекунд. Необходимо закончить тем, что видели, что каждые 20 миллисекунд перемещают единицы N*1 в этом случае 10 каждых 20 миллисекунд.

Отредактируйте - Относительно предложения.

Вместо того, чтобы установить это как работоспособное, необходимо удалить внедрение Работоспособных от это класс и создать новое Работоспособное, которое возьмет единственного Болла в качестве параметра.

private static class MovingRunnable implements Runnable{
   private final Ball b;
   private MovingRunnable(Ball b){this.b=b;}
   public void run(){
      for(;;){
         b.move(); 
         b.repaint();
         Thread.sleep(20);
      }
   }
}

Позже в вашем методе начала

public void start() {
        for (Ball ball: ballList) {
            Thread t;
            t = new Thread(new MovingRunnable(ball));
            t.start();
        }//end for

    }//end start

Таким образом, здесь у каждого Болла есть своя собственная нить с Работоспособным своим собственным. Каждый шар теперь только призовет движение однажды за нить каждые 20 миллисекунд.

Но это все еще не прекрасно, потому что , перекрашивание должно только быть призвано нитью UI, призвав его каждой нитью, может вызвать другие вопросы (хотя вы не можете заметить никого, это просто стоит сказать).

6
добавлено
Большой. Позвольте мне объяснить в том, чтобы редактировать.
добавлено автор John Vint, источник
@ChrisDevo I' ll обновляют с предложением
добавлено автор John Vint, источник
@ChrisDevo Да я понимаю, we' ve все там. Однако многопоточное программирование очень трудное, так держите его, по крайней мере, в перспективе:).
добавлено автор John Vint, источник
Миллион благодарностей, Джон. Обмен, в то время как и для фиксированного это. Хотя я don' t думают, что я следую, как каждая нить перемещает все шары.
добавлено автор ChrisDevo, источник
Какие-либо предложения о том, как иметь класс Болла, расширяют Нить (или осуществите Работоспособный) так, чтобы каждый бежал как ее собственная нить?
добавлено автор ChrisDevo, источник
Еще раз спасибо, Джон. I' m относительно в новинку для Явы (и кодирующий в целом). Кажется, что я часто достигаю точки убывающей доходности, где после работы над проблемой в течение многих часов и дней I can' t выясняют вещи, которые кажутся простыми и очевидными ретроспективно.
добавлено автор ChrisDevo, источник
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async