mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 03:30:13 +01:00
Fix other game modes
This commit is contained in:
@@ -225,6 +225,13 @@ class TextureWrapper:
|
|||||||
tex_object.y[index] += distance
|
tex_object.y[index] += distance
|
||||||
logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}")
|
logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}")
|
||||||
|
|
||||||
|
def clear_screen(self, color: Color):
|
||||||
|
if isinstance(color, tuple):
|
||||||
|
clear_color = [color[0], color[1], color[2], color[3]]
|
||||||
|
else:
|
||||||
|
clear_color = [color.r, color.g, color.b, color.a]
|
||||||
|
ray.ClearBackground(clear_color)
|
||||||
|
|
||||||
def _draw_texture_untyped(self, subset: str, texture: str, color: tuple[int, int, int, int], frame: int, scale: float, center: bool,
|
def _draw_texture_untyped(self, subset: str, texture: str, color: tuple[int, int, int, int], frame: int, scale: float, center: bool,
|
||||||
mirror: str, x: float, y: float, x2: float, y2: float,
|
mirror: str, x: float, y: float, x2: float, y2: float,
|
||||||
origin: tuple[float, float], rotation: float, fade: float,
|
origin: tuple[float, float], rotation: float, fade: float,
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class DanGameScreen(GameScreen):
|
|||||||
song, genre_index, difficulty, level = songs[self.song_index]
|
song, genre_index, difficulty, level = songs[self.song_index]
|
||||||
session_data.selected_difficulty = difficulty
|
session_data.selected_difficulty = difficulty
|
||||||
self.player_1.difficulty = difficulty
|
self.player_1.difficulty = difficulty
|
||||||
self.tja = TJAParser(song.file_path, start_delay=self.start_delay, distance=tex.screen_width - GameScreen.JUDGE_X)
|
self.tja = TJAParser(song.file_path, start_delay=self.start_delay)
|
||||||
if self.song_music is not None:
|
if self.song_music is not None:
|
||||||
audio.unload_music_stream(self.song_music)
|
audio.unload_music_stream(self.song_music)
|
||||||
self.song_music = None
|
self.song_music = None
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import math
|
||||||
from collections import deque
|
from collections import deque
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -9,7 +10,7 @@ from libs.animation import Animation
|
|||||||
from libs.audio import audio
|
from libs.audio import audio
|
||||||
from libs.background import Background
|
from libs.background import Background
|
||||||
from libs.global_data import Modifiers, PlayerNum, global_data
|
from libs.global_data import Modifiers, PlayerNum, global_data
|
||||||
from libs.tja import Balloon, Drumroll, Note, NoteType, TJAParser, apply_modifiers
|
from libs.tja import Balloon, Drumroll, NoteType, TJAParser, TimelineObject, apply_modifiers
|
||||||
from libs.utils import get_current_ms
|
from libs.utils import get_current_ms
|
||||||
from libs.texture import tex
|
from libs.texture import tex
|
||||||
from scenes.game import DrumHitEffect, DrumType, GameScreen, JudgeCounter, LaneHitEffect, Player, Side
|
from scenes.game import DrumHitEffect, DrumType, GameScreen, JudgeCounter, LaneHitEffect, Player, Side
|
||||||
@@ -23,29 +24,28 @@ class PracticeGameScreen(GameScreen):
|
|||||||
|
|
||||||
def init_tja(self, song: Path):
|
def init_tja(self, song: Path):
|
||||||
"""Initialize the TJA file"""
|
"""Initialize the TJA file"""
|
||||||
self.tja = TJAParser(song, start_delay=self.start_delay, distance=tex.screen_width - GameScreen.JUDGE_X)
|
self.tja = TJAParser(song, start_delay=self.start_delay)
|
||||||
self.scrobbling_tja = TJAParser(song, start_delay=self.start_delay, distance=tex.screen_width - GameScreen.JUDGE_X)
|
self.scrobbling_tja = TJAParser(song, start_delay=self.start_delay)
|
||||||
global_data.session_data[global_data.player_num].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
|
global_data.session_data[global_data.player_num].song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
|
||||||
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None:
|
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None:
|
||||||
self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song')
|
self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song')
|
||||||
self.player_1 = PracticePlayer(self.tja, global_data.player_num, global_data.session_data[global_data.player_num].selected_difficulty, False, global_data.modifiers[global_data.player_num])
|
self.player_1 = PracticePlayer(self.tja, global_data.player_num, global_data.session_data[global_data.player_num].selected_difficulty, False, global_data.modifiers[global_data.player_num])
|
||||||
notes, branch_m, branch_e, branch_n = self.tja.notes_to_position(self.player_1.difficulty)
|
notes, branch_m, branch_e, branch_n = self.tja.notes_to_position(self.player_1.difficulty)
|
||||||
|
self.scrobble_timeline = notes.timeline
|
||||||
_, self.scrobble_note_list, self.bars = apply_modifiers(notes, self.player_1.modifiers)
|
_, self.scrobble_note_list, self.bars = apply_modifiers(notes, self.player_1.modifiers)
|
||||||
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
|
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
|
||||||
self.scrobble_index = 0
|
self.scrobble_index = 0
|
||||||
self.scrobble_time = self.bars[self.scrobble_index].hit_ms
|
self.scrobble_time = self.bars[self.scrobble_index].hit_ms
|
||||||
self.scrobble_move = Animation.create_move(200, total_distance=0)
|
self.scrobble_move = Animation.create_move(200, total_distance=0)
|
||||||
|
|
||||||
self.markers = self.get_gogotime_markers(self.scrobble_note_list)
|
self.markers = self.get_gogotime_markers(self.scrobble_timeline)
|
||||||
|
|
||||||
def get_gogotime_markers(self, note_list: deque[Note | Drumroll | Balloon]):
|
def get_gogotime_markers(self, timeline: list[TimelineObject]):
|
||||||
marker_list = []
|
marker_list = []
|
||||||
for i, note in enumerate(note_list):
|
for obj in timeline:
|
||||||
if i == 0 and note.gogo_time:
|
if hasattr(obj, 'gogo_time'):
|
||||||
marker_list.append(note.hit_ms)
|
if obj.gogo_time:
|
||||||
elif i > 0 and note.gogo_time:
|
marker_list.append(obj.hit_ms)
|
||||||
if not note_list[i-1].gogo_time:
|
|
||||||
marker_list.append(note.hit_ms)
|
|
||||||
return marker_list
|
return marker_list
|
||||||
|
|
||||||
def pause_song(self):
|
def pause_song(self):
|
||||||
@@ -120,7 +120,7 @@ class PracticeGameScreen(GameScreen):
|
|||||||
elif ray.is_key_pressed(ray.KeyboardKey.KEY_RIGHT):
|
elif ray.is_key_pressed(ray.KeyboardKey.KEY_RIGHT):
|
||||||
self.scrobble_index = (self.scrobble_index + 1) % len(self.bars)
|
self.scrobble_index = (self.scrobble_index + 1) % len(self.bars)
|
||||||
|
|
||||||
time_difference = self.bars[self.scrobble_index].load_ms - self.bars[old_index].load_ms
|
time_difference = self.bars[self.scrobble_index].hit_ms - self.bars[old_index].hit_ms
|
||||||
|
|
||||||
self.scrobble_move = Animation.create_move(400, total_distance=time_difference, ease_out='quadratic')
|
self.scrobble_move = Animation.create_move(400, total_distance=time_difference, ease_out='quadratic')
|
||||||
self.scrobble_move.start()
|
self.scrobble_move.start()
|
||||||
@@ -149,50 +149,52 @@ class PracticeGameScreen(GameScreen):
|
|||||||
|
|
||||||
return self.global_keys()
|
return self.global_keys()
|
||||||
|
|
||||||
def get_position_x(self, width: int, current_ms: float, load_ms: float, pixels_per_frame: float) -> int:
|
def get_position_x(self, note, current_ms):
|
||||||
"""Calculates the x-coordinate of a note based on its load time and current time"""
|
speedx = note.bpm / 240000 * note.scroll_x * (tex.screen_width - GameScreen.JUDGE_X)
|
||||||
if self.paused:
|
return (GameScreen.JUDGE_X + (note.hit_ms - current_ms) * speedx) - self.scrobble_move.attribute
|
||||||
time_diff = load_ms - self.scrobble_time - self.scrobble_move.attribute
|
|
||||||
else:
|
|
||||||
time_diff = load_ms - current_ms
|
|
||||||
return int(width + pixels_per_frame * 0.06 * time_diff - (tex.textures["notes"]["1"].width//2))
|
|
||||||
|
|
||||||
def get_position_y(self, current_ms: float, load_ms: float, pixels_per_frame: float, pixels_per_frame_x) -> int:
|
|
||||||
"""Calculates the y-coordinate of a note based on its load time and current time"""
|
|
||||||
time_diff = load_ms - current_ms
|
|
||||||
return int((pixels_per_frame * 0.06 * time_diff) + ((self.tja.distance * pixels_per_frame) / pixels_per_frame_x))
|
|
||||||
|
|
||||||
def draw_drumroll(self, current_ms: float, head: Drumroll, current_eighth: int, index: int):
|
def get_position_y(self, note, current_ms):
|
||||||
|
speedy = note.bpm / 240000 * note.scroll_y * ((tex.screen_width - GameScreen.JUDGE_X)/tex.screen_width) * tex.screen_width
|
||||||
|
return (note.hit_ms - current_ms) * speedy
|
||||||
|
|
||||||
|
def draw_drumroll(self, current_ms: float, head: Drumroll):
|
||||||
"""Draws a drumroll in the player's lane"""
|
"""Draws a drumroll in the player's lane"""
|
||||||
start_position = self.get_position_x(tex.screen_width, current_ms, head.load_ms, head.pixels_per_frame_x)
|
start_position = self.get_position_x(head, current_ms)
|
||||||
tail = next((note for note in self.scrobble_note_list if note.index == index+1), self.scrobble_note_list[index+1])
|
tail = next((note for note in self.scrobble_note_list if note.type == NoteType.TAIL and note.index > head.index), self.scrobble_note_list[1])
|
||||||
is_big = int(head.type == NoteType.ROLL_HEAD_L)
|
is_big = int(head.type == NoteType.ROLL_HEAD_L)
|
||||||
end_position = self.get_position_x(tex.screen_width, current_ms, tail.load_ms, tail.pixels_per_frame_x)
|
end_position = self.get_position_x(tail, current_ms)
|
||||||
length = end_position - start_position
|
length = end_position - start_position
|
||||||
color = ray.Color(255, head.color, head.color, 255)
|
color = ray.Color(255, head.color, head.color, 255)
|
||||||
y = tex.skin_config["notes"].y
|
y = tex.skin_config["notes"].y + self.get_position_y(head, current_ms)
|
||||||
moji_y = tex.skin_config["moji"].y
|
moji_y = tex.skin_config["moji"].y
|
||||||
moji_x = tex.skin_config["moji"].x
|
|
||||||
if head.display:
|
if head.display:
|
||||||
if length > 0:
|
tex.draw_texture('notes', "8", frame=is_big, x=start_position, y=y, x2=length+tex.skin_config["drumroll_width_offset"].width, color=color)
|
||||||
tex.draw_texture('notes', "8", frame=is_big, x=start_position+(tex.textures["notes"]["8"].width//2), y=y, x2=length+tex.skin_config["drumroll_width_offset"].width, color=color)
|
if is_big:
|
||||||
if is_big:
|
tex.draw_texture('notes', "drumroll_big_tail", x=end_position, y=y, color=color)
|
||||||
tex.draw_texture('notes', "drumroll_big_tail", x=end_position+tex.textures["notes"]["drumroll_big_tail"].width//2, y=y, color=color)
|
else:
|
||||||
else:
|
tex.draw_texture('notes', "drumroll_tail", x=end_position, y=y, color=color)
|
||||||
tex.draw_texture('notes', "drumroll_tail", x=end_position+tex.textures["notes"]["drumroll_tail"].width//2, y=y, color=color)
|
tex.draw_texture('notes', str(head.type), x=start_position - tex.textures["notes"]["1"].width//2, y=y, color=color)
|
||||||
tex.draw_texture('notes', str(head.type), frame=current_eighth % 2, x=start_position, y=y, color=color)
|
|
||||||
|
|
||||||
tex.draw_texture('notes', 'moji_drumroll_mid', x=start_position + tex.skin_config["moji_drumroll"].x, y=moji_y, x2=length)
|
tex.draw_texture('notes', 'moji_drumroll_mid', x=start_position, y=moji_y, x2=length)
|
||||||
tex.draw_texture('notes', 'moji', frame=head.moji, x=start_position - moji_x, y=moji_y)
|
tex.draw_texture('notes', 'moji', frame=head.moji, x=start_position - (tex.textures["notes"]["moji"].width//2), y=moji_y)
|
||||||
tex.draw_texture('notes', 'moji', frame=tail.moji, x=end_position - tex.skin_config["moji_drumroll"].width, y=moji_y)
|
tex.draw_texture('notes', 'moji', frame=tail.moji, x=end_position - (tex.textures["notes"]["moji"].width//2), y=moji_y)
|
||||||
|
|
||||||
def draw_balloon(self, current_ms: float, head: Balloon, current_eighth: int, index: int):
|
def draw_balloon(self, current_ms: float, head: Balloon):
|
||||||
"""Draws a balloon in the player's lane"""
|
"""Draws a balloon in the player's lane"""
|
||||||
offset = tex.skin_config["balloon_offset"].x
|
offset = tex.skin_config["balloon_offset"].x
|
||||||
start_position = self.get_position_x(tex.screen_width, current_ms, head.load_ms, head.pixels_per_frame_x)
|
if hasattr(head, 'sudden_appear_ms') and hasattr(head, 'sudden_moving_ms'):
|
||||||
tail = next((note for note in self.scrobble_note_list if note.index == index+1), self.scrobble_note_list[index+1])
|
appear_ms = head.hit_ms - head.sudden_appear_ms
|
||||||
end_position = self.get_position_x(tex.screen_width, current_ms, tail.load_ms, tail.pixels_per_frame_x)
|
moving_start_ms = head.hit_ms - head.sudden_moving_ms
|
||||||
pause_position = tex.skin_config["balloon_pause_position"].x
|
if current_ms < appear_ms:
|
||||||
|
return
|
||||||
|
if current_ms < moving_start_ms:
|
||||||
|
current_ms = moving_start_ms
|
||||||
|
start_position = self.get_position_x(head, current_ms)
|
||||||
|
tail = next((note for note in self.scrobble_note_list if note.type == NoteType.TAIL and note.index > head.index), self.scrobble_note_list[1])
|
||||||
|
end_position = self.get_position_x(tail, current_ms)
|
||||||
|
pause_position = GameScreen.JUDGE_X
|
||||||
|
y = tex.skin_config["notes"].y + self.get_position_y(head, current_ms)
|
||||||
if current_ms >= tail.hit_ms:
|
if current_ms >= tail.hit_ms:
|
||||||
position = end_position
|
position = end_position
|
||||||
elif current_ms >= head.hit_ms:
|
elif current_ms >= head.hit_ms:
|
||||||
@@ -200,61 +202,53 @@ class PracticeGameScreen(GameScreen):
|
|||||||
else:
|
else:
|
||||||
position = start_position
|
position = start_position
|
||||||
if head.display:
|
if head.display:
|
||||||
tex.draw_texture('notes', str(head.type), frame=current_eighth % 2, x=position-offset, y=tex.skin_config["notes"].y)
|
tex.draw_texture('notes', str(head.type), x=position-offset - tex.textures["notes"]["1"].width//2, y=y)
|
||||||
tex.draw_texture('notes', '10', frame=current_eighth % 2, x=position-offset+tex.textures["notes"]["10"].width, y=tex.skin_config["notes"].y)
|
tex.draw_texture('notes', '10', x=position-offset+tex.textures["notes"]["10"].width - tex.textures["notes"]["1"].width//2, y=y)
|
||||||
|
|
||||||
def draw_scrobble_list(self):
|
def draw_bars(self, current_ms: float, current_bars):
|
||||||
bar_draws = []
|
"""Draw bars in the player's lane"""
|
||||||
for bar in reversed(self.bars):
|
if not current_bars:
|
||||||
|
return
|
||||||
|
|
||||||
|
for bar in reversed(current_bars):
|
||||||
if not bar.display:
|
if not bar.display:
|
||||||
continue
|
continue
|
||||||
x_position = self.get_position_x(tex.screen_width, self.current_ms, bar.load_ms, bar.pixels_per_frame_x)
|
x_position = self.get_position_x(bar, current_ms)
|
||||||
y_position = self.get_position_y(self.current_ms, bar.load_ms, bar.pixels_per_frame_y, bar.pixels_per_frame_x)
|
y_position = self.get_position_y(bar, current_ms)
|
||||||
if x_position < tex.skin_config["past_judge_circle"].x or x_position > tex.screen_width:
|
if y_position != 0:
|
||||||
continue
|
angle = math.degrees(math.atan2(bar.scroll_y, bar.scroll_x))
|
||||||
if hasattr(bar, 'is_branch_start'):
|
|
||||||
frame = 1
|
|
||||||
else:
|
else:
|
||||||
frame = 0
|
angle = 0
|
||||||
bar_draws.append((str(bar.type), frame, x_position + tex.skin_config["moji_drumroll"].x, y_position+tex.skin_config["moji_drumroll"].y))
|
tex.draw_texture('notes', str(bar.type), x=x_position+tex.skin_config["moji_drumroll"].x- (tex.textures["notes"]["1"].width//2), y=y_position+tex.skin_config["moji_drumroll"].y, rotation=angle)
|
||||||
|
|
||||||
for bar_type, frame, x, y in bar_draws:
|
def draw_notes(self, current_ms: float, current_notes_draw):
|
||||||
tex.draw_texture('notes', bar_type, frame=frame, x=x, y=y)
|
"""Draw notes in the player's lane"""
|
||||||
|
if not current_notes_draw:
|
||||||
|
return
|
||||||
|
|
||||||
for note in reversed(self.scrobble_note_list):
|
for note in reversed(current_notes_draw):
|
||||||
if note.type == NoteType.TAIL:
|
if note.type == NoteType.TAIL:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
x_position = self.get_position_x(note, current_ms)
|
||||||
|
y_position = self.get_position_y(note, current_ms)
|
||||||
if isinstance(note, Drumroll):
|
if isinstance(note, Drumroll):
|
||||||
self.draw_drumroll(self.current_ms, note, 0, note.index)
|
self.draw_drumroll(current_ms, note)
|
||||||
elif isinstance(note, Balloon) and not note.is_kusudama:
|
elif isinstance(note, Balloon) and not note.is_kusudama:
|
||||||
x_position = self.get_position_x(tex.screen_width, self.current_ms, note.load_ms, note.pixels_per_frame_x)
|
self.draw_balloon(current_ms, note)
|
||||||
y_position = self.get_position_y(self.current_ms, note.load_ms, note.pixels_per_frame_y, note.pixels_per_frame_x)
|
tex.draw_texture('notes', 'moji', frame=note.moji, x=x_position, y=tex.skin_config["moji"].y + y_position)
|
||||||
if x_position < tex.skin_config["past_judge_circle"].x or x_position > tex.screen_width:
|
|
||||||
continue
|
|
||||||
self.draw_balloon(self.current_ms, note, 0, note.index)
|
|
||||||
tex.draw_texture('notes', 'moji', frame=note.moji, x=x_position - tex.skin_config["moji"].x, y=tex.skin_config["moji"].y + y_position)
|
|
||||||
else:
|
else:
|
||||||
x_position = self.get_position_x(tex.screen_width, self.current_ms, note.load_ms, note.pixels_per_frame_x)
|
|
||||||
y_position = self.get_position_y(self.current_ms, note.load_ms, note.pixels_per_frame_y, note.pixels_per_frame_x)
|
|
||||||
if x_position < tex.skin_config["past_judge_circle"].x or x_position > tex.screen_width:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if note.display:
|
if note.display:
|
||||||
tex.draw_texture('notes', str(note.type), x=x_position, y=y_position+tex.skin_config["notes"].y, center=True)
|
tex.draw_texture('notes', str(note.type), x=x_position - (tex.textures["notes"]["1"].width//2), y=y_position+tex.skin_config["notes"].y, center=True)
|
||||||
color = ray.WHITE
|
tex.draw_texture('notes', 'moji', frame=note.moji, x=x_position - (tex.textures["notes"]["moji"].width//2), y=tex.skin_config["moji"].y + y_position)
|
||||||
if note.index in self.player_1.input_log:
|
|
||||||
if self.player_1.input_log[note.index] == 'GOOD':
|
|
||||||
color = ray.Color(255, 233, 0, 255)
|
|
||||||
elif self.player_1.input_log[note.index] == 'BAD':
|
|
||||||
color = ray.Color(34, 189, 243, 255)
|
|
||||||
tex.draw_texture('notes', 'moji', frame=note.moji, x=x_position - tex.skin_config["moji"].x, y=tex.skin_config["moji"].y + y_position, color=color)
|
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
tex.clear_screen(ray.BLACK)
|
||||||
self.background.draw()
|
self.background.draw()
|
||||||
self.player_1.draw(self.current_ms, self.start_ms, self.mask_shader)
|
self.player_1.draw(self.current_ms, self.start_ms, self.mask_shader)
|
||||||
if self.paused:
|
if self.paused:
|
||||||
self.draw_scrobble_list()
|
self.draw_bars(self.scrobble_time, self.bars)
|
||||||
|
self.draw_notes(self.scrobble_time, self.scrobble_note_list)
|
||||||
tex.draw_texture('practice', 'large_drum', index=0)
|
tex.draw_texture('practice', 'large_drum', index=0)
|
||||||
tex.draw_texture('practice', 'large_drum', index=1)
|
tex.draw_texture('practice', 'large_drum', index=1)
|
||||||
self.player_1.draw_overlays(self.mask_shader)
|
self.player_1.draw_overlays(self.mask_shader)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from libs.audio import audio
|
|||||||
from libs.utils import global_data
|
from libs.utils import global_data
|
||||||
from libs.video import VideoPlayer
|
from libs.video import VideoPlayer
|
||||||
import pyray as ray
|
import pyray as ray
|
||||||
from libs.texture import tex
|
|
||||||
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Player, Background, ResultTransition
|
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Player, Background, ResultTransition
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -75,7 +74,7 @@ class TwoPlayerGameScreen(GameScreen):
|
|||||||
|
|
||||||
def init_tja(self, song: Path):
|
def init_tja(self, song: Path):
|
||||||
"""Initialize the TJA file"""
|
"""Initialize the TJA file"""
|
||||||
self.tja = TJAParser(song, start_delay=self.start_delay, distance=tex.screen_width - GameScreen.JUDGE_X)
|
self.tja = TJAParser(song, start_delay=self.start_delay)
|
||||||
if self.tja.metadata.bgmovie != Path() and self.tja.metadata.bgmovie.exists():
|
if self.tja.metadata.bgmovie != Path() and self.tja.metadata.bgmovie.exists():
|
||||||
self.movie = VideoPlayer(self.tja.metadata.bgmovie)
|
self.movie = VideoPlayer(self.tja.metadata.bgmovie)
|
||||||
self.movie.set_volume(0.0)
|
self.movie.set_volume(0.0)
|
||||||
|
|||||||
Reference in New Issue
Block a user