-
-
Notifications
You must be signed in to change notification settings - Fork 319
Technical Improvements #1 #755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 8 commits
d20e9e3
cd78437
24537d1
ae4ad98
18a88a5
0f7724e
5c899ee
7716ef2
b803496
892e3ac
ed46121
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| package funkin.game; | ||
|
|
||
| import flixel.tweens.misc.VarTween; | ||
| import flixel.tweens.FlxTween; | ||
| import flixel.sound.FlxSound; | ||
| import funkin.backend.scripting.events.gameplay.CountdownEvent; | ||
|
|
||
| enum CountdownAnimationPreset { | ||
|
|
||
| /** | ||
| * The default animation for Codename Engine's countdown. | ||
| */ | ||
| DEFAULT; | ||
|
|
||
| /** | ||
| * The classic animation, similar to Funkin's countdown. | ||
| */ | ||
| CLASSIC; | ||
|
|
||
| /** | ||
| * A more enhanced version of Funkin's countdown animation. | ||
| */ | ||
| BEATING; | ||
|
|
||
| } | ||
|
|
||
| typedef CountdownParams = { | ||
|
|
||
| /** | ||
| * The CountdownEvent to be used. | ||
| */ | ||
| var event:CountdownEvent; | ||
|
|
||
| /** | ||
| * Whether the countdown should be visible or not. | ||
| */ | ||
| var enabled:Bool; | ||
|
|
||
| /** | ||
| * Whether each tick from the countdown should play a sound. | ||
| */ | ||
| var playSound:Bool; | ||
|
|
||
| /** | ||
| * The animation preset to be used for the countdown. | ||
| */ | ||
| var animationPreset:CountdownAnimationPreset; | ||
|
|
||
| /** | ||
| * The duration of the countdown's animation. | ||
| */ | ||
| var duration:Float; | ||
|
|
||
| /** | ||
| * The speed of the countdown's animation. The lower it is, the slower it goes and vice-versa. | ||
| */ | ||
| var speed:Float; | ||
|
|
||
| } | ||
|
|
||
| class Countdown extends FlxTypedSpriteGroup<FlxSprite> { | ||
| public var event:CountdownEvent; | ||
| public var enabled:Bool; | ||
| public var playSound:Bool; | ||
| public var animationPreset:CountdownAnimationPreset; | ||
| public var duration:Float; | ||
| public var speed:Float; | ||
|
|
||
| /** | ||
| * Create a new Countdown component. | ||
| * @param params | ||
| */ | ||
| public function new(params:CountdownParams) { | ||
| super(); | ||
|
|
||
| this.event = params.event; | ||
| this.enabled = params.enabled; | ||
| this.playSound = params.playSound; | ||
| this.animationPreset = params.animationPreset; | ||
| this.duration = params.duration; | ||
| this.speed = params.speed; | ||
|
|
||
| this.__createSprite(); | ||
| } | ||
|
|
||
| @:noPrivateAccess | ||
| private function __createSprite():Void { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this a function? Also why is it private within private access which hscript will bypass
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hello! Sorry if it took a while since I didn't think this'd get really accepted as a pr, hehe. I've been coding Haxe for a bit now, and I had this unnecessary habit of putting @:noPrivateAccess with private functions. I'll remove the annotation real quick. |
||
| if (!this.enabled) { | ||
| return; | ||
| } | ||
|
|
||
| var sprite:FlxSprite = null; | ||
| var sound:FlxSound = null; | ||
| var tween:FlxTween = null; | ||
|
|
||
| if (!this.event.cancelled) { | ||
| if (this.event.spritePath != null) { | ||
| // Add 1.0 to defaultSize if animationPreset is BEATING. | ||
| var defaultSize:Float = this.event.scale; | ||
| var isBeatingPreset:Bool = (this.animationPreset == BEATING); | ||
| var targetSize:Float = defaultSize + ((!isBeatingPreset) ? 0.0 : 0.15); | ||
|
|
||
| var spr = this.event.spritePath; | ||
|
|
||
| if (!Assets.exists(spr)) { | ||
| spr = Paths.image('$spr'); | ||
| } | ||
|
|
||
| sprite = new FunkinSprite().loadAnimatedGraphic(spr); | ||
| sprite.scale.set(targetSize, targetSize); | ||
| sprite.scrollFactor.set(); | ||
| sprite.antialiasing = this.event.antialiasing; | ||
| sprite.updateHitbox(); | ||
| sprite.screenCenter(); | ||
| add(sprite); | ||
|
|
||
| switch(this.animationPreset) { | ||
| case CLASSIC: | ||
| tween = __createTween(sprite, {alpha: 0}, FlxEase.cubeInOut); | ||
| case BEATING: | ||
| tween = __createTween(sprite, {alpha: 0, "scale.x": defaultSize, "scale.y": defaultSize}, FlxEase.expoOut); | ||
| default: // DEFAULT | ||
| tween = __createTween(sprite, {y: sprite.y + 100, alpha: 0}, FlxEase.cubeInOut); | ||
| } | ||
| } | ||
|
|
||
| if (this.event.soundPath != null && this.playSound) { | ||
| var sfx = this.event.soundPath; | ||
| if (!Assets.exists(sfx)) { | ||
| sfx = Paths.sound(sfx); | ||
| } | ||
| sound = FlxG.sound.play(sfx, this.event.volume); | ||
| } | ||
|
|
||
| this.event.sprite = sprite; | ||
| this.event.sound = sound; | ||
| this.event.spriteTween = tween; | ||
| this.event.cancelled = false; | ||
| } | ||
| } | ||
|
|
||
| @:noPrivateAccess | ||
| private function __createTween(sprite:FlxSprite, values:Dynamic, easing:EaseFunction):VarTween { | ||
| return FlxTween.tween(sprite, values, (this.duration / this.speed), { | ||
| ease: easing, | ||
| onComplete: function(twn:FlxTween) { | ||
| sprite.destroy(); | ||
| remove(sprite, true); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -996,50 +996,23 @@ class PlayState extends MusicBeatState | |
| * Creates a fake countdown. | ||
| */ | ||
| public function countdown(swagCounter:Int) { | ||
| var event:CountdownEvent = gameAndCharsEvent("onCountdown", EventManager.get(CountdownEvent).recycle( | ||
| swagCounter, | ||
| 1, | ||
| introSounds[swagCounter], | ||
| introSprites[swagCounter], | ||
| 0.6, true, null, null, null)); | ||
|
|
||
| var sprite:FlxSprite = null; | ||
| var sound:FlxSound = null; | ||
| var tween:FlxTween = null; | ||
|
|
||
| if (!event.cancelled) { | ||
| if (event.spritePath != null) { | ||
| var spr = event.spritePath; | ||
| if (!Assets.exists(spr)) spr = Paths.image('$spr'); | ||
|
|
||
| sprite = new FunkinSprite().loadAnimatedGraphic(spr); | ||
| sprite.scrollFactor.set(); | ||
| sprite.scale.set(event.scale, event.scale); | ||
| sprite.updateHitbox(); | ||
| sprite.screenCenter(); | ||
| sprite.antialiasing = event.antialiasing; | ||
| add(sprite); | ||
| tween = FlxTween.tween(sprite, {y: sprite.y + 100, alpha: 0}, Conductor.crochet / 1000, { | ||
| ease: FlxEase.cubeInOut, | ||
| onComplete: function(twn:FlxTween) | ||
| { | ||
| sprite.destroy(); | ||
| remove(sprite, true); | ||
| } | ||
| }); | ||
| } | ||
| if (event.soundPath != null) { | ||
| var sfx = event.soundPath; | ||
| if (!Assets.exists(sfx)) sfx = Paths.sound(sfx); | ||
| sound = FlxG.sound.play(sfx, event.volume); | ||
| } | ||
| } | ||
| event.sprite = sprite; | ||
| event.sound = sound; | ||
| event.spriteTween = tween; | ||
| event.cancelled = false; | ||
| var countdown:Countdown = new Countdown({ | ||
| event: gameAndCharsEvent("onCountdown", EventManager.get(CountdownEvent).recycle( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do wish to address this particular hunk. What would be the use case of not being able to manage most of the properties of
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, yeah, now that I think about it, it does feel like it's set up a little oddly. I thought of making an event as a parameter and just handling it (the event) within the Countdown class itself. Now that this has been brought up I start to wonder whether or not it'll break some backend functionality but it seemed to work as intended. Reverting back to old CNE code where it has an event variable (in PlayState's It's an odd setup I know 😅, and my apologies if I replied late. I was asleep by that time. I'll try coming up with an alternative solution later. For now, this is all I've really got. |
||
| swagCounter, | ||
| 1, | ||
| introSounds[swagCounter], | ||
| introSprites[swagCounter], | ||
| 0.6, true, null, null, null)), | ||
| enabled: true, | ||
| playSound: true, | ||
| animationPreset: DEFAULT, | ||
| duration: (Conductor.crochet / 1000), | ||
| speed: 1.0 | ||
| }); | ||
| countdown.cameras = [camHUD]; | ||
| add(countdown); | ||
|
|
||
| gameAndCharsEvent("onPostCountdown", event); | ||
| gameAndCharsEvent("onPostCountdown", countdown.event); | ||
| } | ||
|
|
||
| @:dox(hide) function startSong():Void | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find these comments unnecessary