Letterkenny Institute of Technology BSc in Computing in Games Development Subject: Games Programming 1 Level: 7 Date: Autumn 2008 Examiners: Dr. J.G. Campbell Dr. M.D.J. McNeill Time Allowed: Two hours. INSTRUCTIONS Answer three questions from five; the maximum number of marks obtainable is 75; marks will be converted appropriately to give a result out of 100%. Failure to properly explain answers and/or calculations may result in loss of marks. Games Programming 1 Page 1 of 22 Autumn 2008
1. Trigonometry and Vector arithmetic. (a) Use Figure 1 to draw a graph of cos a from 0 to 360 in steps of 30. There is an enlarged copy of Figure 1 on page 22 which you should detach and use for your answer; remember to include it in your answer book. [6 marks Figure 1: Circle and cosine. (b) If you know cos b = p, what is cos b? [2 marks (c) e 1 = e 2 = a = b = c = [ 1 0 [ 0 1 [ 1 4 [ 4 2 [ 4 2 (1) (2) (3) (4) (5) (i) Compute a + b. [2 marks (ii) Verify your answer to (i) using either the head to tail rule or the parallelogram rule. You must provide a diagram. (iii) Compute b + c. (iv) Compute 4a. [2 marks [2 marks [2 marks Games Programming 1 Page 2 of 22 Autumn 2008
(d) (e) (i) Compute a b (scalar product). (ii) Compute c e 2. (i) Compute the magnitude (length) of b, b. (ii) Compute the magnitude (length) of c, c. [2 marks [2 marks [3 marks [2 marks Games Programming 1 Page 3 of 22 Autumn 2008
2. Graphics programming. Figure 2 shows some simple shapes and Figure 3 shows the Java code used to draw them. Note: Figure 2 is created in a graphics framework in which the y-axis point upwards and start points of rectangles and ellipses are the bottom left. Figure 2: Simple shapes. Games Programming 1 Page 4 of 22 Autumn 2008
private Ellipse2D createcircle(point2d c, double r) return new Ellipse2D.Double( c.getx() - r, c.gety() - r, r*2.0, r*2.0); Ellipse2D e = new Ellipse2D.Double(-145., 125., 80., 100.); g2.setpaint(color.red); g2.fill(e); // C Rectangle2D r1 = new Rectangle2D.Double(-145., 125., 80., 100.); g2.setpaint(color.blue); g2.draw(r1); Rectangle2D r2 = new Rectangle2D.Double(-195., 25., 150., 80.); g2.setpaint(color.red); g2.draw(r2); Point2D pc = new Point2D.Double(250.0, 220.0); Ellipse2D circ = createcircle(pc, 80.0); g2.setpaint(color.red); g2.draw(circ); Point2D pc2 = new Point2D.Double(200.0, -100.0); Ellipse2D circ2 = createcircle(pc2, 60.0); g2.setpaint(color.green); g2.fill(circ2); Color c3 = new Color(0, 0, 255, 60); // D Point2D pc3 = new Point2D.Double(300.0, 0.0); Ellipse2D circ3 = createcircle(pc3, 30.0); g2.setpaint(c3); g2.fill(circ3); // A GeneralPath path = new GeneralPath(); path.moveto(0.0f, 80.0f); path.lineto(40.0f, 40.0f); path.lineto(140.0f, 40.0f); path.lineto(180.0f, 80.0f); path.lineto(140.0f, 120.0f); path.lineto(40.0f, 120.0f); path.lineto(0.0f, 80.0f); g2.fill(path); g2.setpaint(color.red); g2.draw(path); // B Point2D p1 = new Point2D.Double(25.0, 205.0); Point2D p2 = new Point2D.Double(155.0, 305.0); Point2D p3 = new Point2D.Double(155.0, 205.0); g2.setpaint(color.black); Line2D l1 = new Line2D.Double(p1, p2); Line2D l2 = new Line2D.Double(p2, p3); Line2D l3 = new Line2D.Double(p3, p1); g2.draw(l1); g2.draw(l2); g2.draw(l3); Figure 3: Simple Shapes Games Programming 1 Page 5 of 22 Autumn 2008
(a) Explain the four parameters of the Color constructor below. Be careful to explain the purpose of the last parameter (value 60 here). Color c3 = new Color(0, 0, 255, 60); // D [5 marks (b) Write code to draw an Rectangle2D whose bottom left corner is (x = 200, y = 150) and whose top right corner (note: top right corner) is at x = 300, y = 200; draw its outline blue. Draw an annotated sketch or write comments showing how you arrived at your answer. [6 marks (c) Referring to the example use of GeneralPath at // A, use the GeneralPath technique to draw the (same) rectangle that is drawn at // C; draw an annotated sketch showing how you arrived at your answer. [7 marks (d) Referring to the example use of Line2D at // B, use lines to draw the lozenge shape (perimeter only) that is drawn at // A; draw an annotated sketch or write comments showing how you arrived at your answer. [7 marks Games Programming 1 Page 6 of 22 Autumn 2008
3. Vector transformations. Figure 4 shows some vectors and the results of applying rotation transformations to them. Figure 5 shows the relevant Java code. Note: it may help to refer to Appendices B and C which contain some facts and formulas on vector and affine transformations. Figure 4: Vectors and transformed vectors. Games Programming 1 Page 7 of 22 Autumn 2008
Vector2DH v10 = new Vector2DH(100.0, 0.0); Point2D p0 = new Point2D.Double(0.0, 0.0); System.out.println( v10 = + v10); v10.draw(p0, Color.black, g2, v10= +v10); Transform2D t1 = new Transform2D(); t1.setrot(math.toradians(30.0)); Vector2DH v1 = t1.transform(v10); v1.draw(p0, Color.black, g2, v1= +v1); System.out.println( t1 = + t1); System.out.println( v1 = + v1); Vector2DH v2 = t1.transform(v1); v2.draw(p0, Color.black, g2, v2= +v2, 0, 0); System.out.println( v2 = + v2); Transform2D t2 = new Transform2D(); t2.setrot(math.toradians(-60.0)); Vector2DH v3 = t2.transform(v2); System.out.println( t2 = + t2); System.out.println( v3 = + v3); v3.draw(p0, Color.black, g2, v3= +v3, 0, 20); Transform2D t3 = new Transform2D(); t3.setrot(math.toradians(150.0)); System.out.println( v10 = + v10); System.out.println( t1 = + t1); System.out.println( t3 = + t3); Transform2D tt = Transform2D.mult(t1, t3); System.out.println( tt = + tt); Vector2DH v4 = tt.transform(v10); v4.draw(p0, Color.black, g2, v4= +v4, 0, 10); System.out.println( v4 = + v4); Figure 5: Vectors and transformed vectors code Games Programming 1 Page 8 of 22 Autumn 2008
(a) Below is the output related to vectors v 10 and v 1. v10 = (100.0, 0.0) t1 = [( 0.866, -0.500, 0.000) ( 0.500, 0.866, 0.000) v1 = ( 86.6, 50.0) (i) Explain the numbers in t1. (ii) Explain how the values in v 1 = (86.6, 50.0) are arrived at. [4 marks [4 marks (b) Explain how the values in v 2 = (50.0, 86.6) are arrived at. [4 marks (c) Explain how the values in v 3 = (100.0, 0.0) are arrived at. [4 marks (d) Below is the output related to vectors v 10 and v 4 and the transformations t1, t3, tt. Explain how the values in tt are arrived at. v10 = (100.0, 0.0) t1 = [( 0.866, -0.500, 0.000) ( 0.500, 0.866, 0.000) t3 = [( -0.866, -0.500, 0.000) ( 0.500, -0.866, 0.000) tt = [( -1.000, 0.000, 0.000) ( 0.000, -1.000, 0.000) v4 = (-100.0, 0.0) [4 marks Games Programming 1 Page 9 of 22 Autumn 2008
(e) Figure 6 shows some vectors and the results of applying a transformation to them. Figure 7 shows the relevant Java code. Figure 6: Vectors and mystery transformation. Question. Derive the values of a11, a12, a21, a22 in the transformation t4. [5 marks Games Programming 1 Page 10 of 22 Autumn 2008
Transform2D t4 = new Transform2D(); t4.set... // mystery transformation System.out.println( t4 = + t4); Vector2DH v01 = new Vector2DH(0.0, 100.0); System.out.println( v10 = + v10); v10.draw(p0, Color.black, g2, v10= +v10); System.out.println( v01 = + v01); v01.draw(p0, Color.black, g2, v01= +v01, 0, 25); Vector2DH vv10 = t4.transform(v10); vv10.draw(p0, Color.black, g2, vv10= +vv10); System.out.println( vv10 = + vv10); Vector2DH vv01 = t4.transform(v01); vv01.draw(p0, Color.black, g2, vv01= +vv01, -100, 0); System.out.println( vv01 = + vv01); Output. t4 = [( a11, a12, 0.000) // actual values replaced by a11 etc. ( a21, a22, 0.000) v10 = (100.0, 0.0) v01 = ( 0.0, 100.0) vv10 = ( 81.9, 57.4) vv01 = (-57.4, 81.9) Figure 7: Mystery transformation Games Programming 1 Page 11 of 22 Autumn 2008
4. Games programming. (a) How can parallax scrolling be used to give a 3D effect in a 2D game? [5 marks (b) Figure 9 shows a level map file for a tile-based game. The sprite and tile images are shown in Figure 8. (A background is displayed separately.) Figure 8: Sprites and tiles. Games Programming 1 Page 12 of 22 Autumn 2008
# Map file for tile-based game # (Lines that start with # are comments) # The tiles are: # (Space) Empty tile # A..Z Tiles A through Z # o Star #! Music Note # * Goal # 1 Bad Guy 1 (grub) # 2 Bad Guy 2 (fly) o o o o o o o o o o o o o o IIIIIII IIIIIII o o 2 o 2 2 2EF EF EGD EF 1 CD 1 1 EGAD * BBBBBBBBGHBBBBBBBGHBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBGAAHBBBBBBBBBBB # # in (c) draw from here --- Figure 9: Map file for tile-based game Give a detailed commentary on how the code in Figures 10 and 11 use the level map file to initialise the game display. [10 marks (c) Draw the right hand eight columns of the display to demonstrate that you understand the meaning of the map file. Question 4, part (d), continues on page 16. [4 marks Games Programming 1 Page 13 of 22 Autumn 2008
private TileMap loadmap(string filename) throws IOException ArrayList lines = new ArrayList(); int width = 0; int height = 0; // read every line in the text file into the list BufferedReader reader = new BufferedReader( new FileReader(filename)); while (true) String line = reader.readline(); // no more lines to read if (line == null) reader.close(); break; // add every line except for comments if (!line.startswith( # )) lines.add(line); width = Math.max(width, line.length()); // parse the lines to create a TileEngine height = lines.size(); TileMap newmap = new TileMap(width, height); for (int y=0; y height; y++) String line = (String)lines.get(y); for (int x=0; x line.length(); x++) char ch = line.charat(x); // check if the char represents tile A, B, C etc. int tile = ch - A ; if (tile = 0 && tile tiles.size()) newmap.settile(x, y, (Image)tiles.get(tile)); // continued... Figure 10: Level reader for a sprite-tile-based game, part 1. Games Programming 1 Page 14 of 22 Autumn 2008
// four lines repeated... int tile = ch - A ; if (tile = 0 && tile tiles.size()) newmap.settile(x, y, (Image)tiles.get(tile)); // check if the char represents a sprite else if (ch == o ) addsprite(newmap, coinsprite, x, y); else if (ch ==! ) addsprite(newmap, musicsprite, x, y); else if (ch == * ) addsprite(newmap, goalsprite, x, y); else if (ch == 1 ) addsprite(newmap, grubsprite, x, y); else if (ch == 2 ) addsprite(newmap, flysprite, x, y); // add the player to the map Sprite player = (Sprite)playerSprite.clone(); player.setx(tilemaprenderer.tilestopixels(3)); player.sety(0); newmap.setplayer(player); return newmap; private void addsprite(tilemap map, Sprite hostsprite, int tilex, int tiley) if (hostsprite!= null) // clone the sprite from the host Sprite sprite = (Sprite)hostSprite.clone(); // center the sprite sprite.setx( TileMapRenderer.tilesToPixels(tileX) + (TileMapRenderer.tilesToPixels(1) - sprite.getwidth()) / 2); // bottom-justify the sprite sprite.sety(tilemaprenderer.tilestopixels(tiley + 1) - sprite.getheight()); // add it to the map map.addsprite(sprite); Figure 11: Level reader for a sprite-tile-based game, part 2. Games Programming 1 Page 15 of 22 Autumn 2008
(d) Explain the use of draw in Figure 12 in updating the positions of a number of sprites in a game. Concentrate on // *1 and // *2; be sure to mention the circumstances in which sprite.getvelocityx() 0 would be true and how the two lines: transform.scale(-1, 1); transform.translate(-sprite.getwidth(), 0); will alter the appearance of a sprite such as grub1 or grub2 in Figure 8. [6 marks public void draw(graphics2d g) // draw background g.drawimage(bgimage, 0, 0, null); AffineTransform transform = new AffineTransform(); for (int i = 0; i NUM SPRITES; i++) Sprite sprite = sprites[i; // *1 transform.settotranslation(sprite.getx(), sprite.gety()); // *2 if (sprite.getvelocityx() 0) transform.scale(-1, 1); transform.translate(-sprite.getwidth(), 0); // draw it g.drawimage(sprite.getimage(), transform, null); Figure 12: Sprite position updater. Games Programming 1 Page 16 of 22 Autumn 2008
5. General topics. Write short notes on the following topics. Each is worth five marks. (a) Double buffering. (b) Anti-aliasing. (c) Little endian versus big endian. Hint: a 32-bit integer occupies four bytes. (d) Threads. (e) Scaling vector transformation. [25 marks Games Programming 1 Page 17 of 22 Autumn 2008
Appendix A, Trigonometry. Figure 13: Sin, cos and and circle. From Figure 13 we can see from Pythagoras s Theorem that Some values. sin 0 = 0, sin 90 = 1. cos 0 = 1, cos 90 = 0. sin 2 θ + cos 2 θ = 1. (6) Radians. A radian is about 57 ; it is the angle subtended by an arc of length r on a circle of radius r. π/2radians = 90, πradians = 180, 2π radians = 360, etc. π = 3.141592635.... Degrees, d, to radians, r: r = (180/π) d. Cos and Sin are periodic over 2π radians or 360. cos and sin repeat themselves after 2π radians or 360 deg. Sin is an odd function: sin θ = sin θ. Cos is an even function: cos θ = cos θ. Games Programming 1 Page 18 of 22 Autumn 2008
Useful equations. sin(θ + φ) = sin θ cos φ + cos θ sin φ, (7) sin(θ φ) = sin θ cos φ cos θ sin φ, (8) cos(θ + φ) = cos θ cos φ sin θ sin φ, (9) cos(θ φ) = cos θ cos φ + sin θ sin φ. (10) sin 2 θ + cos 2 θ = 1. (11) sin 2 θ = 1 (1 cos 2θ). (12) 2 cos 2 θ = 1 (1 + cos 2θ). (13) 2 cos 2θ = cos 2 θ sin 2 θ = 1 sin 2 θ = 2 cos 2 θ 1. (14) Games Programming 1 Page 19 of 22 Autumn 2008
Appendix B, 2D Linear Transformations. Scaling [ vx v y [ sx 0 = 0 s y [ ux u y. (15) Rotation [ vx v y [ cos b sin b = sin b cos b [ ux u y. (16) Shear Shear along the x axis, [ vx v y = [ 1 a 0 1 [ ux u y. (17) Shear along the y axis, [ vx v y = [ 1 0 b 1 [ ux u y. (18) Reflection Reflect about the y axis (x-coordinates are negated), [ [ [ vx 1 0 ux =. (19) 0 1 v y u y Reflect about the x axis (y-coordinates are negated), [ [ [ vx 1 0 ux = 0 1 v y u y. (20) Projection Projection onto x-axis, [ vx v y = [ 1 0 0 0 [ ux u y. (21) Projection onto the y-axis, [ vx v y = [ 0 0 0 1 [ ux u y. (22) Translation [ vx v y = [ tx t y + [ ux u y. (23) Games Programming 1 Page 20 of 22 Autumn 2008
Appendix C, 3D Affine Transformations using Homogeneous Coordinates. Translation v x v y v z v w = 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 u x u y u z u w. (24) Rotation about the z-axis Rotation about the x-axis Rotation about the y-axis R z (b) = R x (b) = R y (b) = cos b sin b 0 0 sin b cos b 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 cos b sin b 0 0 sin b cos b 0 0 0 0 1 cos b 0 sin b 0 0 1 0 0 sin b 0 cos b 0 0 0 0 1. (25). (26). (27) Games Programming 1 Page 21 of 22 Autumn 2008
y 1 0.8 a = 30 cos(a) 0.8 0.4 0.2 1 0.8 0.6.4.2 O 0.2 0.4 0.6 0.8 1 X 0 0.2 0.4 0.6 0.8 1 a Figure 14: To be use in answering question 1.(a). Detach and include in your answer book. Games Programming 1 Page 22 of 22 Autumn 2008