This page is optimized for mobile devices, if you would prefer the desktop version just click here

1.11 Game 2302-0130: putting the game-math library to work  (Page 19/20)

Listing 20 . Source code for the program named VectorAdd06.

/*VectorAdd06.java Copyright 2008, R.G.BaldwinRevised 02/22/08. This is an update to the program named VectorAdd05. Thebehavior of this program is similar to the earlier program except that instead of displaying a static view ofthe translated geometric object when the Replot button is clicked, this program animates the geometric objectcausing it to move from its original location to its new location in 100 incremental steps along a straight linepath. The animation loop sleeps for ten milliseconds during eachof the 100 iterations. Therefore, approximately one second (1000 milliseconds and possibly more) is required for the object to make the trip from its initial location to itsnew location. Once it reaches the new location, the program is ready for the user to change input values andclick the Replot button again. As with the program named VectorAdd05, this program usesthe addVectorToPoint method of the GM2D04.Point class to translate a geometric object from one location in space toa different location in space. In this program, however, the translation is performed in 100 incremental stepsto produce an animation. The animated geometric object is drawn in red to make it visually distinct from theoriginal object. The original object is not erased from the display.The program initially constructs and draws a black hexagon in the upper-left corner of the canvas. The six pointsthat define the vertices of the hexagon lie on a circle with a radius of 50 units. The points at the vertices andthe lines that connect the points are drawn initially. A GUI is provided that allows the user to specify thefollowing items and click a Replot button to cause the animation to begin:Number points X-component of the displacement vector.Y-component of the displacement vector. A checkbox to specify whether points are to be drawn.A checkbox to specify whether lines are to be drawn. Changing the number of points causes the number ofvertices that describe the geometric object to change. For a large number of points, the geometric object becomesa circle. For only three points, it becomes a triangle. For four points, it becomes a rectangle. For two points,it becomes a line, etc. On the computer that I am now using, the animation becomes jerky at about 700 pointswhen both the points and the lines are drawn. Changing the components of the displacement vector causesthe geometric object to be translated to a different location.Checking and unchecking the checkboxes causes the points and/or the lines to either be drawn or not drawn.Tested using JDK 1.6 under WinXP. *********************************************************/import java.awt.*; import javax.swing.*;import java.awt.geom.*; import java.awt.event.*;class VectorAdd06{ public static void main(String[]args){ GUI guiObj = new GUI();}//end main }//end controlling class VectorAdd06//======================================================// class GUI extends JFrame implements ActionListener{//Specify the horizontal and vertical size of a JFrame // object.int hSize = 400; int vSize = 400;Image osi;//an off-screen image int osiWidth;//off-screen image widthint osiHeight;//off-screen image height MyCanvas myCanvas;//a subclass of CanvasGraphics2D g2D;//off-screen graphics context.//The following two variables are used to establish the // location of the origin.double xAxisOffset; double yAxisOffset;int numberPoints = 6;//Can be modified by the user. JTextField numberPointsField; //User input field.//The components of the following displacement vector // can be modified by the user.GM2D04.Vector vector = new GM2D04.Vector(new GM2D04.ColMatrix(0,0));JTextField vectorX;//User input field. JTextField vectorY;//User input field.//The following variables are used to determine whether// to draw the points and/or the lines. boolean drawPoints = true;boolean drawLines = true; Checkbox drawPointsBox;//User input fieldCheckbox drawLinesBox;//User input field.//The following variables are used to refer to array // objects containing the points that define the// vertices of the geometric objects. GM2D04.Point[]points; GM2D04.Point[]newPoints;boolean animation = false; //----------------------------------------------------//GUI(){//constructor//Instantiate the array objects that will be used to // store the points that define the vertices of the// geometric object. points = new GM2D04.Point[numberPoints]; newPoints = new GM2D04.Point[numberPoints];//Set JFrame size, title, and close operation. setSize(hSize,vSize);setTitle("Copyright 2008,R.G.Baldwin"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Instantiate the user input components.numberPointsField =new JTextField("6"); vectorX = new JTextField("300");vectorY = new JTextField("100"); drawPointsBox = new Checkbox("Draw Points",true);drawLinesBox = new Checkbox("Draw Lines",true); JButton button = new JButton("Replot");//Instantiate a JPanel that will house the user input // components and set its layout manager.JPanel controlPanel = new JPanel(); controlPanel.setLayout(new GridLayout(3,3));//Add the user input component and appropriate labels // to the control panel.controlPanel.add(new JLabel(" Number Points")); controlPanel.add(numberPointsField);controlPanel.add(drawPointsBox); controlPanel.add(new JLabel(" Vector X"));controlPanel.add(vectorX); controlPanel.add(drawLinesBox);controlPanel.add(new JLabel(" Vector Y")); controlPanel.add(vectorY);controlPanel.add(button); //Add the control panel to the SOUTH position in the// JFrame. this.getContentPane().add(BorderLayout.SOUTH,controlPanel); //Instantiate a new drawing canvas and add it to the// CENTER of the JFrame above the control panel. myCanvas = new MyCanvas();this.getContentPane().add( BorderLayout.CENTER,myCanvas);//This object must be visible before you can get an // off-screen image. It must also be visible before// you can compute the size of the canvas. setVisible(true);//Make the size of the off-screen image match the// size of the canvas. osiWidth = myCanvas.getWidth();osiHeight = myCanvas.getHeight();//Set the values that will be used to establish the // origin, thus defining a coordinate frame.xAxisOffset = osiWidth/2; yAxisOffset = osiHeight/2;//Create an off-screen image and get a graphics// context on it. osi = createImage(osiWidth,osiHeight);g2D = (Graphics2D)(osi.getGraphics());//Erase the off-screen image, establish the // coordinate frame by translating the origin to the// new location and draw the axes setCoordinateFrame(g2D,xAxisOffset,yAxisOffset,true);//Create the Point objects that define the geometric // object and manipulate them to produce the desired// results. drawOffScreen(g2D);//Register this object as an action listener on the// button. button.addActionListener(this);//Cause the overridden paint method belonging to // myCanvas to be executed.myCanvas.repaint();}//end constructor //----------------------------------------------------////The purpose of this method is to Create the Point// objects that define the vertices of the geometric // object and manipulate them to produce the desired// results. void drawOffScreen(Graphics2D g2D){//Erase the off-screen image and draw new axes, but // don't change the coordinate frame.setCoordinateFrame(g2D,xAxisOffset,yAxisOffset,false);//Create a set of Point objects that specify // locations on the circumference of a circle and// save references to the Point objects in an array. // Position the circle at the upper-left corner of the// canvas. for(int cnt = 0;cnt<numberPoints;cnt++){ points[cnt]= new GM2D04.Point( new GM2D04.ColMatrix(50*Math.cos((cnt*360/numberPoints) *Math.PI/180) - 150,50*Math.sin((cnt*360/numberPoints) *Math.PI/180) - 100));if(drawPoints){//Draw points if true points[cnt].draw(g2D); }//end if}//end for loopGM2D04.Line line; if(drawLines){//Instantiate and draw lines if true.for(int cnt = 0;cnt<numberPoints-1;cnt++){ //Begin by drawing all of the lines but one.line = new GM2D04.Line(points[cnt],points[cnt+1]); line.draw(g2D);}//end for loop //Draw the remaining line required to close the// polygon. line = new GM2D04.Line(points[numberPoints-1], points[0]); line.draw(g2D);}//end ifg2D.setColor(Color.RED);//Change drawing color to RED. if(animation){//This code is executed only after the Replot button // has been clicked once.//Translate the geometric object and save the points // that define the translated object in another// array. for(int cnt = 0;cnt<numberPoints;cnt++){ newPoints[cnt]= points[cnt].addVectorToPoint(vector); if(drawPoints){//Draw points if true.newPoints[cnt].draw(g2D);}//end if }//end for loopif(drawLines){//Instantiate and draw lines if true.for(int cnt = 0;cnt<numberPoints-1;cnt++){ line = new GM2D04.Line(newPoints[cnt], newPoints[cnt+1]); line.draw(g2D);}//end for loop //Draw the remaining line required to close the// polygon. line = new GM2D04.Line(newPoints[numberPoints-1], newPoints[0]); line.draw(g2D);}//end if }//end if(animation)}//end drawOffScreen //----------------------------------------------------////This method is used to set the coordinate frame of // the off-screen image by setting the origin to the// specified offset values relative to the origin of the // world. The origin of the world is the upper-left// corner of the off-screen image. //The method draws black orthogonal axes on the// off-screen image. //There is no intention to perform mathematical// operations on the axes, so they are drawn // independently of the classes and methods in the// game-math library using the simplest available method // for drawing lines.//The method assumes that the origin is at the // upper-left corner when the method is first called.//Each time the method is called, it paints the // background white erasing anything already there.//The fourth parameter is used to determine if the // origin should be translated by the values of the// second and third parameters. private void setCoordinateFrame(Graphics2D g2D,double xOffset, double yOffset,boolean translate){ //Paint the background whiteg2D.setColor(Color.WHITE); g2D.fillRect(-(int)xOffset,-(int)yOffset,(int)osiWidth,(int)osiHeight); //Translate the origin by the specified amount if the// fourth parameter is true. if(translate){g2D.translate((int)xOffset,(int)yOffset);}//end if //Draw new X and Y-axes in BLACKg2D.setColor(Color.BLACK); g2D.drawLine(-(int)(xOffset - 10),0,(int)(xOffset - 10),0);g2D.drawLine(0,-(int)(yOffset - 10), 0,(int)(yOffset - 10));}//end setCoordinateFrame method //----------------------------------------------------////This method is called to respond to a click on the// button. public void actionPerformed(ActionEvent e){//Get user input values and use them to modify several // values that control the translation and the// drawing. numberPoints = Integer.parseInt(numberPointsField.getText());vector.setData( 0,Double.parseDouble(vectorX.getText()));vector.setData( 1,Double.parseDouble(vectorY.getText()));if(drawPointsBox.getState()){ drawPoints = true;}else{ drawPoints = false;}//end elseif(drawLinesBox.getState()){ drawLines = true;}else{ drawLines = false;}//end else//Instantiate two new array objects with a length // that matches the new value for numberPoints.points = new GM2D04.Point[numberPoints];newPoints = new GM2D04.Point[numberPoints];//Set the animation flag to true to enable animation. animation = true;//Spawn an animation thread Animate animate = new Animate();animate.start(); }//end actionPerformed//====================================================////This is an inner class of the GUI class. class MyCanvas extends Canvas{//Override the update method to eliminate the default // clearing of the Canvas in order to reduce or// eliminate the flashing that that is often caused by // such default clearing.//In this case, it isn't necessary to clear the canvas // because the off-screen image is cleared each time// it is updated. This method will be called when the // JFrame and the Canvas appear on the screen or when// the repaint method is called on the Canvas object. public void update(Graphics g){paint(g);//Call the overridden paint method. }//end overridden update()//Override the paint() method. The purpose of the// paint method in this program is simply to copy the // off-screen image onto the canvas. This method is// called by the update method above. public void paint(Graphics g){g.drawImage(osi,0,0,this); }//end overridden paint()}//end inner class MyCanvas //====================================================////This is an animation thread.class Animate extends Thread{ public void run(){//During each iteration of the following loop, an // incremental displacement vector is created with// X and Y components that are equal to 1/100 of the // user-specified displacement vector multiplied by// the loop counter value. //The incremental displacement vector is used by the// code in the drawOffScreen method to translate // the geometric object to a new location on the// off-screen image. Then the repaint method is // called on the canvas to cause the off-screen// image to be copied onto the canvas. After that, // this thread sleeps for ten milliseconds before// starting the next iteration. //The bottom line is that this code causes the// geometric object to move in incremental steps // from its initial location to a new location based// on a displacement vector specified by the user. // In other words, the geometric object reaches its// final location in a straight-line animated // manner, taking 100 steps to get there.//Compute the incremental distances that the // geometric object will move during each iteration.double xInc = vector.getData(0)/100; double yInc = vector.getData(1)/100;//Do the animated move.for(int cnt = 0;cnt<100;cnt++){ vector.setData(0,cnt*xInc);vector.setData(1,cnt*yInc);//Draw a new off-screen image based on the // incremental displacement vector and other user// inputs. drawOffScreen(g2D);//Copy off-screen image to canvas. myCanvas.repaint();//Sleep for ten milliseconds.try{ Thread.currentThread().sleep(10);}catch(InterruptedException ex){ ex.printStackTrace();}//end catch }//end for loop}//end run }//end inner class named Animate//====================================================// }//end class GUI//======================================================//
<< Chapter < Page Page > Chapter >>

Read also:

OpenStax, Game 2302 - mathematical applications for game development. OpenStax CNX. Jan 09, 2016 Download for free at https://legacy.cnx.org/content/col11450/1.33
Google Play and the Google Play logo are trademarks of Google Inc.
Jobilize.com uses cookies to ensure that you get the best experience. By continuing to use Jobilize.com web-site, you agree to the Terms of Use and Privacy Policy.