简体   繁体   English

如何在Java游戏中重绘图像

[英]How to repaint over images in Java game

Hello everyone I am having trouble with painting over coins that the user intersects with. 大家好,我在绘制与用户相交的硬币时遇到麻烦。 What I want this code to do is when the user sprite intersects with any of the ten coin images it paints over the coin so that it no longer appears on the screen (also need to add in some kind of counter so that when the user collects all ten coins it will stop the thread, and say "You Win!"). 我要这段代码要做的是,当用户精灵与它绘制在硬币上的十个硬币图像中的任何一个相交时,它不再出现在屏幕上(还需要添加某种计数器,以便当用户收集时所有十枚硬币将停止线程,并说“ You Win!”)。 My question is how would I go about doing this because I have tried using repaint() in the if statements, and it is not compiling correctly anymore. 我的问题是我将如何去做,因为我已经尝试过在if语句中使用repaint(),并且它现在无法正确编译。 Any help on how to paint over the coins, and possibly even add some kind of counter (thinking a for loop would come in handy) would be greatly appreciated! 非常感谢您提供有关如何在硬币上绘画的帮助,甚至可能添加某种计数器(认为for循环会派上用场)! Here is the code: 这是代码:

public void paint(Graphics g)
{
    g.clearRect(0, 0, this.getWidth(), this.getHeight());
    one.paintComponent(g);
    two.paintComponent(g);
    three.paintComponent(g);
    four.paintComponent(g);
    five.paintComponent(g);
    six.paintComponent(g);
    seven.paintComponent(g);
    eight.paintComponent(g);
    nine.paintComponent(g);
    ten.paintComponent(g);
    monster.setLocation(r.nextInt(10) - 5 + monster.x, r.nextInt(10 - 5 + monster.y));
    monster.paintComponent(g);
    user.paintComponent(g);
    if(user.intersects(one))
    {
    }
    if(user.intersects(two))
    {
    }
    if(user.intersects(three))
    {
    }
    if(user.intersects(four))
    {
    }
    if(user.intersects(five))
    {
    }
    if(user.intersects(six))
    {
    }
    if(user.intersects(seven))
    {
    }
    if(user.intersects(eight))
    {
    }
    if(user.intersects(nine))
    {
    }
    if(user.intersects(ten))
    {
    }
    if(user.intersects(monster))
    {
            g.setFont(new Font("Serif", Font.BOLD, 35));
            g.drawString("YOU HAVE DIED, YOU LOSE!", 100, 100); //Prints this when you lose
            thread.interrupt(); //Stopping the thread if you die
    }
}

At first, you should put the coins in a list. 首先,您应该将硬币放入列表中。 Then, if there's an interection, you simply remove the item (coin) of the list. 然后,如果有干扰,您只需删除列表中的项目(硬币)。 Like this: 像这样:

private List<Coin> coins;

public ClassConstructor() {
    coins = new ArrayList();
    coins.add(new Coin(type value,...)); //this ten times if every Coin is different from other
    //or this if every Coin are same:
    for (int i = 0; i < 10; i++) {
        coins.add(new Coin(type value,...));
    }
}

public void update() {
    //whatever
    for (int i = coins.size(); i >= 0; i--) {
        if (user.intersects(coins.get(i))) {
            coins.remove(i);
            //...
        }
    }

}

public void paint(Graphics g) {
    for (int i = coins.size(); i >= 0; i--) {
        coins.get(i).paintComponent(g);
    }
}

Now, you shouldnt end a Thread with thread.interrupt(). 现在,您不应该使用thread.interrupt()结束线程。 If that thread is your game loop, you should send a flag that ends the loop. 如果该线程是您的游戏循环,则应发送结束循环的标志。 The Thread of you game loop: 您的游戏循环线程:

@Override
public void run() {
    while (running) { //boolean running
        update();
        paint(g);
    }}

And, finally, your update will be like: 最后,您的更新将如下所示:

