简体   繁体   中英

Java Applet Grid Game Flashing On Refresh/Keypress

I made a simple game on a grid in java that involves controlling a white square with the WASD keys. Whenever I press W,S,A, or D, the screen sometimes flickers before drawing the grid again. I am fairly new to coding, so the more you can dumb it down for me, the better.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
/**
 * DotGame.applet
 * 
 * A simple game where the player controls a white circle with the WASD keys.
 *  - If the user moves his circle over a green circle, his score will go up by 1, and another red circle will spawn.
 *  - If the user moves his circle over a red circle, his score will go down by 1, and one less red circle will be generated.
 *  - There is no win condition, it is just a test game.
 *  
 * @author -----------
 * @version 11-9-2014 
 */

public class DotGame extends Applet
implements KeyListener, MouseListener
{
int width,height;
int powerup = 1;
int click = 0;
int x,y;
final int size = 40;
int ox = size,oy = size;
int rx = 0, ry = 0;
int reddots = 0;
int red[][] = new int[1000][2];
String s = "";
int score = 0;
int DrawGrid = 0;
String sc = "";
int powerupdots = 1;
int yellow[][] = new int[1][2];
int powerupcounter = 0;
int shield = 0;
int blue[][] = new int[1][2];

public void init()
{
    this.setSize(740,500);        
    width = 640;
    height = 480;        
    setBackground( Color.black );
    x = width/2;
    y = height/2;
    s = "CLICK TO START";
    addMouseListener( this );
    addKeyListener( this );
}

public void keyPressed( KeyEvent e ) { }

public void keyReleased ( KeyEvent e ) { }

public void keyTyped( KeyEvent e )
{
    char c = e.getKeyChar();
    String t = c+"";
    //This will change the coordinates of the user-controlled circle by the size of the circle based on what button is pressed
    if(powerupcounter > 0)
    {
        powerup = 2;
    }
    else if(powerupcounter == 0)
    {
        powerup = 1;
    }

    if( t.equalsIgnoreCase("w" )&& oy > 0+((powerup-1)*size))
    {
        oy = oy-(size*powerup);
    }
    else if( t.equalsIgnoreCase("s") && oy < height-(size*powerup))
    {
        oy = oy+(size*powerup);
    }
    else if( t.equalsIgnoreCase("a")&& ox > 0+((powerup-1)*size))
    {
        ox = ox-(size*powerup);
    }
    else if( t.equalsIgnoreCase("d") && ox < width-(size*powerup))
    {
        ox = ox+(size*powerup);
    }
    else if(t.equalsIgnoreCase("w" ) && oy == 0)
    {
        oy = height-(size*powerup);
    }
    else if(t.equalsIgnoreCase("s") && oy == height-size)
    {
        oy = 0+((powerup-1)*size);
    }
    else if(t.equalsIgnoreCase("a") && ox == 0)
    {
        ox = width-(size*powerup);
    }
    else if(t.equalsIgnoreCase("d") && ox == width-size)
    {
        ox = 0+((powerup-1)*size);
    }
    else if(t.equalsIgnoreCase("w") && oy == size && powerup ==2)
    {
        oy = height-size;
    }
    else if(t.equalsIgnoreCase("s") && oy == height -(size*powerup) && powerup ==2)
    {
        oy = 0;
    }
    else if(t.equalsIgnoreCase("a") && ox == size && powerup ==2)
    {
        ox = width-size;
    }
    else if(t.equalsIgnoreCase("d") && ox == width -(size*powerup) && powerup ==2)
    {
        ox = 0;
    }

    if(powerupcounter > 0)
    {
        powerupcounter--;
    }

    repaint();
    e.consume();
}

public void mouseEntered( MouseEvent e) {}

public void mouseExited( MouseEvent e) {}

public void mousePressed( MouseEvent e) {}

public void mouseReleased( MouseEvent e) {}

public void mouseClicked( MouseEvent e) 
{
    if(click == 0)
    {
        randomYellow();
        randomBlue();
        DrawRandom();            
        x = e.getX();
        y = e.getY();
        s = "";
        repaint();
        e.consume();
        click = 1;
    }
}

public void CheckScore()
{
    if(ox == rx && oy == ry)
    {
        score++;
        reddots+=10;
        DrawRandom();
    }
}

public void DrawRandom()
{
    //The reason we divide by the size and then multiply after it is an int is to
    //make sure that the random circle drawn is in the same base as the size of the circle,
    //so that the player's circle can move directly over it, and not be of by a fraction
    //of the predetermined size.

    rx = (int)(Math.random()*width/size)*size;
    ry = (int)(Math.random()*height/size)*size;
    while(rx == ox && ry == oy)
    {
        rx = (int)(Math.random()*width/size)*size;
        ry = (int)(Math.random()*height/size)*size;
    }

    for(int y = 0 ; y < reddots ; y++)
    {
        red[y][0] = (int)(Math.random()*width/size)*size;
        red[y][1] = (int)(Math.random()*height/size)*size;
        while(red[y][0] == rx && red[y][1] == ry || red[y][0] == yellow[0][0] && red[y][1] == yellow[0][1] 
        || red[y][0] == ox && red[y][1] == oy || red[y][0] == blue[0][0] && red[y][1] == blue[0][1])
        {
            red[y][0] = (int)(Math.random()*width/size)*size;
            red[y][1] = (int)(Math.random()*height/size)*size;
        }
    }

}

public void randomYellow()
{
    yellow[0][0] = (int)(Math.random()*width/size)*size;
    yellow[0][1] = (int)(Math.random()*height/size)*size;
    while(yellow[0][0] == rx && yellow[0][1] == ry)
    {
        yellow[0][0] = (int)(Math.random()*width/size)*size;
        yellow[0][1] = (int)(Math.random()*height/size)*size;
    }
}

public void randomBlue()
{
    blue[0][0] = (int)(Math.random()*width/size)*size;
    blue[0][1] = (int)(Math.random()*height/size)*size;
    while(blue[0][0] == rx && blue[0][1] == ry || blue[0][0] == yellow[0][0] && blue[0][1] == yellow[0][1])
    {
        blue[0][0] = (int)(Math.random()*width/size)*size;
        blue[0][1] = (int)(Math.random()*height/size)*size;
    }
}

public void CheckDeath()
{
    for(int y = 0 ; y < reddots ; y++)
    {
        if(ox == red[y][0] && oy == red[y][1] && shield == 0)
        {
            score--;
            reddots--;
            DrawRandom();
        }
        else if(ox == red[y][0] && oy == red[y][1] && shield !=0)
        {
            shield--;
            DrawRandom();
        }
    }
}

public void CheckPowerup()
{
    for(int y = 0 ; y < powerupdots ; y++)
    {
        if(ox == yellow[y][0] && oy == yellow[y][1])
        {
            powerupcounter += 10;
            randomYellow();
        }
    }
}

public void CheckShield()
{
    if(ox == blue[0][0] && oy == blue[0][1] && shield < 5)
    {
        shield++;
        randomBlue();
    }
    else if(ox == blue[0][0] && oy == blue[0][1] && shield >= 5)
    {
        randomBlue();
    }
}

public void CheckWin( Graphics g )
{
    g.setColor(Color.black);
    g.fillRect(0,0,width,height);
    while(1 == 1)
    {
        g.drawString( "YOU WIN" , width/2, height/2);
    }

}

public void paint( Graphics g )
{

    CheckScore();
    if(score == 20)
    {
        CheckWin(g);
    }
    CheckDeath();
    CheckPowerup();
    CheckShield();
    DrawGrid(g);
    g.setColor(Color.yellow);
    g.fillRect(yellow[0][0],yellow[0][1],size+1,size+1);
    g.setColor(Color.red);
    for(int y = 0; y < reddots ; y++)
    {
        g.fillRect(red[y][0],red[y][1],size+1,size+1);
    }
    sc = ""+score;
    //Draw user
    g.setColor(Color.white);
    g.fillRect(ox,oy,size+1,size+1);
    //Draw shield around user if they have shields (max 5)
    if(shield >= 1)
    {
        g.setColor(Color.blue);
        g.fillRect(ox,oy,size+1,5);
        g.fillRect(ox,oy,5,size+1);
        g.fillRect(ox,oy+size-4,size+1,5);
        g.fillRect(ox+size-4,oy,5,size+1);
    }
    //Draw green tile
    g.setColor(Color.green);
    g.fillRect(rx,ry,size+1,size+1);
    //Draw shield tile
    g.setColor(Color.blue);
    g.fillRect(blue[0][0],blue[0][1],size+1,size+1);        
    g.setColor( Color.green );
    g.drawString( s, x, y );
    g.drawString( "Score : "+sc, 650, 20);
    g.drawString( "Powerups : "+powerupcounter, 650, 40);
    g.drawString( "Red Dots : "+reddots, 650,60);
    g.drawString( "Shield : "+shield,650,80);   
}

public void DrawGrid( Graphics g )
{
    g.setColor(Color.orange);
    for(int x = 0 ; x <= width ; x += size)
    {
        g.drawLine(x,0,x,height);
    }
    for(int y = 0 ; y <= height ; y+= size)
    {
        g.drawLine(0,y,width,y);
    }
}

}

My advice is to move as much of your calculation as possible into methods called from your keypress events, and keep your paint() method as short and direct as possible. Don't do math inside your paint() method if you can help it - use your keypress method to build the picture of everything you need to paint before you call repaint(), and make your paint() method's only job to be to draw the current state of the board. Also, don't redraw the whole board anytime you don't have to. For instance, when moving from the current square to an empty square, all you should draw is a black square over your previous position, and a new user square in the new position. When hitting a yellow or blue square, all you need to draw is the new yellow or blue square (and update the appropriate status messages). You only need to redraw the whole board when hitting a red or green square.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM