![](/img/trans.png)
[英]How can i make that when i move the mouse ober pictureBox1 it will draw points automatic on pictureBox2?
[英]I can`t get move PictureBox
我无法制作一个函数,以便在图片框移动期间发生 while 循环。
我在某些坐标上执行了一个脚本,我尝试使用 switch 语句来执行它,但该函数根本不起作用
当你运行它时,什么都没有发生,就好像这行代码不存在一样。
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.Threading;
namespace shadowfiend_minigame
{
public partial class Form1 : Form
{
private int _first_shadowrazeX = 404, _first_shadowrazeY = 204;
private int _second_shadowrazeX = 724, _second_shadowrazeY = 204;
private int _third_shadowrazeX = 1106, _third_shadowrazeY = 204;
private int zeus_hp = 1000;
private int shadow_fiend_hp = 2800;
Point point = new Point(1106, 204);
Point point2 = new Point(724, 204);
Point point3 = new Point(404, 204);
private int speed_zeus, damage_zeus;
private int shadow_fiend_damage;
Thread thread = new Thread(ShadowRaze_Click);
public Form1()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(ShadowRaze_Click);
KeyPreview = true;
}
bool CheckedBox()
{
bool checked1 = checkBox1.Checked;
bool checked2 = checkBox2.Checked;
bool checked3 = checkBox3.Checked;
if (checked1 == false && checked2 == false && checked3 == false)
{
return false;
}
else return true;
}
private async void Start_Click(object sender, EventArgs e)
{
Thread thread = new Thread(Zeus);
if (CheckedBox() == false)
{
MessageBox.Show("Выберите сложность игры!");
}
else
{
Start.Visible = false;
checkBox1.Visible = false;
checkBox2.Visible = false;
checkBox3.Visible = false;
thread.Start();
}
}
private async void Zeus()
{
Thread thread = new Thread(Zeus);
while (shadow_fiend_hp != 0)
{
for (int i = 0; i < 50; i++)
{
var x = _zeus.Location.X;
this.Invoke(new Action(() => _zeus.Location = new Point(_zeus.Location.X - 20, _zeus.Location.Y)));
Thread.Sleep(speed_zeus);
switch (_zeus.Location.X)
/*
* Here it is necessary that when the picturebox reaches a certain point while moving, the function is executed
*/
{
case 1106:
zeus_hp = zeus_hp - 200;
this.Invoke(new Action(() => label4.Text = "zeus_hp: " + zeus_hp));
break;
case 724:
zeus_hp = zeus_hp - 200;
this.Invoke(new Action(() => label4.Text = "zeus_hp: " + zeus_hp));
break;
case 404:
zeus_hp = zeus_hp - 200;
this.Invoke(new Action(() => label4.Text = "zeus_hp: " + zeus_hp));
break;
}
}
Zeus_Attack(damage_zeus);
if (shadow_fiend_hp == 0)
{
MessageBox.Show("You lose");
this.Invoke(new Action(() => Start.Visible = true));
this.Invoke(new Action(() => checkBox1.Visible = true));
this.Invoke(new Action(() => checkBox2.Visible = true));
this.Invoke(new Action(() => checkBox3.Visible = true));
}
else if (zeus_hp == 0)
{
MessageBox.Show("You win");
this.Invoke(new Action(() => Start.Visible = true));
this.Invoke(new Action(() => checkBox1.Visible = true));
this.Invoke(new Action(() => checkBox2.Visible = true));
this.Invoke(new Action(() => checkBox3.Visible = true));
}
for (int i = 0; i < 50; i++)
{
this.Invoke(new Action(() => _zeus.Location = new Point(_zeus.Location.X + 20, _zeus.Location.Y)));
Thread.Sleep(speed_zeus);
}
}
thread.Join();
ResetAll();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
checkBox3.Checked = false;
checkBox1.Checked = false;
speed_zeus = 30;
damage_zeus = 200;
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
checkBox1.Checked = false;
checkBox2.Checked = false;
speed_zeus = 10;
damage_zeus = 400;
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
checkBox3.Checked = false;
checkBox2.Checked = false;
speed_zeus = 50;
damage_zeus = 100;
}
private async void Zeus_Attack(int damage)
{
shadow_fiend_hp = shadow_fiend_hp - damage;
this.Invoke(new Action(() => hp.Text = "HP: " + shadow_fiend_hp));
}
private async void ShadowFiend_Attack()
{
zeus_hp = zeus_hp - 200;
this.Invoke(new Action(() => label4.Text = "HP: " + shadow_fiend_hp));
}
private void ResetAll()
=> this.Invoke(new Action(() => hp.Text = "HP: 2800"));
private async void ShadowRaze_Click(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Z:
shock.Location = new Point(_first_shadowrazeX, _first_shadowrazeY);
shock.Visible = true;
this.Update();
Thread.Sleep(100);
shock.Visible = false;
break;
case Keys.X:
shock.Location = new Point(_second_shadowrazeX, _second_shadowrazeY);
shock.Visible = true;
this.Update();
Thread.Sleep(100);
shock.Visible = false;
break;
case Keys.C:
shock.Location = new Point(_third_shadowrazeX, _third_shadowrazeY);
shock.Visible = true;
this.Update();
Thread.Sleep(100);
shock.Visible = false;
break;
}
}
}
}
这是一些非常简单的代码,可以使用async
和await
在屏幕上移动图片框。 它不是基于您的代码 - 您的代码远非最小可复制示例。 这是。
我在表单中删除了一些 coptrols:
然后我创建了这个enum
来说明我想要移动图片框的方向:
public enum Direction
{
SouthEast,
East,
NorthEast,
North,
NorthWest,
West,
SouthWest,
South,
}
然后我创建了这个工人阶级:
internal class PictureBoxMover
{
public bool enabled = true;
Direction _direction;
int _offset;
int _period;
Form1 _theForm;
private static Dictionary<Direction, (int deltaX, int deltaY)> _deltaRules = new Dictionary<Direction, (int deltaX, int deltaY)> {
{ Direction.North, (0, -1) },
{ Direction.South, (0, 1) },
{ Direction.East, (1, 0) },
{ Direction.West, (-1, 0) },
{ Direction.NorthEast, (1, -1) },
{ Direction.NorthWest, (-1, -1) },
{ Direction.SouthEast, (1, 1) },
{ Direction.SouthWest, (-1, 1) },
};
public PictureBoxMover (Form1 parentForm, Direction direction, int offset, int period)
{
_theForm = parentForm;
_direction=direction;
_offset=offset;
_period=period;
}
public void Disable()
{
enabled = false;
}
public async Task Run()
{
var directionRule = _deltaRules[_direction];
var offsetXY = (directionRule.deltaX * _offset, directionRule.deltaY * _offset);
while (enabled)
{
_theForm.pictureBox1.Location = new Point(_theForm.pictureBox1.Location.X + offsetXY.Item1, _theForm.pictureBox1.Location.Y + offsetXY.Item2);
await Task.Delay(_period);
}
}
}
静态_deltaRules
字典对Directions
有意义。 ( 1, -1 )
表示两个整数的元组(即, _deltaRules
是一个字典,其中一个Direction
作为键,一个两个整数元组作为值
此类实例的主要原因是允许它们轻松取消(/禁用)。
在表单的构造函数中,我将 Direction 下拉组合框绑定到 Direction 的可能值:
DirectionDropDown.DataSource = Enum.GetNames<Direction>();
表单类的其余部分如下所示:
private PictureBoxMover? _currentPictureBoxMover = null;
private async void GoBtn_Click(object sender, EventArgs e)
{
if (Enum.TryParse<Direction>(DirectionDropDown.SelectedItem.ToString(), out var direction) &&
int.TryParse(OffsetTxt.Text, out var offset) &&
int.TryParse(PeriodTxt.Text, out var period))
{
if (_currentPictureBoxMover != null)
{
_currentPictureBoxMover.Disable();
}
_currentPictureBoxMover = new PictureBoxMover(this, direction, offset, period);
await _currentPictureBoxMover.Run();
}
}
private void StopBtn_Click(object sender, EventArgs e)
{
if (_currentPictureBoxMover != null)
{
_currentPictureBoxMover.Disable();
}
_currentPictureBoxMover = null;
}
我跟踪_currentPictureBoxMover
以便在我开始朝新方向移动时禁用它。 否则代码是不言自明的。
请注意,因为一切都是通过async
和await
完成的,所以我没有线程问题,也不需要担心计时器。
需要注意的一件事:使用周期/偏移控制的部分原因是为了显示(并向我自己证明)表单在事物移动时功能齐全
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.