为什么我的图像不按预期加载和移动?

问题描述 投票:0回答:1

我正在开发一个项目,我可以将一组固定数据加载到列表框中。每行数据都与图片框中的图像相关联。当我点击我的加载按钮时,数据应该被加载到列表框中,并且应该加载每个图像,并开始在屏幕上移动。

当我点击加载时,最初会短暂加载4张图像。然后第四个消失,只有前三个图像开始在屏幕上移动。但是,当我创建一个新对象时,数据会被添加到列表框中,但图像不是相关的新对象图像,而是我应该加载的第四个图像。所以我加载的图像总是落后一步,但我的列表框是最新的。

我对编码非常陌生,并且正在努力了解现阶段的大局。很多代码都是我从各个地方采用的例子,我模糊地理解了发生了什么,但还不足以解决这个问题。

有没有人有任何关于为什么会发生这种情况的提示?任何关于我出错的建议或想法都会非常感激。

MyClass.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;


namespace ACarter_A1_New
{
    class MyClass
    {
        //private variables
        private string animalId;
        private int typeId; //Animal type id
        private string typeName;
        private int xPosition;
        private int yPosition;
        private int width;
        private int height;
        private int xStep; //move speed
        private int yStep;
        private PictureBox animalPic; //Picture

        //public variables
        public string AnimalId { get => animalId; set => animalId = value; }
        public int TypeId { get => typeId; set => typeId = value; }
        public string TypeName { get => typeName; set => typeName = value; }
        public int XPosition { get => xPosition; set => xPosition = value; }
        public int YPosition { get => yPosition; set => yPosition = value; }
        public int Width { get => width; set => width = value; }
        public int Height { get => height; set => height = value; }
        public int XStep { get => xStep; set => xStep = value; }
        public int YStep { get => yStep; set => yStep = value; }
        public PictureBox AnimalPic { get => animalPic; set => animalPic = value; }

        public MyClass(string id, PictureBox iniPic, int seed)
        {
            AnimalId = id; //the string id is now equal to AnimalId 
            TypeId = seed; //the int seed is now equal to TypeId

            //set up type name
            switch (TypeId) //TypeId = seed
            {
                case 1:
                    TypeName = "Angry Dog"; //= seed 1           
                    break;
                case 2:
                    TypeName = "Sleepy Dog"; //= seed 2                  
                    break;
                case 3:
                    TypeName = "Dirty Dog"; //= seed 3                    
                    break;
                case 4:
                    TypeName = "Happy Dog"; //= seed 4                   
                    break;
            }
            AnimalPic = iniPic; //load picture


            //set up picture location by (X, Y, W, H)
            XPosition = seed * 20;
            YPosition = seed * 10;
            Width = animalPic.Width;
            Height = animalPic.Height;

            XStep = seed * 5; //moving speed
            YStep = seed * 5 / 3;
        }

        //Method DrawPic(...) displays an object image on the screen
        public void DrawPic(Graphics canvas)
        {
            Image pic; //Image variable called pic
            pic = AnimalPic.Image; //that image pic is now equal to the public picturebox AnimalPic
            canvas.DrawImage(pic, XPosition, YPosition, Width, Height);
        }

        //Method move() changes the position of the object - simulates moving
        public void Move()
        {
            if ((XPosition + Width >= 503 || (XPosition <= 0)))
            {//change direction if on the edge
                XStep = -XStep;
            }
            XPosition = XPosition + XStep; //move one step on x direction

            if ((YPosition + height >= 421 || (YPosition <= 0)))
            {//change direction if on the edge
                YStep = -YStep;
            }
            YPosition = YPosition + YStep; //move one step on Y direction
        }

        //Method ToString() enables the object to be displayed as a string in the Listbox
        public override string ToString()
        {
            return AnimalId + ", " + TypeId + ", " + TypeName + ", " + "x speed: " + XStep.ToString() + ", Y speed: " + YStep.ToString();
        }
    }
}

FileManager.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;
using System.Drawing;

namespace ACarter_A1_New
{
    class FileManager
    {
        public List<MyClass> LoadAnimals(string fn)
        {
            StreamReader sr = new StreamReader(fn); //create a new instance of streamreader to use to read our .txt file, called sr and pass in the string fn
            List<MyClass> loaddogs = new List<MyClass>(); //create a list based on the MyClass.cs class object, call the list loadDogs

            //declare variables for object parameters from the MyClass class
            string animalId; //we want the animalId, pic and seed info
            PictureBox pic = new PictureBox();
            int seed;

            while (!sr.EndOfStream) //use a while loop to read through the file until the end - while not at the end, continue
            {
                string temp = sr.ReadLine(); //create a temp string called temp to store each read line that the sr reads
                string[] values = temp.Split(','); //create a string array called value to store the information stored in temp, and split the indexed info on each line by commas
                animalId = values[0]; //state that the animal id will be the first index at index 0 in our string array values
                seed = int.Parse(values[1]); //state that seed will be the second index at index 1 in our string array values, we have to use int.Parse to convert int to string
                                             //create new object, picture will be setup in form application

                MyClass d = new MyClass(animalId, pic, seed); //create an object from MyClass called d, with properties for animalId, pic and seed
                loaddogs.Add(d); //add what is stored in d to loaddogs list
            }
            sr.Dispose(); //finish using the sr streamreader
            return loaddogs; //return a list loaddogs to the SaveAnimal method

        }
    }
}

Form1.cs - 加载/创建新对象的代码


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.IO;
using System.Collections;

namespace ACarter_A1_New
{
    public partial class Form1 : Form
    {
        Random seed = new Random();
        int animalTypeId;
        int animalId;


        List<MyClass> animals = new List<MyClass>();

        Graphics screen;

        public Form1()
        {

            InitializeComponent();
            //setup screen and initialize animal id
            screen = picScreen.CreateGraphics(); //declare and initialise the screen to equal the 
            animalId = 0; //declare and initalise the animalId variable

        }

