首先先和各位旅行者道个歉,混池都过去这么久了才把软件开发好并发布出来 >_<
创作目的:为给各位旅行者(当然包括我自己)估测混池抽取的出货率以及让各位旅行者可以过手瘾,故开发了此项目作为参考。
创作说明:该软件的一切结果仅可作为参考,并非游戏内所得结果;软件在部分情况下可能运行不佳,个人开发软件兼容性可能较差请谅解。
目录
一、软件基本介绍
(一)软件的基本运行需求
(二)软件的基本界面
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;//绘制的圆角半径
#endregion
private 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-250
if ((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()));
#endregion
private 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/1
randomNum = 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/1
Code = 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-29
randomNum = CreateRandomNumber(12);
Code = 17 + randomNum;
NUM_Prayer++;//4星累计保底值
}
else if (randomNum >= 498 && randomNum <= 994)
{//4星武器,30-49
randomNum = CreateRandomNumber(20);//该卡池内总共有20把4星武器
Code = 29 + randomNum;
NUM_Prayer++;//4星累计保底值
}
else
{//4星保底有0.6%概率抽取到5星
if (WillingCount == 0)
{//定轨为0/1
randomNum = 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/1
Code = 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/1
randomNum = 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/1
Code = 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);
}
#endregion
private 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
}
#endregion
private 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;
#endregion
private 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;
}//根据祈愿次数修改、重置UI
label_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;
#endregion
private 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();
#endregion
private 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字