首先先和各位旅行者道个歉,混池都过去这么久了才把软件开发好并发布出来 >_<
创作目的:为给各位旅行者(当然包括我自己)估测混池抽取的出货率以及让各位旅行者可以过手瘾,故开发了此项目作为参考。
创作说明:该软件的一切结果仅可作为参考,并非游戏内所得结果;软件在部分情况下可能运行不佳,个人开发软件兼容性可能较差请谅解。
目录
一、软件基本介绍
(一)软件的基本运行需求
(二)软件的基本界面
1.加载界面
2.主界面
3.详情界面
4.历史记录界面
5.祈愿结果界面
(三)软件的基本使用方法
(四)常见问题的解决方法
1.打开时显示缺少FrameWork框架
2.运行过程中显示文件不存在
3.其他问题
二、软件与项目获取途径
(一)软件安装包
(二)项目开源压缩包
三、项目源代码
(一)LoadForm窗体
(二)MDIForm窗体
(三)MainForm窗体
(四)PrayerForm窗体
(五)InformationForm窗体
(六)HistoryForm窗体
(七).manifest文件
四、其他说明
一、软件基本介绍
(一)软件的基本运行需求
- 系统版本需求:最佳运行环境为Windows11。
- Framework需求:最低版本为.NET Framework 4.6.1。
- 内存(运存)需求:最少0.5GB.
- 存储大小需求:最少70MB,包含Framework则最少200MB.
(二)软件的基本界面
1.加载界面
2.主界面
3.详情界面
4.历史记录界面
5.祈愿结果界面
(三)软件的基本使用方法
软件的基本使用与游戏内几乎一致,略有不同的地方在下方列出声明:
- 进行祈愿之前必须先选择定轨目标,否则将无法进行祈愿。
- 点击加载界面可跳过加载。
- 祈愿结果界面点击空白处即可返回祈愿界面。
- 根据旅行者不同需求,模拟器保留了自由选择生成随机数参数的方法,软件将使用用户选择的方法生成随机数,软件默认以“密码学随机数”方法生成随机数。
- “详情”界面与游戏内或有不同,因软件开始开发时混池已经结束,无法直接获取关于混池的详情界面内容。
- 点击界面右上角叉号将直接退出软件,若不想退出软件,请按照游戏内操作方法点击界面内部的关闭按钮。
- 历史记录界面支持滚轮滚动切换页数。
(四)常见问题的解决方法
1.打开时显示缺少FrameWork框架
请在微软官网下载并安装Framework框架,要求最低版本为4.6.1 。
2.运行过程中显示文件不存在
说明您的安装包被修改过或安装后被修改,请尝试恢复被修改的资源或卸载并重新安装,若安装后还是出现此错误,请在本界面所附的连接下载该软件的安装包。
3.其他问题
运行过程中出现的一切无法处理的问题均可以向作者反馈。
二、软件与项目获取途径
注:所有下载均为免费,若遇到需要收费以下载此软件的途径,请将其视为诈骗。
(一)软件安装包
CSDN站内:安装包CSDN站内下载传送门
百度网盘:安装包下载-百度网盘途径-传送门 提取码:YSHC
123云盘:安装包下载-123云盘途径-传送门
(二)项目开源压缩包
CSDN站内:项目开源CSDN站内下载传送门
百度网盘:项目开源下载-百度网盘途径-传送门 提取码:YSHC
123云盘:项目开源下载-123云盘途径-传送门
三、项目源代码
注:此处仅展示完整代码,不作技术描述,关键的部分都有注释,若追求更好的体验请下载开源项目。程序入口为LoadForm()。
(一)LoadForm窗体
设计样式:
页面源代码:
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 原神混池模拟器
{public partial class LoadForm : Form{public LoadForm(){InitializeComponent();}#region 变量的声明MDIForm MF = null;int ActionCounter = 0;private const int BorderRadius = 125;//绘制的圆角半径#endregionprivate void LoadForm_Load(object sender, EventArgs e){panel_Load.Width = 0;}protected override void OnPaint(PaintEventArgs e){//绘制圆角窗体base.OnPaint(e);GraphicsPath path = new GraphicsPath();path.AddArc(0, 0, BorderRadius, BorderRadius, 180, 90); // 左上角 path.AddArc(this.Width - BorderRadius, 0, BorderRadius, BorderRadius, 270, 90); // 右上角 path.AddArc(this.Width - BorderRadius, this.Height - BorderRadius, BorderRadius, BorderRadius, 0, 90); // 右下角 path.AddArc(0, this.Height - BorderRadius, BorderRadius, BorderRadius, 90, 90); // 左下角 path.CloseFigure();this.Region = new Region(path);}private void timer_Ticker_Tick(object sender, EventArgs e)//仅负责加载动画{ActionCounter++;//1-140,140-240,240-250if ((ActionCounter >= 0) && (ActionCounter <= 140)){panel_Load.Width = 5 * ActionCounter;}else{if ((ActionCounter > 240) && (ActionCounter <= 250))panel_Load.Width = 5 * (ActionCounter - 100);}if (ActionCounter==275){timer_Ticker.Stop();MF = new MDIForm();MF.Show();this.Hide();}}private void LoadForm_MouseClick(object sender, MouseEventArgs e){if (ActionCounter<=240)ActionCounter = 240;}private void pictureBox_Load_MouseClick(object sender, MouseEventArgs e){if (ActionCounter <= 240)ActionCounter = 240;}private void panel_Load_MouseClick(object sender, MouseEventArgs e){if (ActionCounter <= 240)ActionCounter = 240;}private void pictureBox1_MouseClick(object sender, MouseEventArgs e){if (ActionCounter <= 240)ActionCounter = 240;}}
}
(二)MDIForm窗体
注:该窗体为MDI父窗体。
设计样式:
页面源代码:
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 原神混池模拟器
{public partial class MDIForm : Form{public MDIForm(){InitializeComponent();this.FormBorderStyle = FormBorderStyle.Sizable;this.MaximumSize = this.MinimumSize = this.Size;this.DoubleBuffered = true;}private void MDIForm_Load(object sender, EventArgs e){InformationForm IF = new InformationForm();IF.MdiParent = this;HistoryForm HF = new HistoryForm();HF.MdiParent = this;PrayerForm PF = new PrayerForm();PF.MdiParent = this;MainForm MF = new MainForm(IF, HF, PF);MF.MdiParent = this;MF.Show();}}
}
(三)MainForm窗体
注:该窗体为MDI子窗体。
设计样式:
页面源代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Security.Cryptography;namespace 原神混池模拟器
{public partial class MainForm : Form{public MainForm(InformationForm InfoForm, HistoryForm HisForm, PrayerForm PraForm){InitializeComponent();IF = InfoForm;HF = HisForm;PF = PraForm;}/*编码(Code)划分表:* 1-6为5星角色(总6件)* 7-17为5星武器(总11件)* 18-29为4星角色(总12件)* 30-49为4星武器(总20件)* 50-62为3星武器(总13件)*/#region 变量的声明Color BottomPanelColor = Color.Gray;public int WillingCount = 0;//记录当前命定值public int NUM_Prayer = 0;//记录当前距离上次出金的抽数public string SelectedWilling = "0";//使用stoi(SW)转化成int,也即int.Parse(SW)string[] NameOfWilling = new string[18] { "0","Eula","Mona","Albedo","Klee","Diluc","Jean","SkywardBlade","AquilaFavonia","BeaconOfTheReedSea","SongOfBrokenPines","Wolf'sGravestone","SkywardPride","SkywardSpine","LostPrayerToTheSacredWinds","SkywardAtlas","Hunter’sPath","SkywardHarp"};//储存编号与名称的映射关系string[] ChineseName=new string[18]{"0","浪沫的旋舞·优菈(冰)","星天水镜·莫娜(水)","白垩之子·阿贝多(岩)","逃跑的太阳·可莉(火)","晨曦的暗面·迪卢克(火)","蒲公英骑士·琴(风)", //这里开始是武器"单手剑·天空之刃","单手剑·风鹰剑","双手剑·苇海信标","双手剑·松籁响起之时","双手剑·狼的末路","双手剑·天空之傲","长柄武器·天空之脊","法器·四风原典","法器·天空之卷","弓·猎人之径","弓·天空之翼"};//储存编号与中文名称的映射关系/** 0是空编号* 1-6分别是列表中的六名角色,顺序一致* 7-17分别为列表中的十一件武器,顺序一致*/string[] NameOf_4_Stars = new string[32] {"TheStringless","FavoniusWarbow","Rust","AlleyHunter","MitternachtsWaltz","SacrificialFragments","FavoniusCodex","EyeOfPerception","WineAndSong","Dragon'sBane","FavoniusLance","FavoniusGreatsword","TheBell","SacrificialGreatsword","Rainslasher","FavoniusSword","TheFlute","Lion'sRoar","SacrificialSword","TheAlleyFlash",//这里开始是4星角色,编号从20开始"Amber","Barbara","Bennett","Diona","Fischl","Kaeya","Lisa","Mika","Noelle","Razor","Rosaria","Sucrose"};//四星武器与角色的名称,0-19为武器,20及之后为角色string[] NameOf_3_Stars = new string[13]{"BlackTassel","ThrillingTalesOfDragonSlayers","EmeraldOrb","MagicGuide","Slingshot","Sharpshooter'sOath","RavenBow","DebateClub","FerrousShadow","BloodtaintedGreatsword","HarbingerOfDawn","SkyriderSword","CoolSteel"};//13件3星武器InformationForm IF = null;//详情界面HistoryForm HF = null;//历史记录界面PrayerForm PF = null;//抽卡显示界面public int NumOfHistory = 0;//记录当前历史记录的条数public string[,] History = new string[1000, 3];//记录祈愿历史记录/* 第一维度为第n次抽取* 第二维度0为类型(第一列),1为名称(第二列),2为时间(第四列)*/bool HistoryIsFull = false;// 线程局部存储的Random对象,确保每个线程都有自己的Random实例 private static ThreadLocal<Random> random = new ThreadLocal<Random>(() => new Random(Guid.NewGuid().GetHashCode()));#endregionprivate void MainForm_Load(object sender, EventArgs e){//this.FormBorderStyle = FormBorderStyle.Sizable;panel_History.BackColor = panel_Info.BackColor =panel_Prayer_1.BackColor = panel_Prayer_10.BackColor = Color.FromArgb(0, 0, 0, 0);for (int i = 0; i < 1000; i++)for (int j = 0; j < 3; j++)History[i, j] = "";//初始化数组radioButton_Rand_1.Checked = true;}private void MainForm_FormClosed(object sender, FormClosedEventArgs e){ExitTheApp();//退出软件}private void MainForm_FormClosing(object sender, FormClosingEventArgs e){ExitTheApp();//退出软件}public void ExitTheApp(){Application.Exit();}//此函数用于检查并处理仍在运行的线程等事件,并退出软件private void pictureBox_Info_Click(object sender, EventArgs e){IF.Show();}private void pictureBox_History_Click(object sender, EventArgs e){//NumOfHistory = 67;//调试用HF.Reshow(History,NumOfHistory);//将数据传入HF并让其显示出来}private void pictureBox_Prayer_1_Click(object sender, EventArgs e){if (SelectedWilling == "0")//如果未定轨MessageBox.Show("您未进行对定轨目标的选择,暂时无法进行祈愿。请先选择您的定轨目标后再进行祈愿。", "提示", MessageBoxButtons.OK);else{//进行了定轨,接下来按定轨内容进行祈愿操作int[] Obtained=new int[1] { PrayerMode() };PF.Reshow(Obtained, 1, (Obtained[0] >= 1 && Obtained[0] <= 17)? true:false);//这里要输入参数}}private void pictureBox_Prayer_10_Click(object sender, EventArgs e){if (SelectedWilling == "0")//如果未定轨MessageBox.Show("您未进行对定轨目标的选择,暂时无法进行祈愿。请先选择您的定轨目标后再进行祈愿。", "提示", MessageBoxButtons.OK);else{//进行了定轨,接下来按定轨内容进行祈愿操作int[] Obtained = new int[10];bool HasGold = false;for (int i = 1; i <= 10; i++){Obtained[i - 1] = PrayerMode();if (!HasGold)HasGold = HasGold || (Obtained[i - 1] >= 1 && Obtained[i - 1] <= 17);}PF.Reshow(Obtained,10,HasGold);//这里也要输入参数}}private int PrayerMode(){//进行单次祈愿模拟的方法,返回值为获取物件对应的编码/*根据游戏内描述:* 90五星保底,10四星保底* 五星0.6%,抽到5星时50%概率为定轨目标* 歪时,定轨角色就歪角色,定轨武器就歪武器* 四星武器和角色各自2.55%* 根据0.6%=60/10000=3/500,2.55%=255/10000=51/2000,所以生成一个1-2000的随机数* 则1-12为五星,13-63为4星角色,64-114为4星武器,其余为3星武器*/int Code = 0;int randomNum;if (NUM_Prayer == 90){//触发保底if (WillingCount == 0){//定轨为0/1randomNum = CreateRandomNumber(1000);if (randomNum >= 1 && randomNum <= 500){//没歪Code = int.Parse(SelectedWilling);}else{//歪了int SW = int.Parse(SelectedWilling);if (SW >= 1 && SW <= 6){//定轨角色只歪角色(1-6中除去定轨的随机生成一个)do{randomNum = CreateRandomNumber(6);} while (randomNum == SW);//一直随机生成直到生成的随机数不是定轨目标}else{//定轨武器只歪武器(7-17中除去定轨随机生成一个)do{randomNum = CreateRandomNumber(11) + 6;//生成范围7-17} while (randomNum == SW);//一直生成随机数直到与用户定轨目标不相同为止}Code = randomNum;WillingCount = 1;//命定值增加1}}else{//定轨为1/1Code = int.Parse(SelectedWilling);WillingCount = 0;//命定值清零}NUM_Prayer = 0;//5星清空保底值}else{//没触发五星保底机制时if (NUM_Prayer%10 == 0){//触发了4星保底randomNum = CreateRandomNumber(1000);if (randomNum >=1 && randomNum <= 497){//4星角色,18-29randomNum = CreateRandomNumber(12);Code = 17 + randomNum;NUM_Prayer++;//4星累计保底值}else if (randomNum >= 498 && randomNum <= 994){//4星武器,30-49randomNum = CreateRandomNumber(20);//该卡池内总共有20把4星武器Code = 29 + randomNum;NUM_Prayer++;//4星累计保底值}else{//4星保底有0.6%概率抽取到5星if (WillingCount == 0){//定轨为0/1randomNum = CreateRandomNumber(1000);if (randomNum >= 1 && randomNum <= 500){//没歪Code = int.Parse(SelectedWilling);}else{//歪了int SW = int.Parse(SelectedWilling);if (SW >= 1 && SW <= 6){//定轨角色只歪角色(1-6中除去定轨的随机生成一个)do{randomNum = CreateRandomNumber(6);} while (randomNum == SW);//一直随机生成直到生成的随机数不是定轨目标}else{//定轨武器只歪武器(7-17中除去定轨随机生成一个)do{randomNum = CreateRandomNumber(11) + 6;//生成范围7-17} while (randomNum == SW);//一直生成随机数直到与用户定轨目标不相同为止}Code = randomNum;WillingCount = 1;//命定值增加1}}else{//定轨为1/1Code = int.Parse(SelectedWilling);WillingCount = 0;//命定值清零}NUM_Prayer = 0;//5星清空保底值}//4星保底抽到5星的算法}else{//没触发4星保底randomNum = CreateRandomNumber(2000);if (randomNum >= 1 && randomNum <= 12){//抽到了五星if (WillingCount == 0){//定轨为0/1randomNum = CreateRandomNumber(1000);if (randomNum >= 1 && randomNum <= 500){//没歪Code = int.Parse(SelectedWilling);}else{//歪了int SW = int.Parse(SelectedWilling);if (SW >= 1 && SW <= 6){//定轨角色只歪角色(1-6中除去定轨的随机生成一个)do{randomNum = CreateRandomNumber(6);} while (randomNum == SW);//一直随机生成直到生成的随机数不是定轨目标}else{//定轨武器只歪武器(7-17中除去定轨随机生成一个)do{randomNum = CreateRandomNumber(11) + 6;//生成范围7-17} while (randomNum == SW);//一直生成随机数直到与用户定轨目标不相同为止}Code = randomNum;WillingCount = 1;//命定值增加1}}else{//定轨为1/1Code = int.Parse(SelectedWilling);WillingCount = 0;//命定值清零}NUM_Prayer = 0;//抽到了五星就要清空五星积累}else if (randomNum >= 13 && randomNum <= 63){//抽到了四星角色randomNum = CreateRandomNumber(12);//该卡池内总共有12个4星角色Code = 17 + randomNum;NUM_Prayer++;//4星累计保底值}else if (randomNum >= 64 && randomNum <= 114){//抽到了四星武器randomNum = CreateRandomNumber(20);//该卡池内总共有20把4星武器Code = 29 + randomNum;NUM_Prayer++;//4星累计保底值}else{//只抽到了三星武器randomNum = CreateRandomNumber(13);//总共13件3星武器Code = 49 + randomNum;NUM_Prayer++;//3星累计保底值}}}label_Num_Willing.Text = WillingCount.ToString();WriteTheHistoryRecord(Code, NumOfHistory);if (NumOfHistory < 1000) NumOfHistory++;if (NumOfHistory == 1000 && (!HistoryIsFull)) HistoryIsFull = true;return Code;}//进行单次祈愿模拟的方法,返回值为获取物件对应的编码private int CreateRandomNumber(int N){//生成随机数的方法int _rand = 0;if (radioButton_Rand_1.Checked){//使用密码学方法生成随机数using (var rng = new RNGCryptoServiceProvider()){// 生成一个随机字节数组 byte[] randomBytes = new byte[4]; // 4 bytes for a uint32 rng.GetBytes(randomBytes);// 将字节数组转换为整数 _rand = BitConverter.ToInt32(randomBytes, 0);_rand = Math.Abs(_rand) % N + 1;}}else{_rand = Math.Abs(random.Value.Next(1, N + 1));//生成1-N的随机数}return _rand;//生成了一个1-N的随机数}//生成随机数的方法private void WriteTheHistoryRecord(int Code,int Num){if (HistoryIsFull){//记录已满,进行迭代for (int i = 0; i < 999; i++)for (int j = 0; j < 3; j++)History[i, j] = History[i + 1, j];//然后History[999,n]的位置空出来的Num = 999;}History[Num, 0] = ((Code >= 1 && Code <= 6) || (Code >= 18 && Code <= 29)) ? "角色" : "武器";History[Num, 1] = PF.ChineseNameOfItem[Code];//从PF窗体获取中文名并写入历史记录//然后把抽取时间写入History[Num,2]History[Num, 2] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");}#region 一大段panel变色代码private void pictureBox_Info_MouseEnter(object sender, EventArgs e){panel_Info.BackColor = BottomPanelColor;}private void pictureBox_Info_MouseLeave(object sender, EventArgs e){panel_Info.BackColor = Color.FromArgb(0, 0, 0, 0);}private void pictureBox_History_MouseEnter(object sender, EventArgs e){panel_History.BackColor = BottomPanelColor;}private void pictureBox_History_MouseLeave(object sender, EventArgs e){panel_History.BackColor = Color.FromArgb(0, 0, 0, 0);}private void pictureBox_Prayer_1_MouseEnter(object sender, EventArgs e){panel_Prayer_1.BackColor = BottomPanelColor;}private void pictureBox_Prayer_1_MouseLeave(object sender, EventArgs e){panel_Prayer_1.BackColor = Color.FromArgb(0, 0, 0, 0);}private void pictureBox_Prayer_10_MouseEnter(object sender, EventArgs e){panel_Prayer_10.BackColor = BottomPanelColor;}private void pictureBox_Prayer_10_MouseLeave(object sender, EventArgs e){panel_Prayer_10.BackColor = Color.FromArgb(0, 0, 0, 0);}private void pictureBox_Change_Willing_MouseEnter(object sender, EventArgs e){panel_ChangeWilling.BackColor = BottomPanelColor;}private void pictureBox_Change_Willing_MouseLeave(object sender, EventArgs e){panel_ChangeWilling.BackColor = Color.FromArgb(0, 0, 0, 0);}#endregionprivate void pictureBox_Change_Willing_MouseDown(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left){// 在鼠标点击的位置显示ContextMenuStrip contextMenuStrip_Willings.Show(pictureBox_Change_Willing, e.Location);}}#region 给SelectedWilling赋值以及将上一个选择赋给HistoryWilling的语句块private void ChangeWilling(string Temp)//修改定轨目标所用的函数{if ((int.Parse(SelectedWilling) != 0)&&(Temp!=SelectedWilling)){DialogResult dr = MessageBox.Show("您确定要把定轨目标从\"" + ChineseName[int.Parse(SelectedWilling)]+ "\"改为\"" + ChineseName[int.Parse(Temp)] + "\"吗?修改后命定值将清零!", "提醒",MessageBoxButtons.YesNo);//询问用户是否更改if (dr == DialogResult.Yes){//用户选择了修改定轨目标的选项WillingCount = 0;label_Num_Willing.Text = "0";SelectedWilling = Temp;}}else if (int.Parse(SelectedWilling) == 0) SelectedWilling = Temp;try{pictureBox_Willing.Image =Image.FromFile("bins\\source\\H_" + NameOfWilling[int.Parse(SelectedWilling)] + ".png");}catch (Exception ex){MessageBox.Show("出现错误:" + ex.Message, "ERROR",MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void 浪末的旋舞优菈冰ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("1");}private void 星天水镜莫娜水ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("2");}private void 白垩之子阿贝多岩ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("3");}private void 逃跑的太阳可莉火ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("4");}private void 晨曦的暗面迪卢克火ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("5");}private void 蒲公英骑士琴风ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("6");}private void 单手剑天空之刃ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("7");}private void 单手剑风鹰剑ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("8");}private void 双手剑苇海信标ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("9");}private void 双手剑松籁响起之时ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("10");}private void 双手剑狼的末路ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("11");}private void 双手剑天空之傲ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("12");}private void 长柄武器天空之脊ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("13");}private void 法器四风原典ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("14");}private void 法器天空之卷ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("15");}private void 弓猎人之径ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("16");}private void 弓天空之翼ToolStripMenuItem_Click(object sender, EventArgs e){ChangeWilling("17");}private void 弓天空之翼ToolStripMenuItem_Click_1(object sender, EventArgs e){ChangeWilling("17");//为什么会有这个事件???//但是没有这段又有bug}#endregionprivate void pictureBox_Willing_Click(object sender, EventArgs e){}private void label_Willing_Click(object sender, EventArgs e){}private void label_Num_Willing_Click(object sender, EventArgs e){}private void pictureBox_Change_Willing_Click(object sender, EventArgs e){}private void panel_ChangeWilling_Paint(object sender, PaintEventArgs e){}private void panel_Info_Paint(object sender, PaintEventArgs e){}private void panel_History_Paint(object sender, PaintEventArgs e){}private void panel_Prayer_1_Paint(object sender, PaintEventArgs e){}}
}
(四)PrayerForm窗体
注:该窗体为MDI子窗体。
设计样式:
页面源代码:
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 原神混池模拟器
{public partial class PrayerForm : Form{public PrayerForm(){InitializeComponent();PB[0] = pictureBox1;PB[1] = pictureBox2;PB[2] = pictureBox3;PB[3] = pictureBox4;PB[4] = pictureBox5;PB[5] = pictureBox6;PB[6] = pictureBox7;PB[7] = pictureBox8;PB[8] = pictureBox9;PB[9] = pictureBox10;P_PB[0] = panel1;P_PB[1] = panel2;P_PB[2] = panel3;P_PB[3] = panel4;P_PB[4] = panel5;P_PB[5] = panel6;P_PB[6] = panel7;P_PB[7] = panel8;P_PB[8] = panel9;P_PB[9] = panel10;}#region ChineseNameOfItem数组的声明,没事别打开!public string[] ChineseNameOfItem = new string[63]{"0",//从1开始"优菈","莫娜","阿贝多","可莉","迪卢克","琴",//以上1-6为5星角色,总6项"天空之刃","风鹰剑","苇海信标","松籁响起之时","狼的末路","天空之傲","天空之脊","四风原典","天空之卷","猎人之径","天空之翼",//以上7-17为5星武器,总11项"安柏","芭芭拉","班尼特","迪奥娜","菲谢尔","凯亚","丽莎","米卡","诺艾尔","雷泽","罗莎莉亚","砂糖",//以上18-29为4星角色,总12项"绝弦","西风猎弓","弓藏","暗巷猎手","幽夜华尔兹","祭礼残章","西风秘典","昭心","暗巷的酒与诗","匣里灭辰","西风长枪","西风大剑","钟剑","祭礼大剑","雨裁","西风剑","笛剑","匣里龙吟","祭礼剑","暗巷闪光",//以上30-49为4星武器,总20项"黑缨枪","讨龙英杰谭","翡玉法球","魔导绪论","弹弓","神射手之誓","鸦羽弓","以理服人","铁影阔剑","沐浴龙血的剑","黎明神剑","飞天御剑","冷刃"//以上50-62为3星武器,总13项};#endregion#region EnglishNameOfItem数组的声明,没事别点开!private string[] EnglishNameOfItem = new string[63]{"0",//从0开始"Eula","Mona","Albedo","Klee","Diluc","Jean",//以上是5星角色"SkywardBlade","AquilaFavonia","BeaconOfTheReedSea","SongOfBrokenPines","Wolf'sGravestone","SkywardPride","SkywardSpine","LostPrayerToTheSacredWinds","SkywardAtlas","Hunter’sPath","SkywardHarp",//以上是5星武器"Amber","Barbara","Bennett","Diona","Fischl","Kaeya","Lisa","Mika","Noelle","Razor","Rosaria","Sucrose",//以上是4星角色"TheStringless","FavoniusWarbow","Rust","AlleyHunter","MitternachtsWaltz","SacrificialFragments","FavoniusCodex","EyeOfPerception","WineAndSong","Dragon'sBane","FavoniusLance","FavoniusGreatsword","TheBell","SacrificialGreatsword","Rainslasher","FavoniusSword","TheFlute","Lion'sRoar","SacrificialSword","TheAlleyFlash",//以上是4星武器"BlackTassel","ThrillingTalesOfDragonSlayers","EmeraldOrb","MagicGuide","Slingshot","Sharpshooter'sOath","RavenBow","DebateClub","FerrousShadow","BloodtaintedGreatsword","HarbingerOfDawn","SkyriderSword","CoolSteel"//以上是3星武器};#endregion#region 变量的声明int[] Obtained = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };//储存获取的角色或武器的Code编码int[] StarNumber = new int[10] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };//储存对应星级的数组int NumOfParyer = 1;PictureBox[] PB = new PictureBox[10];Panel[] P_PB = new Panel[10];int TimeCounter = 0;#endregionprivate void PrayerForm_Load(object sender, EventArgs e){label_Exit.Location = new Point(this.Width / 2 - label_Exit.Width / 2, label_Exit.Location.Y);}public void Reshow(int[] TheRecoed,int Num=1,bool Has_5_Stars=false){Obtained = TheRecoed;NumOfParyer = Num;for (int i = 0; i < Num; i++)StarNumber[i] = CodeTurnTheStarNumber(Obtained[i]);bool HasGold = false;switch (NumOfParyer){case 1:for (int i=1;i<10;i++)PB[i].Visible = P_PB[i].Visible = false;//隐藏不必出现的控件PB[0].Location = new Point(737, 150);P_PB[0].Location = new Point(737, 671);//显示图片try{PB[0].Image = Image.FromFile("bins\\source\\" + EnglishNameOfItem[Obtained[0]] + ".png");}catch(Exception Ex){MessageBox.Show("出现错误:" + Ex.Message, "出错啦", MessageBoxButtons.OK);}switch (StarNumber[0]){case 5:P_PB[0].BackColor = Color.Gold;break;case 4:P_PB[0].BackColor = Color.Purple;break;case 3:P_PB[0].BackColor = Color.RoyalBlue;break;}break;case 10:{for (int i = 0; i < 10; i++){PB[i].Location = new Point(50 + 155 * i, 150);P_PB[i].Location = new Point(PB[i].Location.X, 671);PB[i].Visible = P_PB[i].Visible = true;HasGold = HasGold || (StarNumber[i] == 5);//判断十连是否出金,后面会用到}int Temp = 0;for (int i = 0; i < 10; i++){for (int j = i+1; j < 10; j++)if (StarNumber[j] > StarNumber[i]){Temp = StarNumber[j];StarNumber[j] = StarNumber[i];StarNumber[i] = Temp;Temp = Obtained[j];Obtained[j] = Obtained[i];Obtained[i] = Temp;}}//对抽到的角色/武器按照星数进行排序for (int i = 0; i < 10; i++){//显示图片try{PB[i].Image = Image.FromFile("bins\\source\\" + EnglishNameOfItem[Obtained[i]] + ".png");}catch (Exception Ex){MessageBox.Show("出现错误:" + Ex.Message, "出错啦", MessageBoxButtons.OK);}switch (StarNumber[i]){case 5: P_PB[i].BackColor = Color.Gold; break;case 4: P_PB[i].BackColor = Color.Purple; break;case 3: P_PB[i].BackColor = Color.RoyalBlue; break;}}break;}default:MessageBox.Show("叫你不要乱改别人代码或者篡改数据,这下好了,出错了!",">_<", MessageBoxButtons.OK);break;}//根据祈愿次数修改、重置UIlabel_Skip.Visible = true;//接下来是动画的加载以及UI中图片的布置if (axWindowsMediaPlayer_Load.Width != 1600) axWindowsMediaPlayer_Load.Width = 1600;axWindowsMediaPlayer_Load.Visible = true;switch (NumOfParyer){case 1://如果是单抽,就包含蓝、紫、金三种抽卡动画{try{axWindowsMediaPlayer_Load.URL = "bins\\Prayer_1_" + StarNumber[0].ToString() + ".mp4";}catch(Exception Ex){MessageBox.Show("出错啦!错误信息:" + Ex.Message, "出错啦", MessageBoxButtons.OK);}break;}case 10://如果是十连,就只有出紫和出金两种动画{try{axWindowsMediaPlayer_Load.URL = "bins\\Prayer_10_" + (4 + ((HasGold) ? 1 : 0)).ToString() + ".mp4";}catch(Exception Ex){MessageBox.Show("出错啦!错误信息:" + Ex.Message, "出错啦", MessageBoxButtons.OK);}break;}default:MessageBox.Show("叫你不要乱改别人代码或者篡改数据,这下好了,出错了!",">_<", MessageBoxButtons.OK);break;}//抽卡动画的加载TimeCounter = 0;timer_Load.Enabled = true;timer_Load.Start();//this.Show();}//让窗体播放动画、重置界面布局、加载内容的方法public int CodeTurnTheStarNumber(int Code){int Num = 3;if (Code >= 1 && Code <= 17) Num = 5;else if (Code >= 18 && Code <= 49) Num = 4;return Num;}//将Code编码转化为星级数的方法private void label_Skip_Click(object sender, EventArgs e){axWindowsMediaPlayer_Load.URL = "";axWindowsMediaPlayer_Load.Width = 0;axWindowsMediaPlayer_Load.Visible = false;label_Skip.Visible = false;}private void PrayerForm_Click(object sender, EventArgs e){this.Hide();}private void label_Exit_Click(object sender, EventArgs e){this.Hide();}private void timer_Load_Tick(object sender, EventArgs e){TimeCounter++;if (TimeCounter>=60){timer_Load.Stop();axWindowsMediaPlayer_Load.Width = 0;axWindowsMediaPlayer_Load.Visible = false;axWindowsMediaPlayer_Load.URL = "";}}}
}
(五)InformationForm窗体
注:该窗体为MDI子窗体。
设计样式:
页面源代码:
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;
using System.Diagnostics;namespace 原神混池模拟器
{public partial class InformationForm : Form{public InformationForm(){InitializeComponent();pictureBox_Info.MouseWheel += new MouseEventHandler(pictureBox_Info_MouseWheel);}#region 变量的声明private bool dragging = false;private Point dragCursorPoint;private Point dragFormPoint;bool MouseWheelMove = false;#endregionprivate void InformationForm_Load(object sender, EventArgs e){}private void pictureBox_Exit_Click(object sender, EventArgs e){this.Hide();}private void pictureBox_Info_MouseDown(object sender, MouseEventArgs e){dragging = true;dragCursorPoint = Cursor.Position;dragFormPoint = pictureBox_Info.Location;}private void pictureBox_Info_MouseEnter(object sender, EventArgs e){MouseWheelMove = true;pictureBox_Info.Focus();}private void pictureBox_Info_MouseLeave(object sender, EventArgs e){MouseWheelMove = false;}private void pictureBox_Info_MouseMove(object sender, MouseEventArgs e){if (dragging){Point dif = Point.Subtract(Cursor.Position, new Size(dragCursorPoint));int minY = -(pictureBox_Info.Height - panel_Info.Height); // 最小 y 坐标 int maxY = 0; // 最大 y 坐标 int y = pictureBox_Info.Location.Y + dif.Y / 25;if (y >= minY && y <= maxY)pictureBox_Info.Location = new Point(pictureBox_Info.Location.X, y);else{if (y < minY) pictureBox_Info.Location = new Point(pictureBox_Info.Location.X, minY);if (y > maxY) pictureBox_Info.Location = new Point(pictureBox_Info.Location.X, maxY);}}}private void pictureBox_Info_MouseUp(object sender, MouseEventArgs e){dragging = false;}private void pictureBox_Info_MouseWheel(object sender, MouseEventArgs e){//使用鼠标滚轮进行控制的操作if (MouseWheelMove){int minY = -(pictureBox_Info.Height - panel_Info.Height); // 最小 y 坐标 int maxY = 0; // 最大 y 坐标 int y = pictureBox_Info.Location.Y + e.Delta / Math.Abs(e.Delta) * 100;if (y >= minY && y <= maxY)pictureBox_Info.Location = new Point(pictureBox_Info.Location.X, y);else{if (y < minY) pictureBox_Info.Location = new Point(pictureBox_Info.Location.X, minY);if (y > maxY) pictureBox_Info.Location = new Point(pictureBox_Info.Location.X, maxY);}}}private void pictureBox_About_Click(object sender, EventArgs e){try{Process.Start("http://sherrychou.blog.csdn.net");}catch (Exception ex){MessageBox.Show("出现错误:" + ex.Message, "出错啦", MessageBoxButtons.OK);}}private void pictureBox_Info_Click(object sender, EventArgs e){}}
}
(六)HistoryForm窗体
注:该窗体为MDI子窗体。
设计样式:
页面源代码:
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 原神混池模拟器
{public partial class HistoryForm : Form{public HistoryForm(/*string[,] _history, int _max=200*/){InitializeComponent();this.MouseWheel += new MouseEventHandler(Form_MouseWheel);//HistoryRecord = _history;//MaxPage = _max;LabelMatrix[0, 0] = label1_1;LabelMatrix[0, 1] = label1_2;LabelMatrix[0, 2] = label1_4;LabelMatrix[1, 0] = label2_1;LabelMatrix[1, 1] = label2_2;LabelMatrix[1, 2] = label2_4;LabelMatrix[2, 0] = label3_1;LabelMatrix[2, 1] = label3_2;LabelMatrix[2, 2] = label3_4;LabelMatrix[3, 0] = label4_1;LabelMatrix[3, 1] = label4_2;LabelMatrix[3, 2] = label4_4;LabelMatrix[4, 0] = label5_1;LabelMatrix[4, 1] = label5_2;LabelMatrix[4, 2] = label5_4;}#region 变量的声明string[,] HistoryRecord = new string[1000, 3];bool MouseWheelMove = false;int CurrentPage = 1;int MaxPage = 200, NumOfHistory = 1000;Label[,] LabelMatrix = new Label[5, 3];const int X_Labeln_2 = 540;PrayerForm _pf = new PrayerForm();#endregionprivate void HistoryForm_Load(object sender, EventArgs e){//Nothing running}private void Form_MouseWheel(object sender, MouseEventArgs e){if (MouseWheelMove){int y = e.Delta / Math.Abs(e.Delta);switch (y){case 1:if (CurrentPage > 1)CurrentPage--;break;case -1:if (CurrentPage < MaxPage-((NumOfHistory % 5 == 0)? 1:0))CurrentPage++;break;default:MessageBox.Show("出现错误:数据错误无法解析!", "x_x", MessageBoxButtons.OK);break;}UpdateTheList(CurrentPage);//更新显示内容}}private void pictureBox_Exit_Click(object sender, EventArgs e){this.Hide();}private void HistoryForm_MouseEnter(object sender, EventArgs e){MouseWheelMove = true;}private void HistoryForm_MouseLeave(object sender, EventArgs e){MouseWheelMove = false;}private void UpdateTheList(int PageNumber){//更新显示出的列表的内容的方法label_Page.Text = PageNumber.ToString();label_Page.Location = new Point((this.Width - label_Page.Width) / 2, label_Page.Location.Y);//以上更新页码显示并使其居中//接下来更新列表显示内容int _temp = 0,LastLine;LastLine = Math.Max(NumOfHistory - (PageNumber - 1) * 5 - 5, 0);label1_3.Text = label2_3.Text = label3_3.Text = label4_3.Text = label5_3.Text = "";for (int i = 0; i <= 4; i++)for (int j = 0; j < 3; j++)LabelMatrix[i, j].Text = "";//先清空原先显示的内容for (int i = NumOfHistory - (PageNumber - 1) * 5-1; i >= LastLine; i--){int Temp = -(i - NumOfHistory + (PageNumber - 1) * 5) - 1;for (int j = 0; j < 3; j++){LabelMatrix[Temp, j].Text = HistoryRecord[i, j];if (j == 1){LabelMatrix[Temp, j].Location = new Point(X_Labeln_2 - LabelMatrix[Temp, j].Width / 2,LabelMatrix[Temp, j].Location.Y);//居中_temp = 0;do{_temp++;if (_pf.ChineseNameOfItem[_temp] == LabelMatrix[Temp, j].Text)break;} while (true);if (_temp >= 1 && _temp <= 17) LabelMatrix[Temp, j].ForeColor = Color.Gold;else if (_temp >= 18 && _temp <= 49) LabelMatrix[Temp, j].ForeColor = Color.Purple;else LabelMatrix[Temp, j].ForeColor = Color.Black;}}switch (Temp){case 0: label1_3.Text = "集录祈愿"; break;case 1: label2_3.Text = "集录祈愿"; break;case 2: label3_3.Text = "集录祈愿"; break;case 3: label4_3.Text = "集录祈愿"; break;case 4: label5_3.Text = "集录祈愿"; break;default: MessageBox.Show("出现错误:数据参数无法解析!", "x_x", MessageBoxButtons.OK); break;}}}private void pictureBox_Left_Click(object sender, EventArgs e){UpdateTheList(CurrentPage = (CurrentPage > 1) ? (CurrentPage - 1) : 1);}private void pictureBox_Right_Click(object sender, EventArgs e){UpdateTheList(CurrentPage = (CurrentPage < MaxPage - ((NumOfHistory % 5 == 0) ? 1 : 0)) ? (CurrentPage + 1) : CurrentPage);}private void pictureBox_Left_DoubleClick(object sender, EventArgs e){if (CurrentPage >= 1)switch (CurrentPage){case 1:case 2:case 3:UpdateTheList(CurrentPage = 1);break;default:UpdateTheList(CurrentPage = CurrentPage - 2);break;}else MessageBox.Show("出现了意料之外的错误!", "x_x", MessageBoxButtons.OK);}private void pictureBox_Right_DoubleClick(object sender, EventArgs e){int TempMaxPage = NumOfHistory / 5 + ((NumOfHistory % 5 == 0) ? 0 : 1);if (CurrentPage <= TempMaxPage)if (CurrentPage == TempMaxPage || CurrentPage == TempMaxPage - 1 || CurrentPage == TempMaxPage - 2)UpdateTheList(CurrentPage = TempMaxPage);else UpdateTheList(CurrentPage = CurrentPage + 2);else MessageBox.Show("出现了意料之外的错误!", "x_x", MessageBoxButtons.OK);}public void Reshow(string[,] _history,int _num=1000){//让该页面重新显示的方法/*内容包括但不限于:* 将History[,]传入该页面* 更新列表内容* 将首先显示出的页面设置为1*/HistoryRecord = _history;MaxPage = _num/5 + 1;NumOfHistory = _num;UpdateTheList(CurrentPage = 1);//将CP重新赋值为1并更新列表显示this.Show();}}
}
(七).manifest文件
将以下代码取消注释:
<application xmlns="urn:schemas-microsoft-com:asm.v3"><windowsSettings><dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware></windowsSettings></application>
四、其他说明
- 该软件不用于盈利,不允许被用于盈利,不允许用作商业用途。
- 软件中的图片与视频素材版权所有仍归游戏《原神》所属公司所有。
- 该模拟器模拟结果仅作为参考,请勿将其当作游戏内祈愿的必定结果。
- 该项目为作者的个人项目,开发力量微薄,出现bug还请谅解,同时也欢迎广大用户反馈!
字数统计菌:28,521字