简体   繁体   English

Java Applet Grid游戏刷新/按键闪烁

[英]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. 我在Java的网格上做了一个简单的游戏,涉及到使用WASD键控制白色正方形。 Whenever I press W,S,A, or D, the screen sometimes flickers before drawing the grid again. 每当我按W,S,A或D时,屏幕有时会闪烁,然后再次绘制网格。 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. 我的建议是将尽可能多的计算转移到按键事件中调用的方法中,并使paint()方法尽可能短而直接。 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. 如果可以帮助您,请不要在paint()方法中进行数学运算-使用keypress方法生成需要绘画的所有东西的图片,然后再调用repaint(),并使paint()方法的唯一工作是绘制电路板的当前状态。 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. 击中红色或绿色方块时,只需要重新绘制整个电路板即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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