impl blast

This commit is contained in:
RandomityGuy 2022-12-06 22:31:24 +05:30
parent f22cce9825
commit 1018208d5c
8 changed files with 161 additions and 12 deletions

View file

@ -114,6 +114,56 @@ final trailParticleOptions:ParticleEmitterOptions = {
}
};
final blastParticleOptions:ParticleEmitterOptions = {
ejectionPeriod: 1,
ambientVelocity: new Vector(0, 0, -0.3),
ejectionVelocity: 4,
velocityVariance: 0,
emitterLifetime: 300,
inheritedVelFactor: 0,
particleOptions: {
texture: 'particles/smoke.png',
blending: Alpha,
spinSpeed: 20,
spinRandomMin: 0,
spinRandomMax: 0,
lifetime: 500,
lifetimeVariance: 100,
dragCoefficient: 1,
acceleration: 0,
colors: [new Vector(0, 1, 1, 0.1), new Vector(0, 1, 1, 0.5), new Vector(0, 1, 1, 0.9)],
sizes: [0.125, 0.125, 0.125],
times: [0, 0.4, 1]
}
}
final blastMaxParticleOptions:ParticleEmitterOptions = {
ejectionPeriod: 1,
ambientVelocity: new Vector(0, 0, -0.3),
ejectionVelocity: 4,
velocityVariance: 0,
emitterLifetime: 300,
inheritedVelFactor: 0,
particleOptions: {
texture: 'particles/smoke.png',
blending: Alpha,
spinSpeed: 20,
spinRandomMin: 0,
spinRandomMax: 0,
lifetime: 500,
lifetimeVariance: 100,
dragCoefficient: 1,
acceleration: 0,
colors: [
new Vector(1, 0.7, 0, 0.1),
new Vector(1, 0.7, 0, 0.5),
new Vector(1, 0.7, 0, 0.9)
],
sizes: [0.125, 0.125, 0.125],
times: [0, 0.4, 1]
}
}
class Marble extends GameObject {
public var camera:CameraController;
public var cameraObject:Object;
@ -178,6 +228,8 @@ class Marble extends GameObject {
var bounceEmitterData:ParticleData;
var trailEmitterData:ParticleData;
var blastEmitterData:ParticleData;
var blastMaxEmitterData:ParticleData;
var trailEmitterNode:ParticleEmitter;
var rollSound:Channel;
@ -215,6 +267,14 @@ class Marble extends GameObject {
this.trailEmitterData.identifier = "MarbleTrailParticle";
this.trailEmitterData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
this.blastEmitterData = new ParticleData();
this.blastEmitterData.identifier = "MarbleBlastParticle";
this.blastEmitterData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
this.blastMaxEmitterData = new ParticleData();
this.blastMaxEmitterData.identifier = "MarbleBlastMaxParticle";
this.blastMaxEmitterData.texture = ResourceLoader.getResource("data/particles/smoke.png", ResourceLoader.getTexture, this.textureResources);
this.rollSound = AudioManager.playSound(ResourceLoader.getResource("data/sound/rolling_hard.wav", ResourceLoader.getAudio, this.soundResources),
this.getAbsPos().getPosition(), true);
this.slipSound = AudioManager.playSound(ResourceLoader.getResource("data/sound/sliding.wav", ResourceLoader.getAudio, this.soundResources),
@ -1501,6 +1561,21 @@ class Marble extends GameObject {
}
}
public function useBlast() {
if (this.level.blastAmount < 0.2 || this.level.game != "ultra")
return;
var impulse = this.level.currentUp.multiply(Math.max(Math.sqrt(this.level.blastAmount), this.level.blastAmount) * 10);
this.applyImpulse(impulse);
AudioManager.playSound(ResourceLoader.getResource('data/sound/blast.wav', ResourceLoader.getAudio, this.soundResources));
this.level.particleManager.createEmitter(this.level.blastAmount > 1 ? blastMaxParticleOptions : blastParticleOptions,
this.level.blastAmount > 1 ? blastMaxEmitterData : blastEmitterData, this.getAbsPos().getPosition(), () -> {
this.getAbsPos().getPosition().add(this.level.currentUp.multiply(-this._radius * 0.4));
},
new Vector(1, 1,
1).add(new Vector(Math.abs(this.level.currentUp.x), Math.abs(this.level.currentUp.y), Math.abs(this.level.currentUp.z)).multiply(-0.8)));
this.level.blastAmount = 0;
}
public function applyImpulse(impulse:Vector) {
this.appliedImpulses.push(impulse);
}

View file

@ -119,6 +119,7 @@ class MarbleWorld extends Scheduler {
public var scene:Scene;
public var scene2d:h2d.Scene;
public var mission:Mission;
public var game:String;
public var marble:Marble;
public var worldOrientation:Quat;
@ -130,6 +131,7 @@ class MarbleWorld extends Scheduler {
public var finishYaw:Float;
public var totalGems:Int = 0;
public var gemCount:Int = 0;
public var blastAmount:Float = 0;
public var cursorLock:Bool = true;
@ -153,6 +155,7 @@ class MarbleWorld extends Scheduler {
var checkpointCollectedGems:Map<Gem, Bool> = [];
var checkpointHeldPowerup:PowerUp = null;
var checkpointUp:Vector = null;
var cheeckpointBlast:Float = 0;
// Replay
public var replay:Replay;
@ -179,6 +182,7 @@ class MarbleWorld extends Scheduler {
this.scene = scene;
this.scene2d = scene2d;
this.mission = mission;
this.game = mission.game.toLowerCase();
this.replay = new Replay(mission.path);
this.isRecording = record;
}
@ -238,7 +242,7 @@ class MarbleWorld extends Scheduler {
public function postInit() {
// Add the sky at the last so that cubemap reflections work
this.playGui.init(this.scene2d, () -> {
this.playGui.init(this.scene2d, this.mission.game.toLowerCase(), () -> {
this.scene.addChild(this.sky);
this._ready = true;
var musicFileName = 'data/sound/music/' + this.mission.missionInfo.music;
@ -300,7 +304,7 @@ class MarbleWorld extends Scheduler {
worker.loadFile(file);
}
this.scene.camera.zFar = Math.max(2000, Std.parseFloat(this.skyElement.visibledistance));
this.scene.camera.zFar = Math.max(4000, Std.parseFloat(this.skyElement.visibledistance));
this.sky = new Sky();
@ -384,6 +388,7 @@ class MarbleWorld extends Scheduler {
this.timeState.gameplayClock = 0;
this.bonusTime = 0;
this.outOfBounds = false;
this.blastAmount = 0;
this.outOfBoundsTime = null;
this.finishTime = null;
this.helpTextTimeState = Math.NEGATIVE_INFINITY;
@ -398,6 +403,7 @@ class MarbleWorld extends Scheduler {
this.checkpointCollectedGems.clear();
this.checkpointHeldPowerup = null;
this.checkpointUp = null;
this.cheeckpointBlast = 0;
if (this.endPad != null)
this.endPad.inFinish = false;
@ -1132,6 +1138,10 @@ class MarbleWorld extends Scheduler {
this.tickSchedule(timeState.currentAttemptTime);
if (Key.isPressed(Settings.controlsSettings.blast) && !this.isWatching && this.game == "ultra") {
this.marble.useBlast();
}
// Replay gravity
if (this.isWatching) {
if (this.replay.currentPlaybackFrame.gravityChange) {
@ -1143,6 +1153,7 @@ class MarbleWorld extends Scheduler {
}
this.updateGameState();
this.updateBlast(timeState);
ProfilerUI.measure("updateDTS");
for (obj in dtsObjects) {
obj.update(timeState);
@ -1315,6 +1326,15 @@ class MarbleWorld extends Scheduler {
this.replay.recordTimeState(timeState.currentAttemptTime, timeState.gameplayClock, this.bonusTime);
}
function updateBlast(timestate:TimeState) {
if (this.game == "ultra") {
if (this.blastAmount < 1) {
this.blastAmount = Util.clamp(this.blastAmount + (timeState.dt / 25), 0, 1);
}
this.playGui.setBlastValue(this.blastAmount);
}
}
function updateTexts() {
var helpTextTime = this.helpTextTimeState;
var alertTextTime = this.alertTextTimeState;
@ -1689,6 +1709,7 @@ class MarbleWorld extends Scheduler {
this.currentCheckpointTrigger = trigger;
this.checkpointCollectedGems.clear();
this.checkpointUp = this.currentUp.clone();
this.cheeckpointBlast = this.blastAmount;
// Remember all gems that were collected up to this point
for (gem in this.gems) {
if (gem.pickedUp)
@ -1735,6 +1756,7 @@ class MarbleWorld extends Scheduler {
this.marble.camera.nextCameraYaw = this.marble.camera.CameraYaw;
this.marble.camera.nextCameraPitch = this.marble.camera.CameraPitch;
this.marble.camera.oob = false;
this.blastAmount = this.cheeckpointBlast;
if (this.isRecording) {
this.replay.recordCameraState(this.marble.camera.CameraYaw, this.marble.camera.CameraPitch);
this.replay.recordMarbleInput(0, 0);

View file

@ -220,12 +220,14 @@ class ParticleEmitter {
var creationTime:Float;
var vel = new Vector();
var getPos:Void->Vector;
var spawnSphereSquish:Vector;
public function new(options:ParticleEmitterOptions, data:ParticleData, manager:ParticleManager, ?getPos:Void->Vector) {
public function new(options:ParticleEmitterOptions, data:ParticleData, manager:ParticleManager, ?getPos:Void->Vector, ?spawnSphereSquish:Vector) {
this.o = options;
this.manager = manager;
this.getPos = getPos;
this.data = data;
this.spawnSphereSquish = spawnSphereSquish != null ? spawnSphereSquish : new Vector(1, 1, 1);
}
public function spawn(time:Float) {
@ -257,6 +259,9 @@ class ParticleEmitter {
pos = pos.add(this.o.spawnOffset()); // Call the spawnOffset function if it's there
// This isn't necessarily uniform but it's fine for the purpose.
var randomPointOnSphere = new Vector(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1).normalized();
randomPointOnSphere.x *= this.spawnSphereSquish.x;
randomPointOnSphere.y *= this.spawnSphereSquish.y;
randomPointOnSphere.z *= this.spawnSphereSquish.z;
// Compute the total velocity
var initialVel = this.o.ejectionVelocity;
initialVel += (this.o.velocityVariance * 2 * Math.random()) - this.o.velocityVariance;
@ -340,8 +345,8 @@ class ParticleManager {
return this.currentTime;
}
public function createEmitter(options:ParticleEmitterOptions, data:ParticleData, initialPos:Vector, ?getPos:Void->Vector) {
var emitter = new ParticleEmitter(options, data, cast this, getPos);
public function createEmitter(options:ParticleEmitterOptions, data:ParticleData, initialPos:Vector, ?getPos:Void->Vector, ?spawnSphereSquish:Vector) {
var emitter = new ParticleEmitter(options, data, cast this, getPos, spawnSphereSquish);
emitter.currPos = (getPos != null) ? getPos() : initialPos.clone();
if (emitter.currPos == null)
emitter.currPos = initialPos.clone();

View file

@ -55,6 +55,7 @@ typedef ControlsSettings = {
var cameraSensitivity:Float;
var invertYAxis:Bool;
var respawn:Int;
var blast:Int;
}
typedef TouchSettings = {
@ -115,7 +116,8 @@ class Settings {
alwaysFreeLook: true,
cameraSensitivity: 0.6,
invertYAxis: false,
respawn: Key.BACKSPACE
respawn: Key.BACKSPACE,
blast: Key.E
};
public static var touchSettings:TouchSettings = {

View file

@ -383,10 +383,11 @@ class OptionsDlg extends GuiImage {
hotkeysPanel);
makeRemapOption("Respawn:", 278, Util.getKeyForButton2(Settings.controlsSettings.respawn), (key) -> Settings.controlsSettings.respawn = key,
hotkeysPanel, true);
makeRemapOption("Blast:", 326, Util.getKeyForButton2(Settings.controlsSettings.blast), (key) -> Settings.controlsSettings.blast = key, hotkeysPanel);
if (Util.isTouchDevice()) {
var textObj = new GuiText(markerFelt32);
textObj.position = new Vector(5, 326);
textObj.position = new Vector(368, 326);
textObj.extent = new Vector(212, 14);
textObj.text.text = "Touch Controls";
textObj.text.textColor = 0xFFFFFF;
@ -394,7 +395,7 @@ class OptionsDlg extends GuiImage {
hotkeysPanel.addChild(textObj);
var remapBtn = new GuiButtonText(loadButtonImages("data/ui/options/bind"), markerFelt24);
remapBtn.position = new Vector(203, 323);
remapBtn.position = new Vector(363 + 203, 323);
remapBtn.txtCtrl.text.text = "Edit";
remapBtn.setExtent(new Vector(152, 49));
remapBtn.pressedAction = (sender) -> {

View file

@ -60,6 +60,10 @@ class PlayGui {
var alertTextForeground:GuiText;
var alertTextBackground:GuiText;
var blastBar:GuiControl;
var blastFill:GuiImage;
var blastFrame:GuiImage;
var imageResources:Array<Resource<Image>> = [];
var textureResources:Array<Resource<Texture>> = [];
var soundResources:Array<Resource<Sound>> = [];
@ -97,7 +101,7 @@ class PlayGui {
}
}
public function init(scene2d:h2d.Scene, onFinish:Void->Void) {
public function init(scene2d:h2d.Scene, game:String, onFinish:Void->Void) {
this.scene2d = scene2d;
this._init = true;
@ -143,6 +147,8 @@ class PlayGui {
});
initCenterText();
initPowerupBox();
if (game == 'ultra')
initBlastBar();
initTexts();
if (Settings.optionsSettings.frameRateVis)
initFPSMeter();
@ -427,6 +433,45 @@ class PlayGui {
playGuiCtrl.addChild(fpsMeterCtrl);
}
function initBlastBar() {
blastBar = new GuiControl();
blastBar.position = new Vector(6, 445);
blastBar.extent = new Vector(120, 28);
blastBar.vertSizing = Top;
this.playGuiCtrl.addChild(blastBar);
blastFill = new GuiImage(ResourceLoader.getResource("data/ui/game/blastbar_bargreen.png", ResourceLoader.getImage, this.imageResources).toTile());
blastFill.position = new Vector(5, 5);
blastFill.extent = new Vector(58, 17);
blastFill.doClipping = false;
blastBar.addChild(blastFill);
blastFrame = new GuiImage(ResourceLoader.getResource("data/ui/game/blastbar.png", ResourceLoader.getImage, this.imageResources).toTile());
blastFrame.position = new Vector(0, 0);
blastFrame.extent = new Vector(120, 28);
blastBar.addChild(blastFrame);
}
public function setBlastValue(value:Float) {
if (value <= 1) {
if (blastFill.extent.y == 16) { // Was previously charged
blastFrame.bmp.tile = ResourceLoader.getResource("data/ui/game/blastbar.png", ResourceLoader.getImage, this.imageResources).toTile();
}
var oldVal = blastFill.extent.x;
blastFill.extent = new Vector(Util.lerp(0, 110, value), 17);
if (oldVal < 22 && blastFill.extent.x >= 22) {
blastFill.bmp.tile = ResourceLoader.getResource("data/ui/game/blastbar_bargreen.png", ResourceLoader.getImage, this.imageResources).toTile();
}
if (oldVal >= 22 && blastFill.extent.x < 22) {
blastFill.bmp.tile = ResourceLoader.getResource("data/ui/game/blastbar_bargray.png", ResourceLoader.getImage, this.imageResources).toTile();
}
} else {
blastFill.extent = new Vector(0, 16); // WE will just use this extra number to store whether it was previously charged or not
blastFrame.bmp.tile = ResourceLoader.getResource("data/ui/game/blastbar_charged.png", ResourceLoader.getImage, this.imageResources).toTile();
}
this.blastBar.render(scene2d);
}
public function setHelpTextOpacity(value:Float) {
helpTextForeground.text.color.a = value;
helpTextBackground.text.color.a = value;

View file

@ -20,7 +20,7 @@ class CubemapRenderer {
this.scene = scene;
this.sky = sky;
this.cubemap = new Texture(128, 128, [Cube, Dynamic, Target], h3d.mat.Data.TextureFormat.RGB8);
this.camera = new Camera(90, 1, 1, 0.02);
this.camera = new Camera(90, 1, 1, 0.02, scene.camera.zFar);
this.position = new Vector();
this.nextFaceToRender = 0;
}

View file

@ -31,7 +31,6 @@ class Blast extends PowerUp {
}
public function use(timeState:TimeState) {
var marble = this.level.marble;
this.level.deselectPowerUp();
this.level.blastAmount = 1.03;
}
}