-1

I'm trying to create a simple sideScroller in java, so far my game runs as expected but i have no idea on how to create a pause menu to go to the main menu and stuff (haven't got any idea on how to create a main manu for that mater) what do you think it's the best idea? this is the relevant code of my game, this panel is called inside a frame:

Game Code

package videojuegoalpha;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Background extends JPanel implements ActionListener, Runnable {

BufferedImage img, marco;

Character character;

Obstacle[] obstacleArray;

Timer time;

//CONSTANTS    
final static int largoPantalla = 800;
final static int borderWidth=24;
final static int diferencialPantalla = 74;
final static int characterFlow=10; 
final static int fontSize=18;
final static int flickerTime=150;
final static int invincibilityTime=2000;

int largonivel;
int controlPaso;
int actualHeight;
int standardHeight;
int maxHeightValue;
int deltaObstaculo;

Thread brinco;

static boolean debug=false;   

boolean jumpCycleDone;
boolean runDone;
boolean maxHeight;
boolean shrinkHeart;
boolean pause;

static Font fontScore,fontMultiplier;


Lives lives;

static MultithreadSystem sounds =  new MultithreadSystem();
static Thread MusicPlayer = new Thread(sounds);

static String BackgroundMusic;    
String hitSound;
String score;

public Background(int actualHeight, int maxHeightValue,
        String characterImage,String characterHitImage, int pasosPersonaje,int speed,
        String imagenFondo,String imagenMarco,
        String lowObstacleImage,String highObstacleImage,int obstacleDistance,
        String musicFile,String jumpSound,String hitSound, String dashSound) {

    controlPaso=0;
    this.standardHeight = actualHeight;
    this.actualHeight = this.standardHeight;
    this.maxHeightValue = maxHeightValue;


    jumpCycleDone = false;
    runDone = false;
    maxHeight = false;
    shrinkHeart=false;
    pause=false;

    character = new Character(characterImage,characterHitImage,pasosPersonaje,
                speed,jumpSound,dashSound);

    lives=new Lives();

    obstacleArray=Obstacle.getObstacleArray(5200,obstacleDistance,
            standardHeight+deltaObstaculo+borderWidth,                                                               (standardHeight+deltaObstaculo)/,lowObstacleImage,highObstacleImage);



    addKeyListener(new AL());
    setFocusable(true);


    try {
        img = CompatibleImage.toCompatibleImage(ImageIO.read(new File(
              "Images"+File.separator+"Background"+
               File.separator+imagenFondo)));
        marco = CompatibleImage.toCompatibleImage(ImageIO.read(new File(
              "Images"+File.separator+imagenMarco)));
        fontScore=(Font.createFont(Font.TRUETYPE_FONT,new FileInputStream(new File(
               "Fonts"+File.separator+"score.ttf")))).deriveFont(Font.BOLD, 18);
        fontMultiplier=(Font.createFont(Font.TRUETYPE_FONT,
                new FileInputStream(new File("Fonts"+File.separator+"multi.ttf"))))
                .deriveFont(Font.BOLD, fontSize+10);


    } catch (IOException | FontFormatException e) {
        System.out.println("Error al cargar" + ":" + e.toString());
    }

    deltaObstaculo=(character.getImage(character.pasoActual).
                   getHeight(null))- (obstacleArray[0].getImage().getHeight(null));

    time = new Timer(5, this);
    time.start();
    BackgroundMusic = "Music/"+musicFile;
    backMusic(BackgroundMusic);        

    this.hitSound=hitSound;
}


public static void backMusic(String MusisBck) {
    sounds.newThread(BackgroundMusic);
    MusicPlayer.start();
    if (MusicPlayer.isAlive() != true) {
        sounds.newThread(BackgroundMusic);
        MusicPlayer.start();
    }
}

@Override
public void actionPerformed(ActionEvent e) {

    if(!pause){
        character.move();
    }                

    condWin(5200);

    condLose();

    avanzaPaso();

    repaint();
}

public void avanzaPaso() {
    if(!pause){
        controlPaso++;            
    }
    if (controlPaso % characterFlow == 0) {
        character.pasoActual++; 
        if (character.pasoActual > character.pasos-3) { 
            character.pasoActual = 0;
        }
        debugMode("Paso: " + character.pasoActual);
    }
    if(controlPaso%(characterFlow*(character.pasos-2))==0){
        shrinkHeart = !shrinkHeart;//oscilación para encojer/desencojer
    }
}

public void condWin(int dist) {

    if (character.getPositionX() == dist) {
        MultithreadSystem sounds = new MultithreadSystem();
        sounds.newThread("Music/FF3Victory.wav");
        Thread sounds_player = new Thread(sounds);
        MusicPlayer.stop();
        sounds_player.start();

        JOptionPane.showMessageDialog(null, "YOU WIN!");
        System.exit(0);
    }
}

public void condLose() {

    if (character.lives == 0) {
        character.isAlive = false;

        if (!character.isAlive) {

            MultithreadSystem sounds = new MultithreadSystem();
            sounds.newThread("Music/gameOver01.wav");
            Thread sounds_player = new Thread(sounds);
            MusicPlayer.stop();
            sounds_player.start();

            JOptionPane.showMessageDialog(null, "YOU SUCK");
            System.exit(0);
        }
    }
}



@Override
public void paint(Graphics g) {


    debugMode("Altura: " + actualHeight);
    if (character.deltaY == 1 && runDone == false) {
        runDone = true;
        brinco = new Thread(this);
        brinco.start();
    }

    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;

    g2d.drawImage(img, largoPantalla - character.getnX2(), 0, null);


    if (character.getPositionX() > diferencialPantalla) {
        g2d.drawImage(img, largoPantalla - character.getnX(), 0, null);
    }

    for (int i = 0; i < obstacleArray.length; i++) {
        if (obstacleArray[i] != null) {

            if (obstacleArray[i].getPositionX() == -character.posicionFija) {
                obstacleArray[i] = null;
            }

            if (obstacleArray[i] != null) {

                if(!pause){
                    obstacleArray[i].move(character.pixPerStep);                        
                }

                if (obstacleArray[i].getPositionX() == 
                           largoPantalla + character.posicionFija) {
                    obstacleArray[i].setVisible(true);
                }

                if (obstacleArray[i].isVisible()) {
                    g2d.drawImage(obstacleArray[i].getImage(),
                          obstacleArray[i].getPositionX(),
                          obstacleArray[i].getPositionY(), null);
                }
                checkCollisions(obstacleArray[i]);
            }
        }

    }


    if (character.paintCharacter) {            
            g2d.drawImage(character.getImage(character.pasoActual),
                  character.posicionFija, actualHeight, null);                        
    }

    character.hit(flickerTime);


    if (shrinkHeart) {
        g2d.drawImage(lives.getImage(character.getLives()),
                borderWidth + 5,
                borderWidth + 5,
                (int) (lives.getImage(character.getLives()).getWidth() * .95),
                (int) (lives.getImage(character.getLives()).getHeight() * .95),
                null);
    } else {
        g2d.drawImage(lives.getImage(character.getLives()),
                borderWidth + 5,
                borderWidth + 5,
                null);
    }

    g2d.drawImage(marco, 0, 0, null);

    g2d.setFont(fontScore);
    g2d.setColor(Color.BLACK);

    score = String.format("%08d", character.score);
    g2d.drawString("score:" + score, 500, borderWidth * 2);

    g2d.setFont(fontMultiplier);
    g2d.drawString(character.multiplier + "", 
        (largoPantalla / 2) - 75, (borderWidth * 2) + 10);
}

private class AL extends KeyAdapter {

    @Override
    public void keyReleased(KeyEvent e) {
        character.keyReleased(e);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if(!pause){
            character.keyPressed(e);
        }
        if (key == KeyEvent.VK_D) {
            debug=(!debug);
        }
        if(key==KeyEvent.VK_P){
            pause=(!pause);
        }
        if (key == KeyEvent.VK_ESCAPE) {
            System.exit(0);
        }
    }
}

public void checkCollisions(Obstacle obstacle) {

    if (character.posicionFija == obstacle.getPositionX()) {

        if (obstacle instanceof LowObstacle) {

            debugMode("Obstaculo Bajo, Altura: "+obstacle.getPositionY());

           if (actualHeight <= (standardHeight - obstacle.getImage().getHeight(null))){

                if (character.multiplier < 4) {

                    character.multiplier++;
                }
            } else {

                if (character.hitAllowed) {

                    sounds = new MultithreadSystem();
                    sounds.newThread("SFX/" + hitSound);
                    Thread sounds_player = new Thread(sounds);
                    sounds_player.start();
                    character.multiplier = 1;
                    character.lives--;
                    character.hitAllowed = false;
                }
            }
        }

        else{
            debugMode("Obstaculo Alto, Altura: "+obstacle.getPositionY());


            if (character.dashPressed) {

                if (character.multiplier < 4) {

                    character.multiplier++;
                }
            } else {

                if (character.hitAllowed) {

                    sounds = new MultithreadSystem();
                    sounds.newThread("SFX/" + hitSound);
                    Thread sounds_player = new Thread(sounds);
                    sounds_player.start();
                    character.multiplier = 1;
                    character.lives--;
                    character.hitAllowed = false;
                }
            }                   
        }
    }
}

public void cycle() {
    if(!pause){
        if (maxHeight == false) {
            actualHeight--;
        }

        if (actualHeight == maxHeightValue) {
            maxHeight = true;
        }

        if (maxHeight == true && actualHeight <= standardHeight) {
            actualHeight++;
            if (actualHeight == standardHeight) {
                jumpCycleDone = true;
            }
        }
}
}

@Override
public void run() {
    character.isJumping = true;
    character.keyAllowed = false; 

    long beforeTime, timeDiff, sleep;
    beforeTime = System.currentTimeMillis();

    while (jumpCycleDone == false) {
        cycle();

        timeDiff = System.currentTimeMillis() - beforeTime;
        sleep = 8 - timeDiff;

        if (sleep < 0) {
            sleep = 2;
        }
        try {
            Thread.sleep(sleep);
        } catch (InterruptedException e) {
        }

        beforeTime = System.currentTimeMillis();
    }

    jumpCycleDone = false;
    maxHeight = false;
    runDone = false;
    character.keyAllowed = true;
    character.isJumping = false;        


}

public static void debugMode(String string){
    if(debug){
        System.out.println(string);
    }
}

// Getters y Setters //
public Character getCharacter() {
    return character;
}

public void setCharacter(Character character) {
    this.character = character;
}
}

