日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

如何在Java中聆聽按鍵時移動圖像

瀏覽:164日期:2024-05-07 14:19:05
(adsbygoogle = window.adsbygoogle || []).push({}); 如何解決如何在Java中聆聽按鍵時移動圖像?

你可以使用Swing計時器為圖像設置動畫:

import java.awt.*;import java.awt.event.*;import javax.swing.*;public class TimerAnimation extends JLabel implements ActionListener{ int deltaX = 2; int deltaY = 3; int directionX = 1; int directionY = 1; public TimerAnimation(int startX, int startY,int deltaX, int deltaY,int directionX, int directionY,int delay) {this.deltaX = deltaX;this.deltaY = deltaY;this.directionX = directionX;this.directionY = directionY;setIcon( new ImageIcon('dukewavered.gif') );// setIcon( new ImageIcon('copy16.gif') );setSize( getPreferredSize() );setLocation(startX, startY);new javax.swing.Timer(delay, this).start(); } public void actionPerformed(ActionEvent e) {Container parent = getParent();// Determine next X positionint nextX = getLocation().x + (deltaX * directionX);if (nextX < 0){ nextX = 0; directionX *= -1;}if ( nextX + getSize().width > parent.getSize().width){ nextX = parent.getSize().width - getSize().width; directionX *= -1;}// Determine next Y positionint nextY = getLocation().y + (deltaY * directionY);if (nextY < 0){ nextY = 0; directionY *= -1;}if ( nextY + getSize().height > parent.getSize().height){ nextY = parent.getSize().height - getSize().height; directionY *= -1;}// Move the labelsetLocation(nextX, nextY); } public static void main(String[] args) {JPanel panel = new JPanel();JFrame frame = new JFrame();frame.setContentPane(panel);frame.setDefaultCloSEOperation( JFrame.EXIT_ON_CLOSE );frame.getContentPane().setLayout(null);// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );frame.getContentPane().add( new TimerAnimation(300, 100, 3, 2, -1, 1, 20) );// frame.getContentPane().add( new TimerAnimation(0, 000, 5, 0, 1, 1, 20) );frame.getContentPane().add( new TimerAnimation(0, 200, 5, 0, 1, 1, 80) );frame.setSize(400, 400);frame.setLocationRelativeto( null );frame.setVisible(true);// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );// frame.getContentPane().add( new TimerAnimation(10, 10, 3, 0, 1, 1, 10) ); }}

你可以將KeyListener添加到面板,它將獨立于圖像動畫進行操作。

是的,Swing計時器和鍵綁定可以很好地工作。這是另一個例子(我的):)

import java.awt.*;import java.awt.event.*;import java.awt.image.BufferedImage;import javax.swing.*;public class AnimationWithKeyBinding { private static void createAndShowUI() { AnimationPanel panel = new AnimationPanel(); // the drawing JPanel JFrame frame = new JFrame('Animation With Key Binding'); frame.getContentPane().add(panel); frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeto(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokelater(new Runnable() { public void run() { createAndShowUI(); } }); }}@SuppressWarnings('serial')class AnimationPanel extends JPanel { public static final int SPRITE_WIDTH = 20; public static final int PANEL_WIDTH = 400; public static final int PANEL_HEIGHT = 400; private static final int MAX_MSTATE = 25; private static final int SPIN_TIMER_PERIOD = 16; private static final int SPRITE_STEP = 3; private int mState = 0; private int mX = (PANEL_WIDTH - SPRITE_WIDTH) / 2; private int mY = (PANEL_HEIGHT - SPRITE_WIDTH) / 2; private int oldMX = mX; private int oldMY = mY; private boolean moved = false; // an array of sprite images that are drawn sequentially private BufferedImage[] spriteImages = new BufferedImage[MAX_MSTATE]; public AnimationPanel() { // create and start the main animation timer new Timer(SPIN_TIMER_PERIOD, new SpinTimerListener()).start(); setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setBackground(Color.white); createSprites(); // create the images setupKeyBinding(); } private void setupKeyBinding() { int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inMap = getInputMap(condition); ActionMap actMap = getActionMap(); // this uses an enum of Direction that holds ints for the arrow keys for (Direction direction : Direction.values()) { int key = direction.getKey(); String name = direction.name(); // add the key bindings for arrow key and shift-arrow key inMap.put(Keystroke.getKeystroke(key, 0), name); inMap.put(Keystroke.getKeystroke(key, InputEvent.SHIFT_DOWN_MASK), name); actMap.put(name, new MyKeyAction(this, direction)); } } // create a bunch of buffered images and place into an array, // to be displayed sequentially private void createSprites() { for (int i = 0; i < spriteImages.length; i++) { spriteImages[i] = new BufferedImage(SPRITE_WIDTH, SPRITE_WIDTH, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = spriteImages[i].createGraphics(); g2.setColor(Color.red); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); double theta = i * Math.PI / (2 * spriteImages.length); double x = SPRITE_WIDTH * Math.abs(Math.cos(theta)) / 2.0; double y = SPRITE_WIDTH * Math.abs(Math.sin(theta)) / 2.0; int x1 = (int) ((SPRITE_WIDTH / 2.0) - x); int y1 = (int) ((SPRITE_WIDTH / 2.0) - y); int x2 = (int) ((SPRITE_WIDTH / 2.0) + x); int y2 = (int) ((SPRITE_WIDTH / 2.0) + y); g2.drawLine(x1, y1, x2, y2); g2.drawLine(y1, x2, y2, x1); g2.dispose(); } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(spriteImages[mState], mX, mY, null); } public void incrementX(boolean right) { oldMX = mX; if (right) { mX = Math.min(getWidth() - SPRITE_WIDTH, mX + SPRITE_STEP); } else { mX = Math.max(0, mX - SPRITE_STEP); } moved = true; } public void incrementY(boolean down) { oldMY = mY; if (down) { mY = Math.min(getHeight() - SPRITE_WIDTH, mY + SPRITE_STEP); } else { mY = Math.max(0, mY - SPRITE_STEP); } moved = true; } public void tick() { mState = (mState + 1) % MAX_MSTATE; } private class SpinTimerListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { tick(); int delta = 20; int width = SPRITE_WIDTH + 2 * delta; int height = width; // make sure to erase the old image if (moved) { int x = oldMX - delta; int y = oldMY - delta; repaint(x, y, width, height); } int x = mX - delta; int y = mY - delta; // draw the new image repaint(x, y, width, height); moved = false; } }}enum Direction { UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN), LEFT(KeyEvent.VK_LEFT), RIGHT(KeyEvent.VK_RIGHT); private int key; private Direction(int key) { this.key = key; } public int getKey() { return key; }}// Actions for the key binding@SuppressWarnings('serial')class MyKeyAction extends AbstractAction { private AnimationPanel draw; private Direction direction; public MyKeyAction(AnimationPanel draw, Direction direction) { this.draw = draw; this.direction = direction; } @Override public void actionPerformed(ActionEvent e) { switch (direction) { case UP: draw.incrementY(false); break; case DOWN: draw.incrementY(true); break; case LEFT: draw.incrementX(false); break; case RIGHT: draw.incrementX(true); break; default: break; } }}

這是另一個使用此精靈表的示例:

在此處輸入圖片說明

從本網站獲得。

同樣,這是在JPanel的paintComponent方法中進行繪制并使用“鍵綁定”指示移動方向的示例。

import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Image;import java.awt.event.*;import java.awt.image.BufferedImage;import java.io.IOException;import java.net.URL;import java.util.ArrayList;import java.util.EnumMap;import java.util.List;import java.util.Map;import javax.imageio.ImageIO;import javax.swing.*;@SuppressWarnings('serial')public class Mcve3 extends JPanel { private static final int PREF_W = 800; private static final int PREF_H = 640; private static final int TIMER_DELAY = 50; private int spriteX = 400; private int spriteY = 320; private SpriteDirection spriteDirection = SpriteDirection.RIGHT; private MySprite sprite = null; private Timer timer = null; public Mcve3() {try { sprite = new MySprite(spriteDirection, spriteX, spriteY);} catch (IOException e) { e.printstacktrace(); System.exit(-1);}setBackground(Color.WHITE);setKeyBindings(SpriteDirection.LEFT, KeyEvent.VK_LEFT);setKeyBindings(SpriteDirection.RIGHT, KeyEvent.VK_RIGHT);setKeyBindings(SpriteDirection.FORWARD, KeyEvent.VK_DOWN);setKeyBindings(SpriteDirection.AWAY, KeyEvent.VK_UP);timer = new Timer(TIMER_DELAY, new TimerListener());timer.start(); } private void setKeyBindings(SpriteDirection dir, int keyCode) {int condition = WHEN_IN_FOCUSED_WINDOW;InputMap inputMap = getInputMap(condition);ActionMap actionMap = getActionMap();Keystroke keypressed = Keystroke.getKeystroke(keyCode, 0, false);Keystroke keyreleased = Keystroke.getKeystroke(keyCode, 0, true);inputMap.put(keypressed, keypressed.toString());inputMap.put(keyreleased, keyreleased.toString());actionMap.put(keypressed.toString(), new MoveAction(dir, false));actionMap.put(keyreleased.toString(), new MoveAction(dir, true)); } @Override public Dimension getPreferredSize() {if (isPreferredSizeSet()) { return super.getPreferredSize();}return new Dimension(PREF_W, PREF_H); } @Override protected void paintComponent(Graphics g) {super.paintComponent(g);sprite.draw(g); } private class MoveAction extends AbstractAction {private SpriteDirection dir;private boolean released;public MoveAction(SpriteDirection dir, boolean released) { this.dir = dir; this.released = released;}@Overridepublic void actionPerformed(ActionEvent e) { if (released) {sprite.setMoving(false); } else {sprite.setMoving(true);sprite.setDirection(dir); }} } private class TimerListener implements ActionListener {@Override public void actionPerformed(ActionEvent e) {if (sprite.isMoving()) { sprite.tick();}repaint(); } } private static void createAndShowGui() {Mcve3 mainPanel = new Mcve3();JFrame frame = new JFrame('MCVE');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()); }}class MySprite { private static final String SPRITE_SHEET_PATH = 'http://' + 'orig12.deviantart.net/7db3/f/2010/338/3/3/' + 'animated_sprite_sheet_32x32_by_digibody-d3479l2.gif'; private static final int MAX_MOVING_INDEX = 4; private static final int DELTA = 4; private SpriteDirection direction; private Map<SpriteDirection, Image> standingImgMap = new EnumMap<>(SpriteDirection.class); private Map<SpriteDirection, List<Image>> movingImgMap = new EnumMap<>(SpriteDirection.class); private int x; private int y; private boolean moving = false; private int movingIndex = 0; public MySprite(SpriteDirection direction, int x, int y) throws IOException {this.direction = direction;this.x = x;this.y = y;createSprites(); } public void draw(Graphics g) {Image img = null;if (!moving) { img = standingImgMap.get(direction);} else { img = movingImgMap.get(direction).get(movingIndex);}g.drawImage(img, x, y, null); } private void createSprites() throws IOException {URL spriteSheetUrl = new URL(SPRITE_SHEET_PATH);BufferedImage img = ImageIO.read(spriteSheetUrl);// get sub-images (sprites) from the sprite sheet// magic numbers for getting sprites from sheet, all obtained by trial and errorint x0 = 0;int y0 = 64;int rW = 32;int rH = 32;for (int row = 0; row < 4; row++) { SpriteDirection dir = SpriteDirection.values()[row]; List<Image> imgList = new ArrayList<>(); movingImgMap.put(dir, imgList); int rY = y0 + row * rH; for (int col = 0; col < 5; coL++) {int rX = x0 + col * rW;BufferedImage subImg = img.getSubimage(rX, rY, rW, rH);if (col == 0) { // first image is standing standingImgMap.put(dir, subImg);} else { // all others are moving imgList.add(subImg);} }} } public SpriteDirection getDirection() {return direction; } public void setDirection(SpriteDirection direction) {if (this.direction != direction) { setMoving(false);}this.direction = direction; } public int getX() {return x; } public void setX(int x) {this.x = x; } public int getY() {return y; } public void setY(int y) {this.y = y; } public boolean isMoving() {return moving; } public void setMoving(boolean moving) {this.moving = moving;if (!moving) { movingIndex = 0;} } public void tick() {if (moving) { switch (direction) { case RIGHT:x += DELTA;break; case LEFT:x -= DELTA;break; case FORWARD:y += DELTA;break; case AWAY:y -= DELTA; } movingIndex++; movingIndex %= MAX_MOVING_INDEX;} } public int getMovingIndex() {return movingIndex; } public void setMovingIndex(int movingIndex) {this.movingIndex = movingIndex; }}enum SpriteDirection { FORWARD, LEFT, AWAY, RIGHT}解決方法

我開始學習Java編程,并且我認為通過游戲開發學習Java很酷。我知道如何繪制圖像并聽按鍵,然后移動該圖像。但是,當窗口正在聽按鍵時,是否可以使圖像在窗口中來回移動?例如,當圖像或對象(如太空飛船)在窗口中從左向右移動時,如果按空格鍵,激光將在屏幕底部發射(很酷的:D)。但是基本上,我只是想知道在窗口正在聽按鍵時如何使圖像左右移動。

我在想將一個關鍵偵聽器添加到我的窗口,然后觸發一個無限循環來移動圖像。還是我需要學習有關線程的知識,以便另一個線程可以移動對象?

請指教。

標簽: java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产一区亚洲| 激情欧美一区| 美女精品久久| 奇米狠狠一区二区三区| 国产精品嫩草影院在线看| 国产精品网址| 巨乳诱惑日韩免费av| 精品久久久中文字幕| 国产精品一站二站| 国产精品香蕉| yellow在线观看网址| 青青久久av| 午夜电影亚洲| 午夜一级在线看亚洲| 免费精品国产的网站免费观看| 99热精品久久| 亚洲黄页一区| 日本精品在线播放| 国产欧美一区二区精品久久久| 日本不卡视频在线| 国产精品亚洲片在线播放| 久草精品视频| 亚洲性图久久| 亚洲免费资源| 国产精品久久久久久久久久久久久久久 | 婷婷国产精品| 国产精品视区| 国产调教精品| 电影天堂国产精品| 蜜臀久久久99精品久久久久久| 青青草精品视频| 日韩不卡免费高清视频| 日韩午夜黄色| 国产精品极品在线观看| 亚洲午夜免费| 亚洲在线一区| 国产精品115| 免费久久久久久久久| 水蜜桃久久夜色精品一区的特点| 在线看片国产福利你懂的| 老牛国内精品亚洲成av人片| 日韩免费精品| 久久在线电影| 日本欧洲一区二区| 国产日韩一区二区三区在线| av在线资源| 亚洲最新av| 精品日韩在线| 天堂av在线一区| 麻豆传媒一区二区三区| 国产综合视频| 国产精品日韩精品在线播放| 久久中文亚洲字幕| 视频一区二区三区入口| 国语精品一区| 亚洲制服一区| 色爱综合av| 国产亚洲字幕| 亚洲欧美网站| 欧美丰满日韩| 亚洲丝袜啪啪| 性感美女一区二区在线观看| 国产日韩精品视频一区二区三区| 激情五月综合| 精品亚洲二区| 四虎精品一区二区免费| 热三久草你在线| 欧美日韩中文| 国产一区清纯| 丁香婷婷久久| 日韩精品免费视频一区二区三区| 日本少妇一区| 国产精品mv在线观看| 亚洲一区国产| 久久久久网站| 麻豆精品99| 日韩不卡手机在线v区| 免费欧美一区| 视频一区国产视频| 亚洲夜间福利| 国产精品亚洲欧美日韩一区在线 | 一区二区电影| 欧美黑人做爰爽爽爽| 亚洲欧美视频一区二区三区| 久久精品国产99国产| 中文视频一区| 99成人在线视频| 精品视频在线一区二区在线| 亚洲欧美日韩国产一区| 免费高潮视频95在线观看网站| 国产日本久久| 日韩中文字幕| 美日韩精品视频| 人人草在线视频| 激情久久99| 国产精品扒开腿做爽爽爽软件| 免费视频最近日韩| 在线视频观看日韩| 免费看av不卡| 久久中文字幕一区二区三区| 亚洲精品欧美| 久久最新视频| 国产亚洲在线| 久久国产88| 99综合视频| 国产精品女主播一区二区三区| 中文另类视频| 久久久精品久久久久久96| 国产精品成人自拍| 国产日韩在线观看视频| 日本aⅴ亚洲精品中文乱码| 亚洲一区二区三区久久久| 国产美女一区| 亚洲永久字幕| 午夜宅男久久久| 亚洲一区二区三区四区五区午夜| 欧美日韩中文一区二区| 久久高清免费| 欧美日韩国产一区二区三区不卡 | 日韩中文在线电影| 国产精品99久久久久久董美香| 一区二区三区网站| 日本a级不卡| 国产精品对白| 久久久久久久久久久9不雅视频| 中文字幕一区二区三区日韩精品 | 蜜桃tv一区二区三区| 新版的欧美在线视频| 久久超级碰碰| 免费一级欧美在线观看视频| 精品午夜视频| 综合日韩av| 999久久久国产精品| 1024精品久久久久久久久| 在线 亚洲欧美在线综合一区| 亚洲激精日韩激精欧美精品| 鲁大师影院一区二区三区| 亚洲三级国产| 国产亚洲精aa在线看 | 国产日产精品_国产精品毛片 | 久久在线91| 国产一区二区三区四区大秀| 久久亚州av| 亚洲va中文在线播放免费| 亚洲香蕉网站| 亚洲一区导航| 国产欧美大片| 日本激情一区| 激情婷婷久久| 亚洲青青久久| 国产精品中文字幕亚洲欧美| 国语精品一区| 秋霞国产精品| 午夜在线精品| 国产日产精品_国产精品毛片 | 丝袜av一区| 免费视频一区三区| 亚洲香蕉久久| 久久精品99久久无色码中文字幕| 久久电影一区| 久久av网站| 国产91在线精品| 三级精品视频| 日本精品不卡| 首页亚洲欧美制服丝腿| 日韩超碰人人爽人人做人人添| 亚洲午夜久久久久久尤物| 亚洲精品麻豆| 美女久久久久久| 香蕉国产精品| 欧美自拍一区| 一本大道色婷婷在线| 久久国产精品毛片| 国产精品久久久久毛片大屁完整版| 麻豆国产在线| 久久av一区二区三区| 久久这里只有| 伊人精品在线| 国产午夜久久av| 久久在线电影| 国产免费播放一区二区| 欧美香蕉视频| 日本不卡视频在线| 毛片在线网站| 日本伊人久久| 中文在线资源| 日本视频在线一区| 久久久精品网| 日本va欧美va精品发布| zzzwww在线看片免费| 亚欧成人精品| 日韩中文影院| 国产精品久久久久久久久免费高清 | 中文字幕亚洲在线观看| 精品国产乱码久久久久久樱花| 国产综合精品一区| 国产精品s色| 亚洲综合另类| 国产精品毛片久久| 亚洲专区视频|