        private void MoveAndShowAnimals() //MoveAndShowAnimals method to call the public Move() and DrawPic methods
        {
            try //use try/catch incase any exceptions are thrown to the code block
            {
                //initally the graphics screen is cleared and is the color dark olive green
                screen.Clear(Color.DarkOliveGreen);
                foreach (MyClass dog in animals) //foreach object that is stored in animals
                {

                    dog.DrawPic(screen);
                    dog.Move();

                    //call the public DrawPic method from the MyClass class for each object

                    //call the public move method from the MyClass class for each object

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error with MoveAndShowAnimals method" + ex);
            }
        }

        private void btnLoadInit_Click(object sender, EventArgs e)
        {
            try //use try/catch incase any exceptions are thrown to the code block
            {

                animals.Clear(); //clear the animals list

                List<MyClass> d = new List<MyClass>(); //create a new list using the MyClass class called d
                lbxObjs.Items.Clear(); //clear the listbox lbxObjs
                FileManager fm = new FileManager(); //create a new instance of FileManger called fm

                //retrieve a list of dog information, without image
                d = fm.LoadAnimals("dogs.txt"); //use the file manager fm, specifically the LoadAnimals(dogs.txt) in FileManager class and store in the list called d

                //declare variables to use Id and seed
                string Id;
                int seed;
                int count = 0; //count used to increment through in foreach loop, initialised to start at 0
                               //  PictureBox Pic;

                foreach (MyClass dog in d) //foreach loop to loop through each object "dog" that is put into the list d. The object being made up of id, seed and a picturebox
                {
                    Id = dog.AnimalId; //specifying that the string Id is equal to the AnimalId specified in the MyClass class
                    seed = dog.TypeId; //specifying that the int seed is equal to the TypeId specified in the MyClass class
                    PictureBox Pic = null; //We need a picturebox, which initially will be null as we need the Pic to be one of four

                    //we can determine which pic should be first, second, third and fourth by using the count variable and if, if else statements

                    if (count == 0)
                    {
                        Pic = picDog1;
                    }
                    else if (count == 1)
                    {
                        Pic = picDog2;
                    }
                    else if (count == 2)
                    {
                        Pic = picDog3;
                    }
                    else if (count == 3)
                    {
                        Pic = picDog4;
                    }

                    //make an active object from retrieved file data
                    MyClass dogfromFile = new MyClass(Id, Pic, seed);

                    // use the active object and add it to the list animals which is our object list
                    animals.Add(dogfromFile);
                    MoveAndShowAnimals();
                    count++; //count++ increment count by 1 each time the foreach loop increments, which will be 4 times as we have four initial objects to load
                }

                if (animals == null) //if animal list is null, then show the error message below
                {
                    MessageBox.Show("Error loading animals");
                }
                else //otherwise, clear the listbox, and add the objects that we have loaded into animals to the listbox
                {
                    lbxObjs.Items.Clear();
                    lbxObjs.Items.AddRange(animals.ToArray());
                    /*MoveAndShowAnimals();*/ //implement the MoveAndShowAnimals() method to animate images
                    timer1.Enabled = true;//start the timer
                }
            }
            catch (Exception ex) //exception ex shows a detailed error message as well as the initial message "Error loading"
            {
                MessageBox.Show("Error loading" + ex); //if an exception is thrown to the above code, display error loading
            }
        }

        private void btnNewObj_Click(object sender, EventArgs e)
        {
            try
            {
                animalId++; //start animal id at 1, has been initialised to 0 already
                            //animalTypeId now equals the random seed which will choose from 4 objs and start at 1
                string fullAnimalId = animalId.ToString(); //pass in string New Dog + the animal id to a string called fullAnimalId
                animalTypeId = seed.Next(4) + 1;
                PictureBox Pic = null; //initially this will be null as we need to choose from 1 of four pictureboxes. we can differentiate which picture to choose by using the animalTypeId
                                       //which is equal to the seed number and give each seed the relevant image name, so Pic can have four variables depending on which seed is chosen

                if (animalTypeId == 1)
                {
                    Pic = picDog1;
                }
                else if (animalTypeId == 2)
                {
                    Pic = picDog2;
                }
                else if (animalTypeId == 3)
                {
                    Pic = picDog3;
                }
                else if (animalTypeId == 4)
                {
                    Pic = picDog4;
                }

                //make an active object from retrieved file data
                MyClass dogfromNew = new MyClass(fullAnimalId, Pic, animalTypeId);

                animals.Add(dogfromNew); //add the active object to the animals object list
                lbxObjs.Items.Clear(); //clear the listbox 
                lbxObjs.Items.AddRange(animals.ToArray()); //take the objects stored in animals list and add them to the listbox
                MoveAndShowAnimals(); //call the MoveAndShowAnimals() method to animate the new images 
                timer1.Enabled = true; //start the timer
            }
            catch (Exception ex) //exception ex shows a detailed error message as well as the initial message "Error creating new object"
            {
                MessageBox.Show("Error creating new object" + ex);
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                MoveAndShowAnimals();
            }
            catch (Exception)
            {
                MessageBox.Show("Error with timer");
            }
        }

dogs.txt文件内容:

1,1 2,2 3,3 4,4

c# class animation timer picturebox
1个回答
0
投票

对于任何有兴趣的人。第四个不断消失的图像实际上与图像本身有关。我尝试调整图像大小,它第一次工作。我通过使用一个只有加载按钮和新对象按钮并使用不同图片的较小程序来解决这个问题,当我与我使用的图像进行比较时,它们的大小只有三分之一。所以我改变了图像大小,在这个项目中,它第一次工作。我猜它在渲染图像时遇到了麻烦,以至于它只是落后于第四个。由于图像在屏幕上的移动速度相当缓慢,现在移动得更快。

© www.soinside.com 2019 - 2024. All rights reserved.