Почему мои изображения не загружаются и не двигаются, как ожидалось? - PullRequest
0 голосов
/ 08 апреля 2019

Я работаю над проектом, в котором я могу загрузить фиксированный набор данных в список. Каждая строка данных привязана к изображению в картинке. Когда я нажимаю на кнопку загрузки, данные должны быть загружены в список, каждое изображение должно быть загружено и начать перемещаться по экрану.

Когда я нажимаю кнопку загрузки, изначально загружаются 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 * +1022 * 4,4

1 Ответ

0 голосов
/ 08 апреля 2019

Для тех, кто заинтересован. Четвертое изображение, которое продолжало исчезать, было фактически связано с самими изображениями. Я попытался изменить размеры изображений, и это сработало в первый раз. Я понял это, используя меньшую программу, в которой были только кнопка загрузки и кнопка нового объекта, и я использовал разные картинки, которые по сравнению с изображениями, которые я использовал, составляли треть от размера. Поэтому я изменил размер изображения и в этом проекте, и это сработало впервые. Я предполагаю, что у него были проблемы с рендерингом изображений настолько часто, что это просто отставало от четвертого. Поскольку изображения двигались по экрану довольно медленно, а теперь движутся намного быстрее.

...