- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对java相当陌生,并且对如何做到这一点感到困惑。我有一个关键监听器,用于监听 WASD,这表明我的 Snake 的运动。主要监听器更改我的 Snakes 片段的 x 和 y 位置。我有一个计时器链接到一个名为“Listener”的监听器,该监听器将运动重新绘制到缓冲区和屏幕上。我的问题是,为什么我的关键监听器指示的运动没有进入缓冲区?另外,我知道我的移动功能可以工作,因为 snek.move(4);在定时器中工作。最后一点,这是一个我刚刚开始的贪吃蛇游戏。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class SnekePanel extends JPanel
{
private static final int FRAME1 = 1000;
private static final int FRAME2 = 1000;
private static final Color BACKGROUND = new Color(0, 0, 0);
private BufferedImage myImage;
private Graphics myBuffer;
private Sneke snek;
private Food food;
private Timer t;
private int points = 0;
public SnekePanel()
{
myImage = new BufferedImage(FRAME1, FRAME2, BufferedImage.TYPE_INT_RGB);
myBuffer = myImage.getGraphics();
myBuffer.setColor(BACKGROUND);
myBuffer.fillRect(0, 0, FRAME1,FRAME2);
int xPos = (int)(Math.random()*(FRAME1-100) + 50);
int yPos = (int)(Math.random()*(FRAME2-100)+ 50);
food = new Food(xPos, yPos, 10, Color.RED);
snek = new Sneke(200,200,1,Color.WHITE);
t = new Timer(5, new Listener());
t.start();
addKeyListener(new Key());
setFocusable(true);
}
public void paintComponent(Graphics g)
{
g.drawImage(myImage, 0, 0, getWidth(), getHeight(), null);
}
private class Key extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W)
{
snek.move(1);
}
if(e.getKeyCode() == KeyEvent.VK_A)
{
snek.move(2);
}
if(e.getKeyCode() == KeyEvent.VK_S)
{
snek.move(3);
}
if(e.getKeyCode() == KeyEvent.VK_D)
{
snek.move(4);
}
}
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(snek.checkBlock() != 0)
{
myBuffer.setColor(BACKGROUND);
myBuffer.fillRect(0,0,FRAME1,FRAME2);
snek.move(4);
collide(snek, food);
food.draw(myBuffer);
snek.draw(myBuffer);
myBuffer.setColor(Color.BLACK);
repaint();
}
}
}
private void collide(Sneke b, Food pd)
{
int sx = b.getX(snek.getLength()-1);
int sy = b.getY(snek.getLength()-1);
int fx = pd.getX();
int fy = pd.getY();
if(sx == sy && fx == fy)
{
snek.setLength(snek.getLength()+1);
}
}
}
最佳答案
why does the movement indicated by my key listener not make it to the buffer?
我心中一个更重要的问题是:为什么你认为它应该进入缓冲区?您仅在调用 snek.move(4)
之后才绘制缓冲区,因此看来只有这样才能将其放入缓冲区。
就我个人而言,我会采取不同的做法,包括(除其他外)
例如,尝试运行以下命令:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class SnakePanel extends JPanel {
// size of the GUI
private static final int PREF_W = 1000;
private static final int PREF_H = 800;
// background and snake color
private static final Color BG = Color.BLACK;
private static final Color SNAKE_COLOR = Color.RED;
private static final int SEGMENT_WIDTH = 20;
// distance moved in each timer tick, and time between each tick
private static final int DELTA = 5;
private static final int TIMER_DELAY = 40; // in msecs
// number of segments in the worm
private static final int WORM_LENGTH = 80;
// initial direction
private Direction direction = Direction.RIGHT;
// initial point
private Point point = new Point(PREF_W / 2, PREF_H / 2);
// Snake is little more than a List of Points
private List<Point> snakePointList = new LinkedList<>();
public SnakePanel() {
// set background color
setBackground(BG);
// fill snake list with points
for (int i = 0; i < WORM_LENGTH; i++) {
snakePointList.add(new Point(point));
}
// set key bindings
setKeyBindings();
// create and start Timer
new Timer(TIMER_DELAY, new TimerListener()).start();
}
// set up our key bindings
private void setKeyBindings() {
int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
setKeyStroke(inputMap, actionMap, keyStroke, Direction.UP);
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
setKeyStroke(inputMap, actionMap, keyStroke, Direction.DOWN);
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
setKeyStroke(inputMap, actionMap, keyStroke, Direction.LEFT);
keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
setKeyStroke(inputMap, actionMap, keyStroke, Direction.RIGHT);
}
private void setKeyStroke(InputMap inputMap, ActionMap actionMap, KeyStroke keyStroke,
Direction dir) {
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), new MyKeyAction(dir));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// smooth out our graphics
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// draw each oval in the Snake
for (Point pt : snakePointList) {
drawPoint(g2, pt);
}
}
private void drawPoint(Graphics2D g2, Point pt) {
g2.setColor(SNAKE_COLOR);
// The pt is actually the center point
// so we need to draw an oval that is centered on this point
int x = pt.x - SEGMENT_WIDTH / 2;
int y = pt.y - SEGMENT_WIDTH / 2;
g2.drawOval(x, y, SEGMENT_WIDTH, SEGMENT_WIDTH);
}
// set gui's size
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
// Action used by key binding
private class MyKeyAction extends AbstractAction {
private Direction dir;
public MyKeyAction(Direction dir) {
this.dir = dir;
}
public void actionPerformed(ActionEvent e) {
// all it does is set the Direction direction enum field
// for this GUI
// the Timer then uses this field
SnakePanel.this.direction = dir;
};
}
// timer ActionListener
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// create a new Point whose direction depends
// on the direction field * multiplier, DELTA
int x = point.x + direction.getX() * DELTA;
int y = point.y + direction.getY() * DELTA;
// create new point and add to snakePointList
point = new Point(x, y);
snakePointList.add(point);
// remove last point in list
snakePointList.remove(0);
repaint();
}
}
// Direction enum
enum Direction {
UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0);
private Direction(int x, int y) {
this.x = x;
this.y = y;
}
private int x;
private int y;
public int getX() {
return x;
}
public int getY() {
return y;
}
}
private static void createAndShowGui() {
SnakePanel mainPanel = new SnakePanel();
JFrame frame = new JFrame("SnakePanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
关于java - 监听器和计时器之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37221669/
我需要在 文档就绪 触发后 5 秒调用我的函数 abc()。 这在 jQuery 中可能吗? $(document).ready(function () { //Wait 5 seconds then
我发现 System.Diagnostics.Stopwatch 类即使在很短的时间段(即 20 秒)内似乎也存在可测量的不准确性。对于编码为运行 20 秒的进程,我的进程显示耗时为 20.3+ 秒:
我正在使用 Ionic Framework 使用 Angular 构建一个 Android/iPhone 食谱应用程序。 功能之一应该是每个成分/步骤的警报/计时器。 我猜 Ionic 是基于 Apa
我有一个 JS 计时器脚本,从 20 秒开始倒计时 var count = 0; var speed = 1000; countdown = setInterval( function
我的 JavaScript 计时器有一个大问题。一切正常,除了 1 个按钮:停止!我不知道如何停止计数器上的所有内容(例如重置每个输入和计数器)。有什么想法可以解决这个问题吗?
所以我有一个 TimerTask 任务 在其 run() 中调用函数 onTimerComplete() onTimerComplete() 看起来像这样: private void onTimerC
我在 Eclipse 中的 windowbuilder 创建的 run() 方法中有计时器。 我不知道如何通过另一种方法停止该计时器。例如通过添加 if(MenuWindow.gameStarted
我对java很陌生,我试图在按下按钮时启动计时器,但无法启动它。我尝试了几行代码,但似乎没有任何效果。 我已经声明了我的标签、文本字段和计时器: private JTextField JTFHours
import java.util.Scanner; import java.util.Timer; import java.util.TimerTask; public class Boggle {
我正在尝试在 JavaScript 中获取计时器的值,因此当计时器为零时它会显示不同的内容; var local_t = new Date(); local_t.setSeconds(local_t.
我需要使用 jquery 为网站创建自定义 slider 。到目前为止,如果我单击按钮,我已经设法让它按照我想要的方式运行,但我想实现一个自动计时器,以便幻灯片在 5 秒后切换。 这是我的 JS 代码
我正在制作一个计时器,记录点击“通过”按钮上的“确定”时的最长时间(个人最好成绩)。我似乎无法弄清楚如何让计数器回到 0,我确信有一种方法可以只用 2 个按钮(开始 + 通过)来完成。我希望计时器在我
我有一个 java.util.Timer 用于限制电子邮件发送(如果最近发送了状态电子邮件,那么现在不要发送,而是创建一个计时器任务以稍后发送任何新状态)。 我想要的是确保最终发送所有排队的电子邮件,
我已经建立了一个在线考试门户,允许学生使用网络浏览器在线参加考试。 现在我还开发了计时器功能,用户必须在规定的时间范围内完成考试。我遇到的麻烦是,当我刷新页面时,计时器再次从新开始,例如 40 分钟。
我想知道在一定时间内禁用按钮的最佳方法是什么。当用户使用其他按钮转到其他页面时,定时器不会被重置,按钮仍将被禁用。 我读过很多关于异步任务、线程的不同方法。但是我非常不确定哪种方法最好。 我希望计时器
我正在制作一个测验应用程序,我想在其中显示用户在玩游戏时所用的时间。它应该采用 HH:MM:SS 格式,从 00:00:00 开始,直到他选择答案。当用户每秒播放时,计时器应该每秒更新一次。另外,我想
您好,计划为该 Activity 开发 android 倒数计时器应用程序,当用户单击开始按钮时显示计时器倒计时并显示计时器倒计时,用户将转到剩余 Activity ,即使计时器在后台运行,如果用户单
我想知道是否有一种简单的方法可以使用 PHP 在数据库中创建计时器,我想在数据库中创建该行 30 分钟后将其删除。如果这不够具体,我很抱歉,但我不知道如何在其中提供更多细节,请随意发表评论,以便我可以
我试图制作一种与我的计时器一起使用的对象。问题是,当我只有裸函数(不在对象中)时,它就可以工作。但是当我把它放在对象内部时它不起作用。 使用此代码我只能看到 00:01 当我只使用函数本身时,它工作正
这个问题已经有答案了: How to format numbers as currency strings (67 个回答) 已关闭 9 年前。 我想显示从 1 到 2500 的美元计时器。当计时器增
我是一名优秀的程序员,十分优秀!