我知道以下代码会直接移动一个对象。如何让物体以波浪线行进?我知道x
变量需要额外的东西。
public void draw(Graphics2D g)
{
g.setColor(Color.WHITE);
g.fillOval ((int) (x - r), (int) (y - r), (int)
(2 * r),
(int) (2 * r));
y++;
if (y - r > height)
y = -r;
}
答案 0 :(得分:5)
使用正弦或余弦函数计算y作为x的函数。
乘以正弦或余弦函数以增加幅度(它的高度)
y = 100 * sin(x) // will make it have peaks of -100 and 100
除以x以增加周期。 (峰之间的距离)
y = sin(x/2) // will make it take twice the x distance between peaks.
这样的事情:
public void draw(Graphics2D g)
{
g.setColor(Color.WHITE);
g.fillOval ((int) (x - r), (int) (y - r), (int)
(2 * r),
(int) (2 * r));
x++; // Left to right movement
// Example, modify the multipliers as necessary
y = 100 * Math.sin(Math.toDegrees(x/4))
}
答案 1 :(得分:2)
在函数中包含sin(x)或cos(x)将提供规则的波形图案,不规则图案需要更复杂的函数
答案 2 :(得分:1)
我知道你已经接受了一个答案,但这里有一些东西可以从我掀起的内容中获得额外的灵感......
package wavy;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Wavy {
public static void main(String[] args) {
final JFrame frame = new JFrame("Wavy!");
final WavyPanel wp = new WavyPanel();
frame.getContentPane().add(wp, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Ticker t = new Ticker(wp);
final Repainter r = new Repainter(wp);
frame.pack();
frame.setVisible(true);
final Timer tickTimer = new Timer();
final Timer paintTimer = new Timer();
paintTimer.schedule(r, 1000, 50);
tickTimer.schedule(t, 1000, 10);
}
private static class WavyPanel extends JPanel {
private final Dimension size = new Dimension(640, 480);
private int amplitude = 50;
private int frequency = 5;
private int x = 0;
private double y = size.height / 2;
private int yBase = 0;
WavyPanel() {
super(true);
}
@Override
protected void paintComponent(final Graphics g) {
final Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, size.width, size.height);
g2.setColor(Color.BLACK);
g2.fillOval(x, (int)y, 30, 30);
}
@Override
public Dimension getPreferredSize() {
return size;
}
@Override
public Dimension getMinimumSize() {
return size;
}
@Override
public Dimension getMaximumSize() {
return size;
}
public void tick() {
//Move a pixel to the right; loop over to the left when reaching edge
x = (++x) % size.width;
//Length of one full wave = panel width divided by frequency
final int waveLength = size.width / frequency;
//Incrementing yBase; capping off at wavelength
yBase = (++yBase) % waveLength;
//Normalizing to [0..1]
final double normalized = (double)yBase / (double)waveLength;
//Full wave at 2*pi, means...
final double radians = normalized * Math.PI * 2;
//Getting the sine
final double sine = Math.sin(radians);
//Multiplying with amplitude, add to center position and we have our y
y = (int)(sine * amplitude) + size.height/2;
}
}
private static class Ticker extends TimerTask {
private final WavyPanel panel;
Ticker(final WavyPanel panel) {
this.panel = panel;
}
@Override
public void run() {
panel.tick();
}
}
private static class Repainter extends TimerTask {
private final WavyPanel panel;
Repainter(final WavyPanel panel) {
this.panel = panel;
}
@Override
public void run() {
panel.repaint();
}
}
}
这应该以大约每秒20帧的速度运行。您可以通过将paintTimer.schedule(r, 1000, 50)
的第二个参数设置为较低来增加此值。通过降低(加速)或增加(慢)tickTimer.schedule(t, 1000, 50)
的第二个参数,可以改变移动速度。
更改WavyPanel的amplitude
字段将更改圆圈的移动高度/低度。将frequency
更改为较高的值会导致较短的波浪,而较低的值会产生较长的波浪。
通过一些额外的工作,您可以添加控件以即时更改幅度和频率。一些补充说明:
tick()
方法添加一些安全措施,以确保在一次调用已经运行时,将跳过其他调用,直到完成第一次调用。否则,计算可能会因短时间间隔而失败。这里可以使用信号量。答案 3 :(得分:0)
我希望我能解释这一点。可以使用x或y坐标的正弦或余弦。我不是在使用java的机器上,所以我现在无法做出示例..
答案 4 :(得分:0)
你是对的,你需要更新x和y变量以获得波浪线。以下是水平线上下波动的一般策略:
y = amplitude * Math.sin(frequency * x)
来获得给定幅度和频率的常规正弦波。)draw
中,在绘制椭圆之前,请计算y = f(x);
。绘制椭圆,然后增加x
。如有必要,请重置x
以使其保持在范围内。如果您想要一条左右波浪的垂直线,只需颠倒上面x
和y
的角色即可。如果你想让椭圆向反方向移动,只需在步骤4中递减而不是递增。
答案 5 :(得分:0)
此样本用于正弦图上的点(一行长度的线)和使用的时钟。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class RunSwing extends JPanel {
static int x1 = 500;
static int y1 = 500;
static int x2 = x1;
static int y2 = y1;
final static int vectorLength = 100;
final static int sinx2 = x2;
final static int siny2 = y2;
static double count = 0;
private static RunSwing run = new RunSwing();
final Timer print = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
//increaseSinusGraph();
increaseClockVector();
count+=6; //for clock for 1 second
/*count++;//for sinus*/
if (count % 360 == 0)
System.out.println((count / 360) + " minute passed");
}
});
RunSwing() {
print.start();
}
public static void main(String[] args) {
JFrame frame = new JFrame("amir");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(run);
frame.setSize(1100, 700);
frame.setVisible(true);
}
static void increaseClockVector() {
double cos = Math.cos(Math.toRadians(count));
double sin = Math.sin(Math.toRadians(count));
y2 = siny2 + (int) (vectorLength * sin);
x2 = sinx2 + (int) (vectorLength * cos);
}
static void increaseSinusGraph() {
double sin = Math.sin(Math.toRadians(count));
y2 = siny2 + (int) (vectorLength * sin);
x2++;
}
private void createPoint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(x2, y2, x2 + 1, y2 + 1);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(0, 0, 0));
g.drawLine(x1, y1, x2, y2);//for clock
/*g.drawLine(x2, y2, x2+1, y2+1);//for sinus*/
repaint();
}
}