Reputation: 47
I am trying to make an animation where two rectangles will appear and disappear from frame when you type in: c with Turtle Graphics. But the problem I have is that I do not understand how to incorporate turtle graphics into a loop. For this, I have to use do-while loop. I am also suppose to have the rectangles that I made move horizontally across the screen. I have the general idea set out, but I do not know how to use turtle graphics with a loop. My code is not the most orderly when I tried to set it up here.
/**
* Write a description of class Animation here.
*
* @author (author)
* @version
*/
import java.util.Scanner;
import java.awt.*;
class Animation
{
//set conditions for turtle to start drawing
public void prepareTurtleToDraw(Turtle myrtle, Color color, int x, int y)
{
myrtle.hide();
myrtle.penUp(); //pick up the pen to avoid leaving a trail when moving the turtle
myrtle.setColor(color); //set myrtle's color
myrtle.moveTo(x, y); //move to coordinates
myrtle.penDown(); //put the pen down to start drawing
}//end of prepareTurtleToDraw method
//draw a line
public void drawLine(Turtle myrtle, int x1, int y1, int x2, int y2)//, int width)
{
myrtle.moveTo(x1, y1); //moves to this coordinate first
myrtle.moveTo(x2, y2); //then moves to this coordinate
//myrtle.setPenWidth(width); //this adjusts the size of the lines
}//end of drawLine method
public static void pressC()
{
String userInput = ""; //declare and initialize a String variable
char key = ' '; //declare and initialize a char variable
Scanner in = new Scanner(System.in); //construct a Scanner object
System.out.println("Please press the c key to watch the animation.");
//do-while loop to wait for the user to enter the letter c
do
{
userInput = in.next(); //accept one token from the keyboard
in.nextLine(); //flush the buffer
key = userInput.charAt(0); //picks off the first character from the userInput String variable
}
while(key != 'c'); //do-while condition statement
System.out.println("Thank you. You may continue");
}//end of main method
}
public class AnimationTester
{
public static void main(String[] args)
{
//Picture pictureObj = new Picture(""); //create a Picture object for the maze background image, has name and etc.
World worldObj = new World(); //create a World object to draw in
//worldObj.setPicture(pictureObj); //set the maze background image in the World object
Turtle lertle = new Turtle(300, 150, worldObj); //create a Turtle object to do the drawing
Animation turt = new Animation();
Turtle dyrtle = new Turtle(150, 150, worldObj);
turt.prepareTurtleToDraw(lertle, Color.BLACK, 250, 150);
turt.drawLine(lertle, 250, 150, 400, 150);
turt.drawLine(lertle, 400, 150, 400, 250);
turt.drawLine(lertle, 400, 250, 250, 250);
turt.drawLine(lertle, 250, 250, 250, 150);
turt.prepareTurtleToDraw(dyrtle, Color.RED, 150, 150);
turt.drawLine(dyrtle, 150, 150, 260, 75);
turt.drawLine(dyrtle, 260, 75, 335, 150);
turt.drawLine(dyrtle, 335, 150, 225, 225);
turt.drawLine(dyrtle, 225, 225, 150, 150);
System.out.println(worldObj);
}
}
Upvotes: 1
Views: 898
Reputation: 321
Well, it seems I can't upload photos I took of my program because I don't have enough reputation. Thanks!
Figure 1. Before pressing C
Figure 2. After pressing C
Main.java
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(() -> {
MainFrame mf = MainFrame.getMainFrame();
new Thread(mf).start();
});
} catch (InvocationTargetException | InterruptedException e) {
System.out.println("Could not create GUI");
}
}
}
import java.awt.BorderLayout;
import javax.swing.JFrame;
class MainFrame extends JFrame implements Runnable {
private static final long serialVersionUID = 1L;
private DisplayPanel dp;
private boolean isRunning;
private double secondsPerFrame = 1.0 / 60.0;
private static MainFrame mf;
private MainFrame() {
super("Title");
dp = new DisplayPanel();
add(dp, BorderLayout.CENTER); // Add display to the center
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
/**
* Static factory
*
* @return A singleton MainFrame
*/
static MainFrame getMainFrame() {
return mf == null ? mf = new MainFrame() : mf;
}
/**
* Game loop
*/
@Override
public void run() {
isRunning = true;
int frames = 0;
double frameCounter = 0;
double lastTime = System.nanoTime() / 1000000000.0;
double unprocessedTime = 0;
while(isRunning) {
boolean render = false;
double startTime = System.nanoTime() / 1000000000.0;
double passedTime = startTime - lastTime;
lastTime = startTime;
unprocessedTime += passedTime;
frameCounter += passedTime;
while(unprocessedTime > secondsPerFrame) {
render = true;
unprocessedTime -= secondsPerFrame;
// Update the state of the rectangles' brightness
dp.update(secondsPerFrame);
if(frameCounter >= 1.0) {
// Show fps count. Updates every second
dp.setFps(frames);
frames = 0;
frameCounter = 0;
}
}
if(render) {
// Render the rectangles
dp.render();
frames++;
} else {
try {
Thread.sleep(1);
} catch (InterruptedException ie) {}
}
}
}
}
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
// Create a display within the window
class DisplayPanel extends Canvas implements KeyListener {
private static final long serialVersionUID = 2L;
private Graphics2D g2; // Drawing tool
private BufferStrategy strategy; // Drawing tool
private FadingRectangle[] fadingRectangles; // Appears/disappears based on elapsed time
private FadingRectangle userControlledRectangle; // Appears/disappears upon command by user
private int fps; // Used to display the fps on screen
DisplayPanel() {
setPreferredSize(new Dimension(800, 600));
addKeyListener(this);
setFocusable(true);
fadingRectangles = new FadingRectangle[2];
fadingRectangles[0] = new FadingRectangle(150, 250, 100, 100);
fadingRectangles[1] = new FadingRectangle(550, 250, 100, 100);
userControlledRectangle = new FadingRectangle(350, 100, 100, 100);
}
/**
* Updates the brightness of rectangles
*
* @param elapsedSeconds Seconds elapsed since the last call to this method
*/
void update(double elapsedSeconds) {
fadingRectangles[0].update(elapsedSeconds);
fadingRectangles[1].update(elapsedSeconds);
}
/**
* Draw everything
*/
void render() {
// Prepare drawing tools
if (strategy == null || strategy.contentsLost()) {
createBufferStrategy(2);
strategy = getBufferStrategy();
Graphics g = strategy.getDrawGraphics();
this.g2 = (Graphics2D) g;
}
// Anti-aliasing
this.g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Clear screen by drawing background on top
this.g2.setColor(Color.BLACK);
this.g2.fillRect(0, 0, getWidth(), getHeight());
// Draw the rectangles
fadingRectangles[0].draw(new Color(255, 0, 0));
fadingRectangles[1].draw(new Color(0, 0, 255));
userControlledRectangle.draw(Color.WHITE);
// Draw fps count on the upper left corner
g2.setColor(Color.WHITE);
g2.drawString("FPS: " + Integer.toString(fps), 10, 20);
// Set the drawn lines visible
if(!strategy.contentsLost())
strategy.show();
}
/**
* @param fps The fps to be drawn when render() is called
*/
void setFps(int fps) {
this.fps = fps;
}
/**
* Used to draw rectangles in the display
*/
private class FadingRectangle {
private int x, y, width, height; // Location and size of the rectangle
private double secondsPassed; // Arbitrary number that determines the brightness of blue
private FadingRectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
/**
* Called by render()
*
* @param color The color of the rectangle to be drawn
*/
private void draw(Color color) {
// Determine color
double fade = Math.abs(Math.sin(secondsPassed));
int red = (int) (color.getRed() * fade);
int green = (int) (color.getGreen() * fade);
int blue = (int) (color.getBlue() * fade);
g2.setColor(new Color(red, green, blue));
// Draw the rectangle
g2.drawRect(x, y, width, height);
}
private void update(double elapsedSeconds) {
secondsPassed += elapsedSeconds;
}
}
// A quick and dirty implementation. Should be fixed to make it clearer
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_C) {
userControlledRectangle.update(Math.PI / 2);
}
}
@Override
public void keyPressed(KeyEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
}
Upvotes: 1