![](/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.