attempt to keep track of scoring for each player

This commit is contained in:
yugecin 2017-12-21 22:43:42 +01:00
parent 5704ebb0c1
commit 35769b31c7
9 changed files with 167 additions and 6 deletions

View File

@ -4,6 +4,7 @@ package awlex.ospu;
* Created by Awlex on 10.10.2016.
*/
import itdelatrisu.opsu.GameData;
import itdelatrisu.opsu.objects.GameObject;
import itdelatrisu.opsu.objects.curves.Vec2f;
import org.newdawn.slick.Color;
@ -35,6 +36,15 @@ public class FakeGameObject extends GameObject {
this.start.y = this.end.y = (start.end.y + end.start.y) / 2;
}
@Override
public GameObject clone(GameData a) {
FakeGameObject o = new FakeGameObject();
o.halfTime = this.halfTime;
o.start = this.start;
o.end = this.end;
return o;
}
@Override
public void draw(Graphics g, int trackPosition, boolean mirrored) {

View File

@ -170,7 +170,7 @@ public class GameData {
HIT_ANIMATION_RESULT = 12; // not a hit result
/** Hit result-related images (indexed by HIT_* constants to HIT_MAX). */
private Image[] hitResults;
protected Image[] hitResults;
/** Counts of each hit result so far (indexed by HIT_* constants to HIT_MAX). */
private int[] hitResultCount;
@ -1409,7 +1409,7 @@ public class GameData {
* @param noIncrementCombo if the combo should not be incremented by this result
* @return the actual hit result (HIT_* constants)
*/
private int handleHitResult(int time, int result, float x, float y, Color color, boolean end,
protected int handleHitResult(int time, int result, float x, float y, Color color, boolean end,
HitObject hitObject, HitObjectType hitResultType, int repeat, boolean noIncrementCombo) {
// update health, score, and combo streak based on hit result
int hitValue = 0;

View File

@ -83,6 +83,11 @@ public class Circle extends GameObject {
super.updateStartEndPositions(time);
}
@Override
public GameObject clone(GameData data) {
return new Circle(hitObject, game, data, comboColorIndex, comboEnd);
}
@Override
public void draw(Graphics g, int trackPosition, boolean mirror) {
Color orig = color;

View File

@ -18,6 +18,7 @@
package itdelatrisu.opsu.objects;
import itdelatrisu.opsu.GameData;
import itdelatrisu.opsu.beatmap.HitObject;
import itdelatrisu.opsu.objects.curves.Vec2f;
@ -29,7 +30,7 @@ import org.newdawn.slick.Graphics;
*/
public class DummyObject extends GameObject {
/** The associated HitObject. */
private HitObject hitObject;
public final HitObject hitObject;
/** The scaled starting x, y coordinates. */
private float x, y;
@ -49,6 +50,11 @@ public class DummyObject extends GameObject {
updateStartEndPositions(0);
}
@Override
public GameObject clone(GameData a) {
return new DummyObject(this.hitObject);
}
@Override
public void draw(Graphics g, int trackPosition, boolean mirror) {}

View File

@ -18,6 +18,7 @@
package itdelatrisu.opsu.objects;
import itdelatrisu.opsu.GameData;
import itdelatrisu.opsu.objects.curves.Vec2f;
import org.newdawn.slick.Color;
@ -114,4 +115,6 @@ public abstract class GameObject {
return hue;
}
public abstract GameObject clone(GameData data);
}

View File

@ -189,6 +189,11 @@ public class Slider extends GameObject {
repeats = hitObject.getRepeatCount();
}
@Override
public GameObject clone(GameData data) {
return new Slider(hitObject, game, data, comboColorIndex, comboEnd);
}
@Override
public void draw(Graphics g, int trackPosition, boolean mirror) {
if (trackPosition > getEndTime()) {

View File

@ -173,6 +173,11 @@ public class Spinner extends GameObject {
rotationsNeeded = spinsPerMinute * (hitObject.getEndTime() - hitObject.getTime()) / 60000f;
}
@Override
public GameObject clone(GameData data) {
return new Spinner(hitObject, game, data);
}
@Override
public void draw(Graphics g, int trackPosition, boolean mirror) {
if (mirror) {

View File

@ -726,7 +726,7 @@ public class Game extends ComplexOpsuState {
g.setColor(Color.black);
g.fillRect(ReplayPlayback.SQSIZE * 2, 0, ReplayPlayback.SQSIZE * 2, displayContainer.height);
for (ReplayPlayback replayPlayback : replays) {
replayPlayback.render(displayContainer.renderDelta, g, i++, trackPosition);
replayPlayback.render(beatmap, hitResultOffset, displayContainer.renderDelta, g, i++, trackPosition);
}
super.render(g);
@ -1718,6 +1718,14 @@ public class Game extends ComplexOpsuState {
}
}
for (ReplayPlayback replayPlayback : replays) {
GameObject[] objs = new GameObject[gameObjects.length];
for (int i = 0; i < objs.length; i++) {
objs[i] = gameObjects[i].clone(replayPlayback.new GData());
}
replayPlayback.setGameObjects(objs);
}
Dancer.instance.setGameObjects(gameObjects);
storyboardOverlay.setGameObjects(gameObjects);
if (!skippedToCheckpoint) {

View File

@ -17,12 +17,18 @@
*/
package yugecin.opsudance;
import itdelatrisu.opsu.GameData;
import itdelatrisu.opsu.beatmap.Beatmap;
import itdelatrisu.opsu.beatmap.HitObject;
import itdelatrisu.opsu.objects.GameObject;
import itdelatrisu.opsu.objects.curves.Curve;
import itdelatrisu.opsu.replay.Replay;
import itdelatrisu.opsu.replay.ReplayFrame;
import itdelatrisu.opsu.ui.Cursor;
import itdelatrisu.opsu.ui.Fonts;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import yugecin.opsudance.core.DisplayContainer;
public class ReplayPlayback {
@ -39,6 +45,12 @@ public class ReplayPlayback {
private boolean hr;
private String player;
private GameObject[] gameObjects;
private int objectIndex = 0;
private int lastkeys = 0;
private Image hitImage;
private int hitImageTimer = 0;
public ReplayPlayback(DisplayContainer container, Replay replay, Color color) {
this.container = container;
this.replay = replay;
@ -89,16 +101,61 @@ public class ReplayPlayback {
this.player = replay.playerName + this.player;
}
public void setGameObjects(GameObject[] gameObjects) {
this.gameObjects = gameObjects;
}
public void resetFrameIndex() {
frameIndex = 0;
currentFrame = replay.frames[frameIndex++];
nextFrame = replay.frames[frameIndex];
}
public void render(int renderdelta, Graphics g, int ypos, int time) {
private void sendKeys(Beatmap beatmap, int trackPosition) {
if (objectIndex >= gameObjects.length) // nothing to do here
return;
int deltakeys = (currentFrame.getKeys() & ~this.lastkeys);
if (deltakeys == ReplayFrame.KEY_NONE) {
return;
}
this.lastkeys = currentFrame.getKeys();
HitObject hitObject = beatmap.objects[objectIndex];
// circles
if (hitObject.isCircle() && gameObjects[objectIndex].mousePressed(currentFrame.getScaledX(), currentFrame.getScaledY(), trackPosition))
objectIndex++; // circle hit
// sliders
else if (hitObject.isSlider())
gameObjects[objectIndex].mousePressed(currentFrame.getScaledX(), currentFrame.getScaledY(), trackPosition);
}
private void update(int trackPosition, Beatmap beatmap, int[] hitResultOffset, int delta) {
boolean keyPressed = currentFrame.getKeys() != ReplayFrame.KEY_NONE;
while (objectIndex < gameObjects.length && trackPosition > beatmap.objects[objectIndex].getTime()) {
// check if we've already passed the next object's start time
boolean overlap = (objectIndex + 1 < gameObjects.length &&
trackPosition > beatmap.objects[objectIndex + 1].getTime() - hitResultOffset[GameData.HIT_50]);
// update hit object and check completion status
if (gameObjects[objectIndex].update(overlap, delta, currentFrame.getScaledX(), currentFrame.getScaledY(), keyPressed, trackPosition)) {
objectIndex++; // done, so increment object index
} else
break;
}
}
public void render(Beatmap beatmap, int[] hitResultOffset, int renderdelta, Graphics g, int ypos, int time) {
if (objectIndex >= gameObjects.length) {
return;
}
while (nextFrame != null && nextFrame.getTime() < time) {
currentFrame = nextFrame;
processKeys();
sendKeys(beatmap, time);
frameIndex++;
if (frameIndex >= replay.frames.length) {
nextFrame = null;
@ -107,6 +164,8 @@ public class ReplayPlayback {
nextFrame = replay.frames[frameIndex];
}
processKeys();
sendKeys(beatmap, time);
update(time, beatmap, hitResultOffset, renderdelta);
g.setColor(color);
ypos *= (SQSIZE + 5);
for (int i = 0; i < 4; i++) {
@ -115,7 +174,11 @@ public class ReplayPlayback {
}
keydelay[i] -= renderdelta;
}
Fonts.SMALLBOLD.drawString(SQSIZE * 5, ypos, this.player, color);
Fonts.SMALLBOLD.drawString(SQSIZE * 5, ypos, this.player + " " + this.objectIndex, color);
int namewidth = Fonts.SMALLBOLD.getWidth(this.player);
if (hitImage != null) {
hitImage.draw(SQSIZE * 5 + namewidth + SQSIZE * 2, ypos + SQSIZE / 2);
}
int y = currentFrame.getScaledY();
if (hr) {
y = container.height - y;
@ -141,4 +204,60 @@ public class ReplayPlayback {
}
}
private GData _data;
public class GData extends GameData {
public GData() {
super();
this.loadImages();
_data = this;
}
@Override
public void sendSliderRepeatResult(int time, float x, float y, Color color, Curve curve, HitObjectType type) {
// ?
}
@Override
public void sendSliderStartResult(int time, float x, float y, Color color, Color mirrorColor, boolean expand) {
// ?
}
@Override
public void sendSliderTickResult(int time, int result, float x, float y, HitObject hitObject, int repeat) {
if (result == HIT_MISS) {
}
}
@Override
public void sendHitResult(int time, int result, float x, float y, Color color, boolean end, HitObject hitObject, HitObjectType hitResultType, boolean expand, int repeat, Curve curve, boolean sliderHeldToEnd) {
sendHitResult(time, result, x, y, color, end, hitObject, hitResultType, expand, repeat, curve, sliderHeldToEnd, true);
}
@Override
public void sendHitResult(int time, int result, float x, float y, Color color, boolean end, HitObject hitObject, HitObjectType hitResultType, boolean expand, int repeat, Curve curve, boolean sliderHeldToEnd, boolean handleResult) {
int hitResult = HIT_300;
if (handleResult) {
hitResult = handleHitResult(time, result, x, y, color, end, hitObject,
hitResultType, repeat, (curve != null && !sliderHeldToEnd));
}
if ((hitResult == HIT_300 || hitResult == HIT_300G || hitResult == HIT_300K)) {
return;
}
if (hitResult < hitResults.length) {
hitImageTimer = 0;
hitImage = hitResults[hitResult].getScaledCopy(SQSIZE, SQSIZE);
}
}
@Override
public void addHitError(int time, int x, int y, int timeDiff) {
//?
}
}
}