spastic_walrus
spastic_walrus

Reputation: 1

Java Applet game double buffering broke with switch statement

I'm just starting out trying to make games and I did a HelloWorld Applet, then tested my idea for scrolling on it, and eventually it started turning into a "helicopter" style game. Now everything worked fine until I decided to put a bunch of switch statements in to handle states(title screen, running, and game over). The code that was functioning before is unchanged, and my new "intro screen" works fine, but when you switch into the game state the double buffering seems to go out of whack. The game foreground flashes on and off quickly and has triangles cut out of it, and the background hardly renders at all. This is just me exploring basic principles of game coding, so it's not elegant or modular or anything, but it should work...

[EDIT] I know that Applets and AWT in general is probably a bad way to go, but I started it like this and I just want to learn how this works and what I'm doing wrong so I can be satisfied and move on.

package testStuff;


import java.awt.*;
import java.applet.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;


public class HelloWorld extends Applet implements Runnable{

//game time counter
int count = 0;

//controller object
Controller control;

//accesses images and creates image variables
File wavesource = new File("C:\\sourceimages\\waves.jpg");
File playerSource = new File("C:\\sourceimages\\plane3.png");
Image player = null;
Image waves = null;

//font for score
Font myFont;

//double buffer objects
Graphics bground;
Image bgImage = null;
private int bgx = 0;

//player position
private int xPos=0;
private int yPos=50;

//arrays for tunnel locations
private int[] topTunnel = new int[200];
private int[] botTunnel = new int[200];

//size of tunnel
private int tunnelSize;

//boolean determines direction of tunnel movement
private boolean tunUp;

//state
private int state;


//"constructor"
public void init(){

    //set state
    state = 0;
    //instantiates controller adds it to the applet
    control = new Controller();
    this.addKeyListener(control);
    //instantiates images
    try {
        waves = ImageIO.read(wavesource);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        player = ImageIO.read(playerSource);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //instantiates arrays and tunnel size
    for(int i=0;i<199;i++){
        topTunnel[i]=-1;
        botTunnel[i]=-1;
    }
    topTunnel[199]=20;
    botTunnel[199]=179;
    tunnelSize = botTunnel[199]-topTunnel[199];
    tunUp = false;
}
public void paint(Graphics g){
    switch(state){
    case 0:
        g.setColor(Color.black);
        myFont = new Font("Courier", Font.BOLD+Font.ITALIC, 12);
        g.setFont(myFont);
        g.drawString("DON'T CRASH THE PLANE BRO", 10, 100);
        myFont = new Font("Courier", Font.PLAIN, 8);
        g.setFont(myFont);
        g.drawString("Press Spacebar to Play", 40, 150);
        break;
    case 1:
        g.drawImage(player, xPos, yPos, null);
        g.setColor(Color.red);
        for(int i=0;i<200;i++){
            g.fillRect(i, 0, 1, topTunnel[i]);
            g.fillRect(i, botTunnel[i], 1, botTunnel[i]);
        }
        g.setColor(Color.cyan);
        myFont = new Font("Helvetica", Font.PLAIN, 12);
        setFont(myFont);
        if(count<170)
            g.drawString("SCORE: " + 0, 0, 12);
        else
            g.drawString("SCORE: " + (this.count-170), 0, 12);
        break;
    }
}

public void start(){
    Thread thread = new Thread(this);
    thread.start();
}

@Override
public void run(){
    while(true){
        switch(state){
        case 0:
            //increases count
            count++;

            //paints
            this.repaint();

            try {
                    Thread.sleep(1000/30);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            if(control.spaceDown()){
                state = 1;
                count = 0;
            }
            break;

        case 1:
            //increases count
            count++;

            //handles scrolling
            if(xPos<75){
                xPos++;
            }
            else{
                if(bgx>-600){
                    bgx--;
                }
                else{
                    bgx=0;
                }
            }
            //handles input
            if(control.spaceDown()==true&&yPos>=0){
                yPos--;
            }
            else if(yPos<180){
                yPos++;
            }
            //repositions tunnel
            if(xPos>=75){
                for(int i=1;i<200;i++){
                    topTunnel[i-1]=topTunnel[i];
                    botTunnel[i-1]=botTunnel[i];
                }
            }
            //defines new tunnel space
            if(topTunnel[199]<=0 || !tunUp)
                topTunnel[199]++;
            if(botTunnel[199]>=200 || tunUp)
                topTunnel[199]--;
            botTunnel[199] = topTunnel[199]+tunnelSize;

            //randomly chooses direction to move tunnel
            double randomNum = Math.random();
            if(randomNum>.5)
                tunUp = true;
            else
                tunUp = false;

            //narrows tunnel
            if(count%20 == 0)
                tunnelSize--;

            //calls update
            this.repaint();
            //handles framerate
            try {
                Thread.sleep(1000/30);
            } catch (InterruptedException e) {
                 //TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        }
    }
}

public void update(Graphics g){

    //instantiates image and graphics on first tick
    if(bgImage == null){
        bgImage = createImage(this.getSize().width, this.getSize().height);
        bground = bgImage.getGraphics();
    }
    //create background based on state
    switch(state){
    case 0:
        //flashing colors!
        if(count%20<10){
            bground.setColor(Color.yellow);
            bground.fillRect(0, 0, 200, 200);
        }
        else{
            bground.setColor(Color.orange);
            bground.fillRect(0, 0, 200, 200);
        }
        break;
    case 1:
        //draws background image(s)
        bground.drawImage(waves,bgx,0,this);
        if(bgx<-399)
            bground.drawImage(waves,bgx+600,0,this);
        break;
    }
    //paint over the background then draw it to screen
    paint(bground);
    g.drawImage(bgImage, 0, 0, this);
}
 }

Upvotes: 0

Views: 430

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

You need to "clear" the graphics on each frame, otherwise you are painting on what was previously painted...

In the example below, I've filled the graphics context while it's "playing", but left as is when it's paused, you should be able to see the difference...

public class HelloWorld extends Applet implements Runnable {

    private int direction = 4;
    private int state = 0;
    private Image bgImage;
    private Graphics bground;
    private int count;

    private int x = 0;

//"constructor"
    public void init() {
        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                    if (state == 0) {
                        state = 1;
                    } else if (state == 1) {
                        state = 0;
                    }
                }
            }

        });
    }

