逐渐加速精灵 [英] Gradually speeding a sprite

查看:101
本文介绍了逐渐加速精灵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图在按下按钮时逐渐加速精灵,而不是仅以恒定速度移动。同时设置最大速度限制。我希望你明白我的意思。

I'm trying to make the sprite speed-up gradually on button press and not to move constant speed only. Also set a max-speed limit. I hope you understand what i mean.

timer = new Timer(5, this);
timer.start();

public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D)g;
    g2d.drawImage(image, x, y, this); //x,y = position
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}

private class TAdapter extends KeyAdapter { 
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
            dx = -1;
        }
        if (key == KeyEvent.VK_RIGHT) {
            dx = 1;
        }
        if (key == KeyEvent.VK_UP) {
            dy = -1;
        }
        if (key == KeyEvent.VK_DOWN) {
            dy = 1;
        }
    }
}   
    public void actionPerformed(ActionEvent e) {
        x += dx;   
        y += dy;
        repaint();  
    }


推荐答案

有几件事(最初)您的示例代码错误...

There are several things (initially) wrong with your example code...


  1. 您将覆盖 paint 方法。建议您改为覆盖 paintComponent 方法。如果你要覆盖顶级容器的 paint 方法,比如 JFrame ,那么建议你不要吨。相反,使用类似 JPanel 的内容作为自定义绘画的基础...

  2. 您正在处置图形过去的上下文。这非常危险,因为这样可以防止其他任何东西被涂上。 Graphics 上下文是共享资源,在此重绘周期中需要更新的所有内容都将使用相同的 Graphics 上下文。

  3. 您使用的是 KeyListener KeyListener 受到焦点问题的困扰。通过使用密钥绑定 API可以轻松解决此问题。键绑定也更灵活,因为它们将物理键与操作分开,允许您轻松地将操作与不同的键相关联和/或重用基础操作(例如使用按钮)。

  1. You are overriding the paint method. It is recommend that you override the paintComponent method instead. If you are overriding the paint method of a top level container, like JFrame, then it is recommended that you don't. Instead, use something like JPanel as the bases for your custom painting...
  2. You are disposing of the Graphics context that is past to you. This is VERY dangerous, as this will prevent anything else from been painted. The Graphics context is a shared resources, everything that needs to be updated during this repaint cycle will using the same Graphics context.
  3. You are using a KeyListener. KeyListener suffers from focus issues. This can easily be remedied through the use of the Key Binding API. Key bindings are also more flexible, as they separate the physical key from the action, allowing you to associate the action with different keys with little effort and/or reuse the underlying action (such as with buttons).

所以。对于你的问题。你需要知道......

So. For your question. You need to know...


  • 目前的速度......

  • 最低允许速度...

  • 最高允许速度......

您还需要维护你正在改变的对象的当前位置。

You will also want to maintain the current position of the object you are altering.

这个例子实际上并没有移动玩家,因为它移动了背景。背景位置由 xDelta 改变,这是变化的速度......

This example doesn't actually move the "player" so much as it moves the background. The background position is altered by the xDelta, which is the speed of change...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestSpeed {

    public static void main(String[] args) {
        new TestSpeed();
    }

    public TestSpeed() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        private BufferedImage background;
        // The current position of the background
        private int xPos = 0;
        // The speed/delta that the xPos is changed...
        private int xDelta = 0;

        public TestPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (xPos < -(getWidth())) {
                        xPos = 0;
                    }
                    xPos -= xDelta;
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "slower");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "faster");

            ActionMap am = getActionMap();
            am.put("slower", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    setSpeed(-1);
                }
            });
            am.put("faster", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    setSpeed(1);
                }
            });
        }

        protected void setSpeed(int delta) {
            xDelta += delta;
            // Check the change in speed to ensure it's within the appropriate range
            if (xDelta < 0) {
                xDelta = 0;
            } else if (xDelta > 9) {
                xDelta = 9;
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        public void invalidate() {
            background = null;
            super.invalidate();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            int x = xPos;
            g.setColor(Color.DARK_GRAY);
            while (x < getWidth()) {
                g.drawLine(x, 0, x, getHeight());
                x += 15;
            }

            int width = getWidth();
            int height = getHeight();
            x = (width / 2) - 5;
            int y = (height / 2) - 5;
            g.setColor(Color.RED);
            g.fillOval(x, y, 10, 10);
        }        
    }    
}

这篇关于逐渐加速精灵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