华容道问题求解_详细设计(六)之简单互动和动画

简单互动

为了增加趣味性,增加了简单的互动功能,即实现了一个简单的华容道游戏。在HrdGame中有两个鼠标操作的函数,在传入的控件中调用这个两个函数就可以了。
代码如下:
Click事件

        private void pnl_GameBoard_MouseClick(object sender, MouseEventArgs e) => _hrdGame.Click(e);

MouseMove事件

      private void pnl_GameBoard_MouseMove(object sender, MouseEventArgs e){if(cbx_ByHuman.Checked)//增加了一个界面控制CheckBox_hrdGame.MouseMove(e);}

mouseMove中的代码相对简单,并没有有抓取棋子的操作,只是在滑过的棋子做了高亮处理,这样显得稍微生动一些。

Click 事件核心代码

       internal void Click(MouseEventArgs e){var openPcsLst = GetOpenPcs();// select an open piecevar basicPcsArr = GetPieces();// pay attention to here , after the serilization !!!!!!!!!!!!!!// 检查鼠标是否在点击了 Open Piece,如果是则认为是选择了该 棋子,如果不是,则认为是把之前的棋子移动到这个位置。foreach (var openPcs in openPcsLst){var idx = openPcs.piece.idx;var pcs = basicPcsArr[idx];Rectangle pcsRect = new Rectangle((int)pcs.PcsLoc.X, (int)pcs.PcsLoc.Y, pcs.PcsSize.Width, pcs.PcsSize.Height);if (pcsRect.Contains(e.Location)){gameState.selPcs = pcs;RefreshLayout();break;}}// 移动到鼠标点击位置的合理性判断,如果是空白区域,则进行移动处理。if (gameState.selPcs == null){return;}var blnkPcs = GetBlanks();foreach (var blkPcs in blnkPcs){//var pcs = openPcs.piece;Rectangle pcsRect = new Rectangle((int)blkPcs.PcsLoc.X, (int)blkPcs.PcsLoc.Y, blkPcs.PcsSize.Width,blkPcs.PcsSize.Height);if (pcsRect.Contains(e.Location)){var selPcs = gameState.selPcs;var selPos = selPcs.GetHrdPos();var blkPos = blkPcs.GetHrdPos();if (Math.Abs(selPos.X - blkPos.X) < 2 + selPcs.PcsSize.Width && Math.Abs(selPos.Y - blkPos.Y) < 2 + selPcs.PcsSize.Height){ // might move the selected block and into the initial stateif (selPcs.MoveDir != ""){//移动时做一个简单的动画处理MoveWithAnimation(selPcs, blkPcs);RefreshLayout();break; ;}}}}var tmpHasCode = GetMyHashCodeV1(gameState);_curHashCode = tmpHasCode;}

简单动画

说明:代码是在GPT给的代码基础上进行改写的。
利用Timer事件,每隔一段时间显示一个画面,并进行痕迹的擦除。使用了大量的成员变量进行传值,这样简化俩Timer函数参数问题。另外对鼠标事件的多次快速点击没有做处理,因此会有重入发生,导致效果有些混乱。
核心代码如下:

       internal void MovePcsWithAnimation(Piece selPcs, HrdPoint srcPos, HrdPoint dstPos, HrdPoint anotherPos, Piece emptySp, Piece anotherES){curSelPcs=selPcs;srcPcsHrdLoc = HrdPosToLoc(srcPos);targeHrdLocLst = new List<PointF>();if(selPcs.GetHrdType()==HRDGame.TYPE_SMALL_PIECE && Math.Abs(srcPos.X - dstPos.X)+Math.Abs(srcPos.Y-dstPos.Y) == 2){// need to move to the another piece first //anotherPos = new HrdPointHrdPosToLoc(dstPos);var anotherLoc =  HrdPosToLoc(anotherPos);targeHrdLocLst.Add(anotherLoc);}targeHrdLocLst.Add(HrdPosToLoc(dstPos));srcBkgdRect = new Rectangle((int)selPcs.PcsLoc.X, (int)selPcs.PcsLoc.Y, selPcs.PcsSize.Width, selPcs.PcsSize.Height);animotionLocLstIdx = 0;timerTuple.selPcs = selPcs;timerTuple.srcPos = srcPos;timerTuple.dstPos= dstPos;timerTuple.anotherPos= anotherPos;timerTuple.emptySp = emptySp;timerTuple.anotherES = anotherES;timer.Start(); // Start the animation}

timer事件调用 movePcs函数,函数没有优化,因此代码比较冗长。核心代码如下

       private void MovePcs(){int speed = 5; // Adjust the speed of the animation//Refresh the background ;//float oldX,oldY;Rectangle tailRec= new Rectangle(0,0,0,0);// used to clear the back ground if(animotionLocLstIdx>= targeHrdLocLst.Count){return;}var targeHrdLoc= targeHrdLocLst[animotionLocLstIdx];//计算移动后的棋子的坐标和大小,并计算移动后需要擦除的区域//#############################################if (srcPcsHrdLoc.X < targeHrdLoc.X){tailRec.X = (int)srcPcsHrdLoc.X;tailRec.Y = (int)srcPcsHrdLoc.Y;tailRec.Width = speed;tailRec.Height = curSelPcs.PcsSize.Height;srcPcsHrdLoc.X += speed;}else if ...}////#############################################// 根据上述计算结果,进行绘制curSelPcs.PcsLoc = srcPcsHrdLoc;var g=_ctrl.CreateGraphics();DrawRegularBox(g, curSelPcs);g.FillRectangle(new SolidBrush(Color.Gray), tailRec);//srcBkgdRect = tRec;if (Math.Abs(srcPcsHrdLoc.X - targeHrdLoc.X) <= 5 && Math.Abs(srcPcsHrdLoc.Y - targeHrdLoc.Y) <= 5){animotionLocLstIdx++;if (animotionLocLstIdx < targeHrdLocLst.Count && animotionLocLstIdx>0){var tLoc = targeHrdLocLst[animotionLocLstIdx-1];//curSelPcs pcs.PcsSize.Width,pcs.PcsSize.HeightsrcBkgdRect = new Rectangle((int)(tLoc.X), (int)(tLoc.Y), curSelPcs.PcsSize.Width, curSelPcs.PcsSize.Height);}//判断是否移动可以移动两步(一个正方形)if (animotionLocLstIdx >= targeHrdLocLst.Count){.....}}}

Timer 的初始化代码

       private void InitializeTimer(){timer = new System.Windows.Forms.Timer();timer.Interval = 10; // Adjust the interval based on the desired smoothnesstimer.Tick += Timer_Tick;}

移动效果的目的是为了让过程更清晰一些,并没有对移动逻辑进行严格的分析和约束,因此移动过程不是很优雅。如果笔者有时间或者感兴趣会优化一下。

笔者在完成上述功能后,又增加了一个简单设计的功能,这样就可以利用这个程序进行一点儿华容道各种不同布局的探索以及之间关系的检测。(待续)

Marasun BJFWDQ
2024-03-10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/735702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为OD面试分享9(2024年)

1.3 告知简历筛选通过 1.8 资格面,就简单问了一下gap原因,离职原因,期望薪水,还问了一下技术栈 这期间本来在准备机试,结果机试我上半年考了一次,但是后面没去od,hr告知成绩好像还有效就没有重新机试。具体题目忘了。 1.17 技术一面 上来先自我介绍,然后问了一下上…

Java服务器-Disruptor使用注意

最近看了一下部署后台的服务器状况&#xff0c;发现我的一个Java程序其占用的CPU时长超过100%&#xff0c;排查后发现竟是Disruptor引起的&#xff0c;让我们来看看究竟为什么Disruptor会有这样的表现。 发现占用CPU时间超过100%的进程 首先是在服务器上用top命令查看服务器状…

C语言 寻找单身狗(2个

此题知识&#xff1a;a^0a;a^a0;传值调用和传址调用要分清作用 题目&#xff1a;在 1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6&#xff0c;1&#xff0c;3&#xff0c;4&#xff0c;5这几个数字中找出只出现一次的数字并打印在屏幕上 解题思路&…

vue,provide和inject,备忘

在Vue.js应用中&#xff0c;provide 和 inject 是一对API&#xff0c;用于实现组件间的跨层级依赖注入。provide 在父组件中定义要向下传递的属性或方法&#xff0c;而 inject 在子组件中声明它需要从祖先组件那里注入的属性。 具体到您的例子&#xff1a; // 在根组件或任意…

超越基础:提升你的数据采集策略与IP代理的高级应用

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【AI辅助研发】-趋势:大势已来,行业变革

【AI辅助研发】-趋势&#xff1a;大势已来&#xff0c;行业变革 引言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术已逐渐渗透到各行各业&#xff0c;其中软件研发行业更是受益匪浅。AI辅助研发已成为大势所趋&#xff0c;不仅提高了软件开发的效…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:动态属性设置)

动态设置组件的属性&#xff0c;支持开发者在属性设置时使用if/else语法&#xff0c;且根据需要使用多态样式设置属性。 说明&#xff1a; 从API Version 11开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 attributeModifier attributeMo…

js之原型链

在JavaScript中&#xff0c;原型链是一种用于实现继承和属性查找的机制。每个对象都有一个内部属性[[Prototype]]&#xff0c;这个属性指向创建该对象时使用的构造函数的“prototype"属性。对象的方法和属性定义在它的原型对象上。 1.原型&#xff08;Prototypes&#xf…

RHCE——一、OpenEuler22.03安装部署及例行性任务

RHCE 一、OpenEuler22.03安装部署及例行性任务 一、网络服务1.准备工作2、RHEL9操作系统的安装部署3、配置并优化OpenEuler22.034、网络配置实验&#xff1a;修改网络配置 二、例行性工作1、 单一执行的例行性任务&#xff1a;at&#xff08;一次性&#xff09;at命令详解 2、循…

AI赋能下的研发新时代:2024年研发趋势展望

引言&#xff1a; 在技术的迅猛发展下&#xff0c;人工智能&#xff08;AI&#xff09;已经不再是科幻小说中的幻想&#xff0c;而是我们日常生活和工作中不可或缺的一部分。特别是在研发领域&#xff0c;AI的应用已经逐渐渗透到了各个环节&#xff0c;为科学家、工程师和研究…

[综述笔记]Graph Neural Networks in Network Neuroscience

论文网址&#xff1a;Graph Neural Networks in Network Neuroscience | IEEE Journals & Magazine | IEEE Xplore 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xf…

linux进程间通信-消息队列

Linux下使用C语言实现进程间的通讯-消息队列 Linux进程间通信-消息队列&#xff08;IPC、mq&#xff09;C/C代码接口 Linux 进程间的通信(三)—消息队列

电脑打字突然变成繁体字如何修改

1. 右键电脑右下角的“中”字 2. 点击字符集&#xff0c;选中简体即可 有用的话记得给我点个赞啊~ 靴靴&#xff01;

学习数据结构和算法的地13天

题目讲解 尾插 #include <stdio.h> #include <stdlib.h> // 定义顺序表结构 #define MAX_SIZE 100 struct ArrayList {int array[MAX_SIZE];int size; // 当前元素个数 }; // 初始化顺序表 void init(struct ArrayList *list) {list->size 0; // 初始时元素个…

【Leetcode每日一题】 位运算 - 位1的个数(难度⭐)(32)

1. 题目解析 题目链接&#xff1a;191. 位1的个数 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给32位二进制数1的个数返回即可。 2.算法原理 位运算特性&#xff1a;通过位运算&#xff0c;特别是按位与(&…

PLC的FC与FB模块程序的功能解析

前文讲了在西门子系列的PLC中四个程序模块的描述&#xff0c;从S7-1200PLC开始就有FC和FB程序块了&#xff0c;但在使用的时候&#xff0c;一些使用者还是不好理解&#xff0c;以至于不知道该如何选择。今天&#xff0c;我们就用大白话的方式给大家讲解FC与FB的功能。 1、FC与…

ElasticSearch 与java的结合使用(二)

不同类型商品数量 {"size": 0, "aggs": {"type_group": {"terms": {"field": "type.keyword"}}} }SearchRequest request new SearchRequest();request.indices("product");// 按照类型分组统计数量A…

zzu2024三月招新(A-F,I-L)

目录 1.A 2.B 3.C 4.D 5.E 6.F 7.I 8.J 9.K 10.L 先吐槽一波,比赛的dev超级难用,没有编辑错误提示,不能复制样例,太草了,开局还开错题了,第一个小时没出题,还好后面写了几个签到,最后出了7题. 1.A 这题n比较小,只有1e3,可以n方暴力过,稍大一点就很难了.具体来说就是…

代码随想录算法训练营第五十五天 583. 两个字符串的删除操作、 72. 编辑距离、 编辑距离总结篇

代码随想录算法训练营第五十五天 | 583. 两个字符串的删除操作、 72. 编辑距离、 编辑距离总结篇 583. 两个字符串的删除操作 题目链接&#xff1a;https://leetcode.cn/problems/delete-operation-for-two-strings/ class Solution {public int minDistance(String word1, …

计算机基础专升本笔记-汇总笔记(五)office最最最基础背诵一

计算机基础专升本笔记-汇总笔记&#xff08;五&#xff09;office最最最基础背诵一 一、Word文档视图 页面视图阅读版式视图Web版式视图大纲视图&#xff08;只能看见文字&#xff0c;不显示图片&#xff09;草稿视图&#xff08;显示标题正文&#xff0c;水平标尺&#xff0…