Java Applet网格游戏在刷新/按键上闪烁

时间:2014-11-12 21:39:08

标签: java applet

我在java中的网格上做了一个简单的游戏,涉及使用WASD键控制白色方块。每当我按下W,S,A或D时,屏幕有时会在再次绘制网格之前闪烁。我对编码很新,所以你越能为我愚蠢,越好。

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);
    }
}

}

1 个答案:

答案 0 :(得分:0)

我的建议是将尽可能多的计算移动到从按键事件调用的方法中,并尽可能保持paint()方法的简短和直接。如果你能帮助它,不要在你的paint()方法中做数学 - 在你调用repaint()之前使用你的按键方法来构建你需要绘制的所有东西的图片,并使你的paint()方法成为可能。唯一的工作是绘制董事会的当前状态。此外,不必在任何时候重新整理整个董事会。例如,当从当前方块移动到空方格时,您应该绘制的是前一个位置上的黑色方块,以及新位置中的新用户方块。当击中黄色或蓝色方块时,您需要绘制的是新的黄色或蓝色方块(并更新相应的状态消息)。你只需要在碰到红色或绿色方块时重新绘制整个板子。