Resource Rollercoaster System. (Part 1)

Discussion in 'Spigot Plugin Development' started by Mickerd, Oct 23, 2017.

  1. Hi.

    I make this tutorial because lately many people are searching for an attraction system for several coasters or attractions.

    This is just part 1.
    Part 2 will be released later.

    What is a ride system?

    It is similar to the following video, pay particular attention to the roller coaster!



    I am currently (yet) busy with recreating such a system open source. If this is finished, there will be a link to the GitHub repo in this topic.

    But how do you make such a ride system?

    I like to start working in the modeling program Blender. In this I create a cyclic bezier curve. After making the Bezier curve I give this a constant speed with loop tools. If this is done I subdivide the bezier 2 a 5 times, it just lies to how many points I want. I export this beziercurve with a certain script.

    Python Script
    Note: You must turn your curve object 90 degrees on X-axis and your bezier-type must be POLY and your textfile must exist!

    Code (Text):
    import bpy

    obj = bpy.context.active_object
    matrix = obj.matrix_world

    file = open("C:/example.txt","w")
    if obj.type == 'CURVE':
       for subcurve in obj.data.splines:
          curvetype = subcurve.type
          print('curve type:', curvetype)
          if curvetype == 'POLY':
                for bezpoint in subcurve.bezier_points:
                   loc = matrix * bezpoint.co
                   x = loc.x
                   y = loc.y
                   z = loc.z
                   file.write("v " + str(x) + " " + str(y) + " " + str(z) + " " + str(tilt) + "\n")
    file.close()
     
    Run this script with the curve selected!

    In Java you load the textfile with:
    Code (Text):
    ArrayList<TrackPoint> track = new ArrayList<TrackPoint>();

    public static void loadBezier(){
       // Load file line by line async
       for(String s : lines){
          String replaced = s.replace("v ","");
          String[] splitted = s.split(" ");
          Double x = Double.valueOf(splitted[0]);
          Double y= Double.valueOf(splitted[1]);
          Double z = Double.valueOf(splitted[2]);
          Double tilt = Double.valueOf(splitted[3]);
          // add this values to a sort of TrackPoint class
          TrackPoint t = new TrackPoint(x,y,z,tilt);
          track.add(t);
       }
    }
    This was part 1.
    Part 2 will be hopefully released tomorrow.

    Have a good day! =}
     
    #1 Mickerd, Oct 23, 2017
    Last edited: Oct 25, 2017
    • Winner Winner x 3
    • Like Like x 2
    • Creative Creative x 2
  2. Woah Thats actually cool, I used splines and bexcurve to do smthn like this last year but anyway a really great thread
     
    • Friendly Friendly x 1
  3. I’m amazed. Nothing else to say but amazed. This is one of the coolest resource threads I’ve ever seen.
     
    • Friendly Friendly x 1
  4. Translation: why the hell are you doing this, you're ruining the whole community with this. Now every carnival server will have this, and nothing will be unique. Thanks for ruining the community, keep up the good work.

    No kid, this isn't ruining the community, open source enriches it.
     
    • Agree Agree x 6
    • Winner Winner x 2
  5. Daum, i always thought this sort of stuff was binded to modding, but now im jumping up and down knowing this is codeable in plugins.
     
    • Friendly Friendly x 1
  6. Looking cool! I look forward to the next parts of this guide!

    Ps: I spotted a small error in the java code, the
    Code (Text):
    String splitted
    should be a
    Code (Text):
    String[] splitted
    :)
     
  7. Haha thanks! I will edit it ;)
     
  8. I totally agree with this! :) opensource to the max!
     
    • Winner Winner x 2
  9. thanks for taking the time to make this. looks cool to me! here's some issues I have, however, with the code.
    for Part 1:
    Code (Text):
    ArrayList<TrackPoint> track = new ArrayList<TrackPoint>();
    you don't need to specify the type for your implementation side. the compiler can infer from it.

    Code (Text):
    public static void loadBezier()
    this needs to be bound by instance, not by class. by the single responsibility principle, this method should be included in a singleton Manager/Factory class which manages the loading and unloading of your files.

    Code (Text):
    String[] splitted
    the correct spelling should be "split".

    for Part 2:
    Code (Text):
    public class TrackPoint()
    extra brackets

    Code (Text):
     public double getTilt(){
            return this.tilt;
        }
     
        public double getX(){
            return this.x;
        }
     
        public double getY(){
            return this.y;
        }
     
        public double getZ(){
            return this.z;
        }
     
        public Location toLocation(){
            return new Location(Main.world,this.x,this.y,this.z);
        }
    no need for getters for the x, y and z values. what you should do is just assign a Location object. for example:
    Code (Text):
    private Location location;

    public TrackPoint(double x, double y, double z) {
      this.location = new Location(x, y, z);
    }

    public Location getLocation() {
      return location;
    }
    this is more convenient than having getters for the x, y and z values. if the user needs the specific values, they can use Location#getX, Location#getY and so on.

    Code (Text):
    Main.world
    you seem to use this to access the world object more than once, and suggests that you are storing the World variable as a class variable in your Main class. the method should not be static, and a getter should be used to retrieve the object. you're violating the OOP principle here.

    Code (Text):
    } else {
                    cancel();
                    as.remove();
    you should be opting to do a "fail-fast"-like check here, i.e.
    Code (Text):
    if (x >= y) {
      cancel();
    } else {
      ....
    }
    you always want to check for all your conditions to be met(fail the method if it is not) first, before actually running the method.
    Code (Text):
    Location fromclone = from.clone();
        Location toclone = to.clone();
    variable names should be lowerCamelCase
     
    • Agree Agree x 2
  10. In addition:
    program to an interface, not an implementation, and favor object composition over class inheritance.

    Don’t use
    ArrayList.... = ....ArrayList...
    Use
    List.... = ....ArrayList...