|
SpaceOddysy: Chapter 5
By now we have all the classes representing the various objects in the
game. So now only two things remain. We must decide how to display the
game and to code the interaction between the various objects.
To display the game, we create a class Screen (extends JPanel). The screen
can be in three mode.
1. The game is being played, the screen is in game mode.
2. The player has cleared a stage, and splash-screen should be displayed.
The game is in splash screen mode.
3. The player is shopping. The game is in shop mode.
Also this class has the responsibilty of showing the scenery behind the
players, such as the planets and faraway stars. Lets look at the code
now.
public class Screen extends JPanel implements Serializable{
private static final Hashtable map = new Hashtable();
static {
map.put(TextAttribute.SIZE, new Float(18.0));
}
List artifacts=new ArrayList();
List justSomeDots=new ArrayList();
List planets=new ArrayList();
int chancePlanetSpawns=200;
String message="noMessage";
AttributedString splashMessage=new AttributedString(" ",map);
final static BasicStroke wideStroke = new BasicStroke(8.0f);
String[] shopMessages;
boolean splashScreenMode=false;
boolean shopMode=false;
Image img;
Font font;
JPanel shopButtons=new JPanel();
.............
In the List artifacts, we keep all things which the game engine wants
us to draw. Like the game engine will add the enemy ships, hero's ship,
bullets etc to this list, without regard to how they are to be drawn.
The Screen class has responsibilty of drawing them. The mode the game
is in is decided using two boolean variables. The planets and stars to
be shown are kept in the list planets and just someDots.
............................
public Screen() {
super();
shopMessages = new String[2];
shopMessages[0] = "";
shopMessages[1] = "";
font = new Font("SansSerif", Font.PLAIN, 20);
setPreferredSize(new Dimension(UW.xSize, UW.ySize));
setLayout(new GraphPaperLayout(new Dimension(15, 15)));
shopButtons.setOpaque(false);
t.start();
for (int i = 0; i < 100; i++) {
double randXPos = (Math.random() * UW.xSize);
double randYPos = (Math.random() * UW.ySize);
Dots d = new Dots(randXPos, randYPos);
justSomeDots.add(d);
}
for (int i = 0; i < 2; i++) {
double randXPos = (Math.random() * UW.xSize);
double randYPos = (Math.random() * UW.ySize);
double randSize = (Math.random() * 30) + 30;
Planets p = new Planets((int) randXPos, (int) randYPos,
(int) randSize);
planets.add(p);
}
}
........................
We initialise all the variables. Since the Screen class must show the
planets and stars, the list is populated using random stars and planets.
.................
public void paintComponent(Graphics g) {
if(splashScreenMode) {
//if(img!=null)
g.drawImage(img, getX(), getY(), getWidth(), getHeight(), this);
Graphics2D graphics2D = (Graphics2D) g;
// graphics2D.setStroke(wideStroke);
AttributedCharacterIterator paragraph=splashMessage.getIterator();
LineBreakMeasurer lineMeasurer=lineMeasurer = new LineBreakMeasurer(paragraph,
new FontRenderContext(null, false, false));
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
// Set formatting width to width of Component.
Dimension size = getSize();
float formatWidth = (float) size.width;
float drawPosY = 50;
lineMeasurer.setPosition(paragraphStart);
// Get lines from lineMeasurer until the entire
// paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout.
TextLayout layout = lineMeasurer.nextLayout(formatWidth);
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Compute pen x position. If the paragraph
is
// right-to-left, we want to align the TextLayouts
// to the right edge of the panel.
float drawPosX;
if (layout.isLeftToRight()) {
drawPosX = 0;
}
else {
drawPosX = formatWidth - layout.getAdvance();
}
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(graphics2D, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
}
else if(shopMode) {
setOpaque(true);
g.drawImage(img,0,0,getWidth(),getHeight(),null);
g.setColor(Color.red);
g.setFont(font);
g.drawString(shopMessages[0], 30, 50);
g.drawString(shopMessages[1], 30, 450);
}
else {
g.setColor(Color.black);
g.fillRect(getX(), getY(), getWidth(), getHeight());
for(Iterator i=justSomeDots.iterator();i.hasNext();) {
((Drawable)i.next()).draw(g);
}
for(Iterator i=planets.iterator();i.hasNext();) {
((Drawable)i.next()).draw(g);
}
for(Iterator i=artifacts.iterator();i.hasNext();) {
((Drawable)i.next()).draw(g);
}
if(message.equals("noMessage"));
else {
g.setColor(Color.WHITE);
g.setFont(font);
g.drawString(message,UW.xSize/4,UW.ySize/3 );
}
}
......................
The paintComponent method of Jpanel is called to draw it. We overide
this so that we can do the drawing our way. We decide the mode the game
is in. If it is in splashcreen mode, the splash screen and the message
is shown. If it is in the shop mode, the shopinng backgrownd is shown
and the various buttons for shopping are shown. If the game is in play
mode, then we get a black background. On this the stars and the planets
are drwan. Then the various objects which the game engine needs to draw
are drawn. The Screen class expects all elements of list Artifact to be
Drawable, so that is can draw them
The other methods are utility methods to help in drawing, along with
getters and setters.
Next Chapter>>>>>
|