繁体   English   中英

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

[英]Java Applet Grid Game Flashing On Refresh/Keypress

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

}

我的建议是将尽可能多的计算转移到按键事件中调用的方法中,并使paint()方法尽可能短而直接。 如果可以帮助您,请不要在paint()方法中进行数学运算-使用keypress方法生成需要绘画的所有东西的图片,然后再调用repaint(),并使paint()方法的唯一工作是绘制电路板的当前状态。 另外,不要在不需要时重画整个电路板。 例如,当从当前正方形移动到一个空正方形时,您所要绘制的只是在先前位置上的黑色正方形,以及在新位置上的新用户正方形。 击中黄色或蓝色方块时,您需要绘制的只是新的黄色或蓝色方块(并更新相应的状态消息)。 击中红色或绿色方块时,只需要重新绘制整个电路板即可。

暂无
暂无

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

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