gpt4 book ai didi

java - 图形 2d 对象的引用在孤立线程中不起作用

转载 作者:行者123 更新时间:2023-11-29 03:33:53 25 4
gpt4 key购买 nike

我正在尝试在 JPanel 中使用 Graphics2D 设计一个简单的游戏。我可以通过覆盖 paintComponent() 方法来绘制普通对象。但是当我在孤立线程中引用 Graphics2D 对象时,它不起作用。我哪里错了?

public void paintComponent(Graphics g) {

super.paintComponent(g);
g2d = (Graphics2D) g;

g2d.drawString("sample",60,100); //Works fine

if(<Certain Condition>){
new Thread(new Runnable(){
//Some Code Here
public void run() {
try{
g2d.drawString("sample2",60,100); //Does not work.. :(
System.out.println("Test Print"); //Shows Output
}
catch (Exception e)
{
}
}
}).start();
}
}

这里是完整的代码供引用。这本质上是一个“乒乓球”游戏。它运作良好,但我无法强调球击中前锋时得分的增加。代码的重要部分被突出显示。是SSCCE。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.util.Random;

public class MovingBall extends JPanel {
int XPos, YPos;
int speedX, speedY;
int diameter;
private JButton jButton1 = new JButton();
private JButton jButton2 = new JButton();
private JLabel jLabel1 = new JLabel();
private static Timer timer;
private static MovingBall movingball;
private int w,h;

private int strikerHeight;
private int strikerWidth;

private int score;
private boolean isBallMoving;

int strikerYPos;
Graphics2D g2d;

public MovingBall() {

//Striker Properties
strikerHeight = 100;
strikerWidth = 20;
strikerYPos = strikerHeight/2;

//Ball Properties
isBallMoving = false;
XPos = strikerWidth + 5;
YPos = 0;
Random r = new Random();
speedX = 2+ Math.abs(r.nextInt()) % 5;
speedY = 2+ Math.abs(r.nextInt()) % 5;
diameter = 50;

//UI Objects
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}

movingball = this; //Helps to access the current class object in inner classes

//Create a timer for animation
timer = new Timer(1, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
movingball.repaint();
}
});
timer.start();
}

public void paintComponent(Graphics g) {

super.paintComponent(g);
g2d = (Graphics2D) g;

Dimension size = getSize();
Insets insets = getInsets();

w = size.width - insets.left - insets.right;
h = size.height - insets.top - insets.bottom;

//Paint the striker
g2d.setColor(Color.DARK_GRAY);
if(strikerYPos < strikerHeight/2) //Top End
g2d.fillRect(0,0, strikerWidth, strikerHeight);
else if(strikerYPos > (h-strikerHeight/2)) //Bottom End
g2d.fillRect(0,h-strikerHeight, strikerWidth, strikerHeight);
else //Anywhere in the middle
g2d.fillRect(0,strikerYPos - (strikerHeight/2), strikerWidth, strikerHeight);

//Paint the ball
if (isBallMoving) {
XPos += speedX;
YPos += speedY;

g2d.drawOval(XPos, YPos, diameter,diameter);

if((XPos+diameter) >= w)
{
//speedX *= -1;
speedX = ((int)Math.signum((double)speedX))*(-1) * (2+ Math.abs(new Random().nextInt()) % 5);
XPos = w-diameter-1;
}
if(XPos <= strikerWidth)
{
if((YPos+diameter/2) >= (strikerYPos-strikerHeight/2) && (YPos+diameter/2) <= (strikerYPos+strikerHeight/2))
{
score++;

//////////////////////////////////////////////////////////////////////
/////THIS IS THE PART TO FOCUS ON///////////////////////////////////////
/////WHEN THE BALL HITS THE STRIKER, I SHOW A '+1' TEXT FADING UPWARDS FROM THE POINT OF HIT
/////(THIS IS TO HIGHLIGHT A +1 INCREASE IN SCORE)///////////////////
//////NOW SINCE THE BALL MAY HIT THE STRIKER AGAIN BEFORE THE PREVIOUS +1 HAS COMPLETELY FADED,
//////I HAVE MADE THIS SIMPLE THREAD TO CREATE A +1 EVERY TIME THERE IS A HIT. SO THERE CAN BE MULTIPLE
//////+1 ON THE SCREEN.
//-------------------------------SADLY, SOMETHING IS WRONG-------------------

//Print a '+1' to show score increase
new Thread(new Runnable(){
int yStart = strikerYPos;
int fadeLength = 0;
Timer pointTimer;
int MAX_FADE_LEN = 50;

public void run() {
try
{

pointTimer = new Timer(1, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if(fadeLength >= MAX_FADE_LEN)
pointTimer.stop();
g2d.setColor(new Color(0,0,0,255));
g2d.setFont(new Font("Times",Font.BOLD,20));
g2d.drawString("+1",60,yStart - fadeLength);
g2d.drawOval(100,100,50,50);
System.out.println("Drawn +1 at x = " + 60 + " y = " + (yStart - fadeLength));
fadeLength++;
}
});
pointTimer.start();
}
catch (Exception e)
{

}
}

}).start();
////////////////THREAD ENDS HERE//////////////////////
}
else
{
score--;
}

//SHOW THE SCORE ON THE LABEL
jLabel1.setText("Score: " + score);
speedX = ((int)Math.signum((double)speedX))*(-1) * (2+ Math.abs(new Random().nextInt()) % 5);
XPos = strikerWidth+1;
}

if(YPos <= 0)
{
speedY = ((int)Math.signum((double)speedY))*(-1) * (2+ Math.abs(new Random().nextInt()) % 5);
YPos = 0;
}
if((YPos+diameter) >= h)
{
speedY = ((int)Math.signum((double)speedY))*(-1) * (2+ Math.abs(new Random().nextInt()) % 5);
YPos = h-diameter;
}
} else {
g2d.drawOval(XPos,YPos,diameter,diameter);
return;
}
}

public static void main(String[] args) {

JFrame frame = new JFrame("Magic Ball");
movingball = new MovingBall();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(movingball);
frame.setSize(450, 700);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

private void jbInit() throws Exception {
jButton1.setText("Start");
jButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jButton1_actionPerformed(e);
}
});
jButton2.setText("Stop");
jButton2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jButton2_actionPerformed(e);
}
});
jLabel1.setText("Score:0");
this.add(jButton1, null);
this.add(jButton2, null);
this.add(jLabel1, null);
this.setBackground(Color.white);
this.addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved(MouseEvent e) {
int coordX = e.getX();
if(coordX < 200)
strikerYPos = e.getY();
}

public void mouseDragged(MouseEvent e) {
}
});
}

private void jButton1_actionPerformed(ActionEvent e) {
if(!isBallMoving)
isBallMoving = true;
}

private void jButton2_actionPerformed(ActionEvent e) {
isBallMoving = false;
}
}

最佳答案

  • paintComponent 中的所有内容都会在 API 中实现的每个鼠标、键和内部方法上(自动)重新绘制,然后您的线程可能永远不会结束,可能有一堆并发线程,没有任何内容被重新绘制、显示

  • Swing GUI 的输出必须在美国东部时间完成

  • 使用 Swing Timer 而不是 new Thread(new Runnable(){

  • 调用重绘()

关于java - 图形 2d 对象的引用在孤立线程中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16545075/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com