How to make a sprite spiral to the center (in Java but if you know a formula, it would help too)

StackOverflow https://stackoverflow.com/questions/18554486

  •  27-06-2022
  •  | 
  •  

Question

I'm making a game in java where enemy sprites spiral to the center and damage the main tower. The only thing I'm having problems with is the formula to make the sprite spiral. All I found on the internet it this: http://scratch.mit.edu/projects/1439249/

That is sort of what I want to do but I want to make them spiral to a point from outside the JFrame, not from a point within the JFrame.

I am in Secondary 4 and I don't have to much knowledge about such formulas yet and sorry if I have problems understanding the formulas. Thanks in advance!

Était-ce utile?

La solution

One simple way of making a sprite appear to spiral is to pretend that it is attached to an arm, like the hand of a clock, that rotates around the center of the spiral. As that arm rotates, slowly move the sprite down the arm towards the center. What you end up with is a classic Archimedan Spiral

I can mock up some code for you, but that's going to take a few minutes.


Okay, here's the code.

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;
}

These are the core of the math. They return the x and y values of an entity that is at the specified distance from the center (length) and angle from the center (angle).

Now, I don't know how you have your code set up, but lets pretend we have a double named spiralProgress that represents how far into its spiral your entity is. At spiralProgress == 0, the entity is just starting, and at spiralProgress == 1, the entity is at the center.

Here is what the code to get the x and y for the entity would look like:

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);

In that snippet, startingRadius is how many units (pixels, if thats what x and y means in your program), the entity should start away from the center, and rotations is how many times the entity should loop around the center before reaching it.

The coordinates this returns are for a spiral around {0, 0}, so if you want to spiral around some other point, say {screenWidth / 2, screenHeight / 2}, you'd add screenWidth / 2 to x and screenHeight / 2 to y.

Here is a full Java program that demonstrates this math. Click the mouse anywhere in the window to reset the spiral.

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();
    }

}

Autres conseils

I am new to java programming too and as part of my course I recently had to program a spiral.

Here is the solution file from my course. This will draw a simple spiral.

I hope this helps you. It also has comments to help you understand what is happening.

enjoy

    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

Here is the test file.

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top