Java Swing小程序:如何在不减慢整个程序的情况下减慢或延迟paint()
我正在java swing小程序上创建一个“打鼹鼠”游戏,但我在计时鼹鼠出现时遇到了麻烦。我似乎无法避免paint()在我身上循环,从而太快地随机化了鼹鼠的坐标。如果鼹鼠没有被击中,我怎么能推迟它们上来停留一段时间,然后再下去呢?如何在不延迟整个程序的情况下创建此延迟
请帮忙
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class Game extends JApplet
{
boolean titleScreen = true;
boolean gameBegin = false;
// /////////////////////////////////
// ///// IMAGE /////////
// /////////////////////////////////
Dimension dim;
Image offscreen;
static Graphics bufferGraphics;
static Image h1, h2, bg, gamebg, button1a, button1b, button2a, button2b;
static Image m1, m1a, m1b, m2a, m2b;
static Image[] mk = new Image [9];
// /////////////////////////////////
// ///// MOUSE /////////
// /////////////////////////////////
Cursor c;
boolean myButtonPressed = false;
boolean myButtonEntered = false;
int myMouseX = 0, myMouseY = 0;
int myRow = -1, myCol = -1;
// /////////////////////////////////
// / GAME VARIABLES ///
// /////////////////////////////////
private static final int[] mX = {5, 170, 335, 5, 170, 335, 5, 170, 335};
private static final int[] mY = {5, 5, 5, 170, 170, 170, 335, 335, 335};
int rand, randm;
static int[] t = new int [9];
static boolean mhhit = false;
static boolean[] mhit = {false, false, false, false, false, false, false, false, false};
private int[] respawnCounter = {0, 0, 0, 0, 0, 0, 0, 0, 0};
private int[] removeCounter = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static int score = 0;
public JFrame window;
// /////////////////////////////////
// ///// BUTTON /////////
// /////////////////////////////////
GameScreen g1 = new GameScreen ();
Timer repaintTimer = null;
// GameTime m1 = new GameTime (t[]);
// GameTime m2 = new GameTime (t[]);
// GameTime m3 = new GameTime (t[]);
// GameTime m4 = new GameTime (t[]);
// GameTime m5 = new GameTime (t[]);
// GameTime m6 = new GameTime (t[]);
// GameTime m7 = new GameTime (t[]);
// GameTime m8 = new GameTime (t[]);
// GameTime m9 = new GameTime (t[]);
public Game ()
{
window = new JFrame ("Monkeying Around");
window.setResizable (false);
window.setSize (800, 400);
window.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
public void init ()
{
// /////////////////////////////////
// ///// IMAGE /////////
// /////////////////////////////////
dim = getSize ();
setBackground (Color.white);
offscreen = createImage (dim.width, dim.height);
bufferGraphics = offscreen.getGraphics ();
// Getting all the images
m1a = getImage (getCodeBase (), "m1a.gif");
m1b = getImage (getCodeBase (), "m1b.gif");
m1 = getImage (getCodeBase (), "m1.gif");
h1 = getImage (getCodeBase (), "hammer.gif");
h2 = getImage (getCodeBase (), "hammer2.gif");
bg = getImage (getCodeBase (), "mainbg.gif");
gamebg = getImage (getCodeBase (), "gbg.gif");
button1a = getImage (getCodeBase (), "button1a.gif");
button1b = getImage (getCodeBase (), "button1b.gif");
button2a = getImage (getCodeBase (), "button2a.gif");
button2b = getImage (getCodeBase (), "button2b.gif");
for (int mnum = 0 ; mnum < 9 ; mnum++)
{
mk [mnum] = m1;
}
///////////////////////
/////// MOUSE /////////
///////////////////////
Toolkit tk = Toolkit.getDefaultToolkit ();
c = tk.createCustomCursor (tk.getImage (""), new Point (0, 0), "invisible");
setCursor (c);
addMouseListener (new MyMouseListener ());
addMouseMotionListener (new MyMouseMotionListener ());
repaintTimer = new Timer (500, new RepaintAction (this));
// start the timer.
} // end init method
public void start ()
{
}
public Image getMouseImage ()
{
if (myButtonPressed)
{
return h2;
}
return h1;
}
public void handleMouseEvents ()
{
int nCol = myMouseX - 50;
int nRow = myMouseY - 50;
if (!myButtonEntered) // assumed to be: if myButtonEntered is
// not = true i.e. false
nCol = nRow = -1;
if (nCol != myCol || nRow != myRow)
{
myRow = nRow;
myCol = nCol;
}
repaint ();
} // end handleMouseEvents method
/////////////////////////////////////
/////// MOUSELISTENER CLASS /////////
/////////////////////////////////////
public class MyMouseListener implements MouseListener
{
public void mousePressed (MouseEvent me)
{
myButtonPressed = true;
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
}
public void mouseReleased (MouseEvent me)
{
myButtonPressed = false;
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
}
public void mouseEntered (MouseEvent me)
{
myButtonEntered = true;
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
}
public void mouseExited (MouseEvent me)
{
myButtonEntered = false;
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
}
public void mouseClicked (MouseEvent me)
{
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
}
} // end MyMouseListener class
public class MyMouseMotionListener implements MouseMotionListener
{
public void mouseMoved (MouseEvent me)
{
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
} // end mouseMoved method
public void mouseDragged (MouseEvent me)
{
myMouseX = me.getX ();
myMouseY = me.getY ();
handleMouseEvents ();
} // end mouseDragged method
} // end MyMouseListener class
public void mouse ()
{
// logic to render mouse...
if (myRow != -1 && myCol != -1)
{ // if you do not hit co-ordinates -1
// (out of bounds) then
Image mouseImage = getMouseImage ();
bufferGraphics.drawImage (mouseImage, myCol, myRow, 100, 100, null, this);
} // end if
}
public void paint (Graphics g)
{
bufferGraphics.clearRect (0, 0, dim.width, dim.height);
repaint ();
if (titleScreen == true)
{
// System.out.println("drawing the main screen");
mainScreen ();
}
if (gameBegin == true)
{
game (g);
}
mouse ();
g.drawImage (offscreen, 0, 0, this);
} // end Paint method
public void update (Graphics g)
{
paint (g);
}
public void mainScreen ()
{
bufferGraphics.drawImage (bg, 0, 0, 600, 500, Color.red, this);
bufferGraphics.drawImage (button1a, 427, 384, 159, 49, Color.red, this);
bufferGraphics.drawImage (button2a, 427, 440, 159, 49, Color.red, this);
mouse ();
if (myButtonPressed == true)
{
if (myRow > (384 - 50) && myRow < (433 - 50) && myCol > (427 - 50)
&& myCol < (586 - 50))
{
titleScreen = false;
gameBegin = true;
}
else if (myRow > (340 - 50) && myRow < (489 - 50)
&& myCol > (427 - 50) && myCol < (586 - 50))
{
titleScreen = false;
}
}
}
public void game (Graphics g)
{
// new ReminderBeep (5);
bufferGraphics.drawImage (gamebg, 0, 0, 600, 500, Color.red, this);
for (int i = 0 ; i < 9 ; i++)
{
bufferGraphics.drawImage (mk [i], mX [i], mY [i], 160, 160, Color.red, this);
}
g.drawString ("har", 520, 140);
}
public void monkeyhit ()
{
if (myButtonPressed == true)
{
for (int hit = 0 ; hit < 9 ; hit++)
if (mhit [hit] == true && myRow > (mY [hit] - 50) && myRow < (mY [hit] + 160 - 50)
&& myCol > (mX [hit] - 50) && myCol < (mX [hit] + 160 - 50))
{
mk [hit] = m1b;
mhhit = true;
mhit [hit] = false;
score += 10;
}
}
// reset ();
}
public void run ()
{
monkey ();
}
// public void reset ()
// {
// mhhit = false;
// for (int x = 0 ; x < 9 ; x++)
// {
// mk [x] = m1;
// mhit [x] = false;
//
// }
//
// }
public void monkey ()
{
rand = ((int) (Math.random () * 100000000)) + 10000000;
randm = ((int) (Math.random () * 100));
if (randm <= 8)
{
for (int a = 0 ; a < 9 ; a++)
{
if (randm == a)
{
mhit [randm] = true;
mk [randm] = m1a;
}
else if (randm != a)
{
mhit [a] = false;
mk [a] = m1;
}
}
for (int i = 0 ; i < rand * 100 ; i++)
{
monkeyhit ();
if (mhit [randm] = false)
mk [randm] = m1;
break;
}
}
}
// Timer
class GameTime
{
Toolkit toolkit;
Timer timer;
public GameTime (int seconds)
{
toolkit = Toolkit.getDefaultToolkit ();
timer = new Timer (seconds, new MTask ());
timer.start ();
}
/*
public void delay(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new Mdelay(), seconds * 1000);
}
*/
class MTask implements ActionListener
{
public void actionPerformed (ActionEvent ae)
{
/*
for (int tsec = 0; tsec < 9; tsec++) {
t[tsec] = ((int) (Math.random() * 11)) * 5;
}
*/
}
}
}
class RepaintAction implements ActionListener
{
Game game;
public RepaintAction (Game game)
{
this.game = game;
}
public void actionPerformed (ActionEvent e)
{
game.repaint ();
}
}
}
# 1 楼答案
这里有一个非常简单的game可以指导您的设计。说明了模型与视图的分离;它还链接到相关示例。一个模型有一个
List<Mole>
,而每个Mole
有一个javax.swing.Timer
看起来很合适。当鼹鼠改变状态时,模型会通知视图,视图可以查询模型进行鼠标点击测试# 2 楼答案
在绘制方法(或从那里调用的方法)中,您应该只进行绘制,而不进行其他操作(如检查鼠标的位置等)
其他一切都应该分开做。例如,计算(随机化)鼹鼠(或猴子?)的位置不应在此处执行,但应在计时器方法中执行,例如
小程序需要有一个模型,该模型将由用户交互和随机事件修改。绘制方法然后查看此模型,并根据此模型进行绘制
# 3 楼答案
从不不覆盖更新()和绘制()。这是在Swing中未使用的旧AWT代码在Swing中,通过重写JPanel或JComponent的paintComponent()方法完成自定义绘制。然后将组件添加到小程序的内容窗格(或框架、对话框或窗口)
有关更多信息和示例,请阅读Swing教程中关于Custom Painting的部分
另外,在Swing中,您永远不会从绘制方法中调用repaint(),因为这会导致无限循环
# 4 楼答案
您可以创建一个具有startTime、upTime和坐标的Mole类,并在主游戏类中创建一个moles的ArrayList。然后,在你的油漆环中,检查是否有任何摩尔已经在分配的时间内上升,如果是,移除它们。为了始终保持相当统一的摩尔数,您可以创建一个新的摩尔,以随机开始时间(基于当前时间)、启动时间和坐标替换被破坏的每个摩尔
线程也可能是一种合适的、但要复杂得多的替代方法