com.google.gwt.demos.gwtcanvas.client.ParticleDemo.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.demos.gwtcanvas.client.ParticleDemo.java

Source

/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.demos.gwtcanvas.client;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.Timer;
import com.google.gwt.widgetideas.graphics.client.Color;
import com.google.gwt.widgetideas.graphics.client.GWTCanvas;

import java.util.Date;

/**
 * Simple particle Simulation showing off some of the Path API.
 */
public class ParticleDemo extends SimpleCanvasDemo {

    /**
     * Model of  a single particle object in the simulation.
     */
    private class Particle {
        public boolean kill = false;
        public float xPos;
        public float xVel;
        public float yPos;
        public float yVel;
        private float gravity = 0.1f;
        private float xDampening = 0.9f;
        private float yDampening = 0.9f;

        public Particle() {
            xPos = (float) (Math.random() * width);
            yPos = (float) (Math.random() * height);
            // Get some negative velocities
            xVel = (float) (Math.random() * 5 - 2.5);
            yVel = (float) (Math.random() * 5 - 2.5);
        }

        public void update() {

            // Reverse direction on boundaries
            if (xPos > width || xPos < 0) {

                xVel = -xVel;
                xPos += xVel;
                // suck out some energy
                xDampening = (float) Math.max(xDampening - 0.1, 0);
                xVel *= xDampening;
            }

            if (yPos > height || yPos < 0) {

                yVel = -yVel;
                yPos += yVel;
                // suck out some energy
                yDampening = (float) Math.max(yDampening - 0.1, 0);
                yVel *= yDampening;

                if ((yPos > height - 4) && (Math.abs(yVel) < 0.1)) {
                    yPos = height;
                    xVel = 0;
                    gravity = 0;
                    kill = true;
                }
            }

            xPos += xVel;
            yPos += yVel;

            // apply gravity
            yVel += gravity;
        }
    }

    /*
     * Not so much controls as feedback for benchmarking.
     */
    class ParticleDemoControls extends Composite {
        private double average = 1;
        private Label averageLabel;

        private double iterations = 1;
        private double refreshRate;
        private Label refreshRateLabel;

        private double startTime = -1;

        public ParticleDemoControls() {
            refreshRateLabel = new Label("");
            averageLabel = new Label("");

            VerticalPanel layout = new VerticalPanel();
            layout.add(refreshRateLabel);
            layout.add(averageLabel);

            initWidget(layout);
        }

        public void doBenchmark(double now) {
            if (startTime < 0) {
                startTime = now;
            } else {
                refreshRate = now - startTime;
                startTime = now;
                average = ((average * iterations) + refreshRate) / (iterations + 1);
                iterations++;

                refreshRateLabel.setText("Refresh Interval: " + String.valueOf(refreshRate));
                averageLabel.setText("Average Interval: " + String.valueOf(average));
            }
        }

        public void resetBenchmark() {
            this.average = 1;
            this.iterations = 1;
            this.startTime = -1;
        }
    }

    private int numParticles = 20;

    private Particle[] particles;

    private Timer t;

    private boolean takeBenchmarks = false;

    public ParticleDemo(GWTCanvas theCanvas) {
        super(theCanvas);
        width = 400;
        height = 300;
        canvas = theCanvas;
        demoName = "Particle Demo";
    }

    public void createControls() {
        this.controls = new ParticleDemoControls();
    }

    public void drawDemo() {
        canvas.resize(width, height);

        particles = new Particle[numParticles];

        for (int i = 0; i < particles.length; i++) {
            particles[i] = new Particle();
        }
        canvas.saveContext();
        canvas.setLineWidth(2);
        canvas.setStrokeStyle(new Color(255, 0, 0));

        t = new Timer() {
            public void run() {
                renderingLoop();
            }
        };
        t.schedule(10);
    }

    public void renderingLoop() {
        canvas.clear();

        for (int i = 0; i < particles.length; i++) {
            if (particles[i].kill) {
                continue;
            }
            particles[i].update();

            canvas.beginPath();
            canvas.moveTo(particles[i].xPos, particles[i].yPos);
            canvas.lineTo(particles[i].xPos - particles[i].xVel, particles[i].yPos - particles[i].yVel);
            canvas.closePath();
            canvas.stroke();
        }

        t.schedule(10);
        // take a benchmark
        if (takeBenchmarks) {
            ((ParticleDemoControls) this.controls).doBenchmark(Math.max(0, (new Date()).getTime()));
        }
    }

    public void stopDemo() {
        t.cancel();
        ((ParticleDemoControls) controls).resetBenchmark();
        canvas.restoreContext();
    }
}