    public void paint(Graphics g) {
        switch (state) {
            case 0:
                g.setColor(Color.black);
                g.drawString("DON'T CRASH THE PLANE BRO", 10, 100);
                g.drawString("Press Spacebar to Play", 40, 150);
                break;
            case 1:
                break;
        }
    }

    public void start() {
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (true) {
            switch (state) {
                case 0:
                    count++;
                    this.repaint();
                    break;
                case 1:

                    x += direction;
                    if (x < 0) {
                        x = 0;
                        direction *= -1;
                    } else if (x > getWidth()) {
                        x = getWidth();
                        direction *= -1;
                    }

                    //calls update
                    this.repaint();
                    //handles framerate
                    try {
                        Thread.sleep(1000 / 30);
                    } catch (InterruptedException e) {
                        //TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
            }
        }
    }

    public void update(Graphics g) {

        //instantiates image and graphics on first tick
        if (bgImage == null) {
            bgImage = createImage(this.getSize().width, this.getSize().height);
            bground = bgImage.getGraphics();
        }
        //create background based on state
        switch (state) {
            case 0:
                //flashing colors!
                if (count % 20 < 10) {
                    bground.setColor(Color.yellow);
                    bground.fillRect(0, 0, 200, 200);
                } else {
                    bground.setColor(Color.orange);
                    bground.fillRect(0, 0, 200, 200);
                }
                break;
            case 1:
                bground.setColor(Color.WHITE);
                bground.fillRect(0, 0, getWidth(), getHeight());
                bground.setColor(Color.RED);
                int y = (getHeight() / 2) - 4;
                bground.fillOval(x, y, 8, 8);
                break;
        }
        //paint over the background then draw it to screen
        paint(bground);
        g.drawImage(bgImage, 0, 0, this);
    }

}

Upvotes: 1

DonJunior
DonJunior

Reputation: 43

I think you should start but adding more braces. I'm a beginner at coding but from what I've been reading, coding lengthy statements without braces on certain statements in your code would result in some errors.

There are a lot of processes going on here and I feel like braces help a

 //defines new tunnel space
        if(topTunnel[199]<=0 || !tunUp)
            topTunnel[199]++;
        if(botTunnel[199]>=200 || tunUp)
            topTunnel[199]--;
        botTunnel[199] = topTunnel[199]+tunnelSize;
        //randomly chooses direction to move tunnel
        double randomNum = Math.random();
        if(randomNum>.5)
            tunUp = true;
        else
            tunUp = false;

        //narrows tunnel
        if(count%20 == 0)
            tunnelSize--;

        //calls update
        this.repaint();

Correct me if I'm wrong, I just want to learn too!

Upvotes: 0

Related Questions