3

我正在使用OvalsGraphics对象在java中编写一个简单的游戏。它被称为病毒,它的工作原理是这样的:中间有一个椭圆,外面有六个椭圆。这些外面的椭圆应该会增加大小,直到被点击,当它们消失并且玩家得分十分时。如果一个椭圆与中央椭圆相接触,中央椭圆的健康度就会下降。当它达到零时,游戏结束。我遇到的问题是外部椭圆的大小不会增加。为什么会这样?

这是我的代码:

package virus;


import java.awt.*;
import java.util.Random;
import javax.swing.JPanel;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class VirusGamePanel extends JPanel implements MouseListener{
    private static final long serialVersionUID = 1L;//serialVersionUID field
    Random colour = new Random();//the outside ovals will always be a random colour
    private int sizeX = 1;//the x size of the outside ovals 
    private int sizeY = 1;//the y size of the outside ovals
    int score = 0;
    static String scorestring = "Score: ";
    Color rand = new Color(colour.nextInt(255),colour.nextInt(255),colour.nextInt(255));//generate the random colour

    public void paint(Graphics g)
    {
        super.paint(g);
        g.setColor(Color.magenta);
        g.drawString(scorestring+score,275,250);
        g.setColor(Color.orange);
        g.drawOval(200,150,200,200);
        g.setColor(rand);
        g.drawOval(270,50,50,50);
        g.drawOval(100,100,50,50);
        g.drawOval(450,100,50,50);
        g.drawOval(100,400,50,50);
        g.drawOval(450,400,50,50);
        g.drawOval(275,450,50,50);
        g.fillOval(270,50,sizeX,sizeY);//these six ovals are supposed to increase in size
        g.fillOval(100,100,sizeX,sizeY);
        g.fillOval(450,100,sizeX,sizeY);
        g.fillOval(100,400,sizeX,sizeY);
        g.fillOval(450,400,sizeX,sizeY);
        g.fillOval(275,450,sizeX,sizeY);
        inc();
    }

    public static void main(String[] args) {
      JPanel panel = new VirusGamePanel();

      JFrame frame = new JFrame("Virus");
      frame.setSize(700, 700);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(panel);
      frame.setVisible(true);
    }

    private void inc()//increase the size of the ovals
    {
        for(int i = 0; i<25000; i++)
        {
            sizeX++;
            sizeY++;
            repaint();
        }
    }

带线程的新代码:

package virus;


import java.awt.*;
import java.util.Random;
import javax.swing.JPanel;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class VirusGamePanel extends JPanel implements MouseListener,Runnable{
    private static final long serialVersionUID = 1L;
    Random colour = new Random();
    private int sizeX = 1;
    private int sizeY = 1;
    int score = 0;
    Thread thr = new Thread();
    static String scorestring = "Score: ";
    Color rand = new Color(colour.nextInt(255),colour.nextInt(255),colour.nextInt(255));

    public void paint(Graphics g)
    {
        super.paint(g);
        thr.start();
        g.setColor(Color.magenta);
        g.drawString(scorestring+score,275,250);
        g.setColor(Color.orange);
        g.drawOval(200,150,200,200);
        g.setColor(rand);

        g.fillOval(270,50,sizeX,sizeY);
        g.fillOval(100,100,sizeX,sizeY);
        g.fillOval(450,100,sizeX,sizeY);
        g.fillOval(100,400,sizeX,sizeY);
        g.fillOval(450,400,sizeX,sizeY);
        g.fillOval(275,450,sizeX,sizeY);
        inc();
    }

    public static void main(String[] args) {}

    private void inc()
    {
        thr.run();
    }
    public void run(){
        for(int i = 0; i<25000; i++)
        {
            sizeX++;
            sizeY++;
            repaint();
            try
            {
                Thread.sleep(10);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
4

3 回答 3

2
 for(int i = 0; i<25000; i++)
    {
        sizeX++;
        sizeY++;
        repaint();
    }

您的计算机无法像 CPU 增加 sizeX 和 sizeY 一样快地重新绘制。以毫秒为单位添加一些等待时间(特别是如果您绘制像 800x600 这样的大区域)

 for(int i = 0; i<25000; i++)
    {
        sizeX++;
        sizeY++;
        repaint();
        try{ sleep(100);} catch(InterruptedException e){}
    }

But, do this from another thread! So, your app. will not freeze.

This is 10 FPS. But you tried 2G FPS. Good day.

Here is an example of a thread.

class TEN_FPS extends Thread
{
    public void run()
    {
        while(working)
        {
             //calculations here
             repaint();
             try{sleep(100);}catch(InterruptedException e){}
        }
     }
 }

Then in the main method:

working=true;
TEN_FPS.start();

When you are done with this program:

working=false;

will release your daemon thread.

于 2012-08-23T14:17:11.223 回答
2

Your code is recursive. In inc(), you call repaint, which calls VirusGamePanel.paint(), which calls inc() ...

Each call to repaint() will reinvoke the paint() method. So instead of looping in inc() do this:

private void inc()// increase the size of the ovals
{
  sizeX++;
  sizeY++;
  repaint();
}     
于 2012-08-23T14:20:39.357 回答
2

This works for me:

public class VirusGamePanel extends JPanel{
    private static final long serialVersionUID = 1L;//serialVersionUID field
    Random colour = new Random();//the outside ovals will always be a random colour
    private int sizeX = 0;//the x size of the outside ovals 
    private int sizeY = 0;//the y size of the outside ovals
    int score = 0;
    static String scorestring = "Score: ";
    Color rand = new Color(colour.nextInt(255), colour.nextInt(255), colour.nextInt(255)); //generate the random colour

    public void paint(Graphics g)
    {
        super.paint(g);
        g.setColor(Color.magenta);
        g.drawString(scorestring+score,275,250);
        g.setColor(Color.orange);
        g.drawOval(200, 150, 200, 200);
        g.setColor(rand);
        g.fillOval(270 - sizeX / 2, 50 - sizeY / 2, sizeX, sizeY);//these six ovals are supposed to increase in size
        g.fillOval(100 - sizeX / 2,100 - sizeY / 2, sizeX, sizeY);
        g.fillOval(450 - sizeX / 2,100 - sizeY / 2, sizeX, sizeY);
        g.fillOval(100 - sizeX / 2,400 - sizeY / 2, sizeX, sizeY);
        g.fillOval(450 - sizeX / 2,400 - sizeY / 2, sizeX, sizeY);
        g.fillOval(275 - sizeX / 2,450 - sizeY / 2, sizeX, sizeY);
        inc();
    }

    public static void main(String[] args) {
      JPanel panel = new VirusGamePanel();

      JFrame frame = new JFrame("Virus");
      frame.setSize(700, 700);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(panel);
      frame.setVisible(true);
    }

    private void inc()//increase the size of the ovals
    {
            sizeX++;
            sizeY++;
            repaint();
    }
}

Just fixed the center points of the ovals and removed the loop in the inc method. If you want the oval boundaries drawn, just add the drawOval commands with the same parameters as the fillOval commands.

EDIT:

If you want to slow down the growth process, just add the following just before the inc() call of the paint method:

try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}
于 2012-08-23T14:29:08.723 回答