mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
end game and level select for hunt
This commit is contained in:
parent
a7d5472088
commit
a0990054ea
11 changed files with 122 additions and 22 deletions
|
|
@ -249,13 +249,15 @@ class CameraController extends Object {
|
|||
|
||||
if (this.finish) {
|
||||
// Move the target to the centre of the finish
|
||||
var padMat = @:privateAccess this.level.endPad.getAbsPos();
|
||||
var offset = padMat.up();
|
||||
var padPos = padMat.getPosition();
|
||||
var focusPos = padPos.add(offset);
|
||||
focusPos.scale(0.025);
|
||||
focusPos = focusPos.add(lastTargetPos.multiply(0.975));
|
||||
marblePosition = focusPos;
|
||||
if (@:privateAccess this.level.endPad != null) {
|
||||
var padMat = @:privateAccess this.level.endPad.getAbsPos();
|
||||
var offset = padMat.up();
|
||||
var padPos = padMat.getPosition();
|
||||
var focusPos = padPos.add(offset);
|
||||
focusPos.scale(0.025);
|
||||
focusPos = focusPos.add(lastTargetPos.multiply(0.975));
|
||||
marblePosition = focusPos;
|
||||
}
|
||||
}
|
||||
|
||||
var up = new Vector(0, 0, 1);
|
||||
|
|
|
|||
|
|
@ -1165,6 +1165,8 @@ class MarbleWorld extends Scheduler {
|
|||
} else if (this.timeState.currentAttemptTime + dt >= 3.5) {
|
||||
this.timeState.gameplayClock += ((this.timeState.currentAttemptTime + dt) - 3.5) * timeMultiplier;
|
||||
}
|
||||
if (this.timeState.gameplayClock < 0)
|
||||
this.gameMode.onTimeExpire();
|
||||
}
|
||||
this.timeState.currentAttemptTime += dt;
|
||||
} else {
|
||||
|
|
@ -1493,7 +1495,7 @@ class MarbleWorld extends Scheduler {
|
|||
} else {
|
||||
nextLevelCode();
|
||||
}
|
||||
}, mission, finishTime);
|
||||
}, mission, this.gameMode.getFinishScore(), this.gameMode.getScoreType());
|
||||
MarbleGame.canvas.pushDialog(egg);
|
||||
this.setCursorLock(false);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ class Radar {
|
|||
}
|
||||
}
|
||||
|
||||
public function blink() {
|
||||
time = 0;
|
||||
}
|
||||
|
||||
public function reset() {
|
||||
time = 0;
|
||||
g.clear();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import modes.GameMode.ScoreType;
|
||||
import h3d.Vector;
|
||||
import haxe.ds.Option;
|
||||
import gui.Canvas;
|
||||
|
|
@ -241,11 +242,13 @@ class Settings {
|
|||
save();
|
||||
}
|
||||
|
||||
public static function saveScore(mapPath:String, score:Score) {
|
||||
public static function saveScore(mapPath:String, score:Score, scoreType:ScoreType = Time) {
|
||||
if (highScores.exists(mapPath)) {
|
||||
var scoreList = highScores.get(mapPath);
|
||||
scoreList.push(score);
|
||||
scoreList.sort((a, b) -> a.time == b.time ? 0 : (a.time > b.time ? 1 : -1));
|
||||
if (scoreType == Score)
|
||||
scoreList.reverse();
|
||||
} else {
|
||||
highScores.set(mapPath, [score]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,6 +297,11 @@ class Util {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static function formatScore(score:Float) {
|
||||
var scoreInt = Std.int(Math.round(score));
|
||||
return '${scoreInt}';
|
||||
}
|
||||
|
||||
public static function formatTime(time:Float) {
|
||||
var et = time * 1000;
|
||||
var thousandth = Std.int(et % 10);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package gui;
|
||||
|
||||
import modes.GameMode.ScoreType;
|
||||
import mis.MisParser;
|
||||
import hxd.BitmapData;
|
||||
import h2d.Tile;
|
||||
|
|
@ -21,7 +22,8 @@ class EndGameGui extends GuiImage {
|
|||
|
||||
var scoreSubmitted:Bool = false;
|
||||
|
||||
public function new(continueFunc:GuiControl->Void, restartFunc:GuiControl->Void, nextLevelFunc:GuiControl->Void, mission:Mission, timeState:TimeState) {
|
||||
public function new(continueFunc:GuiControl->Void, restartFunc:GuiControl->Void, nextLevelFunc:GuiControl->Void, mission:Mission, score:Float,
|
||||
scoreType:ScoreType) {
|
||||
var res = ResourceLoader.getImage("data/ui/xbox/BG_fadeOutSoftEdge.png").resource.toTile();
|
||||
super(res);
|
||||
this.horizSizing = Width;
|
||||
|
|
@ -86,12 +88,15 @@ class EndGameGui extends GuiImage {
|
|||
return arial14;
|
||||
}
|
||||
|
||||
var beatPar = timeState.gameplayClock < mission.qualifyTime;
|
||||
var beatPar = score < mission.qualifyTime;
|
||||
|
||||
var egResultLeft = new GuiMLText(arial14, mlFontLoader);
|
||||
egResultLeft.position = new Vector(28, 26);
|
||||
egResultLeft.extent = new Vector(180, 100);
|
||||
egResultLeft.text.text = '<p align="right"><font color="${beatPar ? "#8DFF8D" : "0xFF7575"}">Time:</font><br/><font color="#88BCEE">Par Time:</font><br/><font color="#EBEBEB">Rating:</font><br/><font color="#EBEBEB">My Best Time:</font></p>';
|
||||
if (scoreType == Time)
|
||||
egResultLeft.text.text = '<p align="right"><font color="${beatPar ? "#8DFF8D" : "#FF7575"}">Time:</font><br/><font color="#88BCEE">Par Time:</font><br/><font color="#EBEBEB">Rating:</font><br/><font color="#EBEBEB">My Best Time:</font></p>';
|
||||
if (scoreType == Score)
|
||||
egResultLeft.text.text = '<p align="right"><font color="#8DFF8D">Score:</font><br/><font color="#EBEBEB">My Best Score:</font></p>';
|
||||
endGameWnd.addChild(egResultLeft);
|
||||
var c0 = 0xEBEBEB;
|
||||
var c1 = 0x8DFF8D;
|
||||
|
|
@ -111,15 +116,17 @@ class EndGameGui extends GuiImage {
|
|||
return (completionBonus + timeBonus) * difficulty;
|
||||
}
|
||||
|
||||
var rating = calcRating(timeState.gameplayClock * 1000, mission.qualifyTime * 1000, mission.goldTime * 1000,
|
||||
Std.parseInt(mission.missionInfo.difficulty));
|
||||
var rating = calcRating(score * 1000, mission.qualifyTime * 1000, mission.goldTime * 1000, Std.parseInt(mission.missionInfo.difficulty));
|
||||
|
||||
var myScore = {name: "Player", time: timeState.gameplayClock};
|
||||
Settings.saveScore(mission.path, myScore);
|
||||
var myScore = {name: "Player", time: score};
|
||||
Settings.saveScore(mission.path, myScore, scoreType);
|
||||
|
||||
var scoreData:Array<Score> = Settings.getScores(mission.path);
|
||||
while (scoreData.length < 1) {
|
||||
scoreData.push({name: "Nardo Polo", time: 5999.999});
|
||||
if (scoreType == Score)
|
||||
scoreData.push({name: "Nardo Polo", time: 0});
|
||||
if (scoreType == Time)
|
||||
scoreData.push({name: "Nardo Polo", time: 5999.999});
|
||||
}
|
||||
|
||||
var bestScore = scoreData[0];
|
||||
|
|
@ -128,7 +135,10 @@ class EndGameGui extends GuiImage {
|
|||
|
||||
egResultRight.position = new Vector(214, 26);
|
||||
egResultRight.extent = new Vector(180, 100);
|
||||
egResultRight.text.text = '<font color="${beatPar ? "#8DFF8D" : "0xFF7575"}">${Util.formatTime(timeState.gameplayClock)}</font><br/><font color="#88BCEE">${Util.formatTime(mission.qualifyTime)}</font><br/><font color="#EBEBEB">${rating}</font><br/><font color="#EBEBEB">${Util.formatTime(bestScore.time)}</font>';
|
||||
if (scoreType == Score)
|
||||
egResultRight.text.text = '<font color="#8DFF8D">${Util.formatScore(score)}</font><br/><font color="#EBEBEB">${Util.formatScore(bestScore.time)}</font>';
|
||||
if (scoreType == Time)
|
||||
egResultRight.text.text = '<font color="${beatPar ? "#8DFF8D" : "0xFF7575"}">${Util.formatTime(score)}</font><br/><font color="#88BCEE">${Util.formatTime(mission.qualifyTime)}</font><br/><font color="#EBEBEB">${rating}</font><br/><font color="#EBEBEB">${Util.formatTime(bestScore.time)}</font>';
|
||||
endGameWnd.addChild(egResultRight);
|
||||
|
||||
var bottomBar = new GuiControl();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package gui;
|
||||
|
||||
import modes.GameMode.ScoreType;
|
||||
import src.Util;
|
||||
import haxe.io.Path;
|
||||
import h2d.filter.DropShadow;
|
||||
|
|
@ -223,16 +224,29 @@ class LevelSelectGui extends GuiImage {
|
|||
loadText.text.visible = false;
|
||||
loadTextBg.text.visible = false;
|
||||
});
|
||||
|
||||
var scoreType = mis.missionInfo.gamemode != null
|
||||
&& mis.missionInfo.gamemode.toLowerCase() == 'scrum' ? ScoreType.Score : ScoreType.Time;
|
||||
|
||||
var myScore = Settings.getScores(mis.path);
|
||||
var scoreDisp = "None";
|
||||
if (myScore.length != 0)
|
||||
scoreDisp = Util.formatTime(myScore[0].time);
|
||||
scoreDisp = scoreType == Time ? Util.formatTime(myScore[0].time) : Util.formatScore(myScore[0].time);
|
||||
var isPar = myScore.length != 0 && myScore[0].time < mis.qualifyTime;
|
||||
var scoreColor = "#EBEBEB";
|
||||
if (isPar)
|
||||
scoreColor = "#8DFF8D";
|
||||
levelInfoMid.text.text = '<p align="left"><font color="${scoreColor}">${scoreDisp}</font><br/><font color="#88BCEE">${Util.formatTime(mis.qualifyTime)}</font></p>';
|
||||
levelInfoRight.text.text = '<p align="left"><font color="#EBEBEB">Level ${mis.missionInfo.level}<br/>Difficulty ${mis.missionInfo.difficulty}</font></p>';
|
||||
if (scoreType == Score && myScore.length == 0)
|
||||
scoreColor = "#EBEBEB";
|
||||
if (scoreType == Time) {
|
||||
levelInfoLeft.text.text = '<p align="right"><font color="#EBEBEB">My Best Time:</font><br/><font color="#EBEBEB">Par Time:</font></p>';
|
||||
levelInfoMid.text.text = '<p align="left"><font color="${scoreColor}">${scoreDisp}</font><br/><font color="#88BCEE">${Util.formatTime(mis.qualifyTime)}</font></p>';
|
||||
}
|
||||
if (scoreType == Score) {
|
||||
levelInfoLeft.text.text = '<p align="right"><font color="#EBEBEB">My Best Score:</font></p>';
|
||||
levelInfoMid.text.text = '<p align="left"><font color="${scoreColor}">${scoreDisp}</font></p>';
|
||||
}
|
||||
levelInfoRight.text.text = '<p align="left"><font color="#EBEBEB">Level ${mis.missionInfo.level}<br/>Difficulty ${mis.missionInfo.difficulty == null ? "" : mis.missionInfo.difficulty}</font></p>';
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -718,6 +718,8 @@ class PlayGui {
|
|||
// 1: green
|
||||
// 2: red
|
||||
public function formatTimer(time:Float) {
|
||||
if (time < 0)
|
||||
time = 0; // Can't support negatives for now
|
||||
var et = time * 1000;
|
||||
var thousandth = et % 10;
|
||||
var hundredth = Math.floor((et % 1000) / 10);
|
||||
|
|
|
|||
|
|
@ -6,13 +6,20 @@ import h3d.Vector;
|
|||
import src.MarbleWorld;
|
||||
import src.Mission;
|
||||
|
||||
enum ScoreType {
|
||||
Time;
|
||||
Score;
|
||||
}
|
||||
|
||||
interface GameMode {
|
||||
public function getSpawnTransform():{position:Vector, orientation:Quat, up:Vector};
|
||||
public function getRespawnTransform():{position:Vector, orientation:Quat, up:Vector};
|
||||
public function missionScan(mission:Mission):Void;
|
||||
public function getStartTime():Float;
|
||||
public function timeMultiplier():Float;
|
||||
|
||||
public function getScoreType():ScoreType;
|
||||
public function getFinishScore():Float;
|
||||
public function onTimeExpire():Void;
|
||||
public function onRestart():Void;
|
||||
public function onGemPickup(gem:Gem):Void;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package modes;
|
||||
|
||||
import gui.AchievementsGui;
|
||||
import modes.GameMode.ScoreType;
|
||||
import shapes.GemBeam;
|
||||
import shapes.Gem;
|
||||
import src.Console;
|
||||
|
|
@ -219,6 +221,7 @@ class HuntMode extends NullMode {
|
|||
var spawnGroup = pickGemSpawnGroup();
|
||||
activeGemSpawnGroup = spawnGroup;
|
||||
fillGemGroup(spawnGroup);
|
||||
@:privateAccess level.radar.blink();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -312,4 +315,41 @@ class HuntMode extends NullMode {
|
|||
'sound/gem_collect.wav'
|
||||
];
|
||||
}
|
||||
|
||||
override function getScoreType():ScoreType {
|
||||
return Score;
|
||||
}
|
||||
|
||||
override function onTimeExpire() {
|
||||
if (level.finishTime != null)
|
||||
return;
|
||||
AudioManager.playSound(ResourceLoader.getResource('data/sound/finish.wav', ResourceLoader.getAudio, @:privateAccess level.soundResources));
|
||||
level.finishTime = level.timeState.clone();
|
||||
level.marble.setMode(Start);
|
||||
level.marble.camera.finish = true;
|
||||
level.finishYaw = level.marble.camera.CameraYaw;
|
||||
level.finishPitch = level.marble.camera.CameraPitch;
|
||||
level.displayAlert("Congratulations! You've finished!");
|
||||
if (!level.isWatching) {
|
||||
var notifies = AchievementsGui.check();
|
||||
var delay = 5.0;
|
||||
var achDelay = 0.0;
|
||||
for (i in 0...9) {
|
||||
if (notifies & (1 << i) > 0)
|
||||
achDelay += 3;
|
||||
}
|
||||
if (notifies > 0)
|
||||
achDelay += 0.5;
|
||||
@:privateAccess level.schedule(level.timeState.currentAttemptTime + Math.max(delay, achDelay), () -> cast level.showFinishScreen());
|
||||
}
|
||||
// Stop the ongoing sounds
|
||||
if (@:privateAccess level.timeTravelSound != null) {
|
||||
@:privateAccess level.timeTravelSound.stop();
|
||||
@:privateAccess level.timeTravelSound = null;
|
||||
}
|
||||
}
|
||||
|
||||
override function getFinishScore():Float {
|
||||
return points;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package modes;
|
||||
|
||||
import modes.GameMode.ScoreType;
|
||||
import shapes.Gem;
|
||||
import h3d.Quat;
|
||||
import h3d.Vector;
|
||||
|
|
@ -83,4 +84,14 @@ class NullMode implements GameMode {
|
|||
public function getPreloadFiles() {
|
||||
return ['data/sound/gem_all.wav'];
|
||||
}
|
||||
|
||||
public function onTimeExpire() {}
|
||||
|
||||
public function getScoreType():ScoreType {
|
||||
return Time;
|
||||
}
|
||||
|
||||
public function getFinishScore():Float {
|
||||
return level.finishTime.gameplayClock;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue