esercizio 4
Questo esercizio crea oggetti palla in thread separati e li anima nella finestra dell'applet. La classe palla rappresenta l'oggetto il cui movimento é autonomo cioé non comandato dall'applet stessa. Sono stati presi gli accorgimenti standard per evitare lo sfarfallio, disegnando in una graphics offscreen gli oggetti cerchio e cancellando sempre e solo la versione offscreen. Tale tecnica impedisce di notare le fasi di disegno e cancellazione che possono sovrapporsi prima dell'avvenuta visualizzazione.
Tramite il parametro num é possibile indicare il numero di cerchi da disegnare.
Le leggi fisiche che regolano il movimento sono le leggi del moto associate alla seconda equazione della dinamica in presenza di accelerazione dei gravità terrestre g=9.81 m/s2

package corsoDrZito.lez3.es4;

import java.applet.Applet;
import java.awt.*;

public class esercizio4 extends Applet implements Runnable
{
	public void init()
	{
		int num = 4;

		d = getSize();

		String param = getParameter("num");
		if (param!=null) num = Integer.parseInt(param);

		palle = new Palla[num];
		for(int i=0;i<palle.length;i++)
			palle[i] = new Palla(d);

		im = createImage(d.width, d.height);
		myg = im.getGraphics();

		setBackground(new Color(48,64,96));

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

	public synchronized void update(Graphics g) { paint(g); }
	public synchronized void paint(Graphics g)
	{
		myg.clearRect(0, 0, d.width, d.height);

		for(int i=0;i<palle.length;i++)
			palle[i].paint(myg);

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

	public void run()
	{
		Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
		do
		{
			for(int i=0;i<palle.length;i++)
				palle[i].muovi();
			repaint();
			try
			{
				Thread.currentThread();
				Thread.sleep(10L);
			}
			catch(InterruptedException ex) {}
		}
		while(true);
	}

	private Palla[] palle;

	private Image im;
	private Graphics myg;
	private Dimension d;
	private Thread t;
}

package corsoDrZito.lez3.es4;

import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Color;

public class Palla
{
	public Palla(Dimension d)
	{
		super();

		radius = (float)Math.random()*Math.min(d.width, d.height) / 10.f + 6f;
		r = (int)radius;

		pos_x = (float)(Math.random()*(d.width  - r));

		pos_y = (float)(Math.random()*(d.height - r));

		vel_x = (float)Math.random()*75.f + 25.f;
		vel_y = (float)Math.random()*75.f + 25.f;

		x = (int)pos_x;
		y = (int)pos_y;

		bounds = d;

		color = new Color( (int)(128+64*Math.random()), (int)(128+64*Math.random()), (int)(128+64*Math.random()) );

		marker = new int[markmax][2];

		millis = System.currentTimeMillis();
	}

	public void muovi()
	{
		long currentMillis = System.currentTimeMillis();
		long delta = currentMillis - millis;
		markcounter += delta;

		pos_x += vel_x * (delta / 1000.f);

		vel_y += acc_y * (delta / 1000.f);
		pos_y += vel_y * (delta / 1000.f);


		x = (int)pos_x;
		y = (int)pos_y;

		if (markcounter > markdelay)
		{
			marker[markindex][0] = x + r / 2;
			marker[markindex][1] = y + r / 2;
			markindex = ++markindex % markmax;
			markcounter = delta % markdelay;
		}

		if(x + r >= bounds.width ) vel_x = - Math.abs(vel_x);
		if(x < 0) vel_x = Math.abs(vel_x);
		if(y + r >= bounds.height) vel_y = - Math.abs(vel_y);
		if(y < 0) vel_y = Math.abs(vel_y);

		millis = currentMillis;

		try
		{
			Thread.currentThread();
			Thread.sleep(5L);
		}
		catch(InterruptedException ex) {}
	}

	public synchronized void paint(Graphics g)
	{
		g.setColor(Color.black);
		g.fillOval( x, y, r, r );
/*
		int px = (x+r+100 < bounds.width)?x+r: x-100;
		g.drawString( "vx:"+vel_x, px, y );
		g.drawString( "vy:"+vel_y, px, y + 12 );

		g.setColor(color);
		g.drawLine(x+r/2, y+r/2, x+r/2+(int)vel_x, y+r/2+(int)vel_y);
*/
		g.setColor(color);
		for(int i=0;i<marker.length; i++)
			g.fillRect( marker[i][0], marker[i][1], 2, 2);
	}

	private static long millis;
	private int r;
	private int x;
	private int y;
	private float radius;
	private float pos_x;
	private float vel_x;
	private float acc_x = 0.0f;
	private float pos_y;
	private float vel_y;
	private float acc_y = 9.81f;
	private Dimension bounds;
	private Color color;
	private int[][] marker;
	private int markindex;
	private int markmax = 20;
	private long markcounter;
	private long markdelay = 500; // millis
}