Code Monkey home page Code Monkey logo

spigot-maps's Introduction

Spigot-Maps

A small library that makes the use of customised maps in Spigot very easy.

Features

  • Dynamic map rendering (based on render context)
  • (Animated) Text, image and animated gif rendering with convenient usage
  • Base class for own renderer implementations
  • API to store renderers persistently
  • Tools to resize / crop / divide images so that they fit the minecraft maps
  • Convenient builder classes and factory methods

YOU CAN FIND AN EXAMPLE PLUGIN HERE

To test this plugin, do

git clone https://github.com/johnnyjayjay/spigot-maps.git
cd spigot-maps/example-plugin
./gradlew shadowJar 

Then add example-plugin-1.0-TEST.jar (found in build/libs) to your plugins folder

Add as dependency

Maven

<repositories>
    <repository>
        <id>jcenter</id>
        <url>https://jcenter.bintray.com/</url>
    </repository>
 </repositories>

<dependencies>
    <dependency>
        <groupId>com.github.johnnyjayjay</groupId>
        <artifactId>spigot-maps</artifactId>
        <version>2.1.1</version>
    </dependency>
</dependencies>

Gradle

repositories {
    jcenter()
}

dependencies {
    implementation("com.github.johnnyjayjay:spigot-maps:2.1.1")
}

I don't use a build tool

An already built .jar file can be found here. Download it and add it to your project like any other jar file (Eclipse -> Build Path, IntelliJ -> Add as Library).

Quick Start

You've got various options when creating renderers and maps:

BufferedImage catImage = ImageIO.read(file); // read an image from a source, e.g. a file
catImage = ImageTools.resizeToMapSize(catImage); // resize the image to the minecraft map size
ImageRenderer catRenderer = ImageRenderer.builder()
        .addPlayers(player1, player2) // set the players this map should be rendered to (omitting this means it renders for everyone)
        .image(catImage) // set the image to render
        .build(); // build the instance

Dimension mapSize = ImageTools.MINECRAFT_MAP_SIZE; // the dimensions of a Minecraft map (in pixels)
SimpleTextRenderer messageRenderer = SimpleTextRenderer.builder()
        .addLines("Cats", "are", "so", "cute") // set the lines that will be drawn onto the map
        .addPlayers(player1, player2)
        .font(myFont) // set a text font
        .startingPoint(new Point(mapSize.width / 2, mapSize.height / 2)) // start in the middle
        .build(); // build the instance 

RenderedMap map = MapBuilder.create() // make a new builder
        .store(myStorage) // set a MapStorage for the map
        .addRenderers(catRenderer, messageRenderer) // add the renderers to this map
        .world(player1.getWorld()) // set the world this map is bound to, e.g. the world of the target player
        .build(); // build the map

ItemStack mapItem = map.createItemStack(); // get an ItemStack from this map to work with

This example would result in a map that has an image of a cat in the background and the text "Cats are so cute" in the foreground.

You can still mutate the renderers afterwards:

messageRenderer.setText("Cats\nare\nstill\ncute");

Note that this will only have effect if renderOnce is set to false while building. The reason for that decision is performance. Only rendering once saves resources, but disables later modification. If you want to mutate a renderer after building but then leave it that way, you may call

messageRenderer.stopRendering();

to save the resources.

Shortcuts

There are even quicker ways to accomplish some of these operations.

Create an ImageRenderer with just an image:

ImageRenderer renderer = ImageRenderer.create(image, player1, player2); // the player arguments are optional

Create an ImageRenderer that renders a single color (e.g. as a background for text):

ImageRenderer backgroundRenderer = ImageRenderer.createSingleColorRenderer(Color.BLUE, player1, player2) // the player arguments are optional

See ImageTools.createSingleColoredImage(Color) to get an instance of BufferedImage for that matter.

Create a TextRenderer with just some lines of text:

SimpleTextRenderer renderer = SimpleTextRenderer.create("This", "is", "noice");

Create a RenderedMap with just some MapRenderers:

RenderedMap map = RenderedMap.create(renderer1, renderer2); // not providing any renderers returns a map without renderers

Advanced

Gifs

This library can handle animated gifs using GifRenderer and GifImage. Instances of GifImage can be obtained via an instance of GifDecoder from this library's dependencies:

GifDecoder decoder = new GifDecoder();
decoder.read("./example.gif"); // this also works with URLs, InputStreams etc.
GifImage gif = GifImage.fromDecoder(decoder);

For more info about GifDecoder, look at this.

You can also implement an algorithm to decode gifs yourself and then make use of GifImage#create(List<Frame>).

GifRenderers are created like any other renderer:

GifRenderer renderer = GifRenderer.builder()
        .gif(gif) // set the GifImage we just created
        .repeat(5) // repeat the gif 5 times: to repeat it indefinitely, omit this setting or set it to GifRenderer.REPEAT_FOREVER
        .build();

This renderer stops rendering automatically after 5 repetitions and can now be added to a MapView / RenderedMap as shown above.

Animated Text

Text doesn't have to be static. This library provides a map renderer that renders text character by character.

AnimatedTextRenderer renderer = AnimatedTextRenderer.builder()
        .addText("This text will appear char by char.")
        .charsPerSecond(10) // 10 characters should appear each second
        .delay(20) // start the animation after 20 ticks (1 second)
        .build();

This renderer automatically stops rendering after having finished.

Splitting images

Images that take more than 1 map to display can be created using ImageTools.divideIntoMapSizedParts(BufferedImage, boolean). This uses an algorithm that makes a square version of the image first. How this is done can be determined via the second boolean parameter. If it is set to true, a square cropped out from the middle of the image will be used (if the image is big enough). If it is false, the whole image will be resized to 1:1.

List<BufferedImage> parts = ImageTools.divideIntoMapSizedParts(image, true);

The exact same methods are available to GifImages.

To turn these into map items:

for (BufferedImage part : parts) {
    ImageRenderer renderer = ImageRenderer.create(part);
    ItemStack mapItem = RenderedMap.create(renderer).createItemStack();
    // do something with it
}

Or, if you want to do it stream-like:

parts.stream()
        .map(ImageRenderer::create)
        .map(RenderedMap::create)
        .map(RenderedMap::createItemStack)
        .forEach((mapItem) -> {
    // do something with it
})

Using MapStorage

The MapStorage API makes it possible to save renderers persistently. To utilise it, you have to implement MapStorage:

public class FileStorage implements MapStorage {

    @Override
    public void store(int id, MapRenderer renderer) {
        // serialize the renderer associated with the given id
    }
    
    @Override
    public boolean remove(int id, MapRenderer renderer) {
        // remove the given renderer's association with the given id
    }
    
    @Override
    public List<MapRenderer> provide(int id) {
        // fetch / deserialize / read all renderers stored for the given id
    }
}

Then, do the following (e.g. on start up):

InitializationListener.register(new FileStorage(), plugin);

spigot-maps's People

Contributors

johnnyjayjay avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.