前言
前几天做了个桌面宠物,将效果和代码分享一下。
效果预览
贴图素材出自《侠客风云传》
1.拥有待机动画,呼吸效果,轮播台词。
2.可以拖动,拖动有交互反馈。
3.可以随时切换贴图,更改台词,切换呼吸频率。
实现技术与控件
- Winform窗体
- 文件流读写
- 多线程与定时器
- 鼠标绑定事件
- 坐标系更新与随机数生成
- PictureBox控件,contextMenuStrip控件,ToolTip控件
- 额外的小功能,锁屏,锁定键盘,用WindowsAPI实现
具体实现
窗体代码
using DeskPet.Properties;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DeskPet
{
public partial class Form1 : Form
{
//键盘操作类
KeyBroadClass KeyBroadBlock = new KeyBroadClass();
bool IsBlock = false;//锁定键盘标志位
//基本参数
private bool IsMouseDown;//是否点击鼠标
private Point MousePoint;//鼠标坐标
public int duration = 5000;//时间间隔
public int Opreation_flag=0;//操作动作标志
public int Duration
{
get
{
return duration;
}
set
{
duration = value;
toolTipTimer.Interval = duration;
}
}
public bool IsSettingOpen = false;//设置窗打开时不弹台词
public string charaterName = "东方未明";//角色名字
public string CharaterName
{
get
{
return charaterName;
}
set
{
charaterName = value;
textform.UserName = value;
}
}
//随机切换表情
private Random random = new Random();
private Image Curimage;//当前表情
private string Curimage_name;//当前表情文件名
private bool IsChanging = false;//防止冲突
//文字集合
public string[] tootipText = {
"哎哟~你干嘛~~", "这是什么武功?", "痛啊,别拖我啦!" };
public string[] TimerText = {
"真是无聊啊~", "努力!加油!终有一天,我也可以成为武林盟主!", "努力修行的一天!" };
public string[] StarText = {
"少侠,好久不见!" };
private string[] TouchText = {
"喂!别乱来啊!你在碰哪呢?", "你是在吃我豆腐吗?","拖就拖,别碰我那里!" };
string CurrentText = "";//当前文字
//定时器
private System.Windows.Forms.Timer toolTipTimer;
//判断窗体是否失去焦点
private bool IsDeactivate = false;
//对话窗
TextForm textform;
//贴图设置
public int Breath_Size_nums = 4; //呼吸幅度
public int Breath_Fre_nums = 200; //呼吸频率
Thread Pic_Bre;
public bool isBreath = true;//是否呼吸
bool IsFirstLoad = false;//第一次加载
public string imageFold = $@"{
Environment.CurrentDirectory}/image/小师弟";//加载贴图的文件夹
public string ImageFold
{
get
{
return imageFold;
}
set
{
imageFold = value;
LoadNewImage(imageFold);
}
}
// 获取指定目录中所有的 PNG 图片文件路径
string[] imageFiles {
get; set; }
public bool IsBreath
{
get
{
return isBreath;
}
set
{
isBreath = value;
if (isBreath && !IsFirstLoad && Pic_Bre == null)
{
Pic_Bre = new Thread(PicBreath);
Pic_Bre.IsBackground = true;
Pic_Bre.Start();
}
IsFirstLoad = false;
}
}
private int old_height;
private int old_top;
public Form1()
{
InitializeComponent();
// 创建计时器
toolTipTimer = new System.Windows.Forms.Timer();
toolTipTimer.Interval = duration; // 设置为5分钟的毫秒数
toolTipTimer.Tick += ToolTipTimer_Tick;
// 启动计时器
toolTipTimer.Start();
//保持前置
TopMost = true;
//隐藏任务栏
ShowInTaskbar = false;
//打开对话窗体
textform = new TextForm(2000, charaterName);
//textform.Visible = false;
textform.Show();
textform.Visible = false;
}
/// <summary>
/// 鼠标点下时切换表情,并且记录鼠标坐标
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MouseDown_Event(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//随机切换表情
ChangePictureBoxImage();
IsMouseDown = true;
MousePoint = Cursor.Position;
//切换文字提示
int TextIndex = ChangeToopTipText(tootipText);
CurrentText = tootipText[TextIndex];
}
}
/// <summary>
/// 鼠标松开时的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MouseUp_Event(object sender, MouseEventArgs e)
{
IsMouseDown = false;
pictureBox1.Image = Curimage;
}
/// <summary>
/// 鼠标移动时的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MouseMove_Event(object sender, MouseEventArgs e)
{
if (IsMouseDown && e.Button == MouseButtons.Left)
{
Point snap = Cursor.Position;
this.Location = new Point(Location.X + (snap.X - MousePoint.X), Location.Y + (snap.Y - MousePoint.Y));
textform.Location = new Point(Location.X, Location.Y - 100);
MousePoint = Cursor.Position;
// 更新ToolTip的位置,使其跟随PictureBox的上方
Point toolTipLocation = new Point(pictureBox1.Location.X + 180, pictureBox1.Location.Y + 200);
toolTip1.Show(CurrentText, pictureBox1, toolTipLocation, 500);
}
}
/// <summary>
/// 窗口透明化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
//初始化贴图
LoadNewImage(imageFold);
this.BackColor = Color.FromArgb(0, 0, 1);
this.TransparencyKey = this.BackColor;
//初始化
Curimage_name = imageFiles[0];
Image randomImage = Image.FromFile(Curimage_name);
Curimage = randomImage;
// 获取程序执行的目录
string programDirectory = Environment.CurrentDirectory;
//拖动时的文字文件
string La_Text_configFilePath = Path.Combine(programDirectory, "La_Text_Config.txt");
//定时弹出的文字文件
string Timer_Text_configFilePath = Path.Combine(programDirectory, "Timer_Text_Config.txt");
//开始时的文字文件
string Start_Text_configFilePath = Path.Combine(programDirectory, "Start_Text_Config.txt");
//配置文件
string ConfigText_configFilePath = Path.Combine(programDirectory, "ConfigText.txt");
//解析文本