简体   繁体   中英

Filling polygon and moving it, but its leaving a trail

Alright, so I've been trying to move my polygon so it bounces around the screen. Right now it does so but leave a trail the entire way. I have a GUI class, extended by an Aquarium class, which fills the screen with the color blue, creates a "creature" object (from Creature class) and uses update to move it down the screen. When it updates however, a trail is left behind. I have tried many methods mentioned in similar cases on the site but nothing works. Can somebody please help me?

GUI class (that holds JPanel etc)

package artilife;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class AquariumGUI {

    private GooPanel gooPanel;

    private boolean loop = true;

    protected int width, height;

    private int frameTimeInMillis = 300;

    private RenderingHints renderingHints = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    @SuppressWarnings("serial")
    class GooPanel extends JPanel {

        public void paintComponent(Graphics g) {

            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHints(renderingHints);
            draw(g2d);
        }
    }

    public AquariumGUI() {

        this(800, 500);
    }

    public AquariumGUI(int w, int h) {

        width = w;
        height = h;

        JFrame frame = new JFrame();
        frame.setSize(width, height);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        gooPanel = new GooPanel();
        gooPanel.setPreferredSize(new Dimension(w, h));
        frame.getContentPane().add(gooPanel);
        frame.pack();

        frame.setVisible(true);
    }

    public void go() {

        while (loop) {

            gooPanel.repaint(); 
            update();


            try {
                Thread.sleep(frameTimeInMillis);
            } catch (InterruptedException e) {
            }
        }
    }

    public void draw(Graphics2D g) {

    }

    public void update(){
    }

    public void setFrameTime(int millis){

        frameTimeInMillis = millis;
    }
}

Aquarium class that extended this and attempts to color the screen and place a Polygon creature on it:

package artilife;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Random;

public class MyAquarium extends AquariumGUI {

    Creature tester;

    public MyAquarium() 
    {
        tester = new Creature();
    }

    public void draw(Graphics2D g) {

        // Fill background 
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        tester.draw(g);

    }

    public void update(){


        tester.move(width, height);

    }

    public static void main(String[] args) {

        MyAquarium aquarium = new MyAquarium();
        aquarium.go();

    }
}

And the creature that is being drawn, and holds the move method:

package artilife;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class Creature 
{
  // Position and radius of the drop
    private double x, y, r, Vx, Vy;
    Polygon p = new Polygon();
    int numSides;

    public Creature() {

        x = 800 / 2;
        r = 10;
        y = 50;
        Vx = 10;
        Vy = 3;
        numSides = 3;
        //creatureShape(numSides); 
    } 

    public void creatureShape (int sides)
    {
        if (sides <= 10){
            for (int i = 0; i < sides; i++){
            p.addPoint((int) (x + 50 * Math.cos((i) * 2 * Math.PI / sides)),
            (int) (y + 50 * Math.sin((i) * 2 * Math.PI / sides)));
            }
        }
        else{
            for (int i = 0; i < 360; i++) {
            double value = i / 360.0;
            p.addPoint((int) (90 + 50 * value * Math.cos(8 * value * Math.PI)),
            (int) (50 + 50 * value * Math.sin(8 * value * Math.PI)));
            }
        }
    }


    public void draw(Graphics2D g) {

        creatureShape(numSides); 
        g.setColor(Color.BLUE);
        g.fillPolygon(p);

    }

    public void move(int width, int height){

        // Move the drop
       x = x + Vx;
       y = y +Vy;
       if (y >= height){
       Vy = -Vy;
       y = height;
       }
       else if(y <= 0){
       Vy = -Vy;
       y = 0;
       }
       if(x >= width){
       Vx = -Vx; 
       x = width;
       }
       if(x <= 0){
       Vx = -Vx; 
       x = 0;
       }


    }
    /*
    public void attraction ()
    {
        if ( 



    }*/
    /*
    public boolean check4Creatures () 
    {
      boolean isThere = false;
      //if there is an another create object within a 60 point radius
      isThere = true;

        return isThere;
    }*/

}

SOLUTION: So fiddle for what feels like forever and it works now. When drawing polygons in motion, some java functions store bits of information regarding the vertices. The best way to move them cleanly is to use translate() instead of manipulating the vertices directly (by updating x and y values) when updating the information, and then draw the fresh polygon.

Thank everyone for taking the time to look at my problem though!

You need to clear the screen between two drawing operations. You can either leave it to the framework, by calling the super.paintComponent() method, or you can do it your way, by filling the screen with something, like a g.fillRect() call.

The first method will actually make a call the the fillRect function, using the panel background color.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM