Использование метода внутри таймера - PullRequest
0 голосов
/ 31 января 2019

Я начал писать игру, но все еще изучаю объектно-ориентированное программирование.
Я использую VS 2015 (Win7).

Я создал класс с именем Ship, метод, который позволяетЯ пока создаю корабль только с двумя параметрами: положение X и Y на карте.

Ship[] submarine = new Ship[100]; 
// create first ship with only two
submarine[0].create_ship(140, 200);
parameters: position X and Y on future map

Я хочу, чтобы Ship перемещался каждую секунду, используя метод move() и таймер.

Мой код:
(также на PasteBin )

public partial class Form1 : Form
{
    class Ship
    {
        private double ship_posX; // position X on map
        private double ship_posY; // position Y on map
        private int ship_heading; // current heading
        private int ship_speed_max; // max speed of a ship
        private int ship_current_speed; // current speed of a ship
        private string ship_class; // surface or submarine
        private string ship_foe; // friend or enemy?
        private string is_controllable; // is controllable by player?
        private int depth; // current depth of a submarine (if a submarine)

        public void move(int heading, int speed)
        {
            if (heading == 0)  ship_posY -= speed; // ship is heading NORTH
            if (heading == 45) // ship is heading NORTH-EAST
            {
                ship_posX += speed;
                ship_posY -= speed;
            }
            if (heading == 90) ship_posX += speed; // ship is heading EAST
            if (heading == 135) // ship is heading SOUTH-EAST
            {
                ship_posX += speed;
                ship_posY += speed;
            }
            if (heading == 180) ship_posY += speed; // ship is heading SOUTH
            if (heading == 225) // ship is heading SOUTH-WEST
            {
                ship_posX -= speed;
                ship_posY += speed;
            }
            if (heading == 270) ship_posX -= speed; // ship is heading WEST
            if (heading == 315) // ship is heading NORTH-WEST
            {
                ship_posX -= speed;
                ship_posY -= speed;
            }
        }

        public void create_ship(double posx, double posy)
        {
            ship_posX = posx;
            ship_posY = posy;
            // only a few parameters for now. Later will be name, speed_max, class, friend or foe and more
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // forms load == game starts
        Ship[] submarine = new Ship[100]; 
        submarine[0].create_ship(140, 200); // create first ship with only two parameters: position X and Y on future map
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        submarine[0].move(90, 15); 
        // ERROR: compiler shows "The name 'submarine' does not exist in the current context
    }
}

Что вызывает ошибку в этом коде ?:

private void timer1_Tick(object sender, EventArgs e)
{
    submarine[0].move(90, 15); 
    //ERROR: compiler shows "The name 'submarine' does not exist in the current context
}

Таймер включен по умолчанию, его интервал установлен на 1000, а модификаторы - Private.

Что я делаю не так?

Он не работает внутри события Timer, но если я использую его внутри Form.Load:

private void Form1_Load(object sender, EventArgs e)
{
     // forms load == game starts
     Ship[] submarine = new Ship[100]; 
      // create first ship with only two parameters: position X and Y on future map
     submarine[0].create_ship(140, 200);
     submarine[0].move(90, 15);
}

Он работает нормально (но только один раз - поэтому я хочу использовать Timer).

Надеюсь, тема поста понятна, и мою проблему я описал достаточно хорошо.

Я пытался изменить public / private в некоторых местах, но это не помогло.

1 Ответ

0 голосов
/ 31 января 2019

scope переменной определяет ее видимость для остальной части программы.В примерах из учебника по основам C # переменные были определены внутри методов.При создании таким образом область действия переменной - это весь метод после объявления

. В вашем случае вы определяете и объявляете метод submarine в Form1_Load в соответствии с приведенным выше определением, submarine доступно только в области действия метода Form1_Load.

Если вы хотите использовать submarine в другом методе класса Form1, вы можете представить его как поле класса.

Это значит:

public partial class Form1 : Form
{
    private static Ship[] submarine;

    .
    .
    .

    private void Form1_Load(object sender, EventArgs e)
    {
        // forms load == game starts

        submarine = new Ship[100]; 
        submarine[0].create_ship(140, 200); // create first ship with only two 
        parameters: position X and Y on future map
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        submarine[0].move(90, 15); // ERROR: compiler shows "The name 'submarine' 
        does not exist in the current context
    }

Теперь вы снова получаете ошибку

, и это потому, что вы не объявили ни одного экземпляра ship в своем массиве: Createстатический метод в ship классе с именем Initial "

public static void Initial()
{
    for(int i = 0; i < 100; i++)
    {
       submarine[i] = new ship();
    }
}

и использование его в Form1_load():

private void Form1_Load(object sender, EventArgs e)
        {
            // forms load == game starts

            submarine = new Ship[100]; 
            ship.Initial();
            submarine[0].create_ship(140, 200); // create first ship with only two 
            parameters: position X and Y on future map
        }

После внесения этих изменений, я думаю, что это работаетправильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...