0

I'm studying programming and I'm currently doing the OOP course.

I have to do a clone of Kingdom Rush, and I was given this example for pathing.

My question is how do I do to make the object iterating over the path to move at a regular speed.

I saw this post asking the same but didn't understand how to implement it.

In the example, I was given a library to create directional vectors (processing/core).

This is the code:

import java.awt.*;
import java.awt.event.*;

import java.awt.geom.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
import java.util.*;
import java.text.*;

import com.entropyinteractive.*;

public class DemoRuta extends Game {
    Fondo fondo;
    Shape carrilUno;
    java.util.List<Point2D> puntos;
    int radius=16;
    Point2D pos=new Point2D.Float(310 - (radius/2),0 - (radius/2) );
    double dbl_idx;

    public static void main(String[] args) {
        DemoRuta game = new DemoRuta();
        game.run(1.0 / 60.0);
        System.exit(0);
    }

    public DemoRuta() {
           super("DemoRuta ", 700, 600);
    }

    public void gameStartup() {
        Path2D path = new Path2D.Double();
        path.moveTo(310,0);
        path.curveTo(310,50,315,100,   320,140);
        path.curveTo(320,170,310,190,  285,220);
        path.curveTo(260,230, 230,250, 200,250);
        path.curveTo(170,275,155,320,  150,350);
        path.curveTo(165,380,190,420,  240,430);
        path.curveTo(280,430,330,430,  400,420);
        path.curveTo(440,440,470,430,  500,450);
        path.curveTo(520,420,550,400,  575,370);
        path.curveTo(620,360,660,360,  700,360);
        carrilUno = path;

        puntos = new ArrayList<>(50);
        PathIterator pi = carrilUno.getPathIterator(null, 0.01);
        while (!pi.isDone()) {
            double[] coords = new double[6];
            switch (pi.currentSegment(coords)) {
                case PathIterator.SEG_MOVETO:
                case PathIterator.SEG_LINETO:
                    puntos.add(new Point2D.Double(coords[0], coords[1]));
                    break;
            }
            pi.next();
        }
        System.out.println("Cantidad de puntos de la ruta: " + puntos.size());
        fondo = new Fondo();
    }

    public void gameUpdate(double delta) {
        dbl_idx += 0.0005;
        int index = Math.min(Math.max(0, (int) (puntos.size() * dbl_idx)), puntos.size() - 1);
        pos = puntos.get(index); // saco una posicion
        dbl_idx = (index >=puntos.size() - 1) ? 0.0 : dbl_idx;

        Keyboard keyboard = getKeyboard();
        LinkedList < KeyEvent > keyEvents = keyboard.getEvents();
        for (KeyEvent event: keyEvents) {
            if ((event.getID() == KeyEvent.KEY_PRESSED) &&
                (event.getKeyCode() == KeyEvent.VK_ESCAPE)) {
                stop();
            }
        }
    }

    public void gameDraw(Graphics2D g) {
        fondo.display(g);

        g.setColor(Color.white);
        g.drawString("Tecla ESC = Fin del Juego ",490,20);

        g.setColor(Color.red);
        g.draw(carrilUno);

        g.setColor(Color.black);
        g.fillOval((int)(pos.getX()- (radius/2)),  (int)(pos.getY()- (radius/2)), radius,radius);
    }

    public void gameShutdown() {

    }
}

class Fondo {
    private BufferedImage img_fondo = null;

    public Fondo() {
            try {
                img_fondo= ImageIO.read(getClass().getResource("nivel1.png"));
            } catch (IOException e) {
                System.out.println(e);
            }
    }

    public int getWidth(){
        return img_fondo.getWidth();
    }
    public int getHeight(){

        return img_fondo.getHeight();
    }

    public void display(Graphics2D g2) {
        g2.drawImage(img_fondo,0,0,null);//movimiento del fondo
     }    
}
Antú Villegas
  • 51
  • 1
  • 10

2 Answers2

0

Remember high-school physics, distance = speed * time. In your update loop, you are given the amount of time that has elapsed since the last update:

public void gameUpdate(double delta)

Instead of adding some really small number to dbl_idx with each update, try multiplying the time by some speed, and adding that:

dbl_idx = SPEED * delta; // you can choose any value you like for speed
Andrew Williamson
  • 8,299
  • 3
  • 34
  • 62
  • The reason why it doesn't move at the same speed all over the path is because it iterates over the points taken from the Path2D with a PathIterator, and in some segments there are more points than in others, so it slows down when iterating them. The post linked talked about creating a vector and moving by that distance instead of jumping to the next point, so it wouldn't care about how many points there are in the segment. – Antú Villegas Jun 11 '17 at 20:58
  • Ah, I see. The time delta is still something that should be fixed, but that is not the main problem. – Andrew Williamson Jun 11 '17 at 21:28
0

Today teachers gave us 2 new libraries that explained how to make a Bezier curve with 4 points (irrelevant), but in that example, while making a List to store the points that makes the curve, was introduced this:

while (!pi.isDone() && Point2D.distance(puntos[0],puntos[1],cursor[0],cursor[1]) < 10){
    pi.next();
    if (!pi.isDone())
        pi.currentSegment(puntos);
    }
}

This part (Point2D.distance(puntos[0],puntos[1],cursor[0],cursor[1]) < 10) uses the method distance of Point2D to skip points if they were relatively close, 10px in this example.

Antú Villegas
  • 51
  • 1
  • 10