Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.*;
- import javax.swing.*;
- import java.awt.Graphics;
- import java.lang.Math;
- /**
- * This will draw a five-point star in an Applet and then
- * bounce it around the canvas whilst rotating it ~1° clockwise.
- * The alogrithmn is still imperfect, so there's some work to
- * do but it's about >75% accurate.
- *
- * @author Shaun B
- * @version 1.0.0a
- * @todo Perfect the maths so that it is >99% accurate when
- * rotating more complex shapes. Find the size in pixels
- * of the rotated shape against the original.
- */
- public class starAnimation extends JApplet implements Runnable
- {
- // This array will draw a simple star:
- private static final int STAR[] =
- {
- /** co-ordinates in array read as
- * x0, y0 to x1, y1. -1 terminates */
- 0, 28, 30, 28,
- 39, 0, 50, 28,
- 79, 28, 55, 46,
- 64, 73, 40, 57,
- 15, 73, 23, 45,
- -1, -1
- };
- // This is a rhombus:
- private static int square[] =
- {
- 0, 0, 80, 0,
- 80, 80, 0, 80,
- -1, -1
- };
- // Here is our buffer for the shape:
- private static int buffer[] =
- {
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1
- };
- // Here's a scrolly messahe:
- private static String scrolly= " Nah nah na na nahh! :-P Donkeysoft MMXII ";
- private static String charBuffer = "";
- private byte updateScrolly = 0;
- // This will be used to rotate the shape, theta is
- // converted to radians and therefore degrees
- // can be within a more human range between zero
- // and 360. The PI representation is accurate according
- // to the Sinclair ZX81 :-)
- private static double theta = (double)(1*3.1415927)/180;
- private static double degrees = (double)0;
- // Identity matrix and rotation matrix not yet
- // implemented
- /**private static int identity[][]=
- {
- { 1, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 1, 0 }
- { 0, 0, 0, 1 }
- };
- private static double matrixRotate[][] =
- {
- { Math.cos(0.10), Math.sin(0.10), 0.00, 0.00 },
- { Math.sin(0.10), Math.cos(0.10), 0.00, 0.00 },
- { 0.00, 0.00, 0.10, 0.00 },
- { 0.00, 0.00, 0.00, 0.10 }
- };*/
- // Starting position of star:
- private int xAxis = 0;
- private int yAxis = 0;
- // Sets the height and width of the image:
- private int widthOfStar = 80;
- private int heightOfStar = 73;
- private int widthOfSquare = 80;
- private int heightOfSquare = 80;
- // Sets the direction of the animation
- // positive to move right/down and negative
- // to move left/up:
- private int xDirection = 1;
- private int yDirection = 1;
- // This will be used to get the width and height of the Applet
- private int width=0;
- private int height=0;
- // This will be used to index through the array above:
- private int index=0;
- // Read up about back buffering, as it's important ;-)
- private Image backBuffer = null;
- private Graphics backg = null;
- // This will be our thread, you need to know about threads too:
- private Thread runner = null;
- /**
- * Called by the browser or applet viewer to inform this JApplet that it
- * has been loaded into the system. It is always called before the first
- * time that the start method is called.
- */
- @Override
- public void init()
- {
- // This is a workaround for a security conflict with some browsers
- // including some versions of Netscape & Internet Explorer which do
- // not allow access to the AWT system event queue which JApplets do
- // on startup to check access. May not be necessary with your browser.
- JRootPane rootPane = this.getRootPane();
- rootPane.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
- // Provide any initialisation necessary for your JApplet
- // Gets the current width and height and creates a back buffer
- // to that height:
- this.width = getSize().width;
- this.height = getSize().height;
- this.backBuffer = createImage(width, height);
- // Creates instance of the back buffer:
- this.backg = backBuffer.getGraphics();
- // Sets default behaviour as focusable:
- this.setFocusable(true);
- this.setVisible(true);
- }
- public void animate(int x, int y, int img[])
- {
- boolean xAndY = (x>=0) && (y>=0);
- if(!xAndY)
- {
- showStatus("Problem with Animate");
- }
- rotate(x, y, img);
- }
- public void scrollText()
- {
- int stringLength = this.scrolly.length();
- this.charBuffer=""+this.scrolly.charAt(0);
- String stringBuffer = ""+
- this.scrolly.substring(1, stringLength)+charBuffer;
- this.scrolly = stringBuffer;
- }
- public void rotate(int x, int y,int [] img)
- {
- do
- {
- this.buffer[index]=img[index];
- this.index++;
- }while(img[index]>=0);
- this.buffer[index+0]=-1;
- this.buffer[index+1]=-1;
- this.index=0;
- this.heightOfStar = heightOfObject(heightOfStar, img);
- this.widthOfStar = widthOfObject(widthOfStar, img);
- // Divides width and height in half
- int px=widthOfStar>>>1;
- int py=heightOfStar>>>1;
- // Sets up variables for the maths:
- double x2=0.00;
- double y2=0.00;
- double x1=0.00;
- double y1=0.00;
- // Degrees to turn:
- if(this.degrees>360)
- {
- this.degrees = (double)0;
- }
- this.degrees += (double)1;
- this.theta = (double)(degrees*3.1415)/180;
- while(this.buffer[index]>=0)
- {
- x1 = buffer[index+0];
- y1 = buffer[index+1];
- x2 = (double)px+(px-x1)*Math.cos(theta)-(py-y1)*Math.sin(theta);
- y2 = (double)py+(px-x1)*Math.sin(theta)+(py-y1)*Math.cos(theta);
- buffer[index+0]=(int)x2*1;
- buffer[index+1]=(int)y2*1;
- index += 2;
- }
- this.index = 0;
- // Calls drawImage method:
- this.drawImage(x, y, buffer);
- }
- public void drawImage(int x, int y, int [] img)
- {
- do
- {
- if(this.buffer[index]!=img[index])
- {
- System.err.println("Image not recognised");
- }
- this.index++;
- }while(img[index]>=0);
- this.index = 0;
- int x0 = 0;
- int y0 = 0;
- int x1 = 0;
- int y1 = 0;
- // Sets the default foreground colour:
- backg.setColor(Color.black);
- // This will step through the array points to draw
- // the star object. There is probably also a fillPolygon
- // or drawPolygon method that could also be used:
- while(this.buffer[index]>=0)
- {
- x0 = x+(this.buffer[index+0]);
- y0 = y+(this.buffer[index+1]);
- if (this.buffer[index+2]!=-1 && this.buffer[index+3]!=-1)
- {
- x1 = x+(this.buffer[index+2]);
- y1 = y+(this.buffer[index+3]);
- }
- else
- {
- // Back to the start:
- x1 = x+(this.buffer[0]);
- y1 = y+(this.buffer[1]);
- }
- this.backg.drawLine( x0, y0, x1, y1 );
- this.index += 2;
- }
- // Resets index to zero, incase the JApplet is reloaded or something:
- this.index = 0;
- }
- public void clearBackBuffer()
- {
- // This will clear the canvas so that there is no trail left by the star
- // by setting the default background colour and then filling it to the
- // width and height of the canvas:
- this.backg.setColor(Color.white);
- this.backg.fillRect(0, 0, this.width, this.height);
- }
- /**
- * Called by the browser or applet viewer to inform this JApplet that it
- * should start its execution. It is called after the init method and
- * each time the JApplet is revisited in a Web page.
- */
- @Override
- public void start()
- {
- // Sets up the thread:
- if(this.runner == null)
- {
- this.runner = new Thread(this);
- this.runner.start();
- }
- // Call to parent (not needed):
- // super.start();
- }
- /**
- * Called by the browser or applet viewer to inform this JApplet that
- * it should stop its execution. It is called when the Web page that
- * contains this JApplet has been replaced by another page, and also
- * just before the JApplet is to be destroyed.
- */
- @Override
- public void stop()
- {
- // Call to parent:
- super.stop();
- }
- public int heightOfObject(int currentHeight, int [] obj)
- {
- this.index = 1;
- while(obj[index]!=-1)
- {
- if(obj[index]>currentHeight)
- {
- currentHeight=obj[index];
- }
- this.index +=2;
- }
- this.index = 0;
- return currentHeight;
- }
- public int widthOfObject(int currentWidth, int [] obj)
- {
- while(obj[index]!=-1)
- {
- if(obj[index]>currentWidth)
- {
- currentWidth=obj[index];
- }
- this.index +=2;
- }
- this.index = 0;
- return currentWidth;
- }
- @Override
- public void run()
- {
- // Checks if this thread has been set to runnable in the start method:
- Thread thisThread = Thread.currentThread();
- while (runner == thisThread)
- {
- // Calls our method to draw the star:
- animate(xAxis, yAxis, STAR);
- try
- {
- // This is the time that it will pause in milliseconds
- // 1000 = 1 second:
- Thread.sleep(33);
- }
- catch (InterruptedException e)
- {
- }
- repaint();
- // This will move the x and y co-ordinates of our object:
- this.xAxis += this.xDirection;
- this.yAxis += this.yDirection;
- // This will check the boundries of the current applet canvas:
- if(xAxis >= (width-widthOfStar))
- {
- this.xDirection =-1;
- }
- if(xAxis <= 0)
- {
- this.xDirection = 1;
- }
- if(yAxis >= (height-heightOfStar))
- {
- this.yDirection =-1;
- }
- if(yAxis <= 0)
- {
- this.yDirection = 1;
- }
- // Clears the canvas, so there is no 'trail'
- // left by the moving star:
- clearBackBuffer();
- this.updateScrolly++;
- if(this.updateScrolly>128)
- {
- this.updateScrolly = 0;
- }
- if(this.updateScrolly%4 == 0)
- {
- scrollText();
- }
- showStatus(scrolly);
- }
- }
- // Main paint method (called on repaint(); I think):
- @Override
- public void paint(Graphics g)
- {
- // Calls to the update method:
- update(g);
- }
- public void update(Graphics g)
- {
- // Gets the backBuffer and draws it to the canvas:
- g.drawImage(backBuffer,0,0,this);
- // the sync toolkit is used for animations as it stops flicker:
- getToolkit().sync();
- }
- /**
- * Called by the browser or applet viewer to inform this JApplet that it
- * is being reclaimed and that it should destroy any resources that it
- * has allocated. The stop method will always be called before destroy.
- */
- @Override
- public void destroy()
- {
- // Calls the garbage collector before calling parent:
- this.runner = null;
- super.destroy();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement