This commit is contained in:
CatWindow 2026-08-14 22:39:56 +03:00
parent ca7e767205
commit 6d2a060f87
5 changed files with 154 additions and 25 deletions

View file

@ -44,18 +44,28 @@ static VALUE rb_playbackPlay(int argc, VALUE *argv, VALUE self) {
return Qnil;
}
static VALUE rb_playbackStop(VALUE self){
static VALUE rb_playbackStop(VALUE self) {
PLAYBACK
pb->stop();
return Qnil;
}
static VALUE rb_playbackPlaying(VALUE self){
static VALUE rb_playbackPlaying(VALUE self) {
PLAYBACK
return rb_bool_new(pb->isPlaying());
}
static VALUE rb_playbackLength(VALUE self) {
PLAYBACK
return INT2FIX(pb->getLength());
}
static VALUE rb_playbackLengthNormalized(VALUE self) {
PLAYBACK
return DBL2NUM(pb->getLengthNormalized());
}
static VALUE rb_playbackAddTag(int argc, VALUE *argv, VALUE self) {
char* c_str;
rb_get_args(argc, argv, c_str RB_ARG_END);
@ -141,15 +151,15 @@ static VALUE rb_playbackGetStartSample(VALUE self) {
return INT2FIX(pb->startSample);
}
static VALUE rb_playbackSetMaxSamples(VALUE self, VALUE samples) {
static VALUE rb_playbackSetMaxSample(VALUE self, VALUE samples) {
PLAYBACK
pb->maxSamples = samples;
pb->maxSample = samples;
return Qnil;
}
static VALUE rb_playbackGetMaxSamples(VALUE self) {
static VALUE rb_playbackGetMaxSample(VALUE self) {
PLAYBACK
return INT2FIX(pb->maxSamples);
return INT2FIX(pb->maxSample);
}
static VALUE rb_playbackSetPosition(VALUE self, VALUE position){
@ -211,6 +221,9 @@ void audioPlaybackBindingInit(){
rb_define_method(audioplayback_klass, "playing", RUBY_METHOD_FUNC(rb_playbackPlaying), 0);
rb_define_method(audioplayback_klass, "length", RUBY_METHOD_FUNC(rb_playbackLength), 0);
rb_define_method(audioplayback_klass, "length_normalized", RUBY_METHOD_FUNC(rb_playbackLengthNormalized), 0);
rb_define_method(audioplayback_klass, "add_tag", RUBY_METHOD_FUNC(rb_playbackAddTag), -1);
rb_define_method(audioplayback_klass, "remove_tag", RUBY_METHOD_FUNC(rb_playbackRemoveTag), -1);
rb_define_method(audioplayback_klass, "clear_tags", RUBY_METHOD_FUNC(rb_playbackClearTags), 0);
@ -227,10 +240,10 @@ void audioPlaybackBindingInit(){
rb_define_method(audioplayback_klass, "pitch=", RUBY_METHOD_FUNC(rb_playbackSetPitch), 1);
rb_define_method(audioplayback_klass, "pitch", RUBY_METHOD_FUNC(rb_playbackGetPitch), 0);
rb_define_method(audioplayback_klass, "start_sample=", RUBY_METHOD_FUNC(rb_playbackSetStartSample), 1);
rb_define_method(audioplayback_klass, "start_sample", RUBY_METHOD_FUNC(rb_playbackGetStartSample), 0);
rb_define_method(audioplayback_klass, "max_samples=", RUBY_METHOD_FUNC(rb_playbackSetMaxSamples), 1);
rb_define_method(audioplayback_klass, "max_samples", RUBY_METHOD_FUNC(rb_playbackGetMaxSamples), 0);
rb_define_method(audioplayback_klass, "start_frame=", RUBY_METHOD_FUNC(rb_playbackSetStartSample), 1);
rb_define_method(audioplayback_klass, "start_frame", RUBY_METHOD_FUNC(rb_playbackGetStartSample), 0);
rb_define_method(audioplayback_klass, "max_frame=", RUBY_METHOD_FUNC(rb_playbackSetMaxSample), 1);
rb_define_method(audioplayback_klass, "max_frame", RUBY_METHOD_FUNC(rb_playbackGetMaxSample), 0);
rb_define_method(audioplayback_klass, "position=", RUBY_METHOD_FUNC(rb_playbackSetPosition), 1);
rb_define_method(audioplayback_klass, "position", RUBY_METHOD_FUNC(rb_playbackGetPosition), 0);

View file

@ -1,9 +1,9 @@
class Scene_OF
BPM = 135
WAIT_TIME = 1.0 * (BPM / 60.0) * Graphics.frame_rate
BPM_TIME = 1.0 / (BPM / 60.0) * Graphics.frame_rate * 2
BUMP_SCALE = 1.2
BUMP_RETURN_SPEED = 0.2
BUMP_SCALE = 1.07
BUMP_RETURN_SPEED = 0.1
ARROW_SIZE = 32
ARROW_SCALE = 2
@ -11,6 +11,8 @@ class Scene_OF
ARROWS_TOP_MARGIN = 32
ARROWS_SIDES_MARGIN = 48
ARROWS_SPEED = 10
SPRITES = {
:cat_base_arrow_left => Rect.new(0, 0, 32, 32), :cat_base_arrow_down => Rect.new(32, 0, 32, 32), :cat_base_arrow_up => Rect.new(64, 0, 32, 32), :cat_base_arrow_right => Rect.new(96, 0, 32, 32),
:cat_pressed_arrow_left => Rect.new(0, 32, 32, 32), :cat_pressed_arrow_down => Rect.new(32, 32, 32, 32), :cat_pressed_arrow_up => Rect.new(64, 32, 32, 32), :cat_pressed_arrow_right => Rect.new(96, 32, 32, 32),
@ -61,9 +63,22 @@ class Scene_OF
def main
Audio.bgm_stop
@arrows_states = [false, false, false, false]
@instruments = Audio.create_sound("Audio/.cats", false, Audio.music_group)
length = @instruments.length
@instruments.max_frame = length / 3
@voice_cat = Audio.create_sound("Audio/.cats", false, Audio.music_group)
@voice_cat.start_frame = length / 6
@voice_cat.max_frame = length / 3
@voice_niko = Audio.create_sound("Audio/.cats", false, Audio.music_group)
@voice_niko.start_frame = length / 3
@voice_niko.max_frame = length / 3 * 2
@viewport_ui = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport_ui.ox = -Graphics.width / 2
@viewport_ui.oy = -Graphics.height / 2
@viewport_arrows = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport_ui.ox = @viewport_arrows.ox = -Graphics.width / 2
@viewport_ui.oy = @viewport_arrows.oy = -Graphics.height / 2
@spritesheet = RPG::Cache.misc(".cats")
@player_arrows = []
@ -86,10 +101,21 @@ class Scene_OF
@cat_arrows << cat_arrow
end
@bump_timeout = WAIT_TIME
@bst_debug = Sprite.new(@viewport_ui)
@bst_debug.bitmap = Bitmap.new(300, 40)
@total_time = 0
@bump_timeout = 0
make_mapping
# Execute transition
Graphics.transition(40)
@instruments.play
@voice_cat.play
@voice_niko.play
# Main loop
while true
# Update game screen
@ -109,14 +135,37 @@ class Scene_OF
end
def update
@total_time += 1
# fl studio b:s:t :3
beat = (@total_time / BPM_TIME / 2).to_i + 1
step = (@total_time / BPM_TIME * 15 / 2).to_i % 15 + 1
tick = (@total_time / BPM_TIME * 24 * 15 / 2).to_i % 24
@bst_debug.bitmap.clear
@bst_debug.bitmap.draw_text(Rect.new(0, 0, 300, 40), "#{beat} : #{step} : #{tick}")
@viewport_arrows.oy += ARROWS_SPEED
@bump_timeout -= 1
if @bump_timeout <= 0
@bump_timeout += WAIT_TIME
@viewport_ui.scale_x = BUMP_SCALE
@viewport_ui.scale_y = BUMP_SCALE
@bump_timeout += BPM_TIME
@viewport_arrows.scale_x = @viewport_ui.scale_x = BUMP_SCALE
@viewport_arrows.scale_y = @viewport_ui.scale_y = BUMP_SCALE
end
@viewport_arrows.scale_x = @viewport_ui.scale_x = @viewport_ui.scale_x * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED
@viewport_arrows.scale_y = @viewport_ui.scale_y = @viewport_ui.scale_y * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED
# player
for i in 1..4
mapped = map_input(i * 2)
is_pressed = Input.press?(i * 2)
if @arrows_states[mapped] != is_pressed
@arrows_states[mapped] = is_pressed
@player_arrows[mapped].bitmap.clear
@player_arrows[mapped].bitmap.stretch_blt(Rect.new(0, 0, ARROW_SIZE, ARROW_SIZE), @spritesheet, SPRITES[PLAYER_ARROWS_SPRITES[@arrows_states[mapped] ? :pressed : :base][mapped]])
end
end
@viewport_ui.scale_x = @viewport_ui.scale_x * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED
@viewport_ui.scale_y = @viewport_ui.scale_y * (1.0 - BUMP_RETURN_SPEED) + BUMP_RETURN_SPEED
end
def map_input(input)
@ -131,6 +180,53 @@ class Scene_OF
2
end
end
def make_mapping
@cat_flying_arrows = []
@player_flying_arrows = []
#beat = (@total_time / BPM_TIME / 2).to_i + 1
#step = (@total_time / BPM_TIME * 15 / 2).to_i % 15 + 1
#tick = (@total_time / BPM_TIME * 24 * 15 / 2).to_i % 24
SONG_MAPPING.each do |line_data|
beat = line_data[1]
step = line_data[2]
tick = line_data[3]
for i in 0..3
if line_data[0][i] == '#'
arrow = make_arrow(i, true)
arrow.x = ARROWS_SIDES_MARGIN + (ARROW_SIZE * ARROW_SCALE + ARROWS_PADDING) * i - Graphics.width / 2
arrow.y = ARROWS_TOP_MARGIN - Graphics.height / 2 +
(beat - 1) * 2 * BPM_TIME * ARROWS_SPEED +
(step - 1) / 15.0 * 2 * BPM_TIME * ARROWS_SPEED +
(tick) / 24.0 / 15.0 * 2 * BPM_TIME * ARROWS_SPEED
@cat_flying_arrows << arrow
end
end
end
end
def make_arrow(direction, meow)
arrow = Sprite.new(@viewport_arrows)
arrow.bitmap = Bitmap.new(ARROW_SIZE, ARROW_SIZE)
arrow.bitmap.stretch_blt(Rect.new(0, 0, ARROW_SIZE, ARROW_SIZE), @spritesheet, SPRITES[(meow ? CAT_ARROWS_SPRITES : PLAYER_ARROWS_SPRITES)[:target][direction]])
arrow.zoom_x = arrow.zoom_y = ARROW_SCALE
arrow
end
SONG_MAPPING = [
#arrows, B, S, T
["# | ", 5, 1, 0],
[" # | ", 5, 3, 0],
[" # | ", 5, 5, 0],
[" #| ", 5, 9, 0],
[" # | ", 5, 13, 0],
["# | ", 6, 1, 0],
[" # | ", 6, 3, 0],
[" # | ", 6, 5, 0],
[" # | ", 6, 9, 0],
["# | ", 6, 13, 0],
]
end
# ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

View file

@ -239,10 +239,10 @@ module Script
end
def self.countdown_update_rue
def self.reflection_update(npc_id, offset_x = 0, offset_y = 0, reverse_x = false, reverse_y = false)
return cdown_update(0)
end
def self.reflection_update(npc_id, offset_x = 0, offset_y = 0, reverse_x = false, reverse_y = false)
event = $game_map.events[npc_id]
event.real_x = reverse_x ? offset_x * 128 - $game_player.real_x : $game_player.real_x + offset_x * 128
event.real_y = reverse_y ? offset_y * 128 - $game_player.real_y : $game_player.real_y + offset_y * 128

View file

@ -112,6 +112,23 @@ bool AudioPlayback::isPlaying() const {
return p_track && MIX_TrackPlaying(p_track);
}
long AudioPlayback::getLength() const {
if (p_source)
return MIX_GetAudioDuration(p_source->getAudio());
return 0.0;
}
double AudioPlayback::getLengthNormalized() const {
if (p_source)
{
MIX_Audio* audio = p_source->getAudio();
SDL_AudioSpec spec;
if (MIX_GetAudioFormat(audio, &spec))
return static_cast<double>(MIX_GetAudioDuration(audio)) / static_cast<double>(spec.freq);
}
return 0.0;
}
void AudioPlayback::addTag(std::string tagName) {
if (!p_track)
return;
@ -253,7 +270,7 @@ bool AudioPlayback::fadeIn(double time) {
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetNumberProperty(props, MIX_PROP_PLAY_FADE_IN_MILLISECONDS_NUMBER, time * 1000.0);
SDL_SetNumberProperty(props, MIX_PROP_PLAY_START_FRAME_NUMBER, startSample);
SDL_SetNumberProperty(props, MIX_PROP_PLAY_MAX_FRAME_NUMBER, maxSamples);
SDL_SetNumberProperty(props, MIX_PROP_PLAY_MAX_FRAME_NUMBER, maxSample);
if (result)
{
result = MIX_PlayTrack(p_track, props);

View file

@ -15,8 +15,11 @@ public:
AudioPlayback(MIX_Mixer* mixer, MIX_Audio* audio, AudioGroup* group);
~AudioPlayback();
int startSample = 0;
int maxSamples = -1;
long startSample = 0;
long maxSample = -1;
long getLength() const;
double getLengthNormalized() const;
bool initialize(MIX_Mixer* mixer, AudioSource* source, AudioGroup* group);
bool initialize(MIX_Mixer* mixer, MIX_Audio* audio, AudioGroup* group);