1

私は、敵のスプライトが中心に向かって螺旋を描き、メイン タワーにダメージを与える Java でゲームを作成しています。私が問題を抱えている唯一のものは、スプライトをらせんにする式です。私がインターネットで見つけたのはこれだけです:http://scratch.mit.edu/projects/1439249/

それは私がやりたいことのようなものですが、JFrame 内のポイントからではなく、JFrame の外側からポイントまでらせん状にしたいと考えています。

私はセカンダリー 4 にいますが、そのような数式についてはまだあまり知識がなく、数式の理解に問題がある場合は申し訳ありません。前もって感謝します!

4

2 に答える 2

3

スプライトをらせん状に見せる簡単な方法の 1 つは、時計の針のように、らせんの中心を中心に回転する腕にスプライトが取り付けられているように見せることです。そのアームが回転するにつれて、スプライトをアームの中心に向かってゆっくりと動かします。最終的に得られるのは、古典的なアルキメダンスパイラルです

コードのモックアップを作成できますが、数分かかります。


さて、これがコードです。

public static double getArmX(double length, double angle) {
    return Math.cos(angle) * length;
}

public static double getArmY(double length, double angle) {
    return Math.sin(angle) * length;
}

これらは数学の核心です。これらは、中心から指定された距離 (長さ) と中心からの角度 (角度) にあるエンティティの x 値と y 値を返します。

さて、あなたのコードがどのように設定されているかはわかりませんが、あなたのエンティティがどの程度スパイラルに入っているかを表すdouble名前があるとしましょう。spiralProgressではspiralProgress == 0、エンティティは開始されたばかりでありspiralProgress == 1、 ではエンティティが中心にあります。

エンティティの x と y を取得するコードは次のようになります。

double startingRadius = 64;
double rotations = 10;

double x = getArmX(startingRadius * (1-t), t * rotations * Math.PI * 2);
double y = getArmY(startingRadius * (1-t), t * rotations * Math.PI * 2);

そのスニペットでstartingRadiusは、エンティティが中心から離れて開始する必要がある単位数 (ピクセル、プログラムで x と y が意味する場合) であり、エンティティがrotations中心に到達する前に中心をループする回数です。

これが返す座標は、{0, 0} を中心とした螺旋の座標です。したがって、他の点を中心に螺旋を描きたい場合は、たとえばにとを{screenWidth / 2, screenHeight / 2}追加screenWidth / 2します。xscreenHeight / 2y

この計算を示す完全な Java プログラムを次に示します。ウィンドウ内の任意の場所でマウスをクリックして、らせんをリセットします。

package net.eonz.stackoverflow.spiral;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class Game extends Canvas implements Runnable, MouseListener {
    private static final long serialVersionUID = 1L;
    public static final String NAME = "untitled";
    public static final int HEIGHT = 600;
    public static final int WIDTH = 600;
    public static final int SCALE = 1;

    private boolean running = false;

    public void start() {
        running = true;
        new Thread(this).start();
        this.addMouseListener(this);
    }

    public void stop() {
        running = false;
    }

    public void run() {
        long last = System.currentTimeMillis();

        while (running) {
            long now = System.currentTimeMillis();
            double dt = (now - last) / 1000.0;
            last = now;
            update(dt);
            render();
        }
    }

    double t = 0;

    public void update(double dt) {
        t += dt / 16;
        if (t > 1)
            t = 1;
    }

    public void render() {
        BufferStrategy bs = getBufferStrategy();

        if (bs == null) {
            createBufferStrategy(3);
            return;
        }

        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.white);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());

        /* SPIRAL MATH IS HERE */

        double startingRadius = this.getHeight() * 0.40;
        double rotations = 10;

        double x = getArmX(startingRadius * (1 - t), t * rotations * Math.PI
                * 2);
        double y = getArmY(startingRadius * (1 - t), t * rotations * Math.PI
                * 2);

        g.setColor(Color.black);
        g.fillRect((int) (x - 8) + this.getWidth() / 2,
                (int) (y - 8) + this.getHeight() / 2, 16, 16);

        /* END SPIRAL MATH */

        g.dispose();
        bs.show();
    }

    public static double getArmX(double length, double angle) {
        return Math.cos(angle) * length;
    }

    public static double getArmY(double length, double angle) {
        return Math.sin(angle) * length;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        this.t = 0;
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    public static void main(String[] args) {
        Game game = new Game();
        game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
        game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));

        JFrame frame = new JFrame(Game.NAME);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(game, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

        game.start();
    }

}
于 2013-09-01T02:00:30.253 に答える
0

私もJavaプログラミングは初めてで、コースの一環として、最近スパイラルをプログラミングする必要がありました。

これが私のコースのソリューションファイルです。これにより、単純ならせんが描かれます。

これがお役に立てば幸いです。また、何が起こっているのかを理解するのに役立つコメントもあります。

楽しい

    import java.awt.Color;

import java.awt.Graphics;

import javax.swing.JPanel;


public class DrawSpiral2 extends JPanel

{

// draws a square shape that continually spirals outward

public void paintComponent( Graphics g )

{

super.paintComponent( g );


g.setColor( Color.GREEN ); 
// draw a green spiral



int x = getWidth() / 2; 
// x coordinate of upperleft corner


int y = getHeight() / 2;
 // y coordinate of upperleft corner


 int radiusStep = 20; 

// distance the radius changes

int diameter = 0; // diameter of the arc


int arc = 180; // amount and direction of arc to sweep


// draws individual lines in to form a spiral

for ( int i = 0; i < 20; i++ )

{

if ( i % 2 == 1 ) // move the x position every other repetition
            x -= 2 * radiusStep;


y -= radiusStep; // move the y position


diameter += 2 * radiusStep; // increase the diameter

         g.drawArc( x, y, diameter, diameter, 0, arc ); 
// draw the arc


arc = -arc; // reverse the direction of the arc

} // end for

} // end method paintComponent

} // end class DrawSpiral2

ここにテストファイルがあります。

public class DrawSpiralTest2

{

public static void main( String args[] )

{

DrawSpiral2 panel = new DrawSpiral2();      

JFrame application = new JFrame();


      application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

      application.add( panel );

application.setSize( 300, 300 );

application.setVisible( true );

} // end main

} // end class DrawSpiralTest2
于 2013-09-01T03:44:43.377 に答える