As you can see I already have a pause variable which pauses everything, but I would like to have a little window popup in the middle while pause its true

  • 1
    Maybe `time.stop()`? An [sscce](http://sscce.org/) might be more amenable to study. – trashgod Apr 06 '12 at 05:08
  • Huh.. getting to over 400 lines of code before realizing you cannot get it to 'stop' & (seemingly) already using the 7 SDK. +1 to the idea of an SSCCE, but for wider attention please make it Java 6 compatible source. – Andrew Thompson Apr 06 '12 at 05:39
  • well the only thing I'm using from Java 7 is the multi-catching of exceptions, other than that everything runs just fine in java 6, I just wanted to know how could I place another panel on top of this one without creating a new window, enabling the boolean pause already pauses everything just fine although I know it doesn't really pauses anything, it just stops movement – Jimmy López Portillo Apr 06 '12 at 17:43

1 Answers1

0

The problem is that your class Background is directly where you draw. Normally your game handles all the frames and stuff, but then you have some kind of GameState object which your main game calls, like this:

public void update() {
    if (pause) {
        gameState = pauseState;
    } else {
        gameState = playState;
    }

    gameState.update();
}

@Override
public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    gameState.paint(g2d)
}

The idea is that you can have as many gameStates as you want. Simply make an interface GameState that provides methods for Update, Paint, Initialize and Dispose (or something like this). Then you can have all kinds of GameStates, for example Play, Pause, MainMenu, SaveGameMenu, etc., each one in charge of updating and drawing itself.

It's the main class (where your game loop is) where you handle the logic to swap the GameStates.

Fermin Silva
  • 3,331
  • 2
  • 17
  • 21
  • This actually seems like the solution, do you know any game or demo which has its source avalaible that uses this so I can look into an implementation? – Jimmy López Portillo Apr 06 '12 at 17:43
  • Not in hava, but in C# [HERE](http://create.msdn.com/downloads/?id=77&filename=GSMSample_4_0_WIN_XBOX.zip). Syntax-wise it should be pretty familiar to you. Just grasp the idea, since the drawing code will be really different since this uses directX behind the curtains – Fermin Silva Apr 10 '12 at 00:33