簡體   English   中英

我無法移動 PictureBox

[英]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;
            }
        }
    }
}

這是一些非常簡單的代碼,可以使用asyncawait在屏幕上移動圖片框。 它不是基於您的代碼 - 您的代碼遠非最小可復制示例。 這是。

我在表單中刪除了一些 coptrols:

  • 一個組合框
  • 兩個文本框(偏移量和周期)
  • 兩個按鈕(開始和停止)
  • 一個 PictureBox(我把它公開並給它一個明顯的背景顏色

然后我創建了這個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以便在我開始朝新方向移動時禁用它。 否則代碼是不言自明的。

請注意,因為一切都是通過asyncawait完成的,所以我沒有線程問題,也不需要擔心計時器。

需要注意的一件事:使用周期/偏移控制的部分原因是為了顯示(並向我自己證明)表單在事物移動時功能齊全

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM