سؤال

I'm new to the site, as well as to Java. I'm playing around in BlueJ for one of my programming classes and we created a drawing and a sunset using slowMoveVertical, but I can't get my sun to "set" behind the horizon... you continue to see it set above it. Is there a way to change the layering so I can get it to "set" behind the horizon? Here's the whole code for the "Picture" class.

public class Picture
{
private Circle hill;
private Square wall;
private Square window;
private Triangle roof;
private Circle sun;

/**
 * Constructor for objects of class Picture
 */
public Picture()
{
    // nothing to do... instance variables are automatically set to null
}

/**
 * Draw this picture.
 */
public void draw()
{
    wall = new Square();
    wall.moveVertical(80);
    wall.changeSize(100);
    wall.makeVisible();

    window = new Square();
    window.changeColor("black");
    window.moveHorizontal(20);
    window.moveVertical(100);
    window.makeVisible();

    roof = new Triangle();
    roof.changeSize(50, 140);
    roof.changeColor("blue");
    roof.moveHorizontal(60);
    roof.moveVertical(70);
    roof.makeVisible();

    sun = new Circle();
    sun.changeColor("yellow");
    sun.moveHorizontal(180);
    sun.moveVertical(-10);
    sun.changeSize(60);
    sun.makeVisible();

    hill = new Circle();
    hill.changeColor("green");
    hill.moveHorizontal(-360);
    hill.moveVertical(160);
    hill.changeSize(1000);
    hill.makeVisible();

}

/**
 * Change this picture to black/white display
 */
public void setBlackAndWhite()
{
    if(wall != null)   // only if it's painted already...
    {
        wall.changeColor("black");
        window.changeColor("white");
        roof.changeColor("black");
        sun.changeColor("black");
        hill.changeColor("black");
    }
}

/**
 * Change this picture to use color display
 */
public void setColor()
{
    if(wall != null)   // only if it's painted already...
    {
        wall.changeColor("red");
        window.changeColor("black");
        roof.changeColor("blue");
        sun.changeColor("yellow");
        hill.changeColor("green");
    }
}

/**
 * Change this picture to make the sun go down
 */
public void setSunset()
{
    if(wall != null) // only if the sun is already up...
    {
        sun.slowMoveVertical(255);
    }

And here is the code for class "Circle".

public class Circle
{
private int diameter;
private int xPosition;
private int yPosition;
private String color;
private boolean isVisible;

/**
 * Create a new circle at default position with default color.
 */
public Circle()
{
    diameter = 30;
    xPosition = 20;
    yPosition = 60;
    color = "blue";
    isVisible = false;
}

/**
 * Make this circle visible. If it was already visible, do nothing.
 */
public void makeVisible()
{
    isVisible = true;
    draw();
}

/**
 * Make this circle invisible. If it was already invisible, do nothing.
 */
public void makeInvisible()
{
    erase();
    isVisible = false;
}

/**
 * Move the circle a few pixels to the right.
 */
public void moveRight()
{
    moveHorizontal(20);
}

/**
 * Move the circle a few pixels to the left.
 */
public void moveLeft()
{
    moveHorizontal(-20);
}

/**
 * Move the circle a few pixels up.
 */
public void moveUp()
{
    moveVertical(-20);
}

/**
 * Move the circle a few pixels down.
 */
public void moveDown()
{
    moveVertical(20);
}

/**
 * Move the circle horizontally by 'distance' pixels.
 */
public void moveHorizontal(int distance)
{
    erase();
    xPosition += distance;
    draw();
}

/**
 * Move the circle vertically by 'distance' pixels.
 */
public void moveVertical(int distance)
{
    erase();
    yPosition += distance;
    draw();
}

/**
 * Slowly move the circle horizontally by 'distance' pixels.
 */
public void slowMoveHorizontal(int distance)
{
    int delta;

    if(distance < 0) 
    {
        delta = -1;
        distance = -distance;
    }
    else 
    {
        delta = 1;
    }

    for(int i = 0; i < distance; i++)
    {
        xPosition += delta;
        draw();
    }
}

/**
 * Slowly move the circle vertically by 'distance' pixels.
 */
public void slowMoveVertical(int distance)
{
    int delta;

    if(distance < 0) 
    {
        delta = -1;
        distance = -distance;
    }
    else 
    {
        delta = 1;
    }

    for(int i = 0; i < distance; i++)
    {
        yPosition += delta;
        draw();
    }
}

/**
 * Change the size to the new size (in pixels). Size must be >= 0.
 */
public void changeSize(int newDiameter)
{
    erase();
    diameter = newDiameter;
    draw();
}

/**
 * Change the color. Valid colors are "red", "yellow", "blue", "green",
 * "magenta" and "black".
 */
public void changeColor(String newColor)
{
    color = newColor;
    draw();
}

/*
 * Draw the circle with current specifications on screen.
 */
private void draw()
{
    if(isVisible) {
        Canvas canvas = Canvas.getCanvas();
        canvas.draw(this, color, new Ellipse2D.Double(xPosition, yPosition, 
                diameter, diameter));
        canvas.wait(10);
    }
}

/*
 * Erase the circle on screen.
 */
private void erase()
{
    if(isVisible) {
        Canvas canvas = Canvas.getCanvas();
        canvas.erase(this);
    }
}
هل كانت مفيدة؟

المحلول

The loop in slowMoveVertical pretty much locks you into drawing the sun in front. If your assignment allows you to bypass slowMoveVertical, then you can manually do the loop it does and render your sun and the hill yourself so the layering is right.

for(int i = 0; i < 190; i++) {
    sun.moveHorizontal(1);
    hill.draw();
}

edit...

There's a wait() at the end of the draw call, which would really only be used on the last object in the "batch". Making another draw method with an optional wait call allows the caller to control it instead of the circle. example...

public void draw() {
    draw(true);  // retain current behavior
{

public void draw(boolean useWait) {
    if(isVisible) {
        Canvas canvas = Canvas.getCanvas();
        canvas.draw(this, color, new Ellipse2D.Double(xPosition, yPosition, 
            diameter, diameter));
        if (useWait) {
            canvas.wait(10);
        }
    }
}

Now you can call sun.draw(false) and hill.draw(true) and it shouldn't flicker (or a at least a lot less).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top