Download presentation
Presentation is loading. Please wait.
Published byBruno Rich Modified over 9 years ago
1
240-492 Java Games: Aliens/81 Games Programming with Java v Objectives –to describe and illustrate techniques for writing larger games u control hierarchies, sprite interactions, managers, sprite subclasses, state diagrams 240-492, Special Topics in Comp. Eng. II Semester 1, 2002-2003 8. Alien Attack v.1
2
240-492 Java Games: Aliens/82 Overview 1. Alien Attack 2. Control Hierarchy 3. The Game Manager 4. The Gun Manager 5. The UFO Manager 6.The Gun Sprite 7.The Missile Sprite 8.The UFO Sprite
3
240-492 Java Games: Aliens/83 1. Alien Attack v Your mission: –to prevent aliens from landing on Earth, by destroying their UFOs before they land u you can shoot missiles at UFOs from a missile launcher –to avoid being touched by a UFO
4
240-492 Java Games: Aliens/84 1.1. Playing the Game continued Alien UFOs (7 of them) a missile the missile launcher the gun barrel
5
240-492 Java Games: Aliens/85 I closed the game
6
240-492 Java Games: Aliens/86 1.2. Game Restrictions v The launcher can only move left or right, and stops at the edges of the window –movement is done using the left and right arrow keys v A missile will not destroy a UFO when it is in its ‘attack’ state. v A destroyed UFO disappears, but a new one appears immediately! continued
7
240-492 Java Games: Aliens/87 v A missile can only be fired straight up –a missile is fired by pressing the up arrow key v Only one missile can be fired at a time –another cannot be fired until the current missile has hit a UFO or gone off the top of the screen
8
240-492 Java Games: Aliens/88 1.3. Game Background v The original version of this game is described in: –"Black Art of Java Game Programming” Joel Fan et al., The Waite Group, 1996 Chapter 5 –I have recoded it to use my sprite classes, and modern Java coding.
9
240-492 Java Games: Aliens/89 2. Control Hierarchy Game Manager Gun ManagerUFO Manager Gun SpriteMissile SpriteUFO Sprites creation and initialisation updates redraws continued method calls
10
240-492 Java Games: Aliens/810 v A hierarchy of managers is a good way to hide details –e.g. the GameManager does not need to know about the low-level interactions between sprites controlled by the GunManager v A hierarchy helps scaleability –as more sprites are added, the top-levels of the game are affected less
11
240-492 Java Games: Aliens/811 Sprite Interactions GunSprite MissileSprite UFOSprite moves from GunManager get gun barrel position; tell gun that it has been hit by a UFO launch from GunManager check if missile intersects a UFO; announce hit
12
240-492 Java Games: Aliens/812 3. The Game Manager v Main tasks: –1. create and initialise gun and ufo managers –2. translate player key presses into calls to the gun manager methods u 2.1. move the gun u 2.2. fire a missile –3. pass update and redraw requests to gun and ufo managers Most managers carry out these 5 kinds of tasks
13
240-492 Java Games: Aliens/813 3.1. GameManager UML
14
240-492 Java Games: Aliens/814 3.2. GameManager.java Code import java.awt.*; import java.awt.event.*; import javax.swing.*; public class GameManager extends JFrame { GameManagerPanel gmp; public GameManager() { super( "Alien Attack!!" ); Container c = getContentPane(); c.setLayout( new BorderLayout() ); gmp = new GameManagerPanel(); c.add( gmp, "Center"); :
15
240-492 Java Games: Aliens/815 addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_LEFT) gmp.moveLeft(); else if (keyCode == KeyEvent.VK_RIGHT) gmp.moveRight(); else if (keyCode == KeyEvent.VK_UP) gmp.fireMissile(); } }); setDefaultCloseOperation( Frame.EXIT_ON_CLOSE); pack(); setResizable(false); show(); } // end of GameManager() a key press is passed to the GameManager Panel
16
240-492 Java Games: Aliens/816 public static void main( String args[] ) { new GameManager(); } } // end of GameManager class
17
240-492 Java Games: Aliens/817 class GameManagerPanel extends JPanel implements ActionListener { static final int PWIDTH = 500; static final int PHEIGHT = 500; private GunManager gm; private UFOManager um; :
18
240-492 Java Games: Aliens/818 public GameManagerPanel() { setBackground(Color.black); setPreferredSize(new Dimension(PWIDTH,PHEIGHT)); gm = new GunManager(PWIDTH, PHEIGHT); um = new UFOManager(gm.getGun(),PWIDTH,PHEIGHT); gm.makeMissile( um.getUFOs() ); // create the timer Timer animatorTimer = new Timer(50, this); animatorTimer.setInitialDelay(0); animatorTimer.setCoalesce(true); animatorTimer.start(); } // end of GameManagerPanel() task 1 Part of initialisation is sharing info. between sub-managers and sprites
19
240-492 Java Games: Aliens/819 public void moveLeft() { gm.moveGunLeft(); } public void moveRight() { gm.moveGunRight(); } public void fireMissile() { gm.fireMissile(); } tasks 2.1 and 2.2
20
240-492 Java Games: Aliens/820 public void actionPerformed(ActionEvent e) // timer triggers execution of this method { gm.updateSprites(); um.updateSprites(); repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); gm.drawSprites(g); um.drawSprites(g); } } // end of GameManagerPanel class task 3
21
240-492 Java Games: Aliens/821 4. The Gun Manager v Main tasks: –1. create and initialise a GunSprite and MissileSprite object –2. pass gun movement requests to GunSprite –3. pass firing requests to MissileSprite –4. pass update and redraw requests to both sprites
22
240-492 Java Games: Aliens/822 4.1. GunManager UML
23
240-492 Java Games: Aliens/823 4.2. GunManager.java Code import javax.swing.*; import java.awt.*; import java.util.*; public class GunManager { private GunSprite gun; private MissileSprite missile; private int pWidth, pHeight; static final int GUN_MOVE = 10; :
24
240-492 Java Games: Aliens/824 public GunManager(int w, int h) // Only the gun is made here; the missile is // created by makeMissile() { gun = new GunSprite(w, h); pWidth = w; pHeight = h; } public void makeMissile(ArrayList targets) { missile = new MissileSprite(targets, pWidth, pHeight); } public void moveGunLeft() { gun.move(-1*GUN_MOVE); } public void moveGunRight() { gun.move(GUN_MOVE); } task 1 task 2
25
240-492 Java Games: Aliens/825 public void fireMissile() { missile.launch( gun.getGunX() ); } public GunSprite getGun() { return gun; } public void updateSprites() { gun.updateSprite(); missile.updateSprite(); } public void drawSprites(Graphics g) { gun.drawSprite(g); missile.drawSprite(g); } } // end of GunManager class task 3 task 4
26
240-492 Java Games: Aliens/826 4.3. Notes The missile sprite is passed an arraylist of UFO references when it is created ( targets ): missile = new MissileSprite(targets, pWidth, pHeight); –this means that the missile can communicate directly with the UFOs
27
240-492 Java Games: Aliens/827 5. The UFO Manager v Main tasks: –1. create and initialise 7 UFOSprite objects u 1.1. these are reused through out the game u 1.2. part of the initialisation is to generate a random starting position for each object –2. pass update and redraw requests to all the sprites
28
240-492 Java Games: Aliens/828 5.1. UFOManager UML
29
240-492 Java Games: Aliens/829 5.2. UFOManager.java Code import javax.swing.*; import java.awt.*; import java.util.*; public class UFOManager { private ArrayList ufos; static final int NUM_UFOS = 7; // the game has 7 ufos private int pWidth, pHeight; :
30
240-492 Java Games: Aliens/830 public UFOManager(GunSprite gun, int w, int h) { int xPosn, yPosn; pWidth = w; pHeight = h; ufos = new ArrayList(); for (int i=0; i < NUM_UFOS; i++) { xPosn = getRand( pWidth ); yPosn = getRand( pHeight/3 ); ufos.add( new UFOSprite(xPosn, yPosn, pWidth, pHeight, gun) ); } } // end of UFOManager() task 1 task 1.2
31
240-492 Java Games: Aliens/831 public ArrayList getUFOs() { return ufos; } public void updateSprites() { UFOSprite ufo; for (int i=0; i < ufos.size(); i++) { ufo = (UFOSprite) ufos.get(i); if ( ufo.isActive()) ufo.updateSprite(); else { // reuse ufo in a new posn initPosition(ufo); ufo.setActive(true); } } } // end of updateSprites() task 2
32
240-492 Java Games: Aliens/832 private void initPosition(UFOSprite ufo) { int xPosn = getRand( pWidth ); int yPosn = getRand( pHeight/3 ); ufo.setPosition(xPosn, yPosn); } public void drawSprites(Graphics g) { UFOSprite ufo; for (int i=0; i < ufos.size(); i++) { ufo = (UFOSprite) ufos.get(i); ufo.drawSprite(g); } } task 2 task 1.1
33
240-492 Java Games: Aliens/833 // random number generator between 0-x private int getRand(int x) { return (int)(x * Math.random()); } } // end of UFOManager class
34
240-492 Java Games: Aliens/834 5.3. Notes Each UFO sprite is passed a reference to the gun sprite when it is created ( gun ): new UFOSprite(xPosn, yPosn, pWidth, pHeight, gun) –this means a UFO can communicate directly with the gun
35
240-492 Java Games: Aliens/835 6. The Gun Sprite v It processes updates and redraws from the Gun manager, and has the interactions: GunSprite UFOSprite moves from GunManager get gun barrel position; tell gun that it has been hit by a UFO
36
240-492 Java Games: Aliens/836 6.1. Gun Positioning v We must calculate the top-left (x,y) coordinate for the gun sprite so that it rests on the bottom of the window. v The sprite must not be allowed to go too far left or right –its central ‘gun barrel’ must never go outside the window
37
240-492 Java Games: Aliens/837 Window Lengths PHeight (panel height) PWidth (panel width) width height barrel continued
38
240-492 Java Games: Aliens/838 Coordinate: ( PWidth/2-width/2, PHeight-height) Minimum x position: -width/2 Maximum x position: PWidth-width/2 The current barrel x-coordinate is the current x-coordinate of the image (locx) + width/2
39
240-492 Java Games: Aliens/839 6.2. GunSprite UML
40
240-492 Java Games: Aliens/840 6.3. GunSprite.java Code import java.awt.*; import javax.swing.*; import AndySprite.ImagesSprite; public class GunSprite extends ImagesSprite { GunSprite(int w, int h) /* Override ImagesSprite() constructor so currect starting posn for sprite can be calculated before image is made visible.*/ { super(w, h); setStep(0,0); // no movement loadImage("image", "gun"); setPosition(getPWidth()/2 - getWidth()/2, getPHeight() - getHeight() ); setActive(true); }
41
240-492 Java Games: Aliens/841 public void move(int xDist) // move but keep barrel on-screen { int newBPosn = locx + xDist + getWidth()/2; // position of gun barrel if (newBPosn getPWidth()) // barrel off screen on rhs locx = getPWidth() - getWidth()/2; else // within screen locx += xDist; setPosition(locx, locy); }
42
240-492 Java Games: Aliens/842 public int getGunX() // return central barrel x-coord position { return locx + getWidth()/2; } public int getGunY() // return gun y-coord position { return locy; } public void hit() // gun is hit by a ufo { System.out.println("Gun is hit by a UFO!"); } public void updateSprite() // no built-in movement behaviour, and // drawing area is fixed { } } // end of GunSprite class
43
240-492 Java Games: Aliens/843 7. The Missile Sprite v It processes updates and redraws from the Gun manager, and has the interactions: MissileSprite UFOSprite launch from GunManager check if missile intersects a UFO; announce hit
44
240-492 Java Games: Aliens/844 7.1. Missile Initialisation v The gun manager can partially initialise the gun sprite: –set its speed in the y-direction v But its (x,y) location is set only when the missile is ‘fired’; then the missile is made active.
45
240-492 Java Games: Aliens/845 7.2. Missile Termination v A missile is finished when: –it passes off the top of the window, or –it hits (intersects) a UFO u this requires an intersection test with each UFO at each update u the missile must have references to all the UFOs v The missile sprite is reused by making it inactive.
46
240-492 Java Games: Aliens/846 7.3. MissileSprite UML
47
240-492 Java Games: Aliens/847 7.4. MissileSprite.java Code import java.awt.*; import javax.swing.*; import java.util.*; import AndySprite.ImagesSprite; public class MissileSprite extends ImagesSprite { static final int Y_SPEED = -27; // missile flies upwards ArrayList targets; // the UFOs :
48
240-492 Java Games: Aliens/848 MissileSprite(ArrayList ts, int w, int h) /* Override ImagesSprite() constructor so sprite can be partially setup. It is started by a separate call to fireMissile(). */ { super(w, h); setStep(0, Y_SPEED); // movement loadImage("image", "missile"); targets = ts; // ufos to try to hit // (x,y) location is not set until // the missile is fired setActive(false); // missile not enabled yet }
49
240-492 Java Games: Aliens/849 public void launch(int xLocation) // xLocation is the barrel posn of the gun { if (!isActive()) { // if not already flying locy = getPHeight() - getHeight(); locx = xLocation; setActive(true); } } the x location is supplied by the gun manager, which gets it from the gun sprite
50
240-492 Java Games: Aliens/850 public void updateSprite() { UFOSprite ufo; if (isActive()) { if (locy+getHeight() <= 0) // off top setActive(false); else { // check if intersects a ufo Rectangle me = getMyRectangle(); for(int i=0; i < targets.size(); i++) { ufo = (UFOSprite) targets.get(i); if ( ufo.intersect(me) ) { ufo.hit(); // tell ufo it is hit setActive(false); break; } } moveSprite(); }} } // end of updateSprite() } // end of MissileSprite class
51
240-492 Java Games: Aliens/851 8. The UFO Sprite v It processes updates and redraws from the UFO manager, and has the interactions: GunSprite MissileSprite UFOSprite get gun barrel position; tell gun that it has been hit by a UFO check if missile intersects a UFO; announce hit
52
240-492 Java Games: Aliens/852 8.1. UFO Behaviour v A UFO sprite must act in an ‘interesting’ way, which cannot be easily predicted by the player. v Each UFO should act in a (slightly) different way. continued
53
240-492 Java Games: Aliens/853 v Complex behaviour is represented by multiple internal states inside the sprite –each state has a different behaviour v A good way to model multiple states is with a state transition diagram. v The unpredicatable behaviour required for a sprite means that the state diagram will use probabilities to decide on its transitions.
54
240-492 Java Games: Aliens/854 8.2. Four UFO States v 1. Standby. –the UFO moves left and right only v 2. Attack. –the UFO moves quickly downwards towards the missile launcher, and left and right –it is invunerable to missiles continued
55
240-492 Java Games: Aliens/855 v 3. Retreat –the UFO moves upwards, away from the missile launcher v 4. Land. –the UFO descends at a slow rate, with the intention of landing
56
240-492 Java Games: Aliens/856 8.3. Simple State Diagram (no probabilities) standby attack retreat land sprite creation land successfully
57
240-492 Java Games: Aliens/857 More Detailed State Diagram (with probabilities and some tests) standby >0.95 attack retreat land sprite creation >0.95 botm? land successfully far? Y N Y or N Y Y N N Y N Y and near N
58
240-492 Java Games: Aliens/858 8.4. State Diagram to Code v Entering a state is coded with the method: –start () –it initialises the sprite’s new movement –it initialises the new state continued
59
240-492 Java Games: Aliens/859 v Processing inside a state (and any tests) is coded with the method: – Action() –it evaluates the tests, calculates probabilities, and then calls the relevant start () method if a new state is going to be entered continued
60
240-492 Java Games: Aliens/860 The entire state diagram is controlled from updateSprite() –it knows the current state by storing the value in the state variable –at each update, it calls the relevant Action() method to decide what to do next
61
240-492 Java Games: Aliens/861 UFOSprite UML 4 Action methods 4 start methods
62
240-492 Java Games: Aliens/862 UFOSprite.java import javax.swing.*; import java.awt.*; import AndySprite.ImagesLoopSprite; public class UFOSprite extends ImagesLoopSprite { static final int UFO_NUMS = 6; int state; // current UFO state // UFO state values, represented by constants static final int STANDBY = 0; static final int ATTACK = 1; static final int RETREAT = 2; static final int LAND = 3; :
63
240-492 Java Games: Aliens/863 // probabilities used in state transitions static final double STANDBY_EXIT =.95; static final double ATTACK_EXIT =.95; static final double RETREAT_EXIT =.95; static final double LAND_EXIT =.95; static final double FLIP_X = 0.9; static final int RETREAT_Y = 17; private GunSprite gun; public UFOSprite(int x, int y, int w, int h, GunSprite g) { super(x, y, w, h, "image", "ufo", UFO_NUMS); gun = g; setCurrentImageNo( getRand(UFO_NUMS-1) ); startStandby(); } // end of UFOSprite()
64
240-492 Java Games: Aliens/864 public void hit() // alien is invulnerable when it's attacking; // otherwise, deactive sprite (so can be reused) { if (state == ATTACK) System.out.println("Your puny missiles have no effect Earthling!"); else { System.out.println( "Arrrgh... UFO destroyed!"); setActive(false); } }
65
240-492 Java Games: Aliens/865 // the state machine for the UFO public void updateSprite() { if (gun.intersect( getMyRectangle() )) { gun.hit(); // UFO has hit the gun setActive(false); } else { // otherwise update UFO state double r1 = Math.random(); double r2 = Math.random(); switch (state) { case STANDBY: standbyAction(r1,r2); break; case ATTACK: attackAction(r1,r2); break; : a switch based on the state value decides which Action() method to call
66
240-492 Java Games: Aliens/866 : case RETREAT: retreatAction(r1,r2); break; case LAND: landAction(r1,r2); break; } super.updateSprite(); // do inherited update as well // which will animate the UFO } } // end of updateSprite()
67
240-492 Java Games: Aliens/867 // For each action decide whether to change // state or stay in the existing state private void standbyAction(double r1, double r2) { if (r1 > STANDBY_EXIT) { // change state if (r2 > 0.5) // attack or land startAttack(); else startLand(); } else if ((locx getPWidth() - getWidth()) || (r2 > FLIP_X)) dx = -dx; // change x direction } // end of standbyAction()
68
240-492 Java Games: Aliens/868 private void attackAction(double r1, double r2) { if ((r1 > ATTACK_EXIT) || (locy > gun.getGunY() - RETREAT_Y)) startRetreat(); else if ((locx getPWidth() - getWidth()) || (r2 > FLIP_X)) dx = -dx; } // end of attackAction()
69
240-492 Java Games: Aliens/869 private void retreatAction(double r1, double r2) { if (r1 > RETREAT_EXIT) { if (r2 > 0.5) // attack or go to standby startAttack(); else startStandby(); } else if (locy < RETREAT_Y) startStandby(); } // end of retreatAction()
70
240-492 Java Games: Aliens/870 private void landAction(double r1, double r2) { if (r1 > LAND_EXIT) startStandby(); else if (locy >=getPHeight()-getHeight()) { // touched the ground System.out.println("ufo landed") ; setActive(false); } } // end of landAction() private void startStandby() { setStep( getRand(8)-4, 0); // move left or right state = STANDBY; }
71
240-492 Java Games: Aliens/871 private void startAttack() { // move left or right; descend quickly setStep( getRand(10)-5, getRand(5)+4 ); state = ATTACK; } private void startRetreat() { setStep(0, -getRand(3) - 2 ); // move up quickly state = RETREAT; } protected void startLand() { setStep( 0, getRand(3) + 2 ); // descend quickly state = LAND; }
72
240-492 Java Games: Aliens/872 // random number generator between 0-x private int getRand(int x) { return (int)(x * Math.random()); } } // end of UFOSprite class
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.