Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/16: Рейтинг темы: голосов - 16, средняя оценка - 4.56
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5972 / 3734 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9

Обработка событий KeyEvent через определённый промежуток времени

28.09.2012, 09:07. Показов 3313. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть окно, которое перерисовывается каждые 100 мс.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    Thread th = new Thread(new Runnable()
    { public void run()
      { while (true)
        { gameCycle();
          try {
          Thread.sleep(100);
          } catch (InterruptedException e) {}
        }
      }
    });
    th.start();
...
  private void gameCycle()
  { ...
    this.repaint(); //обновить
  }
как сделать, чтобы можно было обработать одно событие KeyEvent раз в 100мс?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.09.2012, 09:07
Ответы с готовыми решениями:

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

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

Действие через определенный промежуток времени
Вообщем, ради обучения взялся сделать аналог Бойцовского Клуба (combats). Застрял на одном моменте, не знаю - как же правильнее его...

3
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
28.09.2012, 10:45
Никак. Сколько событий придет - столько раз обработчик и вызовется. Можете глотать события.

Вы вообще что сделать хотите?
1
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5972 / 3734 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
28.09.2012, 13:25  [ТС]
я пишу змейку.
Просто если быстро нажимать клавиши, то змейка меняет свое положение и не успевает отрисоваться в окне.
А если как-то отфильтровать события. Например, брать только последнее.

вот весь код
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
import java.io.*;           //?
import java.util.Random;
import java.util.ArrayList; //списки
import java.awt.*;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.awt.geom.Area;  //TODO заменить на двухмерный массив
 
import javax.swing.JFrame;
import javax.swing.JPanel;
////////////////////////////////////////////////////////////////////////
class Snake
{ public static final int DIR_PAUSE = 0;
  public static final int DIR_UP = 1;
  public static final int DIR_RIGHT = 2;
  public static final int DIR_DOWN = 3;
  public static final int DIR_LEFT = 4;
  private ArrayList<Point> body = new ArrayList<Point>();
  private int SIZE; //размер клетки
  private int direction = DIR_PAUSE;
  public Snake(int x0, int y0, int sz)
  { SIZE = sz;
    int x = x0 * sz + 2;
    int y = y0 * sz + 2;
    body.add(new Point(x, y));
  }
  public void setDirection(int direction)
  { this.direction = direction;
  }
  public void paint(Graphics2D g2)
  { for (Point p : body)
    { g2.setColor(Color.green);
      g2.fillArc(p.x, p.y, SIZE, SIZE, 0, 360);
      g2.setColor(Color.black);
      g2.drawArc(p.x, p.y, SIZE, SIZE, 0, 360);
    }
  }
  public Point move()
  { Point last = body.get(body.size() - 1);
    Point pp = last;
    if (direction != DIR_PAUSE)
    { body.remove(0);
      switch (direction)
      { case DIR_UP:
          pp = new Point(last.x, last.y - SIZE);
          break;
        case DIR_RIGHT:
          pp = new Point(last.x + SIZE, last.y);
          break;
        case DIR_DOWN:
          pp = new Point(last.x, last.y + SIZE);
          break;
        case DIR_LEFT:
          pp = new Point(last.x - SIZE, last.y);
          break;
      }
      body.add(pp);
      this.delete();
    }
    return pp;
  }
  public void add()
  { body.add(0, new Point(body.get(0).x, body.get(0).y));
  }
  private void delete()
  { for (int i=1; i < body.size(); i++)
      if (body.get(i).equals(body.get(0)))
        body.removeAll(body.subList(i, body.size()));
  }
}
////////////////////////////////////////////////////////////////////////
class SnakeGame extends JPanel
{ private static final int SIZE = 15;       //размер клетки
  private static final int SPEED = 100;     //мс
  private final Random rand = new Random(); //генератор
  private Shape walls1 = new Polygon();     //?
  private Shape walls2 = new Polygon();
  private Shape walls3 = new Polygon();
  private Snake snake = new Snake(2, 2, SIZE);//x,y,size
  private boolean GameOver = false;   //конец игры?
  private int lastPressedKey = 0;     //предыдущая клавиша
  private ArrayList<Point> red = new ArrayList<Point>();//яблоко
  private boolean [][] pole = new boolean[40][40];
  public SnakeGame()
  { super(true);
    getLevel("123.txt"); //!!!
    setPreferredSize(new Dimension(40*SIZE, 40*SIZE));//размеры
    putRed(); //яблоко
    Thread th = new Thread(new Runnable()
    { public void run()
      { while (true)
        { gameCycle();
          try {
          Thread.sleep(SPEED);
          } catch (InterruptedException e) {}
        }
      }
    });
    th.start();
  }
  private void putRed()
  { int x, y;
    for (int i=0; i<20; i++)
    { do
      { x = SIZE * rand.nextInt(40) + 2;
        y = SIZE * rand.nextInt(40) + 2;
      } while (walls2.contains(x, y));//TODO и проверка что б не в змею и не в яблоко
      red.add(new Point(x, y));
    }
  }
  private void gameCycle()
  { Point p = snake.move();
    for (int i=0; i<red.size(); i++)
      if (red.get(i).x == p.x && red.get(i).y == p.y)//съел яблоко
      { red.remove(p);
        snake.add();
        break;
      }
    if (walls2.contains(p))
    { GameOver = true;
      snake.setDirection(Snake.DIR_PAUSE);
    }
    //TODO что б сам себя не съел
    //TODO проверка съедены все яблоки
    //TODO таймер на добавление яблока
    this.repaint(); //обновить
  }
  public void paint(Graphics g)
  { Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(Color.white);
    g2.fillRect(0, 0, getWidth(), getHeight());
 
    g2.setColor(Color.gray);
    g2.fill(walls3);
    g2.setColor(Color.lightGray);
    g2.fill(walls1);
    g2.setColor(Color.white);
    g2.fill(walls2);
 
    g2.setColor(Color.red);
    for (int i=0; i<red.size(); i++)
      g2.fillArc(red.get(i).x, red.get(i).y, SIZE, SIZE, 0, 360);
    g2.setColor(Color.black);
    for (int i=0; i<red.size(); i++)
      g2.drawArc(red.get(i).x, red.get(i).y, SIZE, SIZE, 0, 360);
 
    snake.paint(g2);
    //g2.setColor(Color.black);
    //g2.drawString("Points: " + points, 2, 10); //TODO другие надписи
  }
  public void keyPressed(KeyEvent ev)
  { if (!GameOver)
      switch (ev.getKeyCode())
      { case KeyEvent.VK_RIGHT:
          if (lastPressedKey != KeyEvent.VK_LEFT)
          { snake.setDirection(Snake.DIR_RIGHT);
            lastPressedKey = ev.getKeyCode();
          }
          break;
        case KeyEvent.VK_LEFT:
          if (lastPressedKey != KeyEvent.VK_RIGHT)
          { snake.setDirection(Snake.DIR_LEFT);
            lastPressedKey = ev.getKeyCode();
          }
          break;
        case KeyEvent.VK_DOWN:
          if (lastPressedKey != KeyEvent.VK_UP)
          { snake.setDirection(Snake.DIR_DOWN);
            lastPressedKey = ev.getKeyCode();
          }
          break;
        case KeyEvent.VK_UP:
          if (lastPressedKey != KeyEvent.VK_DOWN)
          { snake.setDirection(Snake.DIR_UP);
            lastPressedKey = ev.getKeyCode();
          }
          break;
      }
    if (ev.getKeyCode() == KeyEvent.VK_ESCAPE)
      System.exit(0);
  }
  private void getLevel(String fileName)//?????????????????????????
  { int minX = 500, maxX = 0, minY = 500, maxY = 0;
        Area w1 = new Area();
        Area w2 = new Area();
        Area w3 = new Area();
 
        BufferedReader input = null;
        try {
            File file = new File(fileName);
            input = new BufferedReader(new FileReader(file));
            String line = null;
 
            for (int y = 0; (line = input.readLine()) != null; y++) {
                for (int x = 0; x < line.length(); x++) {
                    if (line.charAt(x) == '1') {
                        minX = Math.min(minX, x * SIZE);
                        maxX = Math.max(maxX, (x + 1) * SIZE + 4);
                        minY = Math.min(minY, y * SIZE);
                        maxY = Math.max(maxY, (y + 1) * SIZE + 4);
                        w1.add(new Area(new Rectangle(x * SIZE, y * SIZE, SIZE, SIZE)));
                        w2.add(new Area(new Rectangle(x * SIZE + 2, y * SIZE + 2, SIZE, SIZE))); //!!!
                        w3.add(new Area(new Rectangle(x * SIZE + 4, y * SIZE + 4, SIZE, SIZE)));
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (input != null) {
                    input.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        walls1 = w1;
        walls2 = w2;
        walls3 = w3;
  }
}
////////////////////////////////////////////////////////////////////////
public class idz
{ public static void main(String[] args)
  { JFrame frame = new JFrame("Snake 0.2");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    final SnakeGame game = new SnakeGame();
    frame.add(game);
    frame.addKeyListener(new KeyAdapter() //перекидывает события в другой метод
    { public void keyPressed(KeyEvent ev)
      { game.keyPressed(ev);
      }
    });
    frame.pack();             //размер окна
    frame.setVisible(true);   //видимость
   // frame.setResizable(false);//запрет изменения размеров
  }
}
и файл 123.txt
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1111111111111111111111111111111111111111
1000000000000000000000000000000000000001
1000000000000000000000000000000000000001
1000000000000000000000001111111111100001
1000000000000000000000000000000000100001
1000000000000010000000000000000000100001
1000000000000010000000000000000000100001
1000000000000011111000000000000000100001
1000000000000000001000000000000000100001
1000111110000000001000001111111111100001
1000110010000000001000000000000000000001
1000111110000000001000000000000000000001
1000000000000000001000000000000000000001
1000000000000000001000000000000000000001
1000000011111111110111111111110000000001
1000000000000000001000000000000000000001
1000000000000000001000000000000000000001
1000000000000000001000000000000000000001
1000000000000000001000000000000000000001
1000000000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001000000000001
1000010000000000001000000001111000000001
1000010000000000000000000000000100000001
1000010000000000000000000000000010000001
1000010000000000000000000000000010000001
1000010000000000000000000000000001000001
1000010000000000000000000000000001000001
1000011110011111111111111100011110000001
1000000000000000000000000000000000000001
1000000000000000000000000000000000000001
1000000000000000000000000000000000000001
1000000000000000000000000000000000000001
1000000000000000000000000000000000000001
1111111111111111111111111111111111111111
Добавлено через 7 минут
кажется придумал. Если в обработчик событий вставить это:
Java
1
this.repaint():
Сейчас проверю.

Добавлено через 3 минуты
Да. Все работает. Теперь при нажатии клавиши окно перерисовывается.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public void keyPressed(KeyEvent ev)
  { if (!GameOver)
      switch (ev.getKeyCode())
      { case KeyEvent.VK_RIGHT:
          if (lastPressedKey != KeyEvent.VK_LEFT)
          { snake.setDirection(Snake.DIR_RIGHT);
            this.repaint(); //обновить
            lastPressedKey = ev.getKeyCode();
          }
          break;
        case KeyEvent.VK_LEFT:
          if (lastPressedKey != KeyEvent.VK_RIGHT)
          { snake.setDirection(Snake.DIR_LEFT);
            this.repaint(); //обновить
            lastPressedKey = ev.getKeyCode();
          }
          break;
        case KeyEvent.VK_DOWN:
          if (lastPressedKey != KeyEvent.VK_UP)
          { snake.setDirection(Snake.DIR_DOWN);
            this.repaint(); //обновить
            lastPressedKey = ev.getKeyCode();
          }
          break;
        case KeyEvent.VK_UP:
          if (lastPressedKey != KeyEvent.VK_DOWN)
          { snake.setDirection(Snake.DIR_UP);
            this.repaint(); //обновить
            lastPressedKey = ev.getKeyCode();
          }
          break;
      }
    if (ev.getKeyCode() == KeyEvent.VK_ESCAPE)
      System.exit(0);
  }
Добавлено через 2 минуты
Можете писать советы, критику, замечания.
0
d!m@n
19.12.2012, 21:36
сам говоришь писал?))))
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.12.2012, 21:36
Помогаю со студенческими работами здесь

Отправка на емайл через определенный промежуток времени.
Добрый день уважаемые спецы. Есть программа, которая перехватывает нажатые клавиши и сохраняет их в отдельный файл. Хочу чтобы это файл...

Исчезание предмета через определённый промежуток времени
Здравствуйте!Такая ситуация: сделал я значит яйцо которое падает и при падении разбивается, как прописать чтобы разбитое яйцо лежало на...

Скриншоты автоматически через определенный промежуток времени
Всем привет. Есть код программы. В него нужно добавить функцию: Делать скриншоты через определенное количество времени, и сохраняется в...

Перелистывание картинок через определённый промежуток времени
К примеру, мне нужно что-бы при запуске конвертировании программы, 5 картинок менялись собой местами беспрерывно.Можно это сделать в C++...

DISCONNECT/CONNECT через определенный промежуток времени
Привет всем, нужен bat -файл, при запуске которого через определенный промежуток времени происходило отключение от беспроводной сети и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru