mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-23 08:07:54 -05:00
Merge branch 'rewrite/master' into title-music-vol-fix
This commit is contained in:
commit
662688023a
13 changed files with 371 additions and 58 deletions
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -85,7 +85,7 @@
|
|||
},
|
||||
"projectManager.git.baseFolders": ["./"],
|
||||
|
||||
"haxecheckstyle.sourceFolders": ["src", "Source"],
|
||||
"haxecheckstyle.sourceFolders": ["src", "source"],
|
||||
"haxecheckstyle.externalSourceRoots": [],
|
||||
"haxecheckstyle.configurationFile": "checkstyle.json",
|
||||
"haxecheckstyle.codeSimilarityBufferSize": 100,
|
||||
|
|
2
assets
2
assets
|
@ -1 +1 @@
|
|||
Subproject commit 0e2c5bf2134c7e517b70cf74afd58abe5c7b5e50
|
||||
Subproject commit 907015a5cd8617d0febccd4a5237b2a25ff1df61
|
2
hmm.json
2
hmm.json
|
@ -146,7 +146,7 @@
|
|||
"name": "polymod",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "be712450e5d3ba446008884921bb56873b299a64",
|
||||
"ref": "5547763a22858a1f10939e082de421d587c862bf",
|
||||
"url": "https://github.com/larsiusprime/polymod"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -100,8 +100,15 @@ class Main extends Sprite
|
|||
|
||||
// George recommends binding the save before FlxGame is created.
|
||||
Save.load();
|
||||
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen);
|
||||
|
||||
addChild(new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen));
|
||||
// FlxG.game._customSoundTray wants just the class, it calls new from
|
||||
// create() in there, which gets called when it's added to stage
|
||||
// which is why it needs to be added before addChild(game) here
|
||||
@:privateAccess
|
||||
game._customSoundTray = funkin.ui.options.FunkinSoundTray;
|
||||
|
||||
addChild(game);
|
||||
|
||||
#if hxcpp_debug_server
|
||||
trace('hxcpp_debug_server is enabled! You can now connect to the game with a debugger.');
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package funkin.audio;
|
||||
|
||||
#if flash11
|
||||
import flash.media.Sound;
|
||||
import flash.utils.ByteArray;
|
||||
#end
|
||||
import flixel.sound.FlxSound;
|
||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||
import flixel.util.FlxSignal.FlxTypedSignal;
|
||||
import flixel.system.FlxAssets.FlxSoundAsset;
|
||||
import funkin.util.tools.ICloneable;
|
||||
import funkin.data.song.SongData.SongMusicData;
|
||||
|
@ -27,6 +24,25 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
|||
{
|
||||
static final MAX_VOLUME:Float = 1.0;
|
||||
|
||||
/**
|
||||
* An FlxSignal which is dispatched when the volume changes.
|
||||
*/
|
||||
public static var onVolumeChanged(get, never):FlxTypedSignal<Float->Void>;
|
||||
|
||||
static var _onVolumeChanged:Null<FlxTypedSignal<Float->Void>> = null;
|
||||
|
||||
static function get_onVolumeChanged():FlxTypedSignal<Float->Void>
|
||||
{
|
||||
if (_onVolumeChanged == null)
|
||||
{
|
||||
_onVolumeChanged = new FlxTypedSignal<Float->Void>();
|
||||
FlxG.sound.volumeHandler = function(volume:Float) {
|
||||
_onVolumeChanged.dispatch(volume);
|
||||
}
|
||||
}
|
||||
return _onVolumeChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using `FunkinSound.load` will override a dead instance from here rather than creating a new one, if possible!
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,9 @@ package funkin.graphics;
|
|||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.graphics.FlxGraphic;
|
||||
import openfl.display3D.textures.TextureBase;
|
||||
import funkin.graphics.framebuffer.FixedBitmapData;
|
||||
import openfl.display.BitmapData;
|
||||
|
||||
/**
|
||||
* An FlxSprite with additional functionality.
|
||||
|
@ -41,7 +44,7 @@ class FunkinSprite extends FlxSprite
|
|||
*/
|
||||
public static function create(x:Float = 0.0, y:Float = 0.0, key:String):FunkinSprite
|
||||
{
|
||||
var sprite = new FunkinSprite(x, y);
|
||||
var sprite:FunkinSprite = new FunkinSprite(x, y);
|
||||
sprite.loadTexture(key);
|
||||
return sprite;
|
||||
}
|
||||
|
@ -55,7 +58,7 @@ class FunkinSprite extends FlxSprite
|
|||
*/
|
||||
public static function createSparrow(x:Float = 0.0, y:Float = 0.0, key:String):FunkinSprite
|
||||
{
|
||||
var sprite = new FunkinSprite(x, y);
|
||||
var sprite:FunkinSprite = new FunkinSprite(x, y);
|
||||
sprite.loadSparrow(key);
|
||||
return sprite;
|
||||
}
|
||||
|
@ -69,7 +72,7 @@ class FunkinSprite extends FlxSprite
|
|||
*/
|
||||
public static function createPacker(x:Float = 0.0, y:Float = 0.0, key:String):FunkinSprite
|
||||
{
|
||||
var sprite = new FunkinSprite(x, y);
|
||||
var sprite:FunkinSprite = new FunkinSprite(x, y);
|
||||
sprite.loadPacker(key);
|
||||
return sprite;
|
||||
}
|
||||
|
@ -89,6 +92,30 @@ class FunkinSprite extends FlxSprite
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an OpenFL `BitmapData` to this sprite.
|
||||
* @param input The OpenFL `BitmapData` to apply
|
||||
* @return This sprite, for chaining
|
||||
*/
|
||||
public function loadBitmapData(input:BitmapData):FunkinSprite
|
||||
{
|
||||
loadGraphic(input);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an OpenFL `TextureBase` to this sprite.
|
||||
* @param input The OpenFL `TextureBase` to apply
|
||||
* @return This sprite, for chaining
|
||||
*/
|
||||
public function loadTextureBase(input:TextureBase):FunkinSprite
|
||||
{
|
||||
var inputBitmap:FixedBitmapData = FixedBitmapData.fromTexture(input);
|
||||
|
||||
return loadBitmapData(inputBitmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an animated texture (Sparrow atlas spritesheet) as the sprite's texture.
|
||||
* @param key The key of the texture to load.
|
||||
|
@ -119,11 +146,20 @@ class FunkinSprite extends FlxSprite
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the texture with the given key is cached.
|
||||
* @param key The key of the texture to check.
|
||||
* @return Whether the texture is cached.
|
||||
*/
|
||||
public static function isTextureCached(key:String):Bool
|
||||
{
|
||||
return FlxG.bitmap.get(key) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the texture with the given key is cached.
|
||||
* @param key The key of the texture to cache.
|
||||
*/
|
||||
public static function cacheTexture(key:String):Void
|
||||
{
|
||||
// We don't want to cache the same texture twice.
|
||||
|
@ -139,7 +175,7 @@ class FunkinSprite extends FlxSprite
|
|||
}
|
||||
|
||||
// Else, texture is currently uncached.
|
||||
var graphic = flixel.graphics.FlxGraphic.fromAssetKey(key, false, null, true);
|
||||
var graphic:FlxGraphic = FlxGraphic.fromAssetKey(key, false, null, true);
|
||||
if (graphic == null)
|
||||
{
|
||||
FlxG.log.warn('Failed to cache graphic: $key');
|
||||
|
|
|
@ -32,11 +32,11 @@ class FixedBitmapData extends BitmapData
|
|||
public static function fromTexture(texture:TextureBase):FixedBitmapData
|
||||
{
|
||||
if (texture == null) return null;
|
||||
final bitmapData = new FixedBitmapData(texture.__width, texture.__height, true, 0);
|
||||
bitmapData.readable = false;
|
||||
final bitmapData:FixedBitmapData = new FixedBitmapData(texture.__width, texture.__height, true, 0);
|
||||
// bitmapData.readable = false;
|
||||
bitmapData.__texture = texture;
|
||||
bitmapData.__textureContext = texture.__textureContext;
|
||||
bitmapData.image = null;
|
||||
// bitmapData.image = null;
|
||||
return bitmapData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,58 @@
|
|||
package funkin.graphics.video;
|
||||
|
||||
import flixel.FlxBasic;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxSignal.FlxTypedSignal;
|
||||
import funkin.audio.FunkinSound;
|
||||
import openfl.display3D.textures.TextureBase;
|
||||
import openfl.events.NetStatusEvent;
|
||||
import openfl.media.SoundTransform;
|
||||
import openfl.media.Video;
|
||||
import openfl.net.NetConnection;
|
||||
import openfl.net.NetStream;
|
||||
|
||||
/**
|
||||
* Plays a video via a NetStream. Only works on HTML5.
|
||||
* This does NOT replace hxCodec, nor does hxCodec replace this. hxCodec only works on desktop and does not work on HTML5!
|
||||
* This does NOT replace hxCodec, nor does hxCodec replace this.
|
||||
* hxCodec only works on desktop and does not work on HTML5!
|
||||
*/
|
||||
class FlxVideo extends FlxBasic
|
||||
class FlxVideo extends FunkinSprite
|
||||
{
|
||||
var video:Video;
|
||||
var netStream:NetStream;
|
||||
|
||||
public var finishCallback:Void->Void;
|
||||
var videoPath:String;
|
||||
|
||||
/**
|
||||
* Doesn't actually interact with Flixel shit, only just a pleasant to use class
|
||||
* A callback to execute when the video finishes.
|
||||
*/
|
||||
public var finishCallback:Void->Void;
|
||||
|
||||
public function new(videoPath:String)
|
||||
{
|
||||
super();
|
||||
|
||||
this.videoPath = videoPath;
|
||||
|
||||
makeGraphic(2, 2, FlxColor.TRANSPARENT);
|
||||
|
||||
video = new Video();
|
||||
video.x = 0;
|
||||
video.y = 0;
|
||||
video.alpha = 0;
|
||||
|
||||
FlxG.addChildBelowMouse(video);
|
||||
FlxG.game.addChild(video);
|
||||
|
||||
var netConnection = new NetConnection();
|
||||
var netConnection:NetConnection = new NetConnection();
|
||||
netConnection.connect(null);
|
||||
|
||||
netStream = new NetStream(netConnection);
|
||||
netStream.client = {onMetaData: client_onMetaData};
|
||||
netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus);
|
||||
netStream.client = {onMetaData: onClientMetaData};
|
||||
netConnection.addEventListener(NetStatusEvent.NET_STATUS, onNetConnectionNetStatus);
|
||||
netStream.play(videoPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the FlxVideo to pause playback.
|
||||
*/
|
||||
public function pauseVideo():Void
|
||||
{
|
||||
if (netStream != null)
|
||||
|
@ -48,6 +61,9 @@ class FlxVideo extends FlxBasic
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the FlxVideo to resume if it is paused.
|
||||
*/
|
||||
public function resumeVideo():Void
|
||||
{
|
||||
// Resume playing the video.
|
||||
|
@ -57,6 +73,29 @@ class FlxVideo extends FlxBasic
|
|||
}
|
||||
}
|
||||
|
||||
var videoAvailable:Bool = false;
|
||||
var frameTimer:Float;
|
||||
|
||||
static final FRAME_RATE:Float = 60;
|
||||
|
||||
public override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
if (frameTimer >= (1 / FRAME_RATE))
|
||||
{
|
||||
frameTimer = 0;
|
||||
// TODO: We just draw the video buffer to the sprite 60 times a second.
|
||||
// Can we copy the video buffer instead somehow?
|
||||
pixels.draw(video);
|
||||
}
|
||||
|
||||
if (videoAvailable) frameTimer += elapsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the FlxVideo to seek to the beginning.
|
||||
*/
|
||||
public function restartVideo():Void
|
||||
{
|
||||
// Seek to the beginning of the video.
|
||||
|
@ -66,6 +105,9 @@ class FlxVideo extends FlxBasic
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the FlxVideo to end.
|
||||
*/
|
||||
public function finishVideo():Void
|
||||
{
|
||||
netStream.dispose();
|
||||
|
@ -74,15 +116,48 @@ class FlxVideo extends FlxBasic
|
|||
if (finishCallback != null) finishCallback();
|
||||
}
|
||||
|
||||
public function client_onMetaData(metaData:Dynamic)
|
||||
public override function destroy():Void
|
||||
{
|
||||
if (netStream != null)
|
||||
{
|
||||
netStream.dispose();
|
||||
|
||||
if (FlxG.game.contains(video)) FlxG.game.removeChild(video);
|
||||
}
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback executed when the video stream loads.
|
||||
* @param metaData The metadata of the video
|
||||
*/
|
||||
public function onClientMetaData(metaData:Dynamic):Void
|
||||
{
|
||||
video.attachNetStream(netStream);
|
||||
|
||||
video.width = FlxG.width;
|
||||
video.height = FlxG.height;
|
||||
onVideoReady();
|
||||
}
|
||||
|
||||
function netConnection_onNetStatus(event:NetStatusEvent):Void
|
||||
function onVideoReady():Void
|
||||
{
|
||||
video.width = FlxG.width;
|
||||
video.height = FlxG.height;
|
||||
|
||||
videoAvailable = true;
|
||||
|
||||
FunkinSound.onVolumeChanged.add(onVolumeChanged);
|
||||
onVolumeChanged(FlxG.sound.muted ? 0 : FlxG.sound.volume);
|
||||
|
||||
makeGraphic(Std.int(video.width), Std.int(video.height), FlxColor.TRANSPARENT);
|
||||
}
|
||||
|
||||
function onVolumeChanged(volume:Float):Void
|
||||
{
|
||||
netStream.soundTransform = new SoundTransform(volume);
|
||||
}
|
||||
|
||||
function onNetConnectionNetStatus(event:NetStatusEvent):Void
|
||||
{
|
||||
if (event.info.code == 'NetStream.Play.Complete') finishVideo();
|
||||
}
|
||||
|
|
|
@ -193,6 +193,11 @@ class BaseCharacter extends Bopper
|
|||
return _data.death?.cameraOffsets ?? [0.0, 0.0];
|
||||
}
|
||||
|
||||
public function getBaseScale():Float
|
||||
{
|
||||
return _data.scale;
|
||||
}
|
||||
|
||||
public function getDeathCameraZoom():Float
|
||||
{
|
||||
return _data.death?.cameraZoom ?? 1.0;
|
||||
|
@ -260,8 +265,8 @@ class BaseCharacter extends Bopper
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the sprite scale to the appropriate value.
|
||||
* @param scale
|
||||
* Set the character's sprite scale to the appropriate value.
|
||||
* @param scale The desired scale.
|
||||
*/
|
||||
public function setScale(scale:Null<Float>):Void
|
||||
{
|
||||
|
|
|
@ -367,11 +367,14 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
|
||||
/**
|
||||
* List all the difficulties in this song.
|
||||
*
|
||||
* @param variationId Optionally filter by a single variation.
|
||||
* @param variationIds Optionally filter by multiple variations.
|
||||
* @param showHidden Include charts which are not accessible to the player.
|
||||
*
|
||||
* @return The list of difficulties.
|
||||
*/
|
||||
public function listDifficulties(?variationId:String, ?variationIds:Array<String>):Array<String>
|
||||
public function listDifficulties(?variationId:String, ?variationIds:Array<String>, showHidden:Bool = false):Array<String>
|
||||
{
|
||||
if (variationIds == null) variationIds = [];
|
||||
if (variationId != null) variationIds.push(variationId);
|
||||
|
@ -387,6 +390,15 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
return difficulty.difficulty;
|
||||
}).nonNull().unique();
|
||||
|
||||
diffFiltered = diffFiltered.filter(function(diffId:String):Bool {
|
||||
if (showHidden) return true;
|
||||
for (targetVariation in variationIds)
|
||||
{
|
||||
if (isDifficultyVisible(diffId, targetVariation)) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
diffFiltered.sort(SortUtil.defaultsThenAlphabetically.bind(Constants.DEFAULT_DIFFICULTY_LIST));
|
||||
|
||||
return diffFiltered;
|
||||
|
@ -405,6 +417,13 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
return false;
|
||||
}
|
||||
|
||||
public function isDifficultyVisible(diffId:String, variationId:String):Bool
|
||||
{
|
||||
var variation = _metadata.get(variationId);
|
||||
if (variation == null) return false;
|
||||
return variation.playData.difficulties.contains(diffId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the cached chart data for each difficulty of this song.
|
||||
*/
|
||||
|
|
|
@ -109,10 +109,11 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
|
|||
{
|
||||
getBoyfriend().resetCharacter(true);
|
||||
// Reapply the camera offsets.
|
||||
var charData = _data.characters.bf;
|
||||
getBoyfriend().scale.set(charData.scale, charData.scale);
|
||||
getBoyfriend().cameraFocusPoint.x += charData.cameraOffsets[0];
|
||||
getBoyfriend().cameraFocusPoint.y += charData.cameraOffsets[1];
|
||||
var stageCharData:StageDataCharacter = _data.characters.bf;
|
||||
var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale;
|
||||
getBoyfriend().setScale(finalScale);
|
||||
getBoyfriend().cameraFocusPoint.x += stageCharData.cameraOffsets[0];
|
||||
getBoyfriend().cameraFocusPoint.y += stageCharData.cameraOffsets[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -122,19 +123,21 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
|
|||
{
|
||||
getGirlfriend().resetCharacter(true);
|
||||
// Reapply the camera offsets.
|
||||
var charData = _data.characters.gf;
|
||||
getGirlfriend().scale.set(charData.scale, charData.scale);
|
||||
getGirlfriend().cameraFocusPoint.x += charData.cameraOffsets[0];
|
||||
getGirlfriend().cameraFocusPoint.y += charData.cameraOffsets[1];
|
||||
var stageCharData:StageDataCharacter = _data.characters.gf;
|
||||
var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale;
|
||||
getGirlfriend().setScale(finalScale);
|
||||
getGirlfriend().cameraFocusPoint.x += stageCharData.cameraOffsets[0];
|
||||
getGirlfriend().cameraFocusPoint.y += stageCharData.cameraOffsets[1];
|
||||
}
|
||||
if (getDad() != null)
|
||||
{
|
||||
getDad().resetCharacter(true);
|
||||
// Reapply the camera offsets.
|
||||
var charData = _data.characters.dad;
|
||||
getDad().scale.set(charData.scale, charData.scale);
|
||||
getDad().cameraFocusPoint.x += charData.cameraOffsets[0];
|
||||
getDad().cameraFocusPoint.y += charData.cameraOffsets[1];
|
||||
var stageCharData:StageDataCharacter = _data.characters.dad;
|
||||
var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale;
|
||||
getDad().setScale(finalScale);
|
||||
getDad().cameraFocusPoint.x += stageCharData.cameraOffsets[0];
|
||||
getDad().cameraFocusPoint.y += stageCharData.cameraOffsets[1];
|
||||
}
|
||||
|
||||
// Reset positions of named props.
|
||||
|
@ -393,23 +396,23 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
|
|||
#end
|
||||
|
||||
// Apply position and z-index.
|
||||
var charData:StageDataCharacter = null;
|
||||
var stageCharData:StageDataCharacter = null;
|
||||
switch (charType)
|
||||
{
|
||||
case BF:
|
||||
this.characters.set('bf', character);
|
||||
charData = _data.characters.bf;
|
||||
stageCharData = _data.characters.bf;
|
||||
character.flipX = !character.getDataFlipX();
|
||||
character.name = 'bf';
|
||||
character.initHealthIcon(false);
|
||||
case GF:
|
||||
this.characters.set('gf', character);
|
||||
charData = _data.characters.gf;
|
||||
stageCharData = _data.characters.gf;
|
||||
character.flipX = character.getDataFlipX();
|
||||
character.name = 'gf';
|
||||
case DAD:
|
||||
this.characters.set('dad', character);
|
||||
charData = _data.characters.dad;
|
||||
stageCharData = _data.characters.dad;
|
||||
character.flipX = character.getDataFlipX();
|
||||
character.name = 'dad';
|
||||
character.initHealthIcon(true);
|
||||
|
@ -421,15 +424,15 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
|
|||
// This ensures positioning is based on the idle animation.
|
||||
character.resetCharacter(true);
|
||||
|
||||
if (charData != null)
|
||||
if (stageCharData != null)
|
||||
{
|
||||
character.zIndex = charData.zIndex;
|
||||
character.zIndex = stageCharData.zIndex;
|
||||
|
||||
// Start with the per-stage character position.
|
||||
// Subtracting the origin ensures characters are positioned relative to their feet.
|
||||
// Subtracting the global offset allows positioning on a per-character basis.
|
||||
character.x = charData.position[0] - character.characterOrigin.x + character.globalOffsets[0];
|
||||
character.y = charData.position[1] - character.characterOrigin.y + character.globalOffsets[1];
|
||||
character.x = stageCharData.position[0] - character.characterOrigin.x + character.globalOffsets[0];
|
||||
character.y = stageCharData.position[1] - character.characterOrigin.y + character.globalOffsets[1];
|
||||
|
||||
@:privateAccess(funkin.play.stage.Bopper)
|
||||
{
|
||||
|
@ -438,16 +441,17 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements
|
|||
character.originalPosition.y = character.y + character.animOffsets[1];
|
||||
}
|
||||
|
||||
character.scale.set(charData.scale, charData.scale);
|
||||
character.cameraFocusPoint.x += charData.cameraOffsets[0];
|
||||
character.cameraFocusPoint.y += charData.cameraOffsets[1];
|
||||
var finalScale = character.getBaseScale() * stageCharData.scale;
|
||||
character.setScale(finalScale); // Don't use scale.set for characters!
|
||||
character.cameraFocusPoint.x += stageCharData.cameraOffsets[0];
|
||||
character.cameraFocusPoint.y += stageCharData.cameraOffsets[1];
|
||||
|
||||
#if debug
|
||||
// Draw the debug icon at the character's feet.
|
||||
if (charType == BF || charType == DAD)
|
||||
{
|
||||
debugIcon.x = charData.position[0];
|
||||
debugIcon.y = charData.position[1];
|
||||
debugIcon.x = stageCharData.position[0];
|
||||
debugIcon.y = stageCharData.position[1];
|
||||
debugIcon2.x = character.x;
|
||||
debugIcon2.y = character.y;
|
||||
}
|
||||
|
|
147
source/funkin/ui/options/FunkinSoundTray.hx
Normal file
147
source/funkin/ui/options/FunkinSoundTray.hx
Normal file
|
@ -0,0 +1,147 @@
|
|||
package funkin.ui.options;
|
||||
|
||||
import flixel.system.ui.FlxSoundTray;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.system.FlxAssets;
|
||||
import flixel.tweens.FlxEase;
|
||||
import openfl.display.Bitmap;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.utils.Assets;
|
||||
import funkin.util.MathUtil;
|
||||
|
||||
/**
|
||||
* Extends the default flixel soundtray, but with some art
|
||||
* and lil polish!
|
||||
*
|
||||
* Gets added to the game in Main.hx, right after FlxGame is new'd
|
||||
* since it's a Sprite rather than Flixel related object
|
||||
*/
|
||||
class FunkinSoundTray extends FlxSoundTray
|
||||
{
|
||||
var graphicScale:Float = 0.30;
|
||||
var lerpYPos:Float = 0;
|
||||
|
||||
var volumeMaxSound:String;
|
||||
|
||||
public function new()
|
||||
{
|
||||
// calls super, then removes all children to add our own
|
||||
// graphics
|
||||
super();
|
||||
removeChildren();
|
||||
|
||||
var bg:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/volumebox")));
|
||||
bg.scaleX = graphicScale;
|
||||
bg.scaleY = graphicScale;
|
||||
addChild(bg);
|
||||
|
||||
y = -height;
|
||||
visible = false;
|
||||
|
||||
// makes an alpha'd version of all the bars (bar_10.png)
|
||||
var backingBar:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/bars_10")));
|
||||
backingBar.x = 10;
|
||||
backingBar.y = 5;
|
||||
backingBar.scaleX = graphicScale;
|
||||
backingBar.scaleY = graphicScale;
|
||||
addChild(backingBar);
|
||||
backingBar.alpha = 0.4;
|
||||
|
||||
// clear the bars array entirely, it was initialized
|
||||
// in the super class
|
||||
_bars = [];
|
||||
|
||||
// 1...11 due to how block named the assets,
|
||||
// we are trying to get assets bars_1-10
|
||||
for (i in 1...11)
|
||||
{
|
||||
var bar:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/bars_" + i)));
|
||||
bar.x = 10;
|
||||
bar.y = 5;
|
||||
bar.scaleX = graphicScale;
|
||||
bar.scaleY = graphicScale;
|
||||
addChild(bar);
|
||||
_bars.push(bar);
|
||||
}
|
||||
|
||||
y = -height;
|
||||
screenCenter();
|
||||
|
||||
volumeUpSound = Paths.sound("soundtray/Volup");
|
||||
volumeDownSound = Paths.sound("soundtray/Voldown");
|
||||
volumeMaxSound = Paths.sound("soundtray/VolMAX");
|
||||
|
||||
trace("Custom tray added!");
|
||||
}
|
||||
|
||||
override public function update(MS:Float):Void
|
||||
{
|
||||
y = MathUtil.coolLerp(y, lerpYPos, 0.1);
|
||||
|
||||
// Animate sound tray thing
|
||||
if (_timer > 0)
|
||||
{
|
||||
_timer -= (MS / 1000);
|
||||
}
|
||||
else if (y > -height)
|
||||
{
|
||||
lerpYPos = -height - 10;
|
||||
|
||||
if (y <= -height)
|
||||
{
|
||||
visible = false;
|
||||
active = false;
|
||||
|
||||
#if FLX_SAVE
|
||||
// Save sound preferences
|
||||
if (FlxG.save.isBound)
|
||||
{
|
||||
FlxG.save.data.mute = FlxG.sound.muted;
|
||||
FlxG.save.data.volume = FlxG.sound.volume;
|
||||
FlxG.save.flush();
|
||||
}
|
||||
#end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the little volume tray slide out.
|
||||
*
|
||||
* @param up Whether the volume is increasing.
|
||||
*/
|
||||
override public function show(up:Bool = false):Void
|
||||
{
|
||||
_timer = 1;
|
||||
lerpYPos = 10;
|
||||
visible = true;
|
||||
active = true;
|
||||
var globalVolume:Int = Math.round(FlxG.sound.volume * 10);
|
||||
|
||||
if (FlxG.sound.muted)
|
||||
{
|
||||
globalVolume = 0;
|
||||
}
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
var sound = up ? volumeUpSound : volumeDownSound;
|
||||
|
||||
if (globalVolume == 10) sound = volumeMaxSound;
|
||||
|
||||
if (sound != null) FlxG.sound.load(sound).play();
|
||||
}
|
||||
|
||||
for (i in 0..._bars.length)
|
||||
{
|
||||
if (i < globalVolume)
|
||||
{
|
||||
_bars[i].visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bars[i].visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,11 @@ class ReloadAssetsDebugPlugin extends FlxBasic
|
|||
{
|
||||
super.update(elapsed);
|
||||
|
||||
#if html5
|
||||
if (FlxG.keys.justPressed.FIVE && FlxG.keys.pressed.SHIFT)
|
||||
#else
|
||||
if (FlxG.keys.justPressed.F5)
|
||||
#end
|
||||
{
|
||||
funkin.modding.PolymodHandler.forceReloadAssets();
|
||||
|
||||
|
|
Loading…
Reference in a new issue