basic implementation of sbv2
This commit is contained in:
parent
fc32040b2f
commit
1803d714a5
|
@ -72,6 +72,7 @@ import org.newdawn.slick.state.transition.EmptyTransition;
|
|||
import org.newdawn.slick.state.transition.FadeInTransition;
|
||||
import yugecin.opsudance.*;
|
||||
import yugecin.opsudance.objects.curves.FakeCombinedCurve;
|
||||
import yugecin.opsudance.sbv2.MoveStoryboard;
|
||||
import yugecin.opsudance.ui.SBOverlay;
|
||||
|
||||
/**
|
||||
|
@ -313,6 +314,7 @@ public class Game extends BasicGameState {
|
|||
private final int state;
|
||||
|
||||
private final Cursor mirrorCursor;
|
||||
private MoveStoryboard msb;
|
||||
private SBOverlay sbOverlay;
|
||||
|
||||
private FakeCombinedCurve knorkesliders;
|
||||
|
@ -363,7 +365,8 @@ public class Game extends BasicGameState {
|
|||
@Override
|
||||
public void init(GameContainer container, StateBasedGame game)
|
||||
throws SlickException {
|
||||
this.sbOverlay = new SBOverlay(this, container);
|
||||
this.msb = new MoveStoryboard(container);
|
||||
this.sbOverlay = new SBOverlay(this, msb, container);
|
||||
this.container = container;
|
||||
this.game = game;
|
||||
input = container.getInput();
|
||||
|
@ -470,6 +473,12 @@ public class Game extends BasicGameState {
|
|||
}
|
||||
}
|
||||
|
||||
float[] sbPosition = sbOverlay.getPoint(trackPosition);
|
||||
if (sbPosition != null) {
|
||||
autoPoint.x = sbPosition[0];
|
||||
autoPoint.y = sbPosition[1];
|
||||
}
|
||||
|
||||
// set mouse coordinates
|
||||
autoMousePosition.set(autoPoint.x, autoPoint.y);
|
||||
}
|
||||
|
|
33
src/yugecin/opsudance/sbv2/StoryboardMove.java
Normal file
33
src/yugecin/opsudance/sbv2/StoryboardMove.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2016 yugecin
|
||||
*
|
||||
* opsu!dance is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu!dance is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.sbv2;
|
||||
|
||||
import org.newdawn.slick.Graphics;
|
||||
import yugecin.opsudance.sbv2.movers.StoryboardMover;
|
||||
|
||||
public interface StoryboardMove {
|
||||
|
||||
void add(StoryboardMover mover);
|
||||
float[] getPointAt(float t);
|
||||
void update(int delta, int x, int y);
|
||||
void mousePressed(int x, int y);
|
||||
void mouseReleased(int x, int y);
|
||||
void recalculateTimes();
|
||||
void render(Graphics g);
|
||||
|
||||
}
|
146
src/yugecin/opsudance/sbv2/StoryboardMoveImpl.java
Normal file
146
src/yugecin/opsudance/sbv2/StoryboardMoveImpl.java
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2016 yugecin
|
||||
*
|
||||
* opsu!dance is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu!dance is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.sbv2;
|
||||
|
||||
import itdelatrisu.opsu.objects.curves.Vec2f;
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.Graphics;
|
||||
import yugecin.opsudance.sbv2.movers.StoryboardMover;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StoryboardMoveImpl implements StoryboardMove {
|
||||
|
||||
private static final int POINTSIZE = 3;
|
||||
|
||||
private Vec2f start;
|
||||
private Vec2f end;
|
||||
private List<StoryboardMover> movers;
|
||||
private List<Vec2f> midPoints;
|
||||
|
||||
private StoryboardMover nextMover;
|
||||
private Vec2f currentPoint;
|
||||
private StoryboardMover prevMover;
|
||||
|
||||
private float totalLength;
|
||||
|
||||
public StoryboardMoveImpl(Vec2f start, Vec2f end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
movers = new ArrayList<>();
|
||||
midPoints = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(StoryboardMover mover) {
|
||||
mover.end = end;
|
||||
if (movers.size() == 0) {
|
||||
mover.start = start;
|
||||
} else {
|
||||
StoryboardMover lastMover = movers.get(movers.size() - 1);
|
||||
Vec2f mid = new Vec2f(
|
||||
(lastMover.start.x + lastMover.end.x) / 2f,
|
||||
(lastMover.start.y + lastMover.end.y) / 2f
|
||||
);
|
||||
midPoints.add(mid);
|
||||
lastMover.end = mid;
|
||||
totalLength -= lastMover.getLength();
|
||||
lastMover.recalculateLength();
|
||||
totalLength += lastMover.getLength();
|
||||
mover.start = mid;
|
||||
}
|
||||
movers.add(mover);
|
||||
recalculateTimes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getPointAt(float t) {
|
||||
if (movers.size() == 0) {
|
||||
return new float[] { end.x, end.y };
|
||||
}
|
||||
float cumulativeTime = 0f;
|
||||
for (StoryboardMover mover : movers) {
|
||||
cumulativeTime += mover.timeLengthPercentOfTotalTime;
|
||||
if (cumulativeTime > t) {
|
||||
return mover.getPointAt((t - (cumulativeTime - mover.timeLengthPercentOfTotalTime)) / mover.timeLengthPercentOfTotalTime);
|
||||
}
|
||||
}
|
||||
return new float[] { end.x, end.y };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int delta, int x, int y) {
|
||||
if (currentPoint != null) {
|
||||
moveCurrentPoint(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(int x, int y) {
|
||||
int i = 0;
|
||||
for (Vec2f point : midPoints) {
|
||||
if (point.x - POINTSIZE <= x && x <= point.x + POINTSIZE && point.y - POINTSIZE <= y && y <= point.y + POINTSIZE) {
|
||||
currentPoint = point;
|
||||
prevMover = movers.get(i);
|
||||
nextMover = movers.get(i + 1);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int x, int y) {
|
||||
if (currentPoint != null) {
|
||||
moveCurrentPoint(x, y);
|
||||
totalLength -= prevMover.getLength() + nextMover.getLength();
|
||||
prevMover.recalculateLength();
|
||||
nextMover.recalculateLength();
|
||||
totalLength += prevMover.getLength() + nextMover.getLength();
|
||||
currentPoint = null;
|
||||
recalculateTimes();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculateTimes() {
|
||||
for (StoryboardMover mover : movers) {
|
||||
mover.timeLengthPercentOfTotalTime = mover.getLength() / totalLength;
|
||||
}
|
||||
}
|
||||
|
||||
private void moveCurrentPoint(int x, int y) {
|
||||
currentPoint.x = x;
|
||||
currentPoint.y = y;
|
||||
prevMover.end = currentPoint;
|
||||
nextMover.start = currentPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics g) {
|
||||
for (StoryboardMover mover : movers) {
|
||||
mover.render(g);
|
||||
}
|
||||
g.setColor(Color.cyan);
|
||||
for (Vec2f point : midPoints) {
|
||||
g.fillRect(point.x - POINTSIZE, point.y - POINTSIZE, POINTSIZE * 2 + 1, POINTSIZE * 2 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
47
src/yugecin/opsudance/sbv2/movers/LinearStoryboardMover.java
Normal file
47
src/yugecin/opsudance/sbv2/movers/LinearStoryboardMover.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2016 yugecin
|
||||
*
|
||||
* opsu!dance is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu!dance is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.sbv2.movers;
|
||||
|
||||
import itdelatrisu.opsu.Utils;
|
||||
import org.newdawn.slick.Color;
|
||||
|
||||
public class LinearStoryboardMover extends StoryboardMover {
|
||||
|
||||
public LinearStoryboardMover() {
|
||||
super(Color.red);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getPointAt(float t) {
|
||||
return new float[] {
|
||||
Utils.lerp(start.x, end.x, t),
|
||||
Utils.lerp(start.y, end.y, t),
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculateLength() {
|
||||
length = Utils.distance(start.x, start.y, end.x, end.y);
|
||||
}
|
||||
|
||||
}
|
53
src/yugecin/opsudance/sbv2/movers/StoryboardMover.java
Normal file
53
src/yugecin/opsudance/sbv2/movers/StoryboardMover.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2016 yugecin
|
||||
*
|
||||
* opsu!dance is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu!dance is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.sbv2.movers;
|
||||
|
||||
import itdelatrisu.opsu.objects.curves.Vec2f;
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.Graphics;
|
||||
|
||||
public abstract class StoryboardMover {
|
||||
|
||||
public static final float CALC_DRAW_INTERVAL = 0.05f;
|
||||
|
||||
protected float length;
|
||||
public Vec2f start;
|
||||
public Vec2f end;
|
||||
private Color renderColor;
|
||||
public float timeLengthPercentOfTotalTime;
|
||||
|
||||
public StoryboardMover(Color renderColor) {
|
||||
this.renderColor = renderColor;
|
||||
}
|
||||
|
||||
public abstract float[] getPointAt(float t);
|
||||
public abstract void recalculateLength();
|
||||
|
||||
public float getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
g.setColor(renderColor);
|
||||
for (float t = 0; t <= 1f; t += StoryboardMover.CALC_DRAW_INTERVAL) {
|
||||
float[] p = getPointAt(t);
|
||||
g.fillRect(p[0] - 1, p[1] - 1, 3, 3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@ import org.newdawn.slick.GameContainer;
|
|||
import org.newdawn.slick.Graphics;
|
||||
import org.newdawn.slick.Input;
|
||||
import yugecin.opsudance.ObjectColorOverrides;
|
||||
import yugecin.opsudance.sbv2.MoveStoryboard;
|
||||
import yugecin.opsudance.ui.OptionsOverlay.OptionTab;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -109,6 +110,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
private int index;
|
||||
|
||||
private final Game game;
|
||||
private final MoveStoryboard msb;
|
||||
private final OptionsOverlay overlay;
|
||||
|
||||
static {
|
||||
|
@ -117,8 +119,9 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
}
|
||||
}
|
||||
|
||||
public SBOverlay(Game game, GameContainer container) {
|
||||
public SBOverlay(Game game, MoveStoryboard msb, GameContainer container) {
|
||||
this.game = game;
|
||||
this.msb = msb;
|
||||
initialOptions = new HashMap<>();
|
||||
overlay = new OptionsOverlay(this, options, 2, container);
|
||||
this.width = container.getWidth();
|
||||
|
@ -131,6 +134,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
if (!Options.isEnableSB() || hide) {
|
||||
return;
|
||||
}
|
||||
msb.render(g);
|
||||
int lh = Fonts.SMALL.getLineHeight();
|
||||
Fonts.SMALL.drawString(10, height - 50 + lh, "save position: ctrl+s, load position: ctrl+l", Color.cyan);
|
||||
Fonts.SMALL.drawString(10, height - 50, "speed: C " + (speed / 10f) + " V", Color.cyan);
|
||||
|
@ -163,6 +167,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
if (Options.isEnableSB() && menu) {
|
||||
overlay.update(delta, mouseX, mouseY);
|
||||
}
|
||||
msb.update(delta, mouseX, mouseY);
|
||||
}
|
||||
|
||||
public boolean keyPressed(int key, char c) {
|
||||
|
@ -234,6 +239,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
public void setGameObjects(GameObject[] gameObjects) {
|
||||
if (this.gameObjects.length != gameObjects.length) {
|
||||
optionsMap = new HashMap[gameObjects.length];
|
||||
msb.setGameObjects(gameObjects);
|
||||
}
|
||||
if (optionsMap.length > 0) {
|
||||
// copy all current settings in first obj map
|
||||
|
@ -246,6 +252,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
}
|
||||
|
||||
public boolean mousePressed(int button, int x, int y) {
|
||||
msb.mousePressed(x, y);
|
||||
if (!menu) {
|
||||
return false;
|
||||
}
|
||||
|
@ -270,6 +277,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
if (index >= optionsMap.length) {
|
||||
return;
|
||||
}
|
||||
msb.setIndex(index);
|
||||
for (; this.index <= index; this.index++) {
|
||||
HashMap options = optionsMap[this.index];
|
||||
if (options == null) {
|
||||
|
@ -289,6 +297,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
overlay.mouseReleased(button, x, y);
|
||||
return true;
|
||||
}
|
||||
msb.mouseReleased(x, y);
|
||||
if (x > 10 || index >= optionsMap.length || optionsMap[index] == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -348,6 +357,10 @@ public class SBOverlay implements OptionsOverlay.Parent {
|
|||
}
|
||||
}
|
||||
|
||||
public float[] getPoint(int trackPosition) {
|
||||
return msb.getPoint(trackPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeave() {
|
||||
menu = false;
|
||||
|
|
72
src/yugecin/opsudance/ui/SimpleButton.java
Normal file
72
src/yugecin/opsudance/ui/SimpleButton.java
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* opsu!dance - fork of opsu! with cursordance auto
|
||||
* Copyright (C) 2016 yugecin
|
||||
*
|
||||
* opsu!dance is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu!dance is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package yugecin.opsudance.ui;
|
||||
|
||||
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.Font;
|
||||
import org.newdawn.slick.Graphics;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
public class SimpleButton {
|
||||
|
||||
private final Color bg;
|
||||
private final Color fg;
|
||||
private final Color border;
|
||||
private final Color hoverBorder;
|
||||
private final Font font;
|
||||
private String text;
|
||||
private int textY;
|
||||
private Rectangle hitbox;
|
||||
private boolean isHovered;
|
||||
|
||||
public SimpleButton(int x, int y, int width, int height, Font font, String text, Color bg, Color fg, Color border, Color hoverBorder) {
|
||||
this.bg = bg;
|
||||
this.fg = fg;
|
||||
this.border = border;
|
||||
this.hoverBorder = hoverBorder;
|
||||
this.hitbox = new Rectangle(x, y, width, height);
|
||||
this.font = font;
|
||||
this.text = text;
|
||||
this.textY = y + (height - font.getLineHeight()) / 2;
|
||||
}
|
||||
|
||||
public void render(Graphics g) {
|
||||
g.setLineWidth(2f);
|
||||
g.setColor(bg);
|
||||
g.fillRect(hitbox.x, hitbox.y, hitbox.width, hitbox.height);
|
||||
g.setColor(fg);
|
||||
font.drawString(hitbox.x + 20, textY, text);
|
||||
if (isHovered) {
|
||||
g.setColor(hoverBorder);
|
||||
} else {
|
||||
g.setColor(border);
|
||||
}
|
||||
g.drawRect(hitbox.x, hitbox.y, hitbox.width, hitbox.height);
|
||||
}
|
||||
|
||||
public void update(int x, int y) {
|
||||
isHovered = hitbox.contains(x, y);
|
||||
}
|
||||
|
||||
public boolean isHovered() {
|
||||
return isHovered;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user