Java 为什么它在错误的地方画线?
我对这个有问题。。。当我画一条线时,字符跟随我画的线,但计算机在其他地方画了一条线: 有人知道发生了什么吗? 我的代码: 很抱歉代码太大,但我不知道出了什么问题。。。 非常感谢所有回答以下问题的人: …是的,主要方法是someGame g=新someGame 1切勿使用油漆。。没有充分的理由。而是扩展JPanel类并覆盖paintComponent 2除非添加功能,否则不要扩展JFrame类 3.别忘了,所有回转组件的创建和操作都应在EDT上完成- 4 Java命名约定是CamelCase,类名的每个新词都应该以大写字母开头,即SomeGame 5在设置可见之前,不要使用setSize,而是覆盖组件getPreferredSize并返回所需的大小,而不要在JFrame上调用pack 6使用而不是KeyListener 7用鼠标代替听筒 8不要扩展Thread类并创建start方法来在runnable类中启动线程,我在下面的代码中没有实现这一点 9不适合执行长时间运行的任务,如加载图像或执行除在paint方法中绘制对象所需之外的任何其他工作。您应该在类初始化时或至少在components paint方法之外加载picture等。我没有在下面的代码中实现这一点 10关于线条绘制不正确的最大问题是:Java 为什么它在错误的地方画线?,java,swing,keylistener,java-2d,mouselistener,Java,Swing,Keylistener,Java 2d,Mouselistener,我对这个有问题。。。当我画一条线时,字符跟随我画的线,但计算机在其他地方画了一条线: 有人知道发生了什么吗? 我的代码: 很抱歉代码太大,但我不知道出了什么问题。。。 非常感谢所有回答以下问题的人: …是的,主要方法是someGame g=新someGame 1切勿使用油漆。。没有充分的理由。而是扩展JPanel类并覆盖paintComponent 2除非添加功能,否则不要扩展JFrame类 3.别忘了,所有回转组件的创建和操作都应在EDT上完成- 4 Java命名约定是CamelCase,类
g.drawLine(x1,x2,y1,y2);
应该是:
下面是代码,现在没有时间解释,希望您能理解:
我添加了一些额外的东西,比如对Graphics2D进行强制转换,以及使用RenderInts进行抗锯齿,正如@MadProgrammer在下面的评论中所建议的那样
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class SomeGame {
public SomeGame() {
JFrame frame = new JFrame("Some Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel dp = new DrawPanel();
frame.add(dp);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SomeGame();
}
});
}
}
class DrawPanel extends JPanel {
ArrayList lines = new ArrayList();
Point2D.Double start;
final Color BROWN = new Color(156, 93, 82);
Slider thread;
Rectangle cow = null;
boolean drawGuy = false;
public DrawPanel() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
Point2D.Double end = new Point2D.Double(me.getX(), me.getY());
lines.add(new Line2D.Double(start, end));
repaint();
}
@Override
public void mousePressed(MouseEvent me) {
super.mousePressed(me);
start = new Point2D.Double(me.getX(), me.getY());
}
});
setKeyBindings();
}
private void setKeyBindings() {
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "P");
getActionMap().put("P", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
thread = new Slider(DrawPanel.this);
thread.action(true);
thread.start();
}
});
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "q");
getActionMap().put("Q", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
thread.action(false);
drawGuy = false;
thread = null;
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(700, 700);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//lets go 2D :)
Graphics2D g2d = (Graphics2D) g;
//turn on anti aliasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
for (int i = 0; i < lines.size(); i++) {
Line2D.Double temp = (Line2D.Double) lines.get(i);
int x1 = Integer.parseInt("" + Math.round(temp.getX1()));
int x2 = Integer.parseInt("" + Math.round(temp.getX2()));
int y1 = Integer.parseInt("" + Math.round(temp.getY1()));
int y2 = Integer.parseInt("" + Math.round(temp.getY2()));
g2d.drawLine(x1, y1, x2, y2);
}
if (drawGuy) {
try {
URL url = this.getClass().getResource("resources/img/world/char.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
g.drawImage(image, cow.x, cow.y, this);
} catch (Exception exc) {
}
}
}
private class Slider extends Thread {
double velocity, gravity;
boolean go = false;
private final DrawPanel dp;
private Slider(DrawPanel dp) {
this.dp = dp;
}
public void run() {
if (go) {
initGuy();
velocity = 0;
gravity = 1;
}
while (go) {
try {
Line2D.Double lineTaken = null;
boolean onLine = false;
int firstOnLine = -1;
for (int i = lines.size() - 1; i >= 0; i--) {
Line2D.Double temp = (Line2D.Double) lines.get(i);
if (temp.intersects(cow.x, cow.y, 50, 50)) {
lineTaken = temp;
onLine = true;
if (firstOnLine != i) {
firstOnLine = i;
gravity = 0;
}
break;
}
}
if (onLine) {
double grav = (lineTaken.y2 - lineTaken.y1) / 50;
double vlct = (lineTaken.x2 - lineTaken.x1) / 100;
if (velocity < 5) {
velocity += vlct;
}
if (gravity < 2.5) {
gravity += grav;
}
} else {
gravity += .2;
}
cow.x += velocity;
cow.y += gravity;
Thread.sleep(75);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dp.repaint();
}
});
} catch (Exception e) {
break;
}
}
}
public void action(boolean b) {
go = b;
}
public void initGuy() {
Line2D.Double firstLine = (Line2D.Double) lines.get(0);
int x = Integer.parseInt("" + Math.round(firstLine.x1));
int y = Integer.parseInt("" + Math.round(firstLine.y1));
cow = new Rectangle(x + 30, y - 20, 30, 30);
drawGuy = true;
}
}
}
你不应该用油漆。。没有充分的理由。而是扩展JPanel类并覆盖paintComponent
2除非添加功能,否则不要扩展JFrame类
3.别忘了,所有回转组件的创建和操作都应在EDT上完成-
4 Java命名约定是CamelCase,类名的每个新词都应该以大写字母开头,即SomeGame
5在设置可见之前,不要使用setSize,而是覆盖组件getPreferredSize并返回所需的大小,而不要在JFrame上调用pack
6使用而不是KeyListener
7用鼠标代替听筒
8不要扩展Thread类并创建start方法来在runnable类中启动线程,我在下面的代码中没有实现这一点
9不适合执行长时间运行的任务,如加载图像或执行除在paint方法中绘制对象所需之外的任何其他工作。您应该在类初始化时或至少在components paint方法之外加载picture等。我没有在下面的代码中实现这一点
10关于线条绘制不正确的最大问题是:
g.drawLine(x1,x2,y1,y2);
应该是:
下面是代码,现在没有时间解释,希望您能理解:
我添加了一些额外的东西,比如对Graphics2D进行强制转换,以及使用RenderInts进行抗锯齿,正如@MadProgrammer在下面的评论中所建议的那样
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class SomeGame {
public SomeGame() {
JFrame frame = new JFrame("Some Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawPanel dp = new DrawPanel();
frame.add(dp);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SomeGame();
}
});
}
}
class DrawPanel extends JPanel {
ArrayList lines = new ArrayList();
Point2D.Double start;
final Color BROWN = new Color(156, 93, 82);
Slider thread;
Rectangle cow = null;
boolean drawGuy = false;
public DrawPanel() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
Point2D.Double end = new Point2D.Double(me.getX(), me.getY());
lines.add(new Line2D.Double(start, end));
repaint();
}
@Override
public void mousePressed(MouseEvent me) {
super.mousePressed(me);
start = new Point2D.Double(me.getX(), me.getY());
}
});
setKeyBindings();
}
private void setKeyBindings() {
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "P");
getActionMap().put("P", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
thread = new Slider(DrawPanel.this);
thread.action(true);
thread.start();
}
});
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "q");
getActionMap().put("Q", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
thread.action(false);
drawGuy = false;
thread = null;
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(700, 700);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//lets go 2D :)
Graphics2D g2d = (Graphics2D) g;
//turn on anti aliasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
for (int i = 0; i < lines.size(); i++) {
Line2D.Double temp = (Line2D.Double) lines.get(i);
int x1 = Integer.parseInt("" + Math.round(temp.getX1()));
int x2 = Integer.parseInt("" + Math.round(temp.getX2()));
int y1 = Integer.parseInt("" + Math.round(temp.getY1()));
int y2 = Integer.parseInt("" + Math.round(temp.getY2()));
g2d.drawLine(x1, y1, x2, y2);
}
if (drawGuy) {
try {
URL url = this.getClass().getResource("resources/img/world/char.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
g.drawImage(image, cow.x, cow.y, this);
} catch (Exception exc) {
}
}
}
private class Slider extends Thread {
double velocity, gravity;
boolean go = false;
private final DrawPanel dp;
private Slider(DrawPanel dp) {
this.dp = dp;
}
public void run() {
if (go) {
initGuy();
velocity = 0;
gravity = 1;
}
while (go) {
try {
Line2D.Double lineTaken = null;
boolean onLine = false;
int firstOnLine = -1;
for (int i = lines.size() - 1; i >= 0; i--) {
Line2D.Double temp = (Line2D.Double) lines.get(i);
if (temp.intersects(cow.x, cow.y, 50, 50)) {
lineTaken = temp;
onLine = true;
if (firstOnLine != i) {
firstOnLine = i;
gravity = 0;
}
break;
}
}
if (onLine) {
double grav = (lineTaken.y2 - lineTaken.y1) / 50;
double vlct = (lineTaken.x2 - lineTaken.x1) / 100;
if (velocity < 5) {
velocity += vlct;
}
if (gravity < 2.5) {
gravity += grav;
}
} else {
gravity += .2;
}
cow.x += velocity;
cow.y += gravity;
Thread.sleep(75);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dp.repaint();
}
});
} catch (Exception e) {
break;
}
}
}
public void action(boolean b) {
go = b;
}
public void initGuy() {
Line2D.Double firstLine = (Line2D.Double) lines.get(0);
int x = Integer.parseInt("" + Math.round(firstLine.x1));
int y = Integer.parseInt("" + Math.round(firstLine.y1));
cow = new Rectangle(x + 30, y - 20, 30, 30);
drawGuy = true;
}
}
}
@戴维德克鲁坎普·奥乌奥我真的不知道那些东西bc我不是很先进加上我在做一本书加上我在做一本书买一本更好的书,这本书对你没有任何好处从它的声音+1为;考虑UimaGaGr.GeTiCon占位符图像。@ Itasi如果每个人都这么说,那么我建议这个语句有权重,如果你的问题是由一个过时的或者简单的写得很差的资源引起的,你应该改变它,这对你没有任何好处favors@Itachi如果这本书把你带到了发布充满坏习惯的代码的地步,那是不明智的。恕我直言,让你误入歧途的消息来源是问题的一部分,当然,这是你的选择,无视那些在你之前的人的建议。@DavidKroukamp o__o我真的不知道那些东西bc我不是很先进加上我在做一本书加上我在做一本书买一本更好的书,从它+1的声音来看,这一个对你没有任何好处;考虑UimaGaGr.GeTiCon占位符图像。@ Itasi如果每个人都这么说,那么我建议这个语句有权重,如果你的问题是由一个过时的或者简单的写得很差的资源引起的,你应该改变它,这对你没有任何好处favors@Itachi如果这本书把你带到了发布充满坏习惯的代码的地步,那是不明智的。恕我直言,导致您误入歧途的消息来源是问题的一部分,当然,您可以选择忽略之前那些人的建议。@ltachi您可能想通读一下,@MadProgrammer+1谢谢您在我的评论中看到了它,但没有在回复中转载它:O@DavidKroukamp顺便说一下,类名不是什么游戏,我只是用一些游戏替换了它,明白吗?@Itachi一个更好的替代品,适合良好的实践是一些游戏:@DavidKroukamp谢谢,顺便说一句谢谢
太多了。。。我完全忘记了x1、y1等的事情!!!谢谢@ltachi您可能想通读一下,@MadProgrammer+1感谢您在我的评论中看到了它,但没有在回复中转载:O@DavidKroukamp顺便说一下,类名不是someGame,我只是用someGame替换了它,明白了吗?@Itachi一个更好的替换,适合良好实践的是someGame:@DavidKroukamp谢谢,顺便说一句,非常感谢。。。我完全忘记了x1、y1等的事情!!!谢谢!!!!