Reputation: 1
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
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
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