java - 非主线程的图片不动

标签 java eclipse multithreading swing

我是java新手,现在正在研究线程。但是现在我有一个大问题: 当我运行以下代码时,除了两个图像在屏幕中移动外,其中一个图像现在移动了,甚至另一个图像也没有显示。我想知道问题是什么: 类敌人:

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Enemy extends JLabel implements Runnable{
    private BufferedImage i;
    private int x,y;
    Enemy()
    {
        x=y=0;
        try{
            i=ImageIO.read(new File("m2.jpg"));
        }catch (Exception e){}
        this.setIcon(new ImageIcon(i));
        this.setLocation(x,y);
        this.setBounds(new Rectangle(new Point(x,y),this.getPreferredSize()));
    }
    Enemy(int X,int Y)
    {
        x=X;
        y=Y;
        try{
            i=ImageIO.read(new File("m2.jpg"));
        }catch (Exception e){}
        this.setIcon(new ImageIcon(i));
        this.setLocation(x,y);
        this.setBounds(new Rectangle(new Point(x,y),this.getPreferredSize()));
    }

    public void move()
    {
        while(true)
        {
            int p=(int)Math.random()*4+1;
            switch (p)
            {
            case 1:x++;break;
            case 2:y++;break;
            case 3:x--;break;
            case 4:y--;break;
            }
            this.setLocation(x,y);
            this.setBounds(new Rectangle(new Point(x,y),this.getPreferredSize()));
        }
    }

    public void run()
    {
        move();
    }
}

玩家等级:

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;


public class Player extends JLabel implements Runnable{
    private BufferedImage i;
    private int x,y;
    Player()
    {
        x=y=0;
        try{
            i=ImageIO.read(new File("m1.jpg"));
        }catch (Exception e){}
        this.setIcon(new ImageIcon(i));
        this.setLocation(x,y);
        this.setBounds(new Rectangle(new Point(x,y),this.getPreferredSize()));
    }

    public void move()
    {
        int p=(int)Math.random()*4+1;
        switch (p)
        {
        case 1:x++;break;
        case 2:y++;break;
        case 3:x--;break;
        case 4:y--;break;
        }
        this.setLocation(x,y);
        this.setBounds(new Rectangle(new Point(x,y),this.getPreferredSize()));
    }

    public void run()
    {
        move();
    }
}

主类:

import javax.swing.JFrame;


public class Test {
    public static void main(String[] args) {
        Enemy e=new Enemy(150,150);
        Player p=new Player();
        JFrame f=new JFrame("Test");
        f.setSize(300,300);
        f.setLayout(null);
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        f.add(e);
        f.add(p);
        Thread pThread=new Thread(p);
        Thread eThread=new Thread(e);
        pThread.start();
        eThread.start();
        while(true)
        {
            f.setVisible(true);
            try
            {
                Thread.sleep(50);
            }catch (Exception q){}
            f.remove(p);
            f.remove(e);
            f.add(p);
            f.add(e);
        }


    }

}

最佳答案

EnemyPlayer 类中对 Math.random() 的调用始终四舍五入为零。您可能想要:

int p = (int) (Math.random() * 4) + 1;

move 方法中限制 xy 的可能值也是一个好主意(maxX = 帧宽度 -敌人/玩家宽度;maxY = 框架高度 - 敌人/玩家高度):

switch (p) {
    case 1:
        if (x < maxX)
            x++;
        break;
    case 2:
        if (y < maxY)
            y++;
        break;
    case 3:
        if (x > 0)
            x--;
        break;
    case 4:
        if (y > 0)
            y--;
        break;
}

最后,您可以通过为 EnemyPlayer 类创建一个公共(public)类来节省一些工作。这里可以放置所有共享代码,此时可以是全部代码;两个对象可以是同一类的实例:

GameObject e = new GameObject(150, 150, size - 150, size - 150, "m2.jpg");
GameObject p = new GameObject(100, 100, size - 100, size - 100, "m1.jpg");

GameObject 类可能如下所示:

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class GameObject extends JLabel implements Runnable {
    private BufferedImage i;
    private int x, y;
    private int maxX;
    private int maxY;

    public GameObject(int X, int Y, int maxX, int maxY, String imagePath) {
        x = X;
        y = Y;
        this.maxX = maxX;
        this.maxY = maxY;
        try {
            this.i = ImageIO.read(new File(imagePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.setIcon(new ImageIcon(this.i));
        this.setLocation(x, y);
        this.setBounds(new Rectangle(new Point(x, y), this.getPreferredSize()));
    }

    public void move() {
        while (i != null) {
            int p = (int) (Math.random() * 4) + 1;
            switch (p) {
                case 1:
                    if (x < maxX)
                        x++;
                    break;
                case 2:
                    if (y < maxY)
                        y++;
                    break;
                case 3:
                    if (x > 0)
                        x--;
                    break;
                case 4:
                    if (y > 0)
                        y--;
                    break;
            }
            this.setLocation(x, y);
            this.setBounds(new Rectangle(new Point(x, y), this.getPreferredSize()));
        }
    }

    public void run() {
        move();
    }
}

关于java - 非主线程的图片不动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29962706/

相关文章:

java - 当提供正则表达式时,Java 中的 String.split() 方法究竟如何工作?

用于无名 JButton 的 Java actionListener?

Java 两个类我需要 main 方法的帮助

java - Android 打开 URL onclick 某个按钮

eclipse - Ubuntu : install lombok in Eclipse IDE show error "can' t write directory"even using sudo

c++ - 将 std::map 对象传递给线程

java - Java中判断文件是否经过PGP加密

Android eclipse edittext 输入计算结果显示在另一个空的 edittext 上(自动)

java - 防御性复制是否足以从可变线程不安全类创建不可变线程安全类?

python - 线程内未捕获异常是只杀死线程还是整个进程?