mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
network helicopter and mega marble properly
This commit is contained in:
parent
6c1ed2e43b
commit
3b16113d02
8 changed files with 211 additions and 94 deletions
144
src/Marble.hx
144
src/Marble.hx
|
|
@ -255,14 +255,15 @@ class Marble extends GameObject {
|
|||
var megaMarbleEnableTime:Float = -1e8;
|
||||
var blastUseTime:Float = -1e8;
|
||||
|
||||
public var helicopterUseTick:Int = 0;
|
||||
public var megaMarbleUseTick:Int = 0;
|
||||
|
||||
public var blastAmount:Float = 0;
|
||||
public var blastTicks:Int = 0;
|
||||
public var blastUseTick:Int = 0; // blast is 12 ticks long
|
||||
|
||||
var blastPerc:Float = 0.0;
|
||||
|
||||
var teleportEnableTime:Null<Float> = null;
|
||||
var teleportDisableTime:Null<Float> = null;
|
||||
var bounceEmitDelay:Float = 0;
|
||||
|
||||
var bounceEmitterData:ParticleData;
|
||||
|
|
@ -286,8 +287,6 @@ class Marble extends GameObject {
|
|||
|
||||
public var prevPos:Vector;
|
||||
|
||||
var cloak:Bool = false;
|
||||
var teleporting:Bool = false;
|
||||
var isUltra:Bool = false;
|
||||
var _firstTick = true;
|
||||
|
||||
|
|
@ -564,7 +563,7 @@ class Marble extends GameObject {
|
|||
var gWorkGravityDir = this.currentUp.multiply(-1);
|
||||
var A = new Vector();
|
||||
A = gWorkGravityDir.multiply(this._gravity);
|
||||
if (currentTime - this.helicopterEnableTime < 5) {
|
||||
if (currentTime - this.helicopterEnableTime < 5 || (helicopterUseTick > 0 && (tick - helicopterUseTick) <= 156)) {
|
||||
A = A.multiply(0.25);
|
||||
}
|
||||
if (this.level != null) {
|
||||
|
|
@ -620,7 +619,7 @@ class Marble extends GameObject {
|
|||
var motionDir = axes[1];
|
||||
var upDir = axes[2];
|
||||
var airAccel = this._airAccel;
|
||||
if (currentTime - this.helicopterEnableTime < 5) {
|
||||
if (currentTime - this.helicopterEnableTime < 5 || (helicopterUseTick > 0 && (tick - helicopterUseTick) <= 156)) {
|
||||
airAccel *= 2;
|
||||
}
|
||||
A.load(A.add(sideDir.multiply(m.d.x).add(motionDir.multiply(m.d.y)).multiply(airAccel)));
|
||||
|
|
@ -954,17 +953,18 @@ class Marble extends GameObject {
|
|||
if (minVelocityBounceSoft <= contactVel) {
|
||||
var hardBounceSpeed = minVelocityBounceHard;
|
||||
var bounceSoundNum = Math.floor(Math.random() * 4);
|
||||
var sndList = (time - this.megaMarbleEnableTime < 10) ? [
|
||||
"data/sound/mega_bouncehard1.wav",
|
||||
"data/sound/mega_bouncehard2.wav",
|
||||
"data/sound/mega_bouncehard3.wav",
|
||||
"data/sound/mega_bouncehard4.wav"
|
||||
] : [
|
||||
"data/sound/bouncehard1.wav",
|
||||
"data/sound/bouncehard2.wav",
|
||||
"data/sound/bouncehard3.wav",
|
||||
"data/sound/bouncehard4.wav"
|
||||
];
|
||||
var sndList = ((time - this.megaMarbleEnableTime < 10)
|
||||
|| (this.megaMarbleUseTick > 0 && (this.level.timeState.ticks - this.megaMarbleUseTick) < 312)) ? [
|
||||
"data/sound/mega_bouncehard1.wav",
|
||||
"data/sound/mega_bouncehard2.wav",
|
||||
"data/sound/mega_bouncehard3.wav",
|
||||
"data/sound/mega_bouncehard4.wav"
|
||||
] : [
|
||||
"data/sound/bouncehard1.wav",
|
||||
"data/sound/bouncehard2.wav",
|
||||
"data/sound/bouncehard3.wav",
|
||||
"data/sound/bouncehard4.wav"
|
||||
];
|
||||
|
||||
var snd = ResourceLoader.getResource(sndList[bounceSoundNum], ResourceLoader.getAudio, this.soundResources);
|
||||
var gain = bounceMinGain;
|
||||
|
|
@ -1016,7 +1016,8 @@ class Marble extends GameObject {
|
|||
if (slipVolume < 0)
|
||||
slipVolume = 0;
|
||||
|
||||
if (time.currentAttemptTime - this.megaMarbleEnableTime < 10) {
|
||||
if (time.currentAttemptTime - this.megaMarbleEnableTime < 10
|
||||
|| (this.megaMarbleUseTick > 0 && (this.level.timeState.ticks - this.megaMarbleUseTick) < 312)) {
|
||||
if (this.rollMegaSound != null) {
|
||||
rollMegaSound.volume = rollVolume;
|
||||
rollSound.volume = 0;
|
||||
|
|
@ -1661,6 +1662,8 @@ class Marble extends GameObject {
|
|||
marbleUpdate.moveQueueSize = this.connection != null ? this.connection.moveManager.getQueueSize() : 255;
|
||||
marbleUpdate.blastAmount = this.blastTicks;
|
||||
marbleUpdate.blastTick = this.blastUseTick;
|
||||
marbleUpdate.heliTick = this.helicopterUseTick;
|
||||
marbleUpdate.megaTick = this.megaMarbleUseTick;
|
||||
marbleUpdate.serialize(b);
|
||||
return b.getBytes();
|
||||
}
|
||||
|
|
@ -1681,6 +1684,8 @@ class Marble extends GameObject {
|
|||
this.omega = p.omega;
|
||||
this.blastTicks = p.blastAmount;
|
||||
this.blastUseTick = p.blastTick;
|
||||
this.helicopterUseTick = p.heliTick;
|
||||
this.megaMarbleUseTick = p.megaTick;
|
||||
if (this.controllable && Net.isClient) {
|
||||
// We are client, need to do something about the queue
|
||||
var mm = Net.clientConnection.moveManager;
|
||||
|
|
@ -1737,6 +1742,19 @@ class Marble extends GameObject {
|
|||
playedSounds = [];
|
||||
advancePhysics(timeState, move.move, collisionWorld, pathedInteriors);
|
||||
physicsAccumulator = 0;
|
||||
|
||||
if (this.megaMarbleUseTick > 0) {
|
||||
if ((this.level.timeState.ticks - this.megaMarbleUseTick) < 312) {
|
||||
this._radius = 0.675;
|
||||
this.collider.radius = 0.675;
|
||||
} else if ((this.level.timeState.ticks - this.megaMarbleUseTick) > 312) {
|
||||
this.collider.radius = this._radius = 0.3;
|
||||
if (!this.isNetUpdate && this.controllable)
|
||||
AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null, false);
|
||||
this.megaMarbleUseTick = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return move;
|
||||
// if (Net.isHost) {
|
||||
// packets.push({b: packUpdate(move, timeState), c: this.connection != null ? this.connection.id : 0});
|
||||
|
|
@ -1771,6 +1789,12 @@ class Marble extends GameObject {
|
|||
|
||||
updatePowerupStates(timeState.currentAttemptTime, timeState.dt);
|
||||
|
||||
if ((this.megaMarbleUseTick > 0 && (this.level.timeState.ticks - this.megaMarbleUseTick) < 312)) {
|
||||
this._marbleScale = this._defaultScale * 2.25;
|
||||
} else {
|
||||
this._marbleScale = this._defaultScale;
|
||||
}
|
||||
|
||||
var s = this._renderScale * this._renderScale;
|
||||
if (s <= this._marbleScale * this._marbleScale)
|
||||
s = 0.1;
|
||||
|
|
@ -1778,29 +1802,13 @@ class Marble extends GameObject {
|
|||
s = 0.4;
|
||||
|
||||
s = timeState.dt / s * 2.302585124969482;
|
||||
s = 1.0 / (s * (s * 0.2349999994039536 * s) + s + 1.0 + 0.4799999892711639 * s * s);
|
||||
s = 1.0 / (s * (s * 0.235 * s) + s + 1.0 + 0.48 * s * s);
|
||||
this._renderScale *= s;
|
||||
s = 1 - s;
|
||||
this._renderScale += s * this._marbleScale;
|
||||
var marbledts = cast(this.getChildAt(0), DtsObject);
|
||||
marbledts.setScale(this._renderScale);
|
||||
|
||||
if (this._radius != 0.675 && timeState.currentAttemptTime - this.megaMarbleEnableTime < 10) {
|
||||
this._prevRadius = this._radius;
|
||||
this._radius = 0.675;
|
||||
this.collider.radius = 0.675;
|
||||
this._marbleScale *= 2.25;
|
||||
var boost = this.currentUp.multiply(5);
|
||||
this.velocity = this.velocity.add(boost);
|
||||
} else if (timeState.currentAttemptTime - this.megaMarbleEnableTime > 10) {
|
||||
if (this._radius != this._prevRadius) {
|
||||
this._radius = this._prevRadius;
|
||||
this.collider.radius = this._radius;
|
||||
this._marbleScale = this._defaultScale;
|
||||
AudioManager.playSound(ResourceLoader.getResource("data/sound/MegaShrink.wav", ResourceLoader.getAudio, this.soundResources), null, false);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateFinishAnimation(timeState.dt);
|
||||
if (this.mode == Finish) {
|
||||
this.setPosition(this.finishAnimPosition.x, this.finishAnimPosition.y, this.finishAnimPosition.z);
|
||||
|
|
@ -1968,8 +1976,6 @@ class Marble extends GameObject {
|
|||
}
|
||||
}
|
||||
|
||||
this.updateTeleporterState(timeState);
|
||||
|
||||
this.updateFinishAnimation(timeState.dt);
|
||||
if (this.mode == Finish) {
|
||||
this.setPosition(this.finishAnimPosition.x, this.finishAnimPosition.y, this.finishAnimPosition.z);
|
||||
|
|
@ -2063,7 +2069,8 @@ class Marble extends GameObject {
|
|||
public function updatePowerupStates(currentTime:Float, dt:Float) {
|
||||
if (!this.controllable && this.connection == null)
|
||||
return;
|
||||
if (currentTime - this.helicopterEnableTime < 5) {
|
||||
if (currentTime - this.helicopterEnableTime < 5
|
||||
|| (helicopterUseTick > 0 && (this.level.timeState.ticks - helicopterUseTick) <= 156)) {
|
||||
this.helicopter.setPosition(x, y, z);
|
||||
this.helicopter.setRotationQuat(this.level.getOrientationQuat(currentTime));
|
||||
this.helicopterSound.pause = false;
|
||||
|
|
@ -2089,7 +2096,8 @@ class Marble extends GameObject {
|
|||
public function getMass() {
|
||||
if (this.level == null)
|
||||
return 1;
|
||||
if (this.level.timeState.currentAttemptTime - this.megaMarbleEnableTime < 10) {
|
||||
if (this.level.timeState.currentAttemptTime - this.megaMarbleEnableTime < 10
|
||||
|| (this.megaMarbleUseTick > 0 && (this.level.timeState.ticks - this.megaMarbleUseTick) < 312)) {
|
||||
return 5;
|
||||
} else {
|
||||
return 1;
|
||||
|
|
@ -2156,46 +2164,18 @@ class Marble extends GameObject {
|
|||
this.appliedImpulses.push({impulse: impulse, contactImpulse: contactImpulse});
|
||||
}
|
||||
|
||||
public function enableHelicopter(time:Float) {
|
||||
this.helicopterEnableTime = time;
|
||||
public function enableHelicopter(timeState:TimeState) {
|
||||
if (this.level.isMultiplayer)
|
||||
this.helicopterUseTick = timeState.ticks;
|
||||
else
|
||||
this.helicopterEnableTime = timeState.currentAttemptTime;
|
||||
}
|
||||
|
||||
public function enableMegaMarble(time:Float) {
|
||||
this.megaMarbleEnableTime = time;
|
||||
}
|
||||
|
||||
function updateTeleporterState(time:TimeState) {
|
||||
var teleportFadeCompletion:Float = 0;
|
||||
|
||||
if (this.teleportEnableTime != null)
|
||||
teleportFadeCompletion = Util.clamp((time.currentAttemptTime - this.teleportEnableTime) / 0.5, 0, 1);
|
||||
if (this.teleportDisableTime != null)
|
||||
teleportFadeCompletion = Util.clamp(1 - (time.currentAttemptTime - this.teleportDisableTime) / 0.5, 0, 1);
|
||||
|
||||
if (teleportFadeCompletion > 0) {
|
||||
var ourDts:DtsObject = cast this.children[0];
|
||||
ourDts.setOpacity(Util.lerp(1, 0.25, teleportFadeCompletion));
|
||||
this.teleporting = true;
|
||||
} else {
|
||||
if (this.teleporting) {
|
||||
var ourDts:DtsObject = cast this.children[0];
|
||||
ourDts.setOpacity(1);
|
||||
this.teleporting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setCloaking(active:Bool, time:TimeState) {
|
||||
this.cloak = active;
|
||||
if (this.cloak) {
|
||||
var completion = (this.teleportDisableTime != null) ? Util.clamp((time.currentAttemptTime - this.teleportDisableTime) / 0.5, 0, 1) : 1;
|
||||
this.teleportEnableTime = time.currentAttemptTime - 0.5 * (1 - completion);
|
||||
this.teleportDisableTime = null;
|
||||
} else {
|
||||
var completion = Util.clamp((time.currentAttemptTime - this.teleportEnableTime) / 0.5, 0, 1);
|
||||
this.teleportDisableTime = time.currentAttemptTime - 0.5 * (1 - completion);
|
||||
this.teleportEnableTime = null;
|
||||
}
|
||||
public function enableMegaMarble(timeState:TimeState) {
|
||||
if (this.level.isMultiplayer)
|
||||
this.megaMarbleUseTick = timeState.ticks;
|
||||
else
|
||||
this.megaMarbleEnableTime = timeState.currentAttemptTime;
|
||||
}
|
||||
|
||||
public function setMode(mode:Mode) {
|
||||
|
|
@ -2221,17 +2201,11 @@ class Marble extends GameObject {
|
|||
this.blastUseTime = Math.NEGATIVE_INFINITY;
|
||||
this.blastUseTick = 0;
|
||||
this.blastTicks = 0;
|
||||
this.helicopterUseTick = 0;
|
||||
this.megaMarbleUseTick = 0;
|
||||
this.lastContactNormal = new Vector(0, 0, 1);
|
||||
this.contactEntities = [];
|
||||
this.cloak = false;
|
||||
this._firstTick = true;
|
||||
if (this.teleporting) {
|
||||
var ourDts:DtsObject = cast this.children[0];
|
||||
ourDts.setOpacity(1);
|
||||
}
|
||||
this.teleporting = false;
|
||||
this.teleportDisableTime = null;
|
||||
this.teleportEnableTime = null;
|
||||
this.finishAnimTime = 0;
|
||||
this.physicsAccumulator = 0;
|
||||
this.prevRot = this.getRotationQuat().clone();
|
||||
|
|
|
|||
|
|
@ -1166,10 +1166,12 @@ class MarbleWorld extends Scheduler {
|
|||
// if (m.serverTicks == ourLastMoveTime) {
|
||||
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
|
||||
if (marbleNeedsPrediction & (1 << Net.clientId) > 0)
|
||||
|
||||
var distFromUs = @:privateAccess marbleToUpdate.newPos.distance(this.marble.newPos);
|
||||
if (distFromUs < 5)
|
||||
m.calculationTicks = ourQueuedMoves.length; // ourQueuedMoves.length;
|
||||
else
|
||||
m.calculationTicks = ourQueuedMoves.length;
|
||||
m.calculationTicks = Std.int(Math.max(1, ourQueuedMoves.length - (distFromUs - 5) / 5));
|
||||
// - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT - ourLastMove.moveQueueSize) / 2);
|
||||
|
||||
marblesToTick.set(client, m);
|
||||
|
|
|
|||
132
src/net/BitStream.hx
Normal file
132
src/net/BitStream.hx
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
package net;
|
||||
|
||||
import haxe.io.BytesOutput;
|
||||
import haxe.io.BytesInput;
|
||||
import haxe.io.Bytes;
|
||||
|
||||
class InputBitStream {
|
||||
var data:Bytes;
|
||||
var position:Int;
|
||||
var shift:Int;
|
||||
|
||||
public function new(data:Bytes) {
|
||||
this.data = data;
|
||||
this.position = 0;
|
||||
this.shift = 0;
|
||||
}
|
||||
|
||||
function readBits(bits:Int = 8) {
|
||||
if (this.shift + bits >= 8) {
|
||||
var extra = (this.shift + bits) % 8;
|
||||
var remain = bits - extra;
|
||||
var first = data.get(position) >> shift;
|
||||
var result = first;
|
||||
this.position++;
|
||||
if (extra > 0) {
|
||||
var second = (data.get(position) & (0xFF >> (8 - extra))) << remain;
|
||||
result |= second;
|
||||
}
|
||||
this.shift = extra;
|
||||
return result;
|
||||
} else {
|
||||
var result = (data.get(position) >> shift) & (0xFF >> (8 - bits));
|
||||
shift += bits;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public function readInt(bits:Int = 32) {
|
||||
var value = 0;
|
||||
var shift = 0;
|
||||
while (bits > 0) {
|
||||
value |= readBits(bits < 8 ? bits : 8) << shift;
|
||||
shift += 8;
|
||||
bits -= 8;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public function readFlag() {
|
||||
return readInt(1);
|
||||
}
|
||||
|
||||
public function readByte() {
|
||||
return readInt(8);
|
||||
}
|
||||
|
||||
public function readUInt16() {
|
||||
return readInt(16);
|
||||
}
|
||||
|
||||
public function readInt32() {
|
||||
return readInt(32);
|
||||
}
|
||||
|
||||
public function readFloat() {
|
||||
return readInt32();
|
||||
}
|
||||
}
|
||||
|
||||
class OutputBitStream {
|
||||
var data:BytesOutput;
|
||||
var position:Int;
|
||||
var shift:Int;
|
||||
var lastByte:Int;
|
||||
|
||||
public function new(data:BytesOutput = null) {
|
||||
this.data = data;
|
||||
if (this.data == null)
|
||||
this.data = new BytesOutput();
|
||||
this.position = 0;
|
||||
this.shift = 0;
|
||||
this.lastByte = 0;
|
||||
}
|
||||
|
||||
function writeBits(value:Int, bits:Int) {
|
||||
value = value & (0xFF >> (8 - bits));
|
||||
if (this.shift + bits >= 8) {
|
||||
var extra = (shift + bits) % 8;
|
||||
var remain = bits - extra;
|
||||
|
||||
var first = value & (0xFF >> (8 - remain));
|
||||
lastByte |= first << shift;
|
||||
|
||||
var second = (value >> remain) & (0xFF >> (8 - extra));
|
||||
this.data.writeByte(this.lastByte);
|
||||
this.lastByte = second;
|
||||
this.shift = extra;
|
||||
} else {
|
||||
lastByte |= (value << this.shift) & (0xFF >> (8 - bits - this.shift));
|
||||
}
|
||||
}
|
||||
|
||||
public function writeInt(value:Int, bits:Int = 32) {
|
||||
while (bits > 0) {
|
||||
this.writeBits(value & 0xFF, bits < 8 ? bits : 8);
|
||||
value >>= 8;
|
||||
bits -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
public function writeFlag(value:Int) {
|
||||
writeInt(value, 1);
|
||||
}
|
||||
|
||||
public function writeByte(value:Int) {
|
||||
writeInt(value, 8);
|
||||
}
|
||||
|
||||
public function writeUInt16(value:Int) {
|
||||
writeInt(value, 16);
|
||||
}
|
||||
|
||||
public function writeInt32(value:Int) {
|
||||
writeInt(value, 32);
|
||||
}
|
||||
|
||||
public function getBytes() {
|
||||
this.data.writeByte(this.lastByte);
|
||||
return this.data.getBytes();
|
||||
}
|
||||
}
|
||||
|
|
@ -25,9 +25,10 @@ class MarblePrediction {
|
|||
}
|
||||
|
||||
public inline function getError(p:MarbleUpdatePacket) {
|
||||
var subs = position.sub(p.position).lengthSq() + velocity.sub(p.velocity).lengthSq() + omega.sub(p.omega).lengthSq();
|
||||
if (isControl)
|
||||
subs += Math.abs(blastAmount - p.blastAmount);
|
||||
// Just doing position errors is enough to make it work
|
||||
var subs = position.sub(p.position).lengthSq(); // + velocity.sub(p.velocity).lengthSq() + omega.sub(p.omega).lengthSq();
|
||||
// if (isControl)
|
||||
// subs += Math.abs(blastAmount - p.blastAmount);
|
||||
return subs;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class Net {
|
|||
isHost = true;
|
||||
isClient = false;
|
||||
clientId = 0;
|
||||
masterWs = new WebSocket("ws://192.168.1.2:8080");
|
||||
masterWs = new WebSocket("ws://localhost:8080");
|
||||
|
||||
masterWs.onmessage = (m) -> {
|
||||
switch (m) {
|
||||
|
|
@ -97,7 +97,7 @@ class Net {
|
|||
}
|
||||
|
||||
public static function joinServer(connectedCb:() -> Void) {
|
||||
masterWs = new WebSocket("ws://192.168.1.2:8080");
|
||||
masterWs = new WebSocket("ws://localhost:8080");
|
||||
masterWs.onopen = () -> {
|
||||
client = new RTCPeerConnection(["stun:stun.l.google.com:19302"], "0.0.0.0");
|
||||
var candidates = [];
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ class MarbleUpdatePacket implements NetPacket {
|
|||
var omega:Vector;
|
||||
var blastAmount:Int;
|
||||
var blastTick:Int;
|
||||
var megaTick:Int;
|
||||
var heliTick:Int;
|
||||
var moveQueueSize:Int;
|
||||
|
||||
public function new() {}
|
||||
|
|
@ -60,6 +62,8 @@ class MarbleUpdatePacket implements NetPacket {
|
|||
b.writeFloat(omega.z);
|
||||
b.writeUInt16(blastAmount);
|
||||
b.writeUInt16(blastTick);
|
||||
b.writeUInt16(heliTick);
|
||||
b.writeUInt16(megaTick);
|
||||
}
|
||||
|
||||
public inline function deserialize(b:haxe.io.BytesInput) {
|
||||
|
|
@ -72,5 +76,7 @@ class MarbleUpdatePacket implements NetPacket {
|
|||
omega = new Vector(b.readFloat(), b.readFloat(), b.readFloat());
|
||||
blastAmount = b.readUInt16();
|
||||
blastTick = b.readUInt16();
|
||||
heliTick = b.readUInt16();
|
||||
megaTick = b.readUInt16();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Helicopter extends PowerUp {
|
|||
}
|
||||
|
||||
public function use(marble:Marble, timeState:TimeState) {
|
||||
marble.enableHelicopter(timeState.currentAttemptTime);
|
||||
marble.enableHelicopter(timeState);
|
||||
this.level.deselectPowerUp(marble);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ class MegaMarble extends PowerUp {
|
|||
}
|
||||
|
||||
public function use(marble:Marble, timeState:TimeState) {
|
||||
marble.enableMegaMarble(timeState.currentAttemptTime);
|
||||
marble.enableMegaMarble(timeState);
|
||||
var boost = marble.currentUp.multiply(5);
|
||||
marble.velocity.load(marble.velocity.add(boost));
|
||||
this.level.deselectPowerUp(marble);
|
||||
if (this.level.marble == marble && @:privateAccess !marble.isNetUpdate)
|
||||
AudioManager.playSound(ResourceLoader.getResource('data/sound/use_mega.wav', ResourceLoader.getAudio, this.soundResources));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue