移动的BufferedImage与键绑定 [英] moving bufferedImage with keyBindings

查看:183
本文介绍了移动的BufferedImage与键绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我也问过几个问题早已但我还没有做出任何形式的突破。于是我跟着这里的例子: http://www.camick.com/java/source/被称我KeyboardAnimation.java 。我换了的JLabel为其扩展JComponent的我的动画测试。但是我仍然没有得到结果。我想可能是从动画类prevents被更新的坐标code。这是否类的键绑定动画干扰?(下面这个类通过对在屏幕上行走的动画不动,但的还是一个图像,另一个与字符移动的两腿之间只是交换一些缓冲的图像循环。)

 进口java.awt.Graphics;
进口java.awt.image.BufferedImage中;进口javax.swing.JComponent中;公共类动画扩展JComponent的{
    私有静态最后的serialVersionUID长1L =;
    公众的BufferedImage设置currentFrame;
    公共布尔行走= FALSE;
    公众诠释x = 50;
    公众诠释Y = 50;
    公众诠释DX,DY;
    公共无效更新()
    {
        如果(步行){
            对(INT帧= 0;帧≤(Art.player.length + 1);帧++)
            {
                尝试{
                    设置currentFrame = Art.player [框架] [0];
                    尝试{
                        视频下载(200);
                        重绘();
                    }赶上(InterruptedException的E1){
                        // TODO自动生成catch块
                        e1.printStackTrace();
                    }
                }赶上(抛出IndexOutOfBoundsException E)
                {
                    帧= 0;
                    设置currentFrame = Art.player [框架] [0];
                    尝试{
                        视频下载(200);
                        重绘();
                    }赶上(InterruptedException的E1){
                        // TODO自动生成catch块
                        e1.printStackTrace();
                    }                }
            }
        }其他
        {
            设置currentFrame = Art.player [0] [0];
        }
    }
    公共无效startAnimation()
    {
        行走= TRUE;
    }
    公共无效stopAnimation()
    {
        行走= FALSE;
    }
    公共无效的paintComponent(图形G)
    {
        g.drawImage(设置currentFrame,X,Y,NULL);
    }}

下面是按键绑定类:

 进口java.awt中的*。
java.awt.event中导入*。
进口java.net *。
进口的java.util.Map;
进口的java.util.HashMap;
进口的javax.swing *。公共类KeyboardAnimation实现的ActionListener
{
    私人最终静态字符串preSSED =pressed
    RELEASED =私人最终静态字符串释放;    私人JComponent的组件;
    私人定时器定时器;
    私人地图<弦乐,点> pressedKeys =新的HashMap<弦乐,点>();    公共KeyboardAnimation(JComponent的组件,诠释延迟)
    {
        this.component =组件;        定时器=新定时器(延迟,这一点);
        timer.setInitialDelay(0);
    }    / *
    *放大器;参数keyStroke的 - 见KeyStroke.getKeyStroke(String)以格式
    *字符串的。除pssed $ P $ |发布的关键词
    *不包括在的字符串中。
    * /
    公共无效的addAction(字符串键击INT DELTAX,诠释DELTAY)
    {
        //从击键的修饰语分开密钥标识符        INT偏移= keyStroke.lastIndexOf();
        字符串键=偏移== -1? keyStroke的:keyStroke.substring(偏移+ 1);
        字符串修饰符= keyStroke.replace(键,);        //获取该组件的的InputMap和ActionMap中        InputMap中的InputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap中的ActionMap = component.getActionMap();        //创建行动,并添加了pressed键绑定        行动pressedAction =新AnimationAction(键,新点(DELTAX,DELTAY));
        字符串pressedKey =修饰符+ preSSED +键;
        的KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(pressedKey);
        inputMap.put(pressedKeyStroke,pressedKey);
        actionMap.put(pressedKey,pressedAction);        //创建行动,并添加绑定的关键公布        行动releasedAction =新AnimationAction(键,NULL);
        字符串releasedKey =修饰语+溶出+键;
        的KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(releasedKey);
        inputMap.put(releasedKeyStroke,releasedKey);
        actionMap.put(releasedKey,releasedAction);
    }    //调用每当关键是pressed或释放    私人无效handleKeyEvent(字符串键,点moveDelta)
    {
        //跟踪哪些键是pressed        如果(moveDelta == NULL)
            pressedKeys.remove(键);
        其他
            pressedKeys.put(键,moveDelta);        //开始计时,当第一个关键是pressed        如果(pressedKeys.size()== 1)
        {
            timer.start();
        }        //停止计时器时,所有按键都被释放        如果(pressedKeys.size()== 0)
        {
            timer.stop();
        }
    }    //调用当定时器触发    公共无效的actionPerformed(ActionEvent的五)
    {
        moveComponent();
    }    //移动组件到新的位置    私人无效moveComponent()
    {
        INT componentWidth = component.getSize()宽。
        INT componentHeight = component.getSize()的高度。        尺寸parentSize = component.getParent()的getSize()。
        INT上级宽度= parentSize.width;
        INT上级高度= parentSize.height;        //计算新举措        INT DELTAX = 0;
        INT DELTAY = 0;        对于(点三角洲:pressedKeys.values​​())
        {
            DELTAX + = delta.x;
            DELTAY + = delta.y;
        }
        //确定下一个X位置        INT nextX = Math.max(component.getLocation()X + DELTAX,0);        如果(nextX + componentWidth>上级宽度)
        {
            nextX =上级宽度 - componentWidth;
        }        //确定下一个Y位置        INT nextY = Math.max(component.getLocation()Y + DELTAY,0);        如果(nextY + componentHeight>上级高度)
        {
            nextY =上级高度 - componentHeight;
        }        //移动组件        component.setLocation(nextX,nextY);
    }    //动作跟踪的关键和点重新present运动
    //组件。关键是释放时指定零点。    私有类AnimationAction扩展AbstractAction实现的ActionListener
    {
        私人点moveDelta;        公共AnimationAction(字符串键,点moveDelta)
        {
            超(键);            this.moveDelta = moveDelta;
        }        公共无效的actionPerformed(ActionEvent的五)
        {
            handleKeyEvent((字符串)的getValue(名称),moveDelta);
        }
    }    公共静态无效的主要(字串[] args)
    {
        动画测试=新动画();        KeyboardAnimation动画=新KeyboardAnimation(测试,24);
        animation.addAction(左,-3,0);
        animation.addAction(右,3,0);
        animation.addAction(UP,0,-3);
        animation.addAction(DOWN,0,3);        animation.addAction(控制左,-5,0);
        animation.addAction(V,5,5);        JFrame的帧=新的JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        。frame.getContentPane()加(试验);
        frame.setSize(600,600);
        frame.setLocationRelativeTo(NULL);
        frame.setVisible(真);
        test.startAnimation();
        test.update();
    }    静态类ColorIcon实现图标
    {
        私人色彩的颜色;
        私人诠释宽度;
        私人诠释高度;        公共ColorIcon(色彩的颜色,诠释的宽度,高度INT)
        {
            this.color =颜色;
            this.width =宽度;
            this.height =高度;
        }        公众诠释getIconWidth()
        {
            返回宽度;
        }        公众诠释getIconHeight()
        {
            返回高度;
        }        公共无效的paintIcon(C组分,图形克,INT的x,int y)对
        {
            g.setColor(颜色);
            g.fillRect(X,Y​​,宽度,高度);
        }
    }
}


解决方案

 视频下载(200);
重绘();

不要阻塞EDT(事件指派线程) - 图形用户界面将冻结当这种情况发生。而不是调用的视频下载(N)实施一个Swing 定时的重复任务。见摇摆 并发更多的细节。

I have asked several questions already but I have yet to make any sort of breakthrough. So I followed the example here:http://www.camick.com/java/source/KeyboardAnimation.java that was referred to me. I switched out the JLabel for my Animation test which extends JComponent. However I am still getting no results. I think it might be the code from the Animation class that prevents the coordinates from being updated. Does this class interfere with the keybindings animation?(This class below loops through some buffered images for the walking animation not moving it across the screen but just switching between one image of a still and another with the legs of the character moving.)

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;



public class Animation extends JComponent{
    private static final long serialVersionUID = 1L;
    public BufferedImage currentFrame;
    public boolean walking=false;
    public int x=50;
    public int y=50;
    public int dx,dy;
    public void update()
    {
        if (walking){
            for(int frame=0;frame<(Art.player.length+1);frame++)
            {
                try{
                    currentFrame=Art.player[frame][0];
                    try {
                        Thread.sleep(200);
                        repaint();
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }           
                }catch(IndexOutOfBoundsException e)
                {
                    frame=0;
                    currentFrame=Art.player[frame][0];
                    try {
                        Thread.sleep(200);
                        repaint();
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }

                }
            }
        }else
        {
            currentFrame=Art.player[0][0];
        }
    }
    public void startAnimation()
    {
        walking=true;
    }
    public void stopAnimation()
    {
        walking=false;
    }
    public void paintComponent(Graphics g)
    {
        g.drawImage(currentFrame,x,y,null);
    }

}

Here is the keybindings class:

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.Map;
import java.util.HashMap;
import javax.swing.*;

public class KeyboardAnimation implements ActionListener
{
    private final static String PRESSED = "pressed ";
    private final static String RELEASED = "released ";

    private JComponent component;
    private Timer timer;
    private Map<String, Point> pressedKeys = new HashMap<String, Point>();

    public KeyboardAnimation(JComponent component, int delay)
    {
        this.component = component;

        timer = new Timer(delay, this);
        timer.setInitialDelay( 0 );
    }

    /*
    *  &param keyStroke - see KeyStroke.getKeyStroke(String) for the format of
    *                     of the String. Except the "pressed|released" keywords
    *                     are not to be included in the string.
    */
    public void addAction(String keyStroke, int deltaX, int deltaY)
    {
        //  Separate the key identifier from the modifiers of the KeyStroke

        int offset = keyStroke.lastIndexOf(" ");
        String key = offset == -1 ? keyStroke :  keyStroke.substring( offset + 1 );
        String modifiers = keyStroke.replace(key, "");

        //  Get the InputMap and ActionMap of the component

        InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = component.getActionMap();

        //  Create Action and add binding for the pressed key

        Action pressedAction = new AnimationAction(key, new Point(deltaX, deltaY));
        String pressedKey = modifiers + PRESSED + key;
        KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(pressedKey);
        inputMap.put(pressedKeyStroke, pressedKey);
        actionMap.put(pressedKey, pressedAction);

        //  Create Action and add binding for the released key

        Action releasedAction = new AnimationAction(key, null);
        String releasedKey = modifiers + RELEASED + key;
        KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(releasedKey);
        inputMap.put(releasedKeyStroke, releasedKey);
        actionMap.put(releasedKey, releasedAction);
    }

    //  Invoked whenever a key is pressed or released

    private void handleKeyEvent(String key, Point moveDelta)
    {
        //  Keep track of which keys are pressed

        if (moveDelta == null)
            pressedKeys.remove( key );
        else
            pressedKeys.put(key, moveDelta);

        //  Start the Timer when the first key is pressed

        if (pressedKeys.size() == 1)
        {
            timer.start();
        }

        //  Stop the Timer when all keys have been released

        if (pressedKeys.size() == 0)
        {
            timer.stop();
        }
    }

    //  Invoked when the Timer fires

    public void actionPerformed(ActionEvent e)
    {
        moveComponent();
    }

    //  Move the component to its new location

    private void moveComponent()
    {
        int componentWidth = component.getSize().width;
        int componentHeight = component.getSize().height;

        Dimension parentSize = component.getParent().getSize();
        int parentWidth  = parentSize.width;
        int parentHeight = parentSize.height;

        //  Calculate new move

        int deltaX = 0;
        int deltaY = 0;

        for (Point delta : pressedKeys.values())
        {
            deltaX += delta.x;
            deltaY += delta.y;
        }


        //  Determine next X position

        int nextX = Math.max(component.getLocation().x + deltaX, 0);

        if ( nextX + componentWidth > parentWidth)
        {
            nextX = parentWidth - componentWidth;
        }

        //  Determine next Y position

        int nextY = Math.max(component.getLocation().y + deltaY, 0);

        if ( nextY + componentHeight > parentHeight)
        {
            nextY = parentHeight - componentHeight;
        }

        //  Move the component

        component.setLocation(nextX, nextY);
    }

    //  Action to keep track of the key and a Point to represent the movement
    //  of the component. A null Point is specified when the key is released.

    private class AnimationAction extends AbstractAction implements ActionListener
    {
        private Point moveDelta;

        public AnimationAction(String key, Point moveDelta)
        {
            super(key);

            this.moveDelta = moveDelta;
        }

        public void actionPerformed(ActionEvent e)
        {
            handleKeyEvent((String)getValue(NAME), moveDelta);
        }
    }

    public static void main(String[] args)
    {
        Animation test = new Animation();

        KeyboardAnimation animation = new KeyboardAnimation(test, 24);
        animation.addAction("LEFT", -3,  0);
        animation.addAction("RIGHT", 3,  0);
        animation.addAction("UP",    0, -3);
        animation.addAction("DOWN",  0,  3);

        animation.addAction("control LEFT", -5,  0);
        animation.addAction("V",  5,  5);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.getContentPane().add(test);
        frame.setSize(600, 600);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
        test.startAnimation();
        test.update();
    }

    static class ColorIcon implements Icon
    {
        private Color color;
        private int width;
        private int height;

        public ColorIcon(Color color, int width, int height)
        {
            this.color = color;
            this.width = width;
            this.height = height;
        }

        public int getIconWidth()
        {
            return width;
        }

        public int getIconHeight()
        {
            return height;
        }

        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor(color);
            g.fillRect(x, y, width, height);
        }
    }
}

解决方案

Thread.sleep(200);
repaint();

Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks. See Concurrency in Swing for more details.

这篇关于移动的BufferedImage与键绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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