public void update() {
    //whatever
    for (int i = coins.size(); i >= 0; i--) {
        if (user.intersects(coins.get(i))) {
            coins.remove(i);
            //...
        }
    }
    if (user.intersects(monster)) {
        youThread.setRunning(false);
        try {
            gameLoopThread.join(); //"wait" until thread ends
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Off the top of my head, put while(true) within your Run() method (you said you were using a thread) and call repaint() within the loop, at the end of the loop (within a try/catch) put something like //thread//.sleep(allotted time) This will stop the thread for the set amount of Milliseconds. 在我的脑海中,将while(true)放入Run()方法(您说过您正在使用线程)中,并在循环内调用repaint(),在循环结束时(在try / catch中)放入类似于//thread//.sleep(allotted time)这将使线程停止设置的毫秒数。 Within the Javadoc of repaint() you'll see that it calls the nearest paint(Graphics g) method. repaint()的Javadoc中,您会看到它调用了最近的paint(Graphics g)方法。 By doing this you can access your paint() method from wherever you are in your program. 这样,您可以从程序中的任何位置访问paint()方法。

My suggestion to the coin's is make it it's own class. 我对硬币的建议是使其成为自己的硬币。 The class would look similar to this: 该类将类似于以下内容:

public class Coin{
int x;
int y;
public void Coin(int x, int y, Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    Image img1 = (//File Location);
    g2.drawImage(img1, x, y, //this);
    //If you have trouble with the ImageObserver (this part) try //class name of the applet.this
    this.x = x;
    this.y = y;

    g2.finalize();
}
public int getX(){
    return x;
}
public int getY(){
    return y;
}
}

After that, in your paint method you could make 10 Coin objects and use g which you instantiate in the parameters. 之后,在绘画方法中,您可以制作10个Coin对象并使用在参数中实例化的g You could then make an array of Coin objects and add 10 Coin s that you make in your paint method manually (yeah, it's a pain) (you have to make them in paint to pass the Graphics variable) 然后,您可以制作一个Coin对象数组,并手动添加您在paint方法中创建的10个Coin (是的,这很痛苦)(必须在paint中使它们通过以传递Graphics变量)

Coin[] coins = new Coin[10];

Is how you make the array, by the way. 顺便说一句,是如何制作数组。 After you make the array of coin's, then make a for loop in your paint method. 制作硬币阵列后,在paint方法中创建一个for循环。 It should look something like this: 它看起来应该像这样:

        for(int i = 0; i < coins.length; i++){
            if(coins[i].getX == //user X && coins[i].getY == //user Y){
                    g.clearRect(coins[i].getX, coins[i].getY, //Coin radius, //Coin radius);
            }

        }

This will make a clear rectangle be drawn over wherever the Coin is at if the user's X and Y is equal to the Coin's X and Y. 如果用户的X和Y等于硬币的X和Y,则将在硬币所在的位置绘制一个清晰的矩形。

This code is taken from my current project (that is working), I tried adjusting it to your project. 该代码取自我当前的项目(正在运行),我尝试将其调整为适合您的项目。

private void render () {
    BufferStrategy bufferstrategy = getBufferStrategy ();

    if (bufferstrategy == null) {
        createBufferStrategy(3);
        return;
    }

    Graphics g = bufferstrategy.getDrawGraphics();

    g.setColor(Color.white);
    g.fillRect(0, 0, getWidth(), getHeight());

    paint (g);

    g.dispose();
    bufferstrategy.show();
}

render() is called from run(), where the Thread is. Thread所在的run()中调用render()

Let's break it down and see if it can help you. 让我们分解一下,看看它是否可以帮助您。

  1. It gets a BufferStrategy for how many images to have ready. 它获得一个BufferStrategy,用于准备多少个图像。 It can be set to anything like you like within reason. 在合理范围内,可以将其设置为任何您喜欢的内容。 2 - 4 will do the trick. 2-4可以解决问题。 One can even work. 一个人甚至可以工作。
  2. It sets your current BufferStrategy to your Graphics . 它将您当前的BufferStrategyGraphics
  3. It then fills the screen with the color of white (could be a clear as well). 然后,它用白色填充屏幕(也可以是透明的)。
  4. Then it paints all components, in your case it calls paint (Graphics g) while in my case it iterates through all drawable objects. 然后,它绘制所有组件,在您的情况下,它称为paint (Graphics g)而在我的情况下,它遍历所有可绘制对象。
  5. It re-renders everything as it now should look. 它重新呈现了现在应该显示的所有内容。

Hope you take some points out from this. 希望您从中得到一些启示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM