又写了一堆屎山

This commit is contained in:
lichx 2024-04-19 10:00:37 +08:00
parent 7cf048fd7c
commit b0efa940c1
81 changed files with 2827 additions and 260 deletions

View File

@ -1,10 +1,10 @@
using CDSAE3_Lian_Lian_Kan.Forms.Interface;
namespace CDSAE3_Lian_Lian_Kan.Boards
{
public partial class Board:IBoard
public partial class Board : IBoard
{
private int[,] Bd = { { } };//y,x
private Dictionary<int, List<(int, int)>> board_Index = new Dictionary<int, List<(int, int)>>();
private Dictionary<int, List<(int, int)>> boardIndex = new Dictionary<int, List<(int, int)>>();
private int[] Vals_per_Image { get; set; } = Array.Empty<int>();
private int total;
private int Total
@ -17,7 +17,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
{
total = value;
if (Total == 0)
Etcs.gameModeForm?.Finished_Handler(this, new FinishArgs { finish_Type = FinishArgs.Finish_Type.All_done });
Etcs.gameModeForm?.Finished_Handler(this, new FinishArgs { finishType = FinishArgs.FinishType.All_done });
}
}
private Board_funcs board_Funcs = new Board_funcs();
@ -41,10 +41,10 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
for (int i = 0; i < sum; i++)
{
Bd[cur_height, cur_width] = board_Funcs.getval(ref temp_val_per_Image, ref last_val, types);
if (board_Index.TryGetValue(Bd[cur_height, cur_width], out var index))
if (boardIndex.TryGetValue(Bd[cur_height, cur_width], out var index))
index.Add((cur_width, cur_height));
else
board_Index.Add(Bd[cur_height, cur_width], new List<(int, int)> { (cur_width, cur_height) });
boardIndex.Add(Bd[cur_height, cur_width], new List<(int, int)> { (cur_width, cur_height) });
cur_width++;
if (cur_width > width)
{
@ -56,7 +56,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
}
public int[,] remake_board()
{
board_Index.Clear();
boardIndex.Clear();
var rand = new Random();
int[] temp_val_per_Image = (int[])Vals_per_Image.Clone();
int types = Vals_per_Image.Length;
@ -68,10 +68,10 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
if (Bd[i, j] != -1)
{
Bd[i, j] = board_Funcs.getval(ref temp_val_per_Image, ref last_val, types);
if (board_Index.TryGetValue(Bd[i, j], out var index))
if (boardIndex.TryGetValue(Bd[i, j], out var index))
index.Add((j, i));
else
board_Index.Add(Bd[i, j], new List<(int, int)> { (j, i) });
boardIndex.Add(Bd[i, j], new List<(int, int)> { (j, i) });
}
return Bd;
}
@ -249,7 +249,9 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
{
int type = Bd[y, x];
Bd[y, x] = -1;
if (!board_Index[type].Remove((x, y)))
if (type == -1)
return;
if (!boardIndex[type].Remove((x, y)))
throw new Exception("Val not Found in board_Index");
Vals_per_Image[type]--;
Total--;
@ -258,7 +260,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
public List<List<(int, int)>> get_tip((int, int) start)
{
List<List<(int, int)>> ans = new List<List<(int, int)>>();
if (board_Index.TryGetValue(Bd[start.Item2, start.Item1], out var tip))
if (boardIndex.TryGetValue(Bd[start.Item2, start.Item1], out var tip))
foreach (var pos in tip)
{
var (result, path) = test(start, pos);
@ -267,6 +269,19 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
}
return ans;
}
public (int, int) GetRandomBlock()
{
Random random = new();
int k = random.Next(0, boardIndex.Count);
for (int i = 0; i < boardIndex.Count(); i++)
{
if (boardIndex[k + i].Count != 0)
return boardIndex[k + i][random.Next(0, boardIndex[k + i].Count)];
}
return (-1, -1);
}
public (int, int) size { get; set; }//width,height
}
}

View File

@ -35,7 +35,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
}
public (int, int) size { get; set; }//width,height
Dictionary<(int,int),Node>Index = new Dictionary<(int,int), Node>();//width,height
private Dictionary<int, List<(int, int)>> board_Index = new Dictionary<int, List<(int, int)>>();
private Dictionary<int, List<(int, int)>> boardIndex = new Dictionary<int, List<(int, int)>>();
Board_funcs board_Funcs = new Board_funcs();
private int total;
private int Total
@ -48,7 +48,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
{
total = value;
if (Total == 0)
Etcs.gameModeForm?.Finished_Handler(this, new FinishArgs { finish_Type = FinishArgs.Finish_Type.All_done });
Etcs.gameModeForm?.Finished_Handler(this, new FinishArgs { finishType = FinishArgs.FinishType.All_done });
}
}
private int[] Vals_per_Image { get; set; } = Array.Empty<int>();
@ -72,7 +72,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
}
else
throw new Exception("Val not Found in Index");
if (!board_Index[type].Remove((x, y)))
if (!boardIndex[type].Remove((x, y)))
throw new Exception("Val not Found in board_Index");
Vals_per_Image[type]--;
Total--;
@ -82,7 +82,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
public List<List<(int, int)>> get_tip((int, int) start)
{
List<List<(int, int)>> ans = new List<List<(int, int)>>();
if (board_Index.TryGetValue(Index[start].value, out var tip))
if (boardIndex.TryGetValue(Index[start].value, out var tip))
foreach (var pos in tip)
{
var (result, path) = test(start, pos);
@ -120,10 +120,10 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
for (int i = 0; i < sum; i++)
{
Bd[cur_height, cur_width] = board_Funcs.getval(ref temp_val_per_Image, ref last_val, types);
if (board_Index.TryGetValue(Bd[cur_height, cur_width], out var index))
if (boardIndex.TryGetValue(Bd[cur_height, cur_width], out var index))
index.Add((cur_width, cur_height));
else
board_Index.Add(Bd[cur_height, cur_width], new List<(int, int)> { (cur_width, cur_height) });
boardIndex.Add(Bd[cur_height, cur_width], new List<(int, int)> { (cur_width, cur_height) });
Index[(cur_width, cur_height)].value = Bd[cur_height, cur_width];
cur_width++;
if (cur_width > width)
@ -151,7 +151,7 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
public int[,] remake_board()
{
board_Index.Clear();
boardIndex.Clear();
int[] temp_val_per_Image = (int[])Vals_per_Image.Clone();
var (width, height) = size;
int[,] Bd = new int[height + 2, width + 2];
@ -165,10 +165,10 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
continue;
node.value = board_Funcs.getval(ref temp_val_per_Image, ref last_val, Etcs.Images_size());
Bd[node.y,node.x] = node.value;
if(board_Index.TryGetValue(node.value,out var list))
if(boardIndex.TryGetValue(node.value,out var list))
list.Add((node.x, node.y));
else
board_Index.Add(node.value, new List<(int, int)> { (node.x, node.y) });
boardIndex.Add(node.value, new List<(int, int)> { (node.x, node.y) });
}
return Bd;
}
@ -308,5 +308,17 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
}
public (int, int) GetRandomBlock()
{
Random random = new();
int k = random.Next(0, boardIndex.Count);
for(int i = 0;i<boardIndex.Count(); i++)
{
if (boardIndex[k + i].Count != 0)
return boardIndex[k + i][random.Next(0, boardIndex[k + i].Count)];
}
return (-1, -1);
}
}
}

View File

@ -14,5 +14,6 @@ namespace CDSAE3_Lian_Lian_Kan.Boards
public void decrease(params (int, int)[] poss);
public List<List<(int, int)>> get_tip((int, int) start);
public (int, int) size { get; set; }//width,height
public (int, int) GetRandomBlock();
}
}

View File

@ -23,7 +23,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FftSharp" Version="1.1.6" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="OpenCvSharp4" Version="4.9.0.20240103" />
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.9.0.20240103" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.9.0.20240103" />
</ItemGroup>
<ItemGroup>
@ -41,6 +45,10 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="Forms\AudioVisualizer\" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties /></VisualStudio></ProjectExtensions>
</Project>

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -65,11 +66,18 @@ namespace CDSAE3_Lian_Lian_Kan
easy = 0,
normal = 1,
hard = 2,
custom = 3
custom = 3,
challenge = 4
}
public enum Algorithm
{
Array = 0,
Graph = 1
}
public enum Theme
{
fruit = 0
fruit = 0,
code = 1
}
public enum Direction
{
@ -106,26 +114,30 @@ namespace CDSAE3_Lian_Lian_Kan
{8,100.0/10 },
{9,100.0/5 },
{10,100.0/3 }};
public static string curAlbum = "C418";
public static int cus_height = 1, cus_width = 1;
public static Algorithm curAlgorithm = Algorithm.Array;
public static Dictionary<string, ThemeInfo> themes { get; set; } = JsonSerializer.Deserialize<ThemeInfos>(File.ReadAllText("Resources\\sources.json"), new JsonSerializerOptions()
{Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
})!.Themes!.ToDictionary(x => x.Name);
public static System.Timers.Timer hunderd_millsecond_timer { get; set; } = new System.Timers.Timer(100) { AutoReset = true, Enabled = true };
public static Difficulty current_difficulty { get; set; } = Difficulty.normal;
public static Theme current_block_theme { get; set; }
public static Theme current_block_theme { get; set; } = Theme.fruit;
public static ThemeInfo currentThemeInfo { get; set; } = themes["Fruit"];
public static Image trans_Image { get; set; } = Resources.trans;
public static (int, int) get_length_width() => current_difficulty != Difficulty.custom ? (7 * (1 + (int)current_difficulty), 4 * (1 + (int)current_difficulty)) : (cus_width, cus_height);
public static List<Image> block_Images { get; set; } = new List<Image> { Resources.Apple, Resources.Banana, Resources.Beetroot, Resources.Cherry, Resources.Corn, Resources.Eggplant, Resources.Grape, Resources.Pear, Resources.Strawberry, Resources.Watermelon };
public static List<Image> disappear_Images { get; set; } = new List<Image> { Resources.Gapple, Resources.Gbanana, Resources.Gbeetroot, Resources.Gcherry, Resources.Gcorn, Resources.Geggplant, Resources.Ggrape, Resources.Gpear, Resources.Gstrawberry, Resources.Gwatermelon };
public static List<Image> direction_Images { get; set; } = new List<Image> { Resources.trans, Resources.u, Resources.r, Resources.ur, Resources.d, Resources.ud, Resources.dr, Resources.udr, Resources.l, Resources.ul, Resources.lr, Resources.ulr, Resources.dl, Resources.udl, Resources.dlr, Resources.udlr };
public static List<Image> tip_direction_Image { get; set; } = new List<Image> { Resources.trans, Resources.tip_u, Resources.tip_r, Resources.tip_ur, Resources.tip_d, Resources.tip_ud, Resources.tip_dr, Resources.tip_udr, Resources.tip_l, Resources.tip_ul, Resources.tip_lr, Resources.tip_ulr, Resources.tip_dl, Resources.tip_udl, Resources.tip_dlr, Resources.tip_udlr };
public static Image get_block_Image(int t) => block_Images[t];
public static Image get_disappear_Images(int t) => disappear_Images[t];
public static Image get_direction_Image(Direction direction) => direction_Images[(int)direction];
public static int Images_size() => current_block_theme switch { Theme.fruit => 10, _ => 0, };
public static Image get_tip_direction_Image(Direction direction) => tip_direction_Image[(int)direction];
public static (int, int) get_length_width() => current_difficulty == Difficulty.challenge ? (18, 9) : (current_difficulty != Difficulty.custom ? (7 * (1 + (int)current_difficulty), 4 * (1 + (int)current_difficulty)) : (cus_width, cus_height));
public static ConcurrentBag<Image> fruit_Images { get; set; } = new() { Resources.Apple, Resources.Banana, Resources.Beetroot, Resources.Cherry, Resources.Corn, Resources.Eggplant, Resources.Grape, Resources.Pear, Resources.Strawberry, Resources.Watermelon };
public static ConcurrentBag<Image> disappear_fruit_Images { get; set; } = new () { Resources.Gapple, Resources.Gbanana, Resources.Gbeetroot, Resources.Gcherry, Resources.Gcorn, Resources.Geggplant, Resources.Ggrape, Resources.Gpear, Resources.Gstrawberry, Resources.Gwatermelon };
public static ConcurrentBag<Image> code_Images { get; set; } = new() { Resources.cpp, Resources.cSharp, Resources.go, Resources.java, Resources.kotlin, Resources.python, Resources.ruby, Resources.rust, Resources.vue};
public static ConcurrentBag<Image> disappear_code_Images { get; set; } = new() { Resources.Gcpp, Resources.GcSharp, Resources.Ggo, Resources.Gjava, Resources.Gkotlin, Resources.Gpython, Resources.Gruby, Resources.Grust, Resources.Gvue };
public static ConcurrentDictionary<Direction, Image> direction_Images { get; set; } = new ConcurrentDictionary<Direction, Image>(new List<Image> { Resources.trans, Resources.u, Resources.r, Resources.ur, Resources.d, Resources.ud, Resources.dr, Resources.udr, Resources.l, Resources.ul, Resources.lr, Resources.ulr, Resources.dl, Resources.udl, Resources.dlr, Resources.udlr }.Select((value, index) => new { Index = (Direction)index, Value = value }).ToDictionary(item => item.Index, item => item.Value));
public static ConcurrentDictionary<Direction,Image> direction_Images_white_version { get; set; } = new ConcurrentDictionary<Direction,Image> (new List<Image>(){ Resources.trans, Resources.w_u, Resources.w_r, Resources.w_ur, Resources.w_d, Resources.w_ud, Resources.w_dr, Resources.w_udr, Resources.w_l, Resources.w_ul, Resources.w_lr, Resources.w_ulr, Resources.w_dl, Resources.w_udl, Resources.w_dlr, Resources.w_udlr }.Select((value, index) => new { Index = (Direction)index, Value = value }).ToDictionary(item => item.Index, item => item.Value));
public static ConcurrentDictionary<Direction,Image> tip_direction_Image { get; set; } = new ConcurrentDictionary<Direction, Image>(new List<Image>{ Resources.trans, Resources.tip_u, Resources.tip_r, Resources.tip_ur, Resources.tip_d, Resources.tip_ud, Resources.tip_dr, Resources.tip_udr, Resources.tip_l, Resources.tip_ul, Resources.tip_lr, Resources.tip_ulr, Resources.tip_dl, Resources.tip_udl, Resources.tip_dlr, Resources.tip_udlr }.Select((value, index) => new { Index = (Direction)index, Value = value }).ToDictionary(item => item.Index, item => item.Value));
public static Image get_block_Image(int t) => current_block_theme == Theme.fruit ? fruit_Images.ElementAt(t) : code_Images.ElementAt(t);
public static Image get_disappear_Images(int t) => current_block_theme == Theme.fruit ? disappear_fruit_Images.ElementAt(t) : disappear_code_Images.ElementAt(t);
public static Image get_direction_Image(Direction direction) => current_difficulty != Difficulty.challenge ? direction_Images.GetOrAdd(direction, (dire) => null!) : direction_Images_white_version.GetOrAdd(direction,(dire)=>null!);
public static int Images_size() => current_block_theme switch { Theme.fruit => fruit_Images.Count(), Theme.code => code_Images.Count(), _ => 0 };
public static Image get_tip_direction_Image(Direction direction) => tip_direction_Image.GetOrAdd(direction, (dire) => null!);
public static LianLianKan? form { get; set; }
public static IGameControl? gameForm { get; set; }//gameBoard
public static IGameMode? gameModeForm { get; set; }//entireGame
@ -135,7 +147,8 @@ namespace CDSAE3_Lian_Lian_Kan
public static Color sel_Color { get; set; } = Color.FromArgb(0, 122, 204);
public static Color mouse_upper_color { get; set; } = Color.FromArgb(97, 97, 108);
public static Dictionary<string, List<string>> musics { get; set; } = new Dictionary<string, List<string>> { { "C418", new List<string> { "C418 - Beginning 2", "C418 - Floating Trees", "C418 - Moog City 2", "C418 - Mutation" } },
{"Sea Power",new List<string>{ "Sea Power - Advesperascit", "Sea Power - Burn, Baby, Burn", "Sea Power - Detective Arriving on the Scene", "Sea Power - Disco Elysium, Pt 1", "Sea Power - Disco Elysium, Pt 2", "Sea Power - Ecstatic Vibrations, Totally Transcendent", "Sea Power - Hope in Work and Joy in Leisure", "Sea Power - Ignus Nilsen Waltz", "Sea Power - Instrument of Surrender", "Sea Power - Krenel, Downwell, Somatosensor", "Sea Power - La Revacholiere", "Sea Power - Live With Me", "Sea Power - Martinaise, Terminal B", "Sea Power - Miss Oranje Disco Dancer", "Sea Power - Off We Go Into the Wild Pale Yonder", "Sea Power - Ployhedrons", "Sea Power - Precinct 41 Major Crime Unit", "Sea Power - Rue de Saint-Gislaine", "Sea Power - Saint-Brune 1147", "Sea Power - The Cryptozoologists", "Sea Power - The Doomed Commercial Area", "Sea Power - The Field Autopsy", "Sea Power - The Insulindian Miracle", "Sea Power - Tiger King", "Sea Power - We Are Not Checkmated", "Sea Power - Whirling In Rags 12Pm", "Sea Power - Whirling in Rags 8am", "Sea Power - Whirling in Rags 8pm", "Sea Power - Your Body Betrays Your Degeneracy", "Sea Power - Zaum" } } };
{"Sea Power",new List<string>{ "Sea Power - Advesperascit", "Sea Power - Burn, Baby, Burn", "Sea Power - Detective Arriving on the Scene", "Sea Power - Disco Elysium, Pt 1", "Sea Power - Disco Elysium, Pt 2", "Sea Power - Ecstatic Vibrations, Totally Transcendent", "Sea Power - Hope in Work and Joy in Leisure", "Sea Power - Ignus Nilsen Waltz", "Sea Power - Instrument of Surrender", "Sea Power - Krenel, Downwell, Somatosensor", "Sea Power - La Revacholiere", "Sea Power - Live With Me", "Sea Power - Martinaise, Terminal B", "Sea Power - Miss Oranje Disco Dancer", "Sea Power - Off We Go Into the Wild Pale Yonder", "Sea Power - Ployhedrons", "Sea Power - Precinct 41 Major Crime Unit", "Sea Power - Rue de Saint-Gislaine", "Sea Power - Saint-Brune 1147", "Sea Power - The Cryptozoologists", "Sea Power - The Doomed Commercial Area", "Sea Power - The Field Autopsy", "Sea Power - The Insulindian Miracle", "Sea Power - Tiger King", "Sea Power - We Are Not Checkmated", "Sea Power - Whirling In Rags 12Pm", "Sea Power - Whirling in Rags 8am", "Sea Power - Whirling in Rags 8pm", "Sea Power - Your Body Betrays Your Degeneracy", "Sea Power - Zaum" } } ,
{"Tatsh",new List<string>{ "Tatsh - Xenolith" } } };
public static Audio_res_manager audio_Res_Manager { get; set; } = new Audio_res_manager();
public static Song_Audio_processer song_Audio_Processer { get; set; } = new Song_Audio_processer();
public static Info_Audio_processer info_Audio_Processer { get; set; } = new Info_Audio_processer();

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace CDSAE3_Lian_Lian_Kan.Extensions
{
public static class BitmapExtensions
{
public static Bitmap GaussianBlur(this Bitmap Bmp)
{
Mat src = BitmapConverter.ToMat(Bmp);
Mat dest = new Mat();
Cv2.Blur(src, dest, new OpenCvSharp.Size(50,50));
return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(dest);
}
}
}

View File

@ -0,0 +1,77 @@
namespace AudioVisualizer
{
partial class MainWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
dataTimer = new System.Windows.Forms.Timer(components);
drawingPanel = new Panel();
drawingTimer = new System.Windows.Forms.Timer(components);
SuspendLayout();
//
// dataTimer
//
dataTimer.Interval = 30;
dataTimer.Tick += DataTimer_Tick;
//
// drawingPanel
//
drawingPanel.Dock = DockStyle.Fill;
drawingPanel.Location = new Point(0, 0);
drawingPanel.Name = "drawingPanel";
drawingPanel.Size = new Size(880, 432);
drawingPanel.TabIndex = 0;
drawingPanel.MouseDoubleClick += DrawingPanel_MouseDoubleClick;
//
// drawingTimer
//
drawingTimer.Interval = 30;
drawingTimer.Tick += DrawingTimer_Tick;
//
// MainWindow
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Black;
ClientSize = new Size(880, 432);
Controls.Add(drawingPanel);
FormBorderStyle = FormBorderStyle.None;
Name = "MainWindow";
Text = "Music Visualizer";
FormClosed += MainWindow_FormClosed;
Load += MainWindow_Load;
ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Timer dataTimer;
private Panel drawingPanel;
private System.Windows.Forms.Timer drawingTimer;
}
}

View File

@ -0,0 +1,466 @@
using LibAudioVisualizer;
using NAudio.CoreAudioApi;
using NAudio.Wave;
using System.Drawing.Drawing2D;
using System.Numerics;
namespace AudioVisualizer
{
public partial class MainWindow : Form
{
WasapiCapture capture; // 音频捕获
Visualizer visualizer; // 可视化
double[]? spectrumData; // 频谱数据
Color[] allColors; // 渐变颜色
public MainWindow()
{
capture = new WasapiLoopbackCapture(); // 捕获电脑发出的声音
visualizer = new Visualizer(256); // 新建一个可视化器, 并使用 256 个采样进行傅里叶变换
allColors = GetAllHsvColors(); // 获取所有的渐变颜色 (HSV 颜色)
capture.WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(8192, 1); // 指定捕获的格式, 单声道, 32位深度, IeeeFloat 编码, 8192采样率
capture.DataAvailable += Capture_DataAvailable; // 订阅事件
InitializeComponent();
}
/// <summary>
/// 获取 HSV 中所有的基础颜色 (饱和度和明度均为最大值)
/// </summary>
/// <returns>所有的 HSV 基础颜色(共 256 * 6 个, 并且随着索引增加, 颜色也会渐变)</returns>
private Color[] GetAllHsvColors()
{
Color[] result = new Color[256 * 6];
for (int i = 0; i < 256; i++)
{
result[i] = Color.FromArgb(255, i, 0);
}
for (int i = 0; i < 256; i++)
{
result[256 + i] = Color.FromArgb(255 - i, 255, 0);
}
for (int i = 0; i < 256; i++)
{
result[512 + i] = Color.FromArgb(0, 255, i);
}
for (int i = 0; i < 256; i++)
{
result[768 + i] = Color.FromArgb(0, 255 - i, 255);
}
for (int i = 0; i < 256; i++)
{
result[1024 + i] = Color.FromArgb(i, 0, 255);
}
for (int i = 0; i < 256; i++)
{
result[1280 + i] = Color.FromArgb(255, 0, 255 - i);
}
return result;
}
/// <summary>
/// 当捕获有数据的时候, 就怼到可视化器里面
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Capture_DataAvailable(object? sender, WaveInEventArgs e)
{
int length = e.BytesRecorded / 4; // 采样的数量 (每一个采样是 4 字节)
double[] result = new double[length]; // 声明结果
for (int i = 0; i < length; i++)
result[i] = BitConverter.ToSingle(e.Buffer, i * 4); // 取出采样值
visualizer.PushSampleData(result); // 将新的采样存储到 可视化器 中
}
/// <summary>
/// 用来刷新频谱数据以及实现频谱数据缓动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataTimer_Tick(object? sender, EventArgs e)
{
double[] newSpectrumData = visualizer.GetSpectrumData(); // 从可视化器中获取频谱数据
newSpectrumData = Visualizer.GetBlurry(newSpectrumData, 2); // 平滑频谱数据
spectrumData = newSpectrumData;
}
/// <summary>
/// 绘制一个渐变的 波浪
/// </summary>
/// <param name="g">绘图目标</param>
/// <param name="down">下方颜色</param>
/// <param name="up">上方颜色</param>
/// <param name="spectrumData">频谱数据</param>
/// <param name="pointCount">波浪中, 点的数量</param>
/// <param name="drawingWidth">波浪的宽度</param>
/// <param name="xOffset">波浪的起始X坐标</param>
/// <param name="yOffset">波浪的其实Y坐标</param>
/// <param name="scale">频谱的缩放(使用负值可以翻转波浪)</param>
private void DrawGradient(Graphics g, Color down, Color up, double[] spectrumData, int pointCount, int drawingWidth, float xOffset, float yOffset, double scale)
{
GraphicsPath path = new GraphicsPath();
PointF[] points = new PointF[pointCount + 2];
for (int i = 0; i < pointCount; i++)
{
double x = i * drawingWidth / pointCount + xOffset;
double y = spectrumData[i * spectrumData.Length / pointCount] * scale + yOffset;
points[i + 1] = new PointF((float)x, (float)y);
}
points[0] = new PointF(xOffset, yOffset);
points[points.Length - 1] = new PointF(xOffset + drawingWidth, yOffset);
path.AddCurve(points);
float upP = (float)points.Min(v => v.Y);
if (Math.Abs(upP - yOffset) < 1)
return;
using Brush brush = new LinearGradientBrush(new PointF(0, yOffset), new PointF(0, upP), down, up);
g.FillPath(brush, path);
}
/// <summary>
/// 绘制渐变的条形
/// </summary>
/// <param name="g">绘图目标</param>
/// <param name="down">下方颜色</param>
/// <param name="up">上方颜色</param>
/// <param name="spectrumData">频谱数据</param>
/// <param name="stripCount">条形的数量</param>
/// <param name="drawingWidth">绘图的宽度</param>
/// <param name="xOffset">绘图的起始 X 坐标</param>
/// <param name="yOffset">绘图的起始 Y 坐标</param>
/// <param name="spacing">条形与条形之间的间隔(像素)</param>
/// <param name="scale"></param>
private void DrawGradientStrips(Graphics g, Color down, Color up, double[] spectrumData, int stripCount, int drawingWidth, float xOffset, float yOffset, float spacing, double scale)
{
float stripWidth = (drawingWidth - spacing * stripCount) / stripCount;
PointF[] points = new PointF[stripCount];
for (int i = 0; i < stripCount; i++)
{
double x = stripWidth * i + spacing * i + xOffset;
double y = spectrumData[i * spectrumData.Length / stripCount] * scale; // height
points[i] = new PointF((float)x, (float)y);
}
float upP = (float)points.Min(v => v.Y < 0 ? yOffset + v.Y : yOffset);
float downP = (float)points.Max(v => v.Y < 0 ? yOffset : yOffset + v.Y);
if (downP < yOffset)
downP = yOffset;
if (Math.Abs(upP - downP) < 1)
return;
using Brush brush = new LinearGradientBrush(new PointF(0, downP), new PointF(0, upP), down, up);
for (int i = 0; i < stripCount; i++)
{
PointF p = points[i];
float y = yOffset;
float height = p.Y;
if (height < 0)
{
y += height;
height = -height;
}
g.FillRectangle(brush, new RectangleF(p.X, y, stripWidth, height));
}
}
/// <summary>
/// 画曲线
/// </summary>
/// <param name="g"></param>
/// <param name="pen"></param>
/// <param name="spectrumData"></param>
/// <param name="pointCount"></param>
/// <param name="drawingWidth"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="scale"></param>
private void DrawCurve(Graphics g, Pen pen, double[] spectrumData, int pointCount, int drawingWidth, double xOffset, double yOffset, double scale)
{
PointF[] points = new PointF[pointCount];
for (int i = 0; i < pointCount; i++)
{
double x = i * drawingWidth / pointCount + xOffset;
double y = spectrumData[i * spectrumData.Length / pointCount] * scale + yOffset;
points[i] = new PointF((float)x, (float)y);
}
g.DrawCurve(pen, points);
}
/// <summary>
/// 画简单的圆环线条
/// </summary>
/// <param name="g"></param>
/// <param name="brush"></param>
/// <param name="spectrumData"></param>
/// <param name="stripCount"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="radius"></param>
/// <param name="spacing"></param>
/// <param name="rotation"></param>
/// <param name="scale"></param>
private void DrawCircleStrips(Graphics g, Brush brush, double[] spectrumData, int stripCount, double xOffset, double yOffset, double radius, double spacing, double rotation, double scale)
{
double rotationAngle = Math.PI / 180 * rotation;
double blockWidth = MathF.PI * 2 / stripCount; // angle
double stripWidth = blockWidth - MathF.PI / 180 * spacing; // angle
PointF[] points = new PointF[stripCount];
for (int i = 0; i < stripCount; i++)
{
double x = blockWidth * i + rotationAngle; // angle
double y = spectrumData[i * spectrumData.Length / stripCount] * scale; // height
points[i] = new PointF((float)x, (float)y);
}
for (int i = 0; i < stripCount; i++)
{
PointF p = points[i];
double sinStart = Math.Sin(p.X);
double sinEnd = Math.Sin(p.X + stripWidth);
double cosStart = Math.Cos(p.X);
double cosEnd = Math.Cos(p.X + stripWidth);
PointF[] polygon = new PointF[]
{
new PointF((float)(cosStart * radius + xOffset), (float)(sinStart * radius + yOffset)),
new PointF((float)(cosEnd * radius + xOffset), (float)(sinEnd * radius + yOffset)),
new PointF((float)(cosEnd * (radius + p.Y) + xOffset), (float)(sinEnd * (radius + p.Y) + yOffset)),
new PointF((float)(cosStart * (radius + p.Y) + xOffset), (float)(sinStart * (radius + p.Y) + yOffset)),
};
g.FillPolygon(brush, polygon);
}
}
/// <summary>
/// 画圆环渐变条
/// </summary>
/// <param name="g"></param>
/// <param name="inner"></param>
/// <param name="outer"></param>
/// <param name="spectrumData"></param>
/// <param name="stripCount"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="radius"></param>
/// <param name="spacing"></param>
/// <param name="scale"></param>
private void DrawCircleGradientStrips(Graphics g, Color inner, Color outer, double[] spectrumData, int stripCount, double xOffset, double yOffset, double radius, double spacing, double rotation, double scale)
{
double rotationAngle = Math.PI / 180 * rotation;
double blockWidth = Math.PI * 2 / stripCount; // angle
double stripWidth = blockWidth - MathF.PI / 180 * spacing; // angle
PointF[] points = new PointF[stripCount];
for (int i = 0; i < stripCount; i++)
{
double x = blockWidth * i + rotationAngle; // angle
double y = spectrumData[i * spectrumData.Length / stripCount] * scale; // height
points[i] = new PointF((float)x, (float)y);
}
double maxHeight = points.Max(v => v.Y);
double outerRadius = radius + maxHeight;
PointF[] polygon = new PointF[4];
for (int i = 0; i < stripCount; i++)
{
PointF p = points[i];
double sinStart = Math.Sin(p.X);
double sinEnd = Math.Sin(p.X + stripWidth);
double cosStart = Math.Cos(p.X);
double cosEnd = Math.Cos(p.X + stripWidth);
PointF
p1 = new PointF((float)(cosStart * radius + xOffset),(float)(sinStart * radius + yOffset)),
p2 = new PointF((float)(cosEnd * radius + xOffset),(float)(sinEnd * radius + yOffset)),
p3 = new PointF((float)(cosEnd * (radius + p.Y) + xOffset), (float)(sinEnd * (radius + p.Y) + yOffset)),
p4 = new PointF((float)(cosStart * (radius + p.Y) + xOffset), (float)(sinStart * (radius + p.Y) + yOffset));
polygon[0] = p1;
polygon[1] = p2;
polygon[2] = p3;
polygon[3] = p4;
PointF innerP = new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
PointF outerP = new PointF((p3.X + p4.X) / 2, (p3.Y + p4.Y) / 2);
Vector2 offset = new Vector2(outerP.X - innerP.X, outerP.Y - innerP.Y);
if (MathF.Sqrt(offset.X * offset.X + offset.Y * offset.Y) < 1) // 渐变笔刷两点之间距离不能太小
continue;
try
{
using LinearGradientBrush brush = new LinearGradientBrush(innerP, outerP, inner, outer); // 这里有玄学 bug, 这个 线性笔刷会 OutMemoryException
g.FillPolygon(brush, polygon); // 但是实际上不应该有这个异常...
}
catch { }
}
}
/// <summary>
/// 画简单的线条
/// </summary>
/// <param name="g"></param>
/// <param name="brush"></param>
/// <param name="spectrumData"></param>
/// <param name="stripCount"></param>
/// <param name="drawingWidth"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="spacing"></param>
/// <param name="scale"></param>
private void DrawStrips(Graphics g, Brush brush, double[] spectrumData, int stripCount, int drawingWidth, float xOffset, float yOffset, float spacing, double scale)
{
float stripWidth = (drawingWidth - spacing * stripCount) / stripCount;
PointF[] points = new PointF[stripCount];
for (int i = 0; i < stripCount; i++)
{
double x = stripWidth * i + spacing * i + xOffset;
double y = spectrumData[i * spectrumData.Length / stripCount] * scale; // height
points[i] = new PointF((float)x, (float)y);
}
for (int i = 0; i < stripCount; i++)
{
PointF p = points[i];
float y = yOffset;
float height = p.Y;
if (height < 0)
{
y += height;
height = -height;
}
g.FillRectangle(brush, new RectangleF(p.X, y, stripWidth, height));
}
}
/// <summary>
/// 画渐变的边框
/// </summary>
/// <param name="g"></param>
/// <param name="inner"></param>
/// <param name="outer"></param>
/// <param name="area"></param>
/// <param name="scale"></param>
/// <param name="width"></param>
private void DrawGradientBorder(Graphics g, Color inner, Color outer, Rectangle area, double scale, float width)
{
int thickness = (int)(width * scale);
if (thickness < 1)
return;
Rectangle rect = new Rectangle(area.X, area.Y, area.Width, area.Height);
Rectangle up = new Rectangle(rect.Location, new Size(rect.Width, thickness));
Rectangle down = new Rectangle(new Point(rect.X, (int)(rect.X + rect.Height - scale * width)), new Size(rect.Width, thickness));
Rectangle left = new Rectangle(rect.Location, new Size(thickness, rect.Height));
Rectangle right = new Rectangle(new Point((int)(rect.X + rect.Width - scale * width), rect.Y), new Size(thickness, rect.Height));
LinearGradientBrush upB = new LinearGradientBrush(up, outer, inner, LinearGradientMode.Vertical);
LinearGradientBrush downB = new LinearGradientBrush(down, inner, outer, LinearGradientMode.Vertical);
LinearGradientBrush leftB = new LinearGradientBrush(left, outer, inner, LinearGradientMode.Horizontal);
LinearGradientBrush rightB = new LinearGradientBrush(right, inner, outer, LinearGradientMode.Horizontal);
upB.WrapMode = downB.WrapMode = leftB.WrapMode = rightB.WrapMode = WrapMode.TileFlipXY;
g.FillRectangle(upB, up);
g.FillRectangle(downB, down);
g.FillRectangle(leftB, left);
g.FillRectangle(rightB, right);
}
int colorIndex = 0;
double rotation = 0;
BufferedGraphics? oldBuffer;
private void DrawingTimer_Tick(object? sender, EventArgs e)
{
if (spectrumData == null)
return;
rotation += 0.1;
colorIndex++;
Color color1 = allColors[colorIndex % allColors.Length];
Color color2 = allColors[(colorIndex + 200) % allColors.Length];
double[] bassArea = Visualizer.TakeSpectrumOfFrequency(spectrumData, capture.WaveFormat.SampleRate, 250); // 低频区域
double bassScale = bassArea.Average() * 100; // 低音导致的缩放 (比例数)
double extraScale = Math.Min(drawingPanel.Width, drawingPanel.Height) / 6; // 低音导致的缩放 (乘上窗口大小)
Rectangle border = new Rectangle(Point.Empty, drawingPanel.Size);
BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate(drawingPanel.CreateGraphics(), drawingPanel.ClientRectangle);
Graphics g = buffer.Graphics;
if (oldBuffer != null)
{
//oldBuffer.Render(buffer.Graphics); // 如果你想要实现 "留影" 效果, 就取消注释这段代码, 并且将 g.Clear 改为 g.FillRectange(xxx, 半透明的黑色)
oldBuffer.Dispose();
}
using Pen pen = new Pen(Color.Pink); // 画音频采样波形用的笔
g.SmoothingMode = SmoothingMode.HighQuality; // 嗨嗨害, 那必须得是高质量绘图
g.Clear(drawingPanel.BackColor);
//DrawGradientBorder(g, Color.FromArgb(0, color1), color2, border, bassScale, drawingPanel.Width / 10);
DrawGradientStrips(g, color1, color2, spectrumData, spectrumData.Length, drawingPanel.Width, 0, drawingPanel.Height, 3, -drawingPanel.Height * 50);
//DrawCircleGradientStrips(g, color1, color2, spectrumData, spectrumData.Length, drawingPanel.Width / 2, drawingPanel.Height / 2, MathF.Min(drawingPanel.Width, drawingPanel.Height) / 4 + extraScale * bassScale, 1, rotation, drawingPanel.Width / 6 * 10);
//DrawCurve(g, pen, visualizer.SampleData, visualizer.SampleData.Length, drawingPanel.Width, 0, drawingPanel.Height / 2, MathF.Min(drawingPanel.Height / 10, 100));
buffer.Render();
oldBuffer = buffer; // 保存一下 buffer (之所以不全局只使用一个 Buffer 是因为,,, 用户可能调整窗口大小, 所以每一帧都必须适应)
}
private void MainWindow_Load(object sender, EventArgs e)
{
capture.StartRecording();
dataTimer.Start();
drawingTimer.Start();
}
private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
{
Environment.Exit(0);
}
private void DrawingPanel_MouseDoubleClick(object sender, MouseEventArgs e)
{
WindowState = WindowState != FormWindowState.Maximized ? FormWindowState.Maximized : FormWindowState.Normal;
FormBorderStyle = WindowState == FormWindowState.Maximized ? FormBorderStyle.None : FormBorderStyle.Sizable;
}
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="dataTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="drawingTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>197, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,106 @@
namespace LibDynamics
{
public class SecondOrderDynamics
{
private double xp;// previous input
private double y, yd; // state variables
private double _w, _z, _d, k1, k2, k3; // dynamics constants
private double _r;
private double _f;
/// <summary>
/// 频率
/// - 即速度, 单位是赫兹(Hz)
/// - 不会影响输出结果的形状, 会影响 '震荡频率'
/// </summary>
public double F
{
get => _f; set
{
_f = value;
InitMotionValues(_f, _z, _r);
}
}
/// <summary>
/// 阻尼 <br />
/// - 当为 0 时, 输出将永远震荡不衰减 <br />
/// - 当大于 0 小于 1 时, 输出会超出结果, 并逐渐趋于目标 <br />
/// - 当为 1 时, 输出的曲线是趋向结果, 并正好在指定频率对应时间内抵达结果 <br />
/// - 当大于 1 时, 输出值同样时取向结果, 但速度会更慢, 无法在指定频率对应时间内抵达结果 <br />
/// </summary>
public double Z
{
get => _z; set
{
_z = value;
InitMotionValues(_f, _z, _r);
}
}
/// <summary>
/// 初始响应
/// - 当为 0 时, 数据需要进行 '加速' 来开始运动 <br />
/// - 当为 1 时, 数据会立即开始响应 <br />
/// - 当大于 1 时, 输出会因为 '速度过快' 而超出目标结果 <br />
/// - 当小于 0 时, 输出会 '预测运动', 即 '抬手动作'. 例如目标是 '加' 时, 输出会先进行 '减', 再进行 '加',
/// - 当运动目标为机械时, 通常取值为 2
/// </summary>
public double R
{
get => _r; set
{
_r = value;
InitMotionValues(_f, _z, _r);
}
}
public SecondOrderDynamics(double f, double z, double r, double x0)
{
//compute constants
InitMotionValues(f, z, r);
// initialize variables
xp = x0;
y = x0;
yd = 0;
}
private void InitMotionValues(double f, double z, double r)
{
_w = 2 * Math.PI * f;
_z = z;
_d = _w * Math.Sqrt(Math.Abs(z * z - 1));
k1 = z / (Math.PI * f);
k2 = 1 / ((2 * Math.PI * f) * (2 * Math.PI * f));
k3 = r * z / (2 * Math.PI * f);
}
public double Update(double deltaTime, double x)
{
double xd = (x - xp) / deltaTime;
double k1_stable, k2_stable;
if (_w * deltaTime < _z)
{
k1_stable = k1;
k2_stable = Math.Max(Math.Max(k2, deltaTime * deltaTime / 2 + deltaTime * k1 / 2), deltaTime * k1);
}
else
{
double t1 = Math.Exp(-_z * _w * deltaTime);
double alpha = 2 * t1 * (_z <= 1 ? Math.Cos(deltaTime * _d) : Math.Cosh(deltaTime * _d));
double beta = t1 * t1;
double t2 = deltaTime / (1 + beta - alpha);
k1_stable = (1 - beta) * t2;
k2_stable = deltaTime * t2;
}
y = y + deltaTime * yd;
yd = yd + deltaTime * (x + k3 * xd - y - k1_stable * yd) / k2_stable;
xp = x;
return y;
}
}
}

View File

@ -0,0 +1,126 @@
namespace LibDynamics
{
public class SecondOrderDynamicsForArray
{
private double[] xps, xds;// previous input
private double[] ys, yds; // state variables
private double _w, _z, _d, k1, k2, k3; // dynamics constants
private double _r;
private double _f;
/// <summary>
/// 频率
/// - 即速度, 单位是赫兹(Hz)
/// - 不会影响输出结果的形状, 会影响 '震荡频率'
/// </summary>
public double F
{
get => _f; set
{
_f = value;
InitMotionValues(_f, _z, _r);
}
}
/// <summary>
/// 阻尼 <br />
/// - 当为 0 时, 输出将永远震荡不衰减 <br />
/// - 当大于 0 小于 1 时, 输出会超出结果, 并逐渐趋于目标 <br />
/// - 当为 1 时, 输出的曲线是趋向结果, 并正好在指定频率对应时间内抵达结果 <br />
/// - 当大于 1 时, 输出值同样时取向结果, 但速度会更慢, 无法在指定频率对应时间内抵达结果 <br />
/// </summary>
public double Z
{
get => _z; set
{
_z = value;
InitMotionValues(_f, _z, _r);
}
}
/// <summary>
/// 初始响应
/// - 当为 0 时, 数据需要进行 '加速' 来开始运动 <br />
/// - 当为 1 时, 数据会立即开始响应 <br />
/// - 当大于 1 时, 输出会因为 '速度过快' 而超出目标结果 <br />
/// - 当小于 0 时, 输出会 '预测运动', 即 '抬手动作'. 例如目标是 '加' 时, 输出会先进行 '减', 再进行 '加',
/// - 当运动目标为机械时, 通常取值为 2
/// </summary>
public double R
{
get => _r; set
{
_r = value;
InitMotionValues(_f, _z, _r);
}
}
/// <summary>
///
/// </summary>
/// <param name="f"></param>
/// <param name="z"></param>
/// <param name="r"></param>
/// <param name="x0"></param>
/// <param name="size">Array size</param>
public SecondOrderDynamicsForArray(double f, double z, double r, double x0, int size)
{
//compute constants
InitMotionValues(f, z, r);
// initialize variables
xps = new double[size];
ys = new double[size];
xds = new double[size];
yds = new double[size];
Array.Fill(xps, x0);
Array.Fill(ys, x0);
}
private void InitMotionValues(double f, double z, double r)
{
_w = 2 * Math.PI * f;
_z = z;
_d = _w * Math.Sqrt(Math.Abs(z * z - 1));
k1 = z / (Math.PI * f);
k2 = 1 / ((2 * Math.PI * f) * (2 * Math.PI * f));
k3 = r * z / (2 * Math.PI * f);
}
public double[] Update(double deltaTime, double[] xs)//xps p for past,xds d for delta,xs current val
{
if (xs.Length != xps.Length)
throw new ArgumentException();
for (int i = 0; i < xds.Length; i++)
xds[i] = (xs[i] - xps[i]) / deltaTime;
double k1_stable, k2_stable;
if (_w * deltaTime < _z)
{
k1_stable = k1;
k2_stable = Math.Max(Math.Max(k2, deltaTime * deltaTime / 2 + deltaTime * k1 / 2), deltaTime * k1);
}
else
{
double t1 = Math.Exp(-_z * _w * deltaTime);
double alpha = 2 * t1 * (_z <= 1 ? Math.Cos(deltaTime * _d) : Math.Cosh(deltaTime * _d));
double beta = t1 * t1;
double t2 = deltaTime / (1 + beta - alpha);
k1_stable = (1 - beta) * t2;
k2_stable = deltaTime * t2;
}
for (int i = 0; i < ys.Length; i++)
{
ys[i] = ys[i] + deltaTime * yds[i];
yds[i] = yds[i] + deltaTime * (xs[i] + k3 * xds[i] - ys[i] - k1_stable * yds[i]) / k2_stable;
}
for (int i = 0; i < xps.Length; i++)
xps[i] = xs[i];
return ys;
}
}
}

View File

@ -0,0 +1,227 @@
using LibDynamics;
using FftComplex = FftSharp.Complex;
using FftTransform = FftSharp.Transform;
namespace LibAudioVisualizer
{
public class Visualizer
{
//private int _m;
private double[] _sampleData;
private DateTime _lastTime;
private SecondOrderDynamicsForArray _dynamics;
private int _size;
/// <summary>
/// 采样数据
/// </summary>
public double[] SampleData => _sampleData;
/// <summary>
/// 尺寸
/// </summary>
public int Size
{
get => _size; set
{
if (!(Get2Flag(value)))
throw new ArgumentException("长度必须是 2 的 n 次幂");
_size = value;
_sampleData = new double[value];
_dynamics = new SecondOrderDynamicsForArray(1, 1, 1, 0, value / 2);
}
}
public int OutputSize => Size / 2;
public Visualizer(int size)
{
if (!(Get2Flag(size)))
throw new ArgumentException("大小必须是 2 的 n 次幂", nameof(size));
_lastTime = DateTime.Now;
_sampleData = new double[size];
_dynamics = new SecondOrderDynamicsForArray(1, 1, 1, 0, size / 2);
}
/// <summary>
/// 判断是否是 2 的整数次幂
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
private bool Get2Flag(int num)
{
if (num < 1)
return false;
return (num & num - 1) == 0;
}
public void PushSampleData(double[] waveData)
{
if (waveData.Length > _sampleData.Length)
{
Array.Copy(waveData, waveData.Length - _sampleData.Length, _sampleData, 0, _sampleData.Length);
}
else
{
Array.Copy(_sampleData, waveData.Length, _sampleData, 0, _sampleData.Length - waveData.Length);
Array.Copy(waveData, 0, _sampleData, _sampleData.Length - waveData.Length, waveData.Length);
}
}
public void PushSampleData(double[] waveData, int count)
{
if (count > _sampleData.Length)
{
Array.Copy(waveData, count - _sampleData.Length, _sampleData, 0, _sampleData.Length);
}
else
{
Array.Copy(_sampleData, count, _sampleData, 0, _sampleData.Length - count);
Array.Copy(waveData, 0, _sampleData, _sampleData.Length - count, count);
}
}
/// <summary>
/// 获取频谱数据 (数据已经删去共轭部分)
/// </summary>
/// <returns></returns>
public double[] GetSpectrumData()
{
DateTime now = DateTime.Now;
double deltaTime = (now - _lastTime).TotalSeconds;
_lastTime = now;
int len = _sampleData.Length;
FftComplex[] data = new FftComplex[len];
for (int i = 0; i < len; i++)
data[i] = new FftComplex(_sampleData[i], 0);
FftTransform.FFT(data);
int halfLen = len / 2;
double[] spectrum = new double[halfLen]; // 傅里叶变换结果左右对称, 只需要取一半
for (int i = 0; i < halfLen; i++)
spectrum[i] = data[i].Magnitude / len;
var window = new FftSharp.Windows.Bartlett();
window.Create(halfLen);
window.ApplyInPlace(spectrum, false);
//return spectrum;
return _dynamics.Update(deltaTime, spectrum);
}
/// <summary>
/// 取指定频率内的频谱数据
/// </summary>
/// <param name="spectrum">源频谱数据</param>
/// <param name="sampleRate">采样率</param>
/// <param name="frequency">目标频率</param>
/// <returns></returns>
public static double[] TakeSpectrumOfFrequency(double[] spectrum, double sampleRate, double frequency)
{
double frequencyPerSampe = sampleRate / spectrum.Length;
int lengthInNeed = (int)(Math.Min(frequency / frequencyPerSampe, spectrum.Length));
double[] result = new double[lengthInNeed];
Array.Copy(spectrum, 0, result, 0, lengthInNeed);
return result;
}
/// <summary>
/// 简单的数据模糊
/// </summary>
/// <param name="data">数据</param>
/// <param name="radius">模糊半径</param>
/// <returns>结果</returns>
public static double[] GetBlurry(double[] data, int radius)
{
double[] GetWeights(int radius)
{
double Gaussian(double x) => Math.Pow(Math.E, (-4 * x * x)); // 憨批高斯函数
int len = 1 + radius * 2; // 长度
int end = len - 1; // 最后的索引
double radiusF = (double)radius; // 半径浮点数
double[] weights = new double[len]; // 权重
for (int i = 0; i <= radius; i++) // 先把右边的权重算出来
weights[radius + i] = Gaussian(i / radiusF);
for (int i = 0; i < radius; i++) // 把右边的权重拷贝到左边
weights[i] = weights[end - i];
double total = weights.Sum();
for (int i = 0; i < len; i++) // 使权重合为 0
weights[i] = weights[i] / total;
return weights;
}
void ApplyWeights(double[] buffer, double[] weights)
{
int len = buffer.Length;
for (int i = 0; i < len; i++)
buffer[i] = buffer[i] * weights[i];
}
double[] weights = GetWeights(radius);
double[] buffer = new double[1 + radius * 2];
double[] result = new double[data.Length];
if (data.Length < radius)
{
Array.Fill(result, data.Average());
return result;
}
for (int i = 0; i < radius; i++)
{
Array.Fill(buffer, data[i], 0, radius + 1); // 填充缺省
for (int j = 0; j < radius; j++) //
{
buffer[radius + 1 + j] = data[i + j];
}
ApplyWeights(buffer, weights);
result[i] = buffer.Sum();
}
for (int i = radius; i < data.Length - radius; i++)
{
for (int j = 0; j < radius; j++) //
{
buffer[j] = data[i - j];
}
buffer[radius] = data[i];
for (int j = 0; j < radius; j++) //
{
buffer[radius + j + 1] = data[i + j];
}
ApplyWeights(buffer, weights);
result[i] = buffer.Sum();
}
for (int i = data.Length - radius; i < data.Length; i++)
{
Array.Fill(buffer, data[i], 0, radius + 1); // 填充缺省
for (int j = 0; j < radius; j++) //
{
buffer[radius + 1 + j] = data[i - j];
}
ApplyWeights(buffer, weights);
result[i] = buffer.Sum();
}
return result;
}
}
}

View File

@ -16,7 +16,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
{
InitializeComponent();
}
public void SetEffect(Color begin, Color end, bool havePicture, Image? picture)
public void SetEffect(Color begin, Color end)
{
BackColor = begin;
this.begin = begin;

View File

@ -0,0 +1,150 @@
namespace CDSAE3_Lian_Lian_Kan.Forms
{
partial class Challenge_Mode
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
AudioVisualizerPanel = new Panel();
game_Panel = new Panel();
PausePanel = new Panel();
= new Label();
= new Label();
= new Label();
timeLine = new TimeLine();
PausePanel.SuspendLayout();
SuspendLayout();
//
// AudioVisualizerPanel
//
AudioVisualizerPanel.Location = new Point(0, 849);
AudioVisualizerPanel.Name = "AudioVisualizerPanel";
AudioVisualizerPanel.Size = new Size(1440, 109);
AudioVisualizerPanel.TabIndex = 0;
//
// game_Panel
//
game_Panel.BackColor = Color.FromArgb(50, 0, 0, 0);
game_Panel.Location = new Point(30, 52);
game_Panel.Name = "game_Panel";
game_Panel.Size = new Size(1380, 776);
game_Panel.TabIndex = 1;
//
// PausePanel
//
PausePanel.BackColor = Color.FromArgb(0, 0, 0);
PausePanel.Controls.Add();
PausePanel.Controls.Add();
PausePanel.Controls.Add();
PausePanel.Dock = DockStyle.Fill;
PausePanel.Location = new Point(0, 0);
PausePanel.Name = "PausePanel";
PausePanel.Size = new Size(1440, 960);
PausePanel.TabIndex = 2;
//
// 返回主菜单
//
.AutoSize = true;
.BackColor = Color.FromArgb(0, 0, 0, 0);
.Font = new Font("Microsoft YaHei UI", 20F);
.ForeColor = Color.White;
.Location = new Point(151, 342);
.Name = "返回主菜单";
.Size = new Size(222, 52);
.TabIndex = 5;
.Text = "返回主菜单";
.Visible = false;
.Click += 退_Click;
.MouseEnter += CanClickLabel_MouseEnter;
.MouseLeave += CanClickLabel_MouseLeave;
//
// 继续游戏
//
.AutoSize = true;
.BackColor = Color.FromArgb(0, 0, 0, 0);
.Font = new Font("Microsoft YaHei UI", 20F);
.ForeColor = Color.White;
.Location = new Point(151, 253);
.Name = "继续游戏";
.Size = new Size(182, 52);
.TabIndex = 4;
.Text = "继续游戏";
.Visible = false;
.Click += _Click;
.MouseEnter += CanClickLabel_MouseEnter;
.MouseLeave += CanClickLabel_MouseLeave;
//
// 游戏暂停
//
.AutoSize = true;
.BackColor = Color.FromArgb(0, 0, 0, 0);
.Font = new Font("Microsoft YaHei UI", 25F);
.ForeColor = Color.FromArgb(192, 192, 255);
.Location = new Point(127, 127);
.Name = "游戏暂停";
.Size = new Size(228, 65);
.TabIndex = 3;
.Text = "游戏暂停";
.Visible = false;
//
// timeLine
//
timeLine.BackColor = Color.FromArgb(0, 0, 0, 0);
timeLine.Location = new Point(0, 0);
timeLine.Name = "timeLine";
timeLine.Size = new Size(1440, 10);
timeLine.TabIndex = 6;
//
// Challenge_Mode
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.Black;
ClientSize = new Size(1440, 960);
Controls.Add(timeLine);
Controls.Add(game_Panel);
Controls.Add(AudioVisualizerPanel);
Controls.Add(PausePanel);
FormBorderStyle = FormBorderStyle.None;
KeyPreview = true;
Name = "Challenge_Mode";
Text = "Challenge_Mode";
PausePanel.ResumeLayout(false);
PausePanel.PerformLayout();
ResumeLayout(false);
}
#endregion
private Panel AudioVisualizerPanel;
private Panel game_Panel;
private Panel PausePanel;
private Label ;
private Label ;
private Label ;
private TimeLine timeLine;
}
}

View File

@ -0,0 +1,291 @@
using CDSAE3_Lian_Lian_Kan.Forms.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using CDSAE3_Lian_Lian_Kan.Extensions;
using Timer = System.Timers.Timer;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using CDSAE3_Lian_Lian_Kan.Sound;
using CDSAE3_Lian_Lian_Kan;
namespace CDSAE3_Lian_Lian_Kan.Forms
{
public partial class Challenge_Mode : Form, IGameMode
{
GameControl gameControl;
public Challenge_Mode()
{
InitializeComponent();
timer = new Timer { Interval = 500, AutoReset = true, Enabled = false };
timer.Elapsed += TimerTick;
Etcs.current_difficulty = Etcs.Difficulty.challenge;
Etcs.loadFinished = false;
gameControl = new GameControl((t) => Challenge_Mode_LoadAsync(this,new EventArgs()));
game_Panel.Controls.Add(gameControl);
gameControl.Dock = DockStyle.Fill;
}
//这里是行动的起源
Timer timer;
double curTime = 0;
int score = 0;
private void TimerTick(object? sender, ElapsedEventArgs e)
{
curTime += 0.1;
timeLine.set_progress(curTime / 140);
}
private async void Challenge_Mode_LoadAsync(object sender, EventArgs e)
{
bool loopStop = false;
PausePanel.BringToFront();
int oriSongVolume = Etcs.Song_Volume;
{
while (Etcs.Song_Volume != 0)
{
Etcs.Song_Volume = Math.Max(Etcs.Song_Volume - 7, 0);
Etcs.song_Audio_Processer.volume_change(Etcs.Song_Volume);
await Task.Delay(100);
}
}
{
Action<string, AudioPlayer> loopPlay = null!;
loopPlay = (s, player) =>
{
if (!loopStop)
Etcs.song_Audio_Processer.set_song("Ambient", 50, loopPlay);
};
Etcs.info_Audio_Processer.playMusicClip("Ambient", 50, loopPlay);
Label label = new Label { TextAlign = ContentAlignment.MiddleCenter, Font = new Font("Microsoft YaHei UI", 20F), ForeColor = Color.White, BackColor = Color.FromArgb(0, 0, 0, 0), AutoSize = false, Size = new Size(1220, 55), Location = new Point(110, 330) };
Controls.Add(label);
label.BringToFront();
string[] strings = { "你也许意识到了", "连连看的实现并不如其规则那样简单", "忙碌的CLR处理着数以千计的事件", "委托,反射,线程冲突不断发生在各处", "代码的堆叠已经到达极限", "这是最后的连连看,集中精力,不要犯错,在歌曲结束前击败它" };
//4* 7 28s 18s in game 10s
for (int i = 0; i < 6; i++)
{
label.Text = strings[i];
Etcs.info_Audio_Processer.playMusicClip("Message", 60);
await Task.Delay(4000);
if (i == 2)
{
loopStop = true;
while (Etcs.Song_Volume != 0)
{
Etcs.Song_Volume = Math.Max(Etcs.Song_Volume - 7, 0);
Etcs.song_Audio_Processer.volume_change(Etcs.Song_Volume);
await Task.Delay(100);
}
Etcs.song_Audio_Processer.pause_song();
Etcs.song_Audio_Processer.set_albums("Tatsh");
Etcs.song_Audio_Processer.set_song(Etcs.song_Audio_Processer.get_next_song());
Thread thread = new Thread(async () =>
{
for (int n = 0; n < 8; n++)
{
Etcs.Song_Volume += 7;
Etcs.song_Audio_Processer.volume_change(Etcs.Song_Volume);
await Task.Delay(500);
}
await Task.Delay(9000);
foreach (var item in new Label[] { , , })
Invoke(() => item.Visible = true);
});
thread.Start();
}
}
_pauseAllow = true;
label.SendToBack();
label.Visible = false;
label.Dispose();
}
PausePanel.Visible = false;
Etcs.song_Audio_Processer.SongFinished += Song_Audio_Processer_SongFinished;
ShowAudioVisualizer();
Etcs.hunderd_millsecond_timer.Elapsed += TimerTick;
}
private async void Song_Audio_Processer_SongFinished(Sound.Song_Audio_processer s, Sound.SongFinishedEventArgs e)
{
foreach (var item in new Label[] { , , })
item.Visible = false;
PausePanel.Visible = true;
PausePanel.BackgroundImage = Properties.Resources.trans;
for(int i=0;i<200;i+=10)
{
Color animRed = Color.FromArgb(i, 0, 0);
game_Panel.BackColor = animRed;
PausePanel.BackColor = animRed;
await Task.Delay(10);
}
PausePanel.BringToFront();
for(int i= 200;i<260;i+=10)
{
Color animRed = Color.FromArgb(i, 0, 0);
PausePanel.BackColor = animRed;
await Task.Delay(10);
}
Etcs.info_Audio_Processer.playMusicClip("failed");
Finished_Handler(this, new FinishArgs { finishType = FinishArgs.FinishType.Time_out });
}
int cur_score = 0;
public void Finished_Handler(object sender, FinishArgs e)
{
BeginInvoke(() =>
{
switch (e.finishType)
{
case FinishArgs.FinishType.All_done:
DoPause();
Form form = new FinishedMessageBox(cur_score, (int)curTime);
form.FormClosed += ((sender, args) =>
{
Dispose();
Close();
Etcs.form?.change_form(Etcs.charts, false, null, null);
});
form.ShowDialog();
break;
case FinishArgs.FinishType.Time_out:
退_Click(this, new EventArgs());
break;
}
});
}
private bool _pauseState = false;
private bool search_mode;
private int search_left_use_time;
/// <summary>
/// 需要测试!!
/// </summary>
private bool _pauseAllow = false;
private void DoPause()
{
if (!_pauseAllow)
return;
timer.Enabled = false;
Etcs.song_Audio_Processer.pause_song();
_pauseState = true;
Bitmap bit = new Bitmap(Width, Height);
Graphics g = Graphics.FromImage(bit);
g.CompositingQuality = CompositingQuality.HighQuality;
g.CopyFromScreen(Etcs.form!.Left+5, Etcs.form!.Top+43, 0, 0, new Size(Width, Height));
PausePanel.BringToFront();
Rectangle rectangle = new Rectangle(0, 0, bit.Width,bit.Height);
PausePanel.BackgroundImage= bit.GaussianBlur();
PausePanel.Visible = true;
GC.Collect();
}
private void DePause()
{
Etcs.song_Audio_Processer.resume_song();
_pauseState = false;
timer.Enabled = true;
PausePanel.Visible = false;
PausePanel.SendToBack();
}
public void TogglePause()
{
if (_pauseState)
DePause();
else
DoPause();
}
private void ShowAudioVisualizer()
{
Form audioVisualizer = new AudioVisualizer.MainWindow();
audioVisualizer.TopLevel = false;
audioVisualizer.Dock = DockStyle.Fill;
AudioVisualizerPanel.Controls.Add(audioVisualizer);
audioVisualizer.Show();
}
private void _Click(object sender, EventArgs e)
{
DePause();
}
private void 退_Click(object sender, EventArgs e)
{
Dispose();
Close();
Etcs.hunderd_millsecond_timer.Elapsed -= TimerTick;
Etcs.gameMenuForm!.playFormToMenu();
}
private void CanClickLabel_MouseEnter(object sender, EventArgs e)
{
(sender as Label)!.BackColor = Color.FromArgb(100, 100, 100);
}
private void CanClickLabel_MouseLeave(object sender, EventArgs e)
{
(sender as Label)!.BackColor = Color.FromArgb(0, 0, 0, 0);
}
public void De_pause(object sender, EventArgs e) { }
public void Score_Change(object sender, ChangeScoreArgs e)
{
if (e.add)
{
score += e.score;
if(search_mode)
{
search_left_use_time--;
if(search_left_use_time==0)
{
search_mode = false;
gameControl.Search_Handler(this, new SearchEventArgs { set_search = false });
}
}
}
else
score = Math.Min(0, score - e.score);
}
public void SetTheme() {
Etcs.current_block_theme = Etcs.Theme.code;
Etcs.gameModeForm = this;
}
private void DoSearch()
{
gameControl.Search_Handler(this, new SearchEventArgs { set_search = true });
search_mode = true;
search_left_use_time = 3;
}
private void DoRemake()
{
Task.Run(() => gameControl.Exchange_Handler(this, new EventArgs()));
}
public void GetGift_Handler(object sender, GiftArgs e)
{
Etcs.info_Audio_Processer.playMusicClip("HitSong");
switch (e.giftType)
{
case GiftArgs.GiftType.Search:
DoSearch();
break;
case GiftArgs.GiftType.ReMake:
DoRemake();
break;
}
}
}
}

View File

@ -1,39 +0,0 @@
namespace CDSAE3_Lian_Lian_Kan
{
partial class Challenge_Mode_MenuForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Challenge_Mode_MenuForm";
}
#endregion
}
}

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CDSAE3_Lian_Lian_Kan
{
public partial class Challenge_Mode_MenuForm : Form
{
public Challenge_Mode_MenuForm()
{
InitializeComponent();
}
}
}

View File

@ -121,7 +121,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
{
Thread thread= new Thread(()=>Invoke(()=>tablePanel.Controls.Clear()));
_left = _top = 0;
await Etcs.form!.change_form((Etcs.gameMenuForm as Form)!, false, null, null, false, null);
await Etcs.form!.change_form((Etcs.gameMenuForm as Form)!, false, null, null);
thread.Start();
}

View File

@ -28,29 +28,14 @@
/// </summary>
private void InitializeComponent()
{
playPanel = new TableLayoutPanel();
initWorker = new System.ComponentModel.BackgroundWorker();
SuspendLayout();
//
// playPanel
//
playPanel.BackColor = Color.FromArgb(0, 0, 0, 0);
playPanel.ColumnCount = 1;
playPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
playPanel.Dock = DockStyle.Fill;
playPanel.Location = new Point(0, 0);
playPanel.Name = "playPanel";
playPanel.RowCount = 1;
playPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
playPanel.Size = new Size(1400, 800);
playPanel.TabIndex = 1;
//
// GameControl
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.FromArgb(0, 0, 0, 0);
Controls.Add(playPanel);
Name = "GameControl";
Size = new Size(1400, 800);
Load += GameControl_Load;
@ -58,8 +43,6 @@
}
#endregion
private TableLayoutPanel playPanel;
private System.ComponentModel.BackgroundWorker initWorker;
}
}

View File

@ -1,5 +1,6 @@
using CDSAE3_Lian_Lian_Kan.Boards;
using CDSAE3_Lian_Lian_Kan.Forms.Interface;
using NAudio.Gui;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -11,36 +12,54 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static CDSAE3_Lian_Lian_Kan.Etcs;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
namespace CDSAE3_Lian_Lian_Kan.Forms
{
public partial class GameControl : UserControl, IGameControl
{
IBoard board = new Graph_Board();
IBoard board = Etcs.curAlgorithm switch
{
Algorithm.Array => new Board(),
Algorithm.Graph => new Graph_Board(),
_ => new Board()
};
IGameMode? iGameMode;
Queue<((int, int), Single_Block)> queue = new Queue<((int, int), Single_Block)>();//y,x
bool do_search = false;
List<Single_Block> hint_blocks = new List<Single_Block>();
bool doRandomGift = false;
bool doSubScore = false;
Dictionary<(int, int), (GiftArgs.GiftType, PictureBox)> giftBlock = new();
public GameControl()
{
}
public GameControl(Action<int>loadFinished)
{
InitializeComponent();
DoubleBuffered = true;
initWorker.WorkerReportsProgress = true;
initWorker.WorkerSupportsCancellation = true;
this.loadFinished = loadFinished;
initWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWorker);
initWorker.RunWorkerCompleted += InitWorker_RunWorkerCompleted;
Etcs.gameForm = this;
iGameMode = Etcs.gameModeForm;
}
Action<int>? loadFinished = null;
private void InitWorker_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e)
{
Etcs.loadFinished = true;
loadFinished?.Invoke(0);
}
public void GameControl_Load(object sender, EventArgs e)
{
if (Etcs.current_difficulty == Etcs.Difficulty.challenge)
doSubScore = doRandomGift = true;
Etcs.gameForm = this;
iGameMode = Etcs.gameModeForm;
Console.WriteLine("start");
Etcs.loadFinished = false;
initWorker.RunWorkerAsync();
@ -58,26 +77,35 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
void playPanel_set(int[,] bd)
{
playPanel.SuspendLayout();
SuspendLayout();
playPanel_size_change();
for (int i = 0; i < playPanel.RowCount; i++)
for (int j = 0; j < playPanel.ColumnCount; j++)
for (int i = 0; i < _row; i++)
for (int j = 0; j < _column; j++)
{
Console.WriteLine(i.ToString() + j.ToString());
if (bd[i, j] == -1)
{
var x = new Single_Block(Etcs.trans_Image, (j, i));
x.Dock = DockStyle.Fill;
Invoke(() => playPanel.Controls.Add(x, j, i));
var x = new Single_Block((j, i));
AddItem(x, i, j);
_index.Add((j, i), x);
}
else
{
var x = new Single_Block(bd[i, j], Etcs.def_Color, Etcs.sel_Color, (j, i));
x.Dock = DockStyle.Fill;
Invoke(() => playPanel.Controls.Add(x, j, i));
AddItem(x, i, j);
_index.Add((j, i), x);
}
}
Invoke(() => playPanel.ResumeLayout());
Invoke(() => ResumeLayout());
}
private void AddItem(Single_Block x, int i, int j)
{
Invoke(() =>
{
x.Size = new Size((int)single_width, (int)single_height);
x.Location = new Point((int)(j * single_width), (int)(i * single_height));
Controls.Add(x);
});
}
/// <summary>
/// 由form和to两个点获取方向
@ -111,14 +139,14 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
if (wait_time != 0)
await Task.Delay(wait_time);
Control? control = playPanel.GetControlFromPosition(point.Item1, point.Item2);
if (control != null && control is Single_Block single_Block)
Single_Block? control = _index.ContainsKey((point.Item1, point.Item2)) ? _index[(point.Item1, point.Item2)] : null;
if (control != null)
{
if (is_hint)
single_Block.hint_path(direction);
control.hint_path(direction);
else
single_Block.to_path(direction);
blocks.Add(single_Block);
control.to_path(direction);
blocks.Add(control);
}
}
async Task to_path((int, int) from, (int, int) to, bool include_end, Etcs.Direction extra_Direction, List<Single_Block> blocks, int wait_time, bool is_hint)
@ -212,6 +240,22 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
_ = Block_ClearAsync(path);
while (queue.Count() > 0)
queue.Dequeue();
foreach (var item in new[] { posa, posb })
{
if (giftBlock.TryGetValue(item, out (GiftArgs.GiftType, PictureBox) result))
{
iGameMode!.GetGift_Handler(this, new GiftArgs { giftType = result.Item1 });
DeleteGiftPicture(item, result);
}
}
if (doRandomGift)
{
Random random = new();
if (random.Next(0, 10) < 1)
{
SetGiftPicture(board.GetRandomBlock(), (GiftArgs.GiftType)(random.Next(1, 3) - 1));
}
}
}
else
{
@ -220,6 +264,10 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
de_set_tip();
set_tip();
}
if (doSubScore)
{
iGameMode!.Score_Change(this, new ChangeScoreArgs { add = false, score = 200 });
}
queue.Enqueue((e.position, sender));
sendera.deselect();
}
@ -244,6 +292,38 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
}
});
}
private void DeleteGiftPicture((int, int) item, (GiftArgs.GiftType, PictureBox) result)
{
Invoke(() =>
{
result.Item2.Visible = false;
result.Item2.SendToBack();
result.Item2.Dispose();
giftBlock.Remove(item);
});
}
private void SetGiftPicture((int, int)pos , GiftArgs.GiftType type)
{
var (picWidth, picHeight) = (single_width / 3, single_height / 3);
PictureBox picture = new PictureBox
{
Image = type switch
{
GiftArgs.GiftType.Search => Properties.Resources.w_search,
GiftArgs.GiftType.ReMake => Properties.Resources.w_exchange,
_ => Properties.Resources.trans
},
Size = new Size((int)picWidth, (int)picHeight),
SizeMode = PictureBoxSizeMode.Zoom,
Location = new Point((int)(((pos.Item1 + 1) * single_width) - picWidth), (int)(pos.Item2 * single_height))
};
Invoke(() => Controls.Add(picture));
Invoke(() => picture.BringToFront());
giftBlock.TryAdd(pos, (type, picture));
}
async Task Block_ClearAsync(List<(int, int)>? path)
{
if (do_search == true)
@ -253,45 +333,54 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
if (path == null)
return;
await path_drawerAsync(path, 20, blocks, false);
Control? controlA = playPanel.GetControlFromPosition(path[0].Item1, path[0].Item2), controlB = playPanel.GetControlFromPosition(path.Last().Item1, path.Last().Item2);
Single_Block? controlA = _index.ContainsKey((path[0].Item1, path[0].Item2)) ? _index[(path[0].Item1, path[0].Item2)] : null;
Single_Block? controlB = _index.ContainsKey((path.Last().Item1, path.Last().Item2)) ? _index[(path.Last().Item1, path.Last().Item2)] : null;
Etcs.info_Audio_Processer.play_random_break_soundScape();
if (controlA != null && controlB != null && controlA is Single_Block single_BlockA && controlB is Single_Block single_BlockB)
if (controlA != null && controlB != null)
{
single_BlockA.destroyAsync();
single_BlockB.destroyAsync();
controlA.destroyAsync();
controlB.destroyAsync();
}
await Task.Delay(200);
foreach (var control in blocks)
control.de_path();
iGameMode?.Score_Add(this, new AddScoreArgs { score = (blocks.Count + 2) * 10 });
iGameMode?.Score_Change(this, new ChangeScoreArgs { score = (blocks.Count + 2) * 10 });
}
private int _row = 0, _column = 0;
private double single_width = 0, single_height = 0;
private Dictionary<(int, int), Single_Block> _index = new();
void playPanel_size_change()
{
var (width, height) = board.size;
playPanel.RowCount = height + 2;
playPanel.ColumnCount = width + 2;
playPanel.ColumnStyles[0] = new ColumnStyle(SizeType.Percent, 100F);
playPanel.RowStyles[0] = new RowStyle(SizeType.Percent, 100F);
for (int i = 0; i < width + 1; i++)
playPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
for (int i = 0; i < height + 1; i++)
playPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
(_row, _column) = (height + 2, width + 2);
single_width = (double)Width / _column;
single_height = (double)Height / _row;
}
public void Exchange_Handler(object? sender, EventArgs e)
{
int[,] bd = board.remake_board();
playPanel.SuspendLayout();
SuspendLayout();
for (int i = 0; i < bd.GetLength(0); i++)
for (int j = 0; j < bd.GetLength(1); j++)
if (bd[i, j] == -1)
continue;
else
{
Control? control = playPanel.GetControlFromPosition(j, i);
if (control != null && control is Single_Block single_Block)
single_Block.Re_create(bd[i, j], null, null, null);
Single_Block? control = _index.ContainsKey((j, i)) ? _index[(j, i)] : null;
if (control != null)
control.Re_create(bd[i, j], null, null, null);
}
playPanel.ResumeLayout();
int length = giftBlock.Count();
foreach (var item in giftBlock)
{
DeleteGiftPicture(item.Key, item.Value);
}
for (int i = 0; i < length; i++)
{
Random random = new();
SetGiftPicture(board.GetRandomBlock(), (GiftArgs.GiftType)(random.Next(1, 3) - 1));
}
ResumeLayout();
}
public void Search_Handler(object? sender, SearchEventArgs e)

View File

@ -6,23 +6,35 @@ using System.Threading.Tasks;
namespace CDSAE3_Lian_Lian_Kan.Forms.Interface
{
public class AddScoreArgs : EventArgs
public class ChangeScoreArgs : EventArgs
{
public bool add { get; set; } = true; //1
public int score { get; set; }
}
public class GiftArgs:EventArgs
{
public enum GiftType
{
Search = 0,
ReMake = 1
}
public GiftType giftType { get; set; }
}
public class FinishArgs : EventArgs
{
public enum Finish_Type
public enum FinishType
{
All_done = 0,
Time_out = 1
}
public Finish_Type finish_Type { get; set; }
public FinishType finishType { get; set; }
}
public interface IGameMode : IThemeChangeable
{
public void TogglePause();
public void De_pause(object sender, EventArgs e);
public void Score_Add(object sender, AddScoreArgs e);
public void Score_Change(object sender, ChangeScoreArgs e);
public void Finished_Handler(object sender, FinishArgs e);
public void GetGift_Handler(object sender, GiftArgs e);
}
}

View File

@ -39,7 +39,6 @@
exchange = new PictureBox();
upper_search = new Item();
game_Panel = new Panel();
gameControl = new GameControl();
((System.ComponentModel.ISupportInitialize)back).BeginInit();
((System.ComponentModel.ISupportInitialize)sp_button).BeginInit();
((System.ComponentModel.ISupportInitialize)search).BeginInit();
@ -159,21 +158,11 @@
// game_Panel
//
game_Panel.BackColor = Color.FromArgb(50, 0, 0, 0);
game_Panel.Controls.Add(gameControl);
game_Panel.Location = new Point(20, 143);
game_Panel.Name = "game_Panel";
game_Panel.Size = new Size(1400, 800);
game_Panel.TabIndex = 0;
//
// gameControl
//
gameControl.BackColor = Color.FromArgb(0, 0, 0, 0);
gameControl.Dock = DockStyle.Fill;
gameControl.Location = new Point(0, 0);
gameControl.Name = "gameControl";
gameControl.Size = new Size(1400, 800);
gameControl.TabIndex = 13;
//
// Leisure_Mode
//
AutoScaleDimensions = new SizeF(11F, 24F);
@ -215,6 +204,5 @@
private PictureBox exchange;
private Item upper_search;
private Panel game_Panel;
private GameControl gameControl;
}
}

View File

@ -18,9 +18,11 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
public partial class Leisure_Mode : Form, IGameMode
{
GameControl gameControl;
public Leisure_Mode()
{
Etcs.gameModeForm = this;
Etcs.current_block_theme = Theme.fruit;
InitializeComponent();
upper_search.Item_Init(Resources.search, (70, 70), Color.FromArgb(253, 161, 60));
time.Text = (left_time / 60).ToString().PadLeft(2, '0') + ":" + (left_time % 60).ToString().PadLeft(2, '0');
@ -28,6 +30,9 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
timer = new System.Timers.Timer(1000);
timer.Elapsed += Timer_Tick;
timer.Enabled = false;
gameControl = new GameControl((t) => t++);
game_Panel.Controls.Add(gameControl);
gameControl.Dock = DockStyle.Fill;
}
System.Timers.Timer timer;
int hundred_up_timer = 0;
@ -80,7 +85,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
if (left_time < 0)
{
timer.Enabled = false;
Finished_Handler(this, new FinishArgs { finish_Type = FinishArgs.Finish_Type.Time_out });
Finished_Handler(this, new FinishArgs { finishType = FinishArgs.FinishType.Time_out });
}
if (is_pause) { timer.Enabled = false; }
}
@ -95,7 +100,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
Sp_button_Click(sender, e);
}
public void Score_Add(object sender, AddScoreArgs e)
public void Score_Change(object sender, ChangeScoreArgs e)
{
cur_score += e.score * factor_val;
current_base += e.score;
@ -136,18 +141,18 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
BeginInvoke(() =>
{
timer.Close();
switch (e.finish_Type)
switch (e.finishType)
{
case FinishArgs.Finish_Type.All_done:
case FinishArgs.FinishType.All_done:
Do_pause(this, new EventArgs());
Form form = new FinishedMessageBox(cur_score, Etcs.left_time - left_time);
form.FormClosed += ((sender, args) => {
Dispose();
Close();
Etcs.form?.change_form(charts, false, null, null, false, null); });
Etcs.form?.change_form(charts, false, null, null); });
form.ShowDialog();
break;
case FinishArgs.Finish_Type.Time_out:
case FinishArgs.FinishType.Time_out:
Thread thread = new Thread(() => MessageBox.Show("时间到!"));
thread.Start();
back_Click(this, new EventArgs());
@ -181,7 +186,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
{
Etcs.ThemeInfo themeInfo = Etcs.currentThemeInfo;
BackColor = Color.FromArgb(themeInfo.ThemeColor![0], themeInfo.ThemeColor[1], themeInfo.ThemeColor[2]);
gameControl.BackColor = BackColor;
//gameControl.BackColor = BackColor;
//gameControl.BackgroundImage = (Image)res_Manager.GetObject(themeInfo.PictureName!, Etcs.res_Culture)!;
if (themeInfo.PlayPanelUsePicture)
{
@ -191,5 +196,12 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
BackgroundImage = (Image)res_Manager.GetObject(themeInfo.PictureName!, Etcs.res_Culture)!;
}
}
public void GetGift_Handler(object sender, GiftArgs e){ }
public void TogglePause()
{
Sp_button_Click(this, new EventArgs());
}
}
}

View File

@ -5,6 +5,7 @@ using System.Text.Encodings.Web;
using System.Text.Unicode;
using System.ComponentModel;
using CDSAE3_Lian_Lian_Kan.Forms.Interface;
using System.Runtime.InteropServices;
namespace CDSAE3_Lian_Lian_Kan.Forms
{
@ -20,14 +21,14 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
{
Etcs.hunderd_millsecond_timer.Elapsed -= StartFunc;
Form? menuForm = null;
Invoke(() => menuForm = new Leisure_Mode_MenuForm());
Invoke(() => change_form(menuForm!, false, null, null, false, null));
Invoke(() => menuForm = new MenuForm());
Invoke(() => change_form(menuForm!, false, null, null));
}
public async Task change_form(Form newForm, bool doAnimation, Color? begin, Color? end, bool haveImage, Image? image)
public async Task change_form(Form newForm, bool doAnimation, Color? begin, Color? end)
{
if (doAnimation)
{
bufferForm.SetEffect(begin!.Value, end!.Value, haveImage, image);
bufferForm.SetEffect(begin!.Value, end!.Value);
bufferForm.BringToFront();
bufferForm.Visible = true;
}
@ -38,6 +39,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
MainPanel.Controls.Add(newForm);
BeginInvoke(() => newForm.Show());
MainPanel.SendToBack();
ActiveControl = newForm;
if (doAnimation)
{
await bufferForm.EffectAsync();
@ -45,5 +47,16 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
}
GC.Collect();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
KeyEventArgs e = new KeyEventArgs(keyData);
if (keyData == (Keys.Space))
{
Etcs.gameModeForm?.TogglePause();
//Console.WriteLine(" TogglePause();");
}
return true;
}
}
}

View File

@ -1,6 +1,6 @@
namespace CDSAE3_Lian_Lian_Kan.Forms
{
partial class Leisure_Mode_MenuForm
partial class MenuForm
{
/// <summary>
/// Required designer variable.
@ -81,6 +81,7 @@
to_Challenge_mode.TabIndex = 3;
to_Challenge_mode.Text = "挑战模式";
to_Challenge_mode.UseVisualStyleBackColor = false;
to_Challenge_mode.Click += to_Challenge_mode_Click;
//
// mainLabel
//
@ -93,7 +94,7 @@
mainLabel.TabIndex = 4;
mainLabel.Text = "连连看";
//
// Leisure_Mode_MenuForm
// MenuForm
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
@ -107,7 +108,7 @@
Controls.Add(to_table_of_scores);
DoubleBuffered = true;
FormBorderStyle = FormBorderStyle.None;
Name = "Leisure_Mode_MenuForm";
Name = "MenuForm";
Text = "MenuForm";
ResumeLayout(false);
}

View File

@ -1,13 +1,11 @@
namespace CDSAE3_Lian_Lian_Kan.Forms
{
public partial class Leisure_Mode_MenuForm : Form, IMenuForm
public partial class MenuForm : Form, IMenuForm
{
public Leisure_Mode_MenuForm()
public MenuForm()
{
InitializeComponent();
Etcs.gameMenuForm = this;
Etcs.song_Audio_Processer.set_albums("C418");
Etcs.song_Audio_Processer.set_song(Etcs.song_Audio_Processer.get_next_song());
SetTheme();
}
Color menuThemeColor, playThemeColor;
@ -49,25 +47,34 @@
mainLabel.ForeColor = Color.FromArgb(theme.FontColor![0], theme.FontColor[1], theme.FontColor[2]);
mainLabel.Location = new Point(theme.FontBlockPos![0], theme.FontBlockPos[1]);
mainLabel.Size = new Size(theme.FontBlockSize![0], theme.FontBlockSize[1]);
Etcs.song_Audio_Processer.set_albums(Etcs.curAlbum);
Etcs.song_Audio_Processer.set_song(Etcs.song_Audio_Processer.get_next_song());
}
public void playFormToMenu()
{
Etcs.form?.change_form(this, true, playThemeColor, menuThemeColor, AnimationUseImage, playPanelImage!);
Etcs.form?.change_form(this, true, playThemeColor, menuThemeColor);
}
private void start_Game_Click(object sender, EventArgs e)
{
Etcs.form?.change_form(new Leisure_Mode(), true, menuThemeColor, playThemeColor, AnimationUseImage, this.BackgroundImage);
Etcs.form?.change_form(new Leisure_Mode(), true, menuThemeColor, playThemeColor);
}
private void to_settings_Click(object sender, EventArgs e)
{
Etcs.form?.change_form(Etcs.setting, false, null, null, false, null);
Etcs.form?.change_form(Etcs.setting, false, null, null);
}
private void to_table_of_scores_Click(object sender, EventArgs e)
{
Etcs.form?.change_form(Etcs.charts, false, null, null, false, null);
Etcs.form?.change_form(Etcs.charts, false, null, null);
}
private void to_Challenge_mode_Click(object sender, EventArgs e)
{
//Etcs.form?.change_form(new Challenge_Mode(), true, menuThemeColor, playThemeColor, AnimationUseImage, this.BackgroundImage);
Etcs.form?.change_form(new Challenge_Mode(), true, menuThemeColor, Color.Black);
}
}
}

View File

@ -68,6 +68,9 @@
hard = new RadioButton();
normal = new RadioButton();
easy = new RadioButton();
groupAlgorithm = new GroupBox();
ArrayAlgorithm = new RadioButton();
GraphAlgorithm = new RadioButton();
((System.ComponentModel.ISupportInitialize)back).BeginInit();
contextPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)psButton).BeginInit();
@ -76,6 +79,7 @@
((System.ComponentModel.ISupportInitialize)soundScapeVolume).BeginInit();
((System.ComponentModel.ISupportInitialize)musicVolume).BeginInit();
groupDifficulty.SuspendLayout();
groupAlgorithm.SuspendLayout();
SuspendLayout();
//
// back
@ -105,6 +109,7 @@
//
contextPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
contextPanel.BackColor = SystemColors.ScrollBar;
contextPanel.Controls.Add(groupAlgorithm);
contextPanel.Controls.Add(button1);
contextPanel.Controls.Add();
contextPanel.Controls.Add(themeSelector);
@ -126,7 +131,7 @@
contextPanel.Controls.Add(groupDifficulty);
contextPanel.Location = new Point(71, 103);
contextPanel.Name = "contextPanel";
contextPanel.Size = new Size(1219, 1209);
contextPanel.Size = new Size(1193, 1209);
contextPanel.TabIndex = 21;
//
// button1
@ -523,6 +528,43 @@
easy.UseVisualStyleBackColor = true;
easy.CheckedChanged += Difficulty_CheckedChanged;
//
// groupAlgorithm
//
groupAlgorithm.BackColor = Color.FromArgb(0, 0, 0, 0);
groupAlgorithm.Controls.Add(GraphAlgorithm);
groupAlgorithm.Controls.Add(ArrayAlgorithm);
groupAlgorithm.Font = new Font("Microsoft YaHei UI", 15F);
groupAlgorithm.Location = new Point(61, 886);
groupAlgorithm.Name = "groupAlgorithm";
groupAlgorithm.Size = new Size(327, 208);
groupAlgorithm.TabIndex = 35;
groupAlgorithm.TabStop = false;
groupAlgorithm.Text = " 内部算法";
//
// ArrayAlgorithm
//
ArrayAlgorithm.AutoSize = true;
ArrayAlgorithm.Checked = true;
ArrayAlgorithm.Location = new Point(25, 45);
ArrayAlgorithm.Name = "ArrayAlgorithm";
ArrayAlgorithm.Size = new Size(102, 43);
ArrayAlgorithm.TabIndex = 0;
ArrayAlgorithm.TabStop = true;
ArrayAlgorithm.Text = "数组";
ArrayAlgorithm.UseVisualStyleBackColor = true;
ArrayAlgorithm.CheckedChanged += Algorithm_CheckedChanged;
//
// GraphAlgorithm
//
GraphAlgorithm.AutoSize = true;
GraphAlgorithm.Location = new Point(25, 105);
GraphAlgorithm.Name = "GraphAlgorithm";
GraphAlgorithm.Size = new Size(72, 43);
GraphAlgorithm.TabIndex = 1;
GraphAlgorithm.Text = "图";
GraphAlgorithm.UseVisualStyleBackColor = true;
GraphAlgorithm.CheckedChanged += Algorithm_CheckedChanged;
//
// Setting
//
AutoScaleDimensions = new SizeF(11F, 24F);
@ -547,6 +589,8 @@
((System.ComponentModel.ISupportInitialize)musicVolume).EndInit();
groupDifficulty.ResumeLayout(false);
groupDifficulty.PerformLayout();
groupAlgorithm.ResumeLayout(false);
groupAlgorithm.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
@ -592,5 +636,8 @@
private RadioButton hard;
private RadioButton normal;
private RadioButton easy;
private GroupBox groupAlgorithm;
private RadioButton GraphAlgorithm;
private RadioButton ArrayAlgorithm;
}
}

View File

@ -87,12 +87,16 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
{
var s = albumSelector.SelectedItem?.ToString();
if (s != null)
{
Etcs.song_Audio_Processer.set_albums(s);
Etcs.curAlbum = s;
}
nextSong_Click(this, new EventArgs());
}
private void musicVolume_Scroll(object? sender, EventArgs e)
{
Etcs.Song_Volume = musicVolume.Value;
Etcs.song_Audio_Processer.volume_change(musicVolume.Value);
if (sender != null)
songVolumeText.Text = musicVolume.Value.ToString();
@ -110,7 +114,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
{
CusSize_Validated(this, new EventArgs());
if (_canBack)
await Etcs.form!.change_form((Etcs.gameMenuForm as Form)!, false, null, null, false, null);
await Etcs.form!.change_form((Etcs.gameMenuForm as Form)!, false, null, null);
}
private void SetTimeText(int t) => time.Text = $"{t / 60}:{((t % 60) < 10 ? ("0" + (t % 60).ToString()) : (t % 60).ToString())}";
private int CalcTime(int total) => (int)(Math.Ceiling((double)total / 50)) * 60;//50per minute 向上取整
@ -136,7 +140,6 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
int ans = CalcTime(a * b);
Etcs.left_time = ans;
SetTimeText(ans);
}
private bool _cusDataChanged = false;
private void cusWidth_TextChanged(object sender, EventArgs e)
@ -255,5 +258,18 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
Etcs.currentThemeInfo = Etcs.themes[s!];
SetTheme();
}
private void Algorithm_CheckedChanged(object sender, EventArgs e)
{
switch ((sender as RadioButton)!.Name)
{
case "ArrayAlgorithm":
Etcs.curAlgorithm = Etcs.Algorithm.Array;
break;
case "GraphAlgorithm":
Etcs.curAlgorithm = Etcs.Algorithm.Graph;
break;
}
}
}
}

View File

@ -54,6 +54,7 @@
Name = "Single_Block";
Padding = new Padding(3);
Size = new Size(40, 40);
Load += Single_Block_Load;
((System.ComponentModel.ISupportInitialize)picture).EndInit();
ResumeLayout(false);
}

View File

@ -21,14 +21,14 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
if (Etcs.gameForm == null)
throw new Exception("game_form is null but try to make a new Single_Block");
Selected += Etcs.gameForm.Selected_Handler;
}
int imageID = -1;
public Single_Block(int image, Color default_backColor, Color select_Color, (int, int) pos)
{
block_id = image;
position = pos;
imageID = image;
InitializeComponent();
Image_change(Etcs.get_block_Image(image));
picture.SizeMode = PictureBoxSizeMode.Zoom;
nor_color = default_backColor;
sel_color = select_Color;
@ -39,7 +39,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
Selected += Etcs.gameForm.Selected_Handler;
}
public Single_Block(Image image, (int, int) pos)
public Single_Block((int, int) pos)
{
position = pos;
InitializeComponent();
@ -87,11 +87,29 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
Etcs.Direction direction = Etcs.Direction.none;
public void hint_path(Etcs.Direction direction)
{
if (picture == null)
{
picture = new PictureBox { Dock = DockStyle.Fill };
Invoke(() =>
{
Controls.Add(picture);
picture.BringToFront();
});
}
this.direction |= direction;
Image_change(Etcs.get_tip_direction_Image(this.direction));
}
public void to_path(Etcs.Direction direction)
{
if (picture == null)
{
picture = new PictureBox { Dock = DockStyle.Fill };
Invoke(() =>
{
Controls.Add(picture);
picture.BringToFront();
});
}
Image_change(Etcs.get_direction_Image(direction));
direction = Etcs.Direction.none;
}
@ -113,17 +131,38 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
int timer_Eplased = 0;
public void Image_Clear(object? sender, ElapsedEventArgs e)
{
if(timer_Eplased++ > 5)
if (timer_Eplased++ > 5)
{
Image_change(Etcs.trans_Image);
Etcs.hunderd_millsecond_timer.Elapsed-= Image_Clear;
Etcs.hunderd_millsecond_timer.Elapsed -= Image_Clear;
try
{
Invoke(() =>
{
if (picture == null)
return;
picture.Visible = false;
picture.Dispose();
Controls.Remove(picture);
picture = null;
});
}
catch
{ }
}
}
ConcurrentQueue<Image>images_queue = new ConcurrentQueue<Image>();
ConcurrentQueue<Image> images_queue = new ConcurrentQueue<Image>();
Thread? Image_setting_thread;
public void Image_change(Image new_image)
{
images_queue.Enqueue(new_image);
try
{
try
{ images_queue.Enqueue(new_image); }
catch (Exception)
{
Console.WriteLine("Unusual Exception");
throw;
}
if (Image_setting_thread == null || !Image_setting_thread.IsAlive)
{
Image_setting_thread = new Thread(() =>
@ -147,13 +186,21 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
Image_setting_thread.Start();
}
}
catch (Exception)
{
Console.WriteLine("unuasual 2");
throw;
}
}
private void Image_set(Image image)
{
try
{
lock (locker)
{
picture.Image = image;
if (picture == null)
picture = new PictureBox { Dock = DockStyle.Fill };
picture!.Image = image;
}
}
catch (Exception)
@ -177,7 +224,7 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
private void picture_MouseEnter(object sender, EventArgs e)
{
if(!can_be_selected || selected)
if (!can_be_selected || selected)
return;
BackColor = mouse_upper_color;
}
@ -189,6 +236,11 @@ namespace CDSAE3_Lian_Lian_Kan.Forms
BackColor = nor_color;
}
private void Single_Block_Load(object sender, EventArgs e)
{
Image_change(imageID == -1 ? Properties.Resources.trans : Etcs.get_block_Image(imageID));
}
public event SelectedEventHandler Selected;
}
public class SelectedEventArgs : EventArgs

View File

@ -0,0 +1,45 @@
namespace CDSAE3_Lian_Lian_Kan.Forms
{
partial class TimeLine
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
SuspendLayout();
//
// TimeLine
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
BackColor = Color.FromArgb(0, 0, 0, 0);
Name = "TimeLine";
Size = new Size(958, 10);
ResumeLayout(false);
}
#endregion
}
}

View File

@ -0,0 +1,45 @@
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CDSAE3_Lian_Lian_Kan.Forms
{
public partial class TimeLine : UserControl
{
public TimeLine()
{
InitializeComponent();
}
private Color _backColor = Color.FromArgb(0,0,0);
private Color _frontColor = Color.FromArgb(97, 97, 108);
public void set_progress(float progress, Color backColor, Color frontColor)
{
_backColor = backColor;
_frontColor = frontColor;
set_progress(progress);
}
public void set_progress(double progress)
{
SolidBrush upperBrush = new SolidBrush(_backColor);
SolidBrush lowerBrush = new SolidBrush(_frontColor);
SolidBrush pointBrush = new SolidBrush(Color.FromArgb(255, 255, 255));
Graphics formGraphics = CreateGraphics();
//formGraphics.SmoothingMode = SmoothingMode.HighQuality;
int wire = (int)(progress * Width);
formGraphics.FillRectangle(lowerBrush, new Rectangle(0, 0, wire, Height));
formGraphics.FillRectangle(pointBrush, new Rectangle(wire,0 , 4, Height));
formGraphics.FillRectangle(upperBrush, new Rectangle(wire + 4, 0, Width, Height));
upperBrush.Dispose();
lowerBrush.Dispose();
formGraphics.Dispose();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -60,6 +60,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] Ambient {
get {
object obj = ResourceManager.GetObject("Ambient", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -230,6 +240,26 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap cpp {
get {
object obj = ResourceManager.GetObject("cpp", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap cSharp {
get {
object obj = ResourceManager.GetObject("cSharp", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -290,6 +320,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] failed {
get {
object obj = ResourceManager.GetObject("failed", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -360,6 +400,26 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Gcpp {
get {
object obj = ResourceManager.GetObject("Gcpp", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap GcSharp {
get {
object obj = ResourceManager.GetObject("GcSharp", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -370,6 +430,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Ggo {
get {
object obj = ResourceManager.GetObject("Ggo", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -380,6 +450,36 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Gjava {
get {
object obj = ResourceManager.GetObject("Gjava", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Gkotlin {
get {
object obj = ResourceManager.GetObject("Gkotlin", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap go {
get {
object obj = ResourceManager.GetObject("go", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -390,6 +490,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Gpython {
get {
object obj = ResourceManager.GetObject("Gpython", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -400,6 +510,26 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Gruby {
get {
object obj = ResourceManager.GetObject("Gruby", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Grust {
get {
object obj = ResourceManager.GetObject("Grust", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -410,6 +540,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Gvue {
get {
object obj = ResourceManager.GetObject("Gvue", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -420,6 +560,36 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] HitSong {
get {
object obj = ResourceManager.GetObject("HitSong", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap java {
get {
object obj = ResourceManager.GetObject("java", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap kotlin {
get {
object obj = ResourceManager.GetObject("kotlin", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -460,6 +630,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] Message {
get {
object obj = ResourceManager.GetObject("Message", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -500,6 +680,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap python {
get {
object obj = ResourceManager.GetObject("python", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -510,6 +700,26 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ruby {
get {
object obj = ResourceManager.GetObject("ruby", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap rust {
get {
object obj = ResourceManager.GetObject("rust", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
@ -820,6 +1030,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] songInfoShow {
get {
object obj = ResourceManager.GetObject("songInfoShow", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
@ -840,6 +1060,16 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] Tatsh___Xenolith {
get {
object obj = ResourceManager.GetObject("Tatsh___Xenolith", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -1080,6 +1310,186 @@ namespace CDSAE3_Lian_Lian_Kan.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap vue {
get {
object obj = ResourceManager.GetObject("vue", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_d {
get {
object obj = ResourceManager.GetObject("w_d", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_dl {
get {
object obj = ResourceManager.GetObject("w_dl", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_dlr {
get {
object obj = ResourceManager.GetObject("w_dlr", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_dr {
get {
object obj = ResourceManager.GetObject("w_dr", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_exchange {
get {
object obj = ResourceManager.GetObject("w_exchange", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_l {
get {
object obj = ResourceManager.GetObject("w_l", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_lr {
get {
object obj = ResourceManager.GetObject("w_lr", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_r {
get {
object obj = ResourceManager.GetObject("w_r", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_search {
get {
object obj = ResourceManager.GetObject("w_search", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_u {
get {
object obj = ResourceManager.GetObject("w_u", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_ud {
get {
object obj = ResourceManager.GetObject("w_ud", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_udl {
get {
object obj = ResourceManager.GetObject("w_udl", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_udlr {
get {
object obj = ResourceManager.GetObject("w_udlr", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_udr {
get {
object obj = ResourceManager.GetObject("w_udr", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_ul {
get {
object obj = ResourceManager.GetObject("w_ul", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_ulr {
get {
object obj = ResourceManager.GetObject("w_ulr", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap w_ur {
get {
object obj = ResourceManager.GetObject("w_ur", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>

View File

@ -427,4 +427,127 @@
<data name="Sea_Power___Zaum" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Sea Power - Zaum.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="Ambient" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Ambient.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="failed" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\failed.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="HitSong" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HitSong.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="Message" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Message.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="songInfoShow" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\songInfoShow.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="Tatsh___Xenolith" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Tatsh - Xenolith.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="w_d" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_d.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_dl" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_dl.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_dlr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_dlr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_dr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_dr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_exchange" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_exchange.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_l" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_l.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_lr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_lr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_r" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_r.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_search" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_search.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_u" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_u.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_ud" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_ud.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_udl" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_udl.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_udlr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_udlr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_udr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_udr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_ul" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_ul.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_ulr" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_ulr.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="w_ur" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\w_ur.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="cpp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\cpp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="cSharp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\cSharp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gcpp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gcpp.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="GcSharp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\GcSharp.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Ggo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Ggo.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gjava" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gjava.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gkotlin" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gkotlin.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="go" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\go.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gpython" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gpython.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gruby" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gruby.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Grust" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Grust.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Gvue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gvue.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="java" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\java.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="kotlin" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\kotlin.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="python" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\python.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ruby" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ruby.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="rust" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\rust.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="vue" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\vue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -30,8 +30,12 @@ namespace CDSAE3_Lian_Lian_Kan.Sound
sound = new MemoryStream(source_obj);
ms = new MemoryStream(StreamToBytes(sound));
ws = new Mp3FileReader(ms);
blockAlignReductionStream = new BlockAlignReductionStream(ws);
wave16ToFloatProvider = new Wave16ToFloatProvider(blockAlignReductionStream);
wave16ToFloatProvider.Volume = volume / 100f;
waveOutEvent = new WaveOutEvent();
waveOutEvent.Init(wave16ToFloatProvider);
@ -73,7 +77,11 @@ namespace CDSAE3_Lian_Lian_Kan.Sound
waveOutEvent.Stop();
sound.Dispose();
ms.Dispose();
try
{
ws.Dispose();
}catch(Exception)
{ }
blockAlignReductionStream.Dispose();
waveOutEvent.Dispose();
GC.SuppressFinalize(this);

View File

@ -14,31 +14,31 @@ namespace CDSAE3_Lian_Lian_Kan.Sound
string last_break_soundScape = "";
Random random = new Random();
internal void set_SoundScape_version(Etcs.break_music version) => soundScape_version = version;
internal void play_random_break_soundScape()
internal void play_random_break_soundScape(int volume = -1, Action<string, AudioPlayer>? finished = null)
{
Task.Run(() =>
{
void finished(string s,AudioPlayer audioPlayer)
{
audioPlayer.Dispose();
}
AudioPlayer audioPlayer = new AudioPlayer(get_random_break_soundScape(), Etcs.Info_Volume,finished);
if (volume == -1)
volume = Etcs.Info_Volume;
if (finished == null)
finished = (s, player) => player.Dispose();
AudioPlayer audioPlayer = new AudioPlayer(get_random_break_soundScape(), volume, finished);
audioPlayer.resume_song();
//object obj = Settings.res_Manager.GetObject(get_random_break_soundScape(), Settings.res_Culture)!;
//var infoOutputDevice = new WaveOutEvent();
//using (var sound = new MemoryStream((byte[])obj))
//using (var ms = new MemoryStream(StreamToBytes(sound)))
//using (var ws = new Mp3FileReader(ms))
//using (var blockAlignReductionStream = new BlockAlignReductionStream(ws))
//{
// var wave16ToFloatProvider = new Wave16ToFloatProvider(blockAlignReductionStream);
// wave16ToFloatProvider.Volume = soundScape_volume / 100f;
// infoOutputDevice.Init(wave16ToFloatProvider);
// infoOutputDevice.PlaybackStopped += InfoOutputDevice_PlaybackStopped;
// infoOutputDevice.Play();
//}
});
}
internal void playMusicClip(string s,int volume = -1,Action<string ,AudioPlayer>?finished = null)
{
Task.Run(() =>
{
if (volume == -1)
volume = Etcs.Info_Volume;
if (finished == null)
finished = (s, player) => player.Dispose();
AudioPlayer audioPlayer = new AudioPlayer(s, volume, finished);
audioPlayer.resume_song();
});
}
private string get_random_break_soundScape()
{

View File

@ -10,13 +10,22 @@ using CDSAE3_Lian_Lian_Kan.Properties;
using NAudio.Wave.SampleProviders;
namespace CDSAE3_Lian_Lian_Kan.Sound
{
public class SongFinishedEventArgs : EventArgs
{
public string SongName { get; set; }
public SongFinishedEventArgs(string songName) => SongName = songName;
}
public delegate void SongFinishedEventHandler(Song_Audio_processer s, SongFinishedEventArgs e);
public class Song_Audio_processer:IDisposable
{
AudioPlayer? audioPlayer;
private List<string> audioFiles = new List<string>();
public event SongFinishedEventHandler? SongFinished;
int next_song = 1;
private void OnPlaybackStopped(string s,object? obj)
{
SongFinished?.Invoke(this, new SongFinishedEventArgs(s));
set_song(get_next_song());
}
public void pause_song()=> audioPlayer?.pause_song();
@ -44,19 +53,20 @@ namespace CDSAE3_Lian_Lian_Kan.Sound
public void volume_change(int val)=> audioPlayer?.volume_change(val);
public void set_albums(string s)
{
next_song = 0;
var result = Etcs.musics.Where(x => x.Key == s).ToList();
if (result.Count == 0)
throw new Exception("no such album");
audioFiles = result.First().Value;
Etcs.setting.SetAlbum(result.First().Key);
}
public void set_song(string s)
internal void set_song(string s,int volume = -1,Action<string,AudioPlayer>? finished = null)
{
Etcs.setting.SetSongInfo(s);
audioPlayer?.Dispose();
try
{
audioPlayer = new AudioPlayer(s, Etcs.Song_Volume, OnPlaybackStopped);
audioPlayer = new AudioPlayer(s, volume == -1 ? Etcs.Song_Volume : volume, finished ?? OnPlaybackStopped);
}
catch (Exception e)
{