Java 如何使用弧度移动对象?
我有一个问题,因为我需要移动我的球,而它只是静止不动。我用一个简单的函数(x=x+1)成功地移动了它,但当涉及到弧度时,它就不起作用了。我在这里读过一些帖子,我认为我做得对,但很明显我错过了一些东西:) 这是我的球类课程:Java 如何使用弧度移动对象?,java,animation,graphics,polar-coordinates,Java,Animation,Graphics,Polar Coordinates,我有一个问题,因为我需要移动我的球,而它只是静止不动。我用一个简单的函数(x=x+1)成功地移动了它,但当涉及到弧度时,它就不起作用了。我在这里读过一些帖子,我认为我做得对,但很明显我错过了一些东西:) 这是我的球类课程: public class Ball { int x = 0; int y = 0; int rightleft = 1; int updown = 1; private static final int sizeBall = 30; float angle = 120;
public class Ball {
int x = 0;
int y = 0;
int rightleft = 1;
int updown = 1;
private static final int sizeBall = 30;
float angle = 120;
float angleInRadians = (float) (angle*Math.PI/180);
private Main main;
public Ball(Main main){
this.main=main;
}
// That function should move my ball
void move() {
x = (int) (x + Math.cos(angleInRadians));
y= (int) (x+Math.sin(angleInRadians));
}
void paint(Graphics2D g) {
g.setColor(Color.red);
g.fillOval(x, y, sizeBall, sizeBall);
}
public Rectangle getSize(){
return new Rectangle(x,y,sizeBall,sizeBall);
}
}
public class Main extends JPanel {
Ball ball = new Ball(this);
private void moveBall() throws InterruptedException{
ball.move();
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
}
public static void main(String[] args) throws InterruptedException {
// TODO code application logic here
JFrame okno = new JFrame("TEST");
Main main = new Main();
okno.add(main);
okno.setSize(500,500);
okno.setVisible(true);
okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while(true){
main.moveBall();
main.repaint();
Thread.sleep(10);
}
}
}
这是我的主要课程:
public class Ball {
int x = 0;
int y = 0;
int rightleft = 1;
int updown = 1;
private static final int sizeBall = 30;
float angle = 120;
float angleInRadians = (float) (angle*Math.PI/180);
private Main main;
public Ball(Main main){
this.main=main;
}
// That function should move my ball
void move() {
x = (int) (x + Math.cos(angleInRadians));
y= (int) (x+Math.sin(angleInRadians));
}
void paint(Graphics2D g) {
g.setColor(Color.red);
g.fillOval(x, y, sizeBall, sizeBall);
}
public Rectangle getSize(){
return new Rectangle(x,y,sizeBall,sizeBall);
}
}
public class Main extends JPanel {
Ball ball = new Ball(this);
private void moveBall() throws InterruptedException{
ball.move();
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
}
public static void main(String[] args) throws InterruptedException {
// TODO code application logic here
JFrame okno = new JFrame("TEST");
Main main = new Main();
okno.add(main);
okno.setSize(500,500);
okno.setVisible(true);
okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while(true){
main.moveBall();
main.repaint();
Thread.sleep(10);
}
}
}
你知道我的错误在哪里吗?x和y总是=0。首先要理解它们是0,然后向它们添加一个正弦或余弦,保证小于1
x = (int) (x + Math.cos(angleInRadians));
y = (int) (x+Math.sin(angleInRadians));
因此,0+一个小于1的数字将小于1
然后,当您强制转换为int时,<1的数字将变为0
也
- 使用摆动计时器,而不是
循环while(true)
- 覆盖JPanel的paintComponent方法,而不是其绘制方法以获得更平滑的动画
- 我会使用双倍数字来表示我的x和y值,并且在使用它们进行绘制时只进行强制转换或舍入李>
- 我不确定你的目标是什么轨迹,但是你当前的代码(如果有效的话)不会以极坐标的方式移动,而是始终与当前点成45%的角度
例如,此GUI由以下代码创建:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyPolar extends JPanel {
private static final int BI_W = 400;
private static final int BI_H = BI_W;
private static final int CTR_X = BI_W / 2;
private static final int CTR_Y = BI_H / 2;
private static final Color AXIS_COLOR = Color.black;
private static final Color GRID_LINE_COLOR = Color.LIGHT_GRAY;
private static final Color DRAWING_COLOR = Color.RED;
private static final float AXIS_LINE_WIDTH = 4f;
private static final double SCALE = BI_W / (2 * 1.25);
private static final float GRID_LINE_WIDTH = 2f;
private static final float DRAWING_WIDTH = 2f;
private static final double DELTA_THETA = Math.PI / (2 * 360);
private static final int TIMER_DELAY = 20;
private BufferedImage axiImg;
private List<Point> ptList = new ArrayList<>();
private double theta = 0;
public MyPolar() {
axiImg = createAxiImg();
int x = xEquation(theta);
int y = yEquation(theta);
ptList.add(new Point(x, y));
new Timer(TIMER_DELAY, new TimerListener()).start();
}
private int xEquation(double theta) {
double r = 2 * Math.sin(4 * theta);
return (int) (SCALE * 0.5 * r * Math.cos(theta)) + CTR_X;
}
private int yEquation(double theta) {
double r = 2 * Math.sin(4 * theta);
return (int) (SCALE * 0.5 * r * Math.sin(theta)) + CTR_Y;
}
private BufferedImage createAxiImg() {
BufferedImage img = new BufferedImage(BI_W, BI_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(AXIS_COLOR);
g2.setStroke(new BasicStroke(AXIS_LINE_WIDTH));
int x1 = 0;
int y1 = CTR_Y;
int x2 = BI_W;
int y2 = y1;
g2.drawLine(x1, y1, x2, y2);
x1 = CTR_X;
y1 = 0;
x2 = x1;
y2 = BI_H;
g2.drawLine(x1, y1, x2, y2);
g2.setColor(GRID_LINE_COLOR);
g2.setStroke(new BasicStroke(GRID_LINE_WIDTH));
x1 = (int) (CTR_X - BI_H * 0.5 * Math.tan(Math.PI / 6));
y1 = BI_H;
x2 = (int) (CTR_X + BI_H * 0.5 * Math.tan(Math.PI / 6));
y2 = 0;
g2.drawLine(x1, y1, x2, y2);
x1 = BI_W - x1;
x2 = BI_W - x2;
g2.drawLine(x1, y1, x2, y2);
x1 = (int) (CTR_X - BI_H * 0.5 * Math.tan(Math.PI / 3));
y1 = BI_H;
x2 = (int) (CTR_X + BI_H * 0.5 * Math.tan(Math.PI / 3));
y2 = 0;
g2.drawLine(x1, y1, x2, y2);
x1 = BI_W - x1;
x2 = BI_W - x2;
g2.drawLine(x1, y1, x2, y2);
for (int i = 1; i < 4; i++) {
int x = (int) (CTR_X - i * SCALE / 2.0);
int y = x;
int width = (int) (i * SCALE);
int height = width;
g2.drawOval(x, y, width, height);
}
g2.dispose();
return img;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (axiImg != null) {
g2.drawImage(axiImg, 0, 0, null);
}
g2.setColor(DRAWING_COLOR);
g2.setStroke(new BasicStroke(DRAWING_WIDTH));
Point prev = null;
for (Point point : ptList) {
if (prev != null) {
int x1 = prev.x;
int y1 = prev.y;
int x2 = point.x;
int y2 = point.y;
g2.drawLine(x1, y1, x2, y2);
}
prev = point;
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(BI_W, BI_H);
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
theta += DELTA_THETA;
if (theta > 2 * Math.PI) {
((Timer) e.getSource()).stop();
} else {
int x = xEquation(theta);
int y = yEquation(theta);
ptList.add(new Point(x, y));
}
repaint();
}
}
private static void createAndShowGui() {
MyPolar mainPanel = new MyPolar();
JFrame frame = new JFrame("MyPolar");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.RenderingHints;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.image.buffereImage;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.*;
@抑制警告(“串行”)
公共类MyPolar扩展JPanel{
专用静态最终int BI_W=400;
私有静态final int BI_H=BI_W;
专用静态最终int CTR_X=BI_W/2;
专用静态最终int CTR_Y=BI_H/2;
专用静态最终颜色轴_Color=Color.black;
私有静态最终颜色网格\u线\u颜色=Color.LIGHT\u灰色;
专用静态最终颜色图\u Color=Color.RED;
专用静态最终浮动轴\线\宽度=4f;
专用静态最终双刻度=BI_W/(2*1.25);
专用静态最终浮动网格线宽度=2f;
专用静态最终浮子图纸_宽度=2f;
专用静态最终双增量θ=Math.PI/(2*360);
专用静态最终int定时器_延迟=20;
私有缓存映像aximg;
private List ptList=new ArrayList();
私人双θ=0;
公共MyPolar(){
axiImg=createAxiImg();
int x=x方程(θ);
int y=y方程(θ);
p添加(新点(x,y));
新定时器(定时器延迟,新定时器延迟()).start();
}
专用整数表达式(双θ){
双r=2*Math.sin(4*theta);
返回(int)(标度*0.5*r*数学cos(θ))+CTR_X;
}
专用积分方程(双θ){
双r=2*Math.sin(4*theta);
返回(int)(标度*0.5*r*数学正弦(θ))+CTR_Y;
}
私有缓冲区映像CreateAximG(){
BuffereImage img=新的BuffereImage(BI_W,BI_H,BuffereImage.TYPE_INT_ARGB);
Graphics2D g2=img.createGraphics();
g2.setRenderingHint(renderingHits.KEY\u ANTIALIASING,renderingHits.VALUE\u ANTIALIAS\u ON);
g2.设置颜色(轴颜色);
g2.设定行程(新的基本行程(轴线宽度));
int-x1=0;
int y1=中心线Y;
int x2=BI_W;
int y2=y1;
g2.拉线(x1、y1、x2、y2);
x1=CTR_X;
y1=0;
x2=x1;
y2=BI_H;
g2.拉线(x1、y1、x2、y2);
g2.设置颜色(网格线颜色);
g2.设定行程(新基本行程(网格线宽度));
x1=(int)(CTR_X-BI_H*0.5*Math.tan(Math.PI/6));
y1=BI_H;
x2=(int)(CTR_X+BI_H*0.5*Math.tan(Math.PI/6));
y2=0;
g2.拉线(x1、y1、x2、y2);
x1=BI_W-x1;
x2=BI_W-x2;
g2.拉线(x1、y1、x2、y2);
x1=(int)(CTR_X-BI_H*0.5*Math.tan(Math.PI/3));
y1=BI_H;
x2=(int)(CTR_X+BI_H*0.5*Math.tan(Math.PI/3));
y2=0;
g2.拉线(x1、y1、x2、y2);
x1=BI_W-x1;
x2=BI_W-x2;
g2.拉线(x1、y1、x2、y2);
对于(int i=1;i<4;i++){
int x=(int)(中心x-i*标度/2.0);
int y=x;
整数宽度=(整数)(i*比例);
整数高度=宽度;
g2.绘制椭圆(x、y、宽度、高度);
}
g2.dispose();
返回img;
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
g2.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
如果(aximg!=null){
g2.drawImage(aximg,0,0,null);
}
g2.设置颜色(图纸颜色);
g2.设定行程(新基本行程(图纸宽度));
上一点=空;
用于(点:ptList){
如果(上一个!=null){
int x1=上一个x;
int y1=上一个y;
int x2=点x;
int y2=点y;
g2.拉线(x1、y1、x2、y2);
}
prev=点;
}
}
@凌驾
公共维度getPreferredSize(){
如果(isPreferredSizeSet()){
返回super.getPreferredSize();
}
返回新维度(BIU W、BIU H);
}
私有类TimerListener实现ActionListener{
@凌驾
已执行的公共无效操作(操作事件e){
θ+=δθ;
if(θ>2*Math.PI){
((计时器)e.getSource()).stop();
}否则{
int x=x方程(θ);
int y=y方程(θ);
p添加(新点(x,y));
}
重新油漆();
}
}
私有静态void createAndShowGui(){
MyPolar主面板=新建MyPolar();
JFrame=新JFrame(“MyPolar”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);