Java小程序重新绘制一个圆形运动 [英] Java applet repaint a moving circle

查看:185
本文介绍了Java小程序重新绘制一个圆形运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚搬了过来,从Pygame的所以Java 2D在一个applet是一个有点新的给我,特别是当它涉及到重绘屏幕。在pygame中你可以简单地做 display.fill([1,1,1]),但我怎么做这在Java的一个小程序?据我所知)使用重绘(但是,这并不清除屏幕 - 从屏幕上任何移动物体是不是'删除'所以你只能画一长排圆圈。

下面是我的code,我一直在与测试:

 包圈;
进口java.applet.Applet中;
进口java.awt.Color中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口了java.util.Random;公共类圆形扩展的Applet实现Runnable {
    私有静态最后的serialVersionUID长= -6945236773451552299L;
    静态随机R =新随机();    弦乐味精=点击播放!;
    静态INT W = 800,H = 800;    INT [] txtPos = {(W / 2)-50,(H / 2)-50};
    INT [] = radiusRange {5,25};
    INT []圈子;
    静态INT [] POSRANGE;    INT X = 0,Y = 0;
    INT半径= 0;
    INT cursorRadius = 10;    布尔游戏= FALSE;    公共静态INT [] POS(){
        INT侧= r.nextInt(5-1)+ 1;
        开关(侧){
            情况1:
                POSRANGE =新INT [] {1,r.nextInt(w)的,r.nextInt((H + 40)-h)+ H,r.nextInt(270-90)+90};
                打破;
            案例2:
                POSRANGE =新INT [] {2,r.nextInt((W + 40)-w)+ W,r.nextInt(h)中,r.nextInt(270-90)+90};
                打破;
            案例3:
                POSRANGE =新INT [] {3,r.nextInt(w)的,r.nextInt(40)-40,r.nextInt(180)};
                打破;
            情况4:
                POSRANGE =新INT [] {4,r.nextInt(40)-40,r.nextInt(h)中,r.nextInt(180)};
                打破;
        }
        的System.out.println(侧面);
        返回POSRANGE;
    }
    公共无效的start(){
        的setSize(500,500);
        的setBackground(Color.BLACK);
        新的Thread(本)。开始();
    }    公共无效的run(){    }
    公共无效更新(图形G){
        油漆(G);
    }    公共无效漆(图形E){
        Graphics2D的G =(Graphics2D的)电子;        如果(System.currentTimeMillis的()%113 == 0){
            X + = 1;
            Y + = 1;
        }        g.setColor(Color.BLUE);
        g.fillOval(X,Y,20,20);        重绘();
    }
}


解决方案

  1. 您需要调用 super.paint(G); 油漆方法,以不能离开油漆文物。


  2. 不要调用重绘()油漆方法内


  3. 不要显式调用油漆,如您在做的update(),当你的意思调用 reapaint()


  4. 刚刚更新 X 更新里面的值( )方法,然后调用重绘()


  5. 您不必采取 A 图形参数的update()


  6. 您需要调用更新()某处反复循环,因为它更新 X reapint()取值


  7. 如果你的类将是一个的Runnable ,那么你应该放在运行一些code()方法。这可能是你应该有你的循环



 进口java.applet.Applet中;
进口java.awt.Color中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;公共类圆形扩展的Applet实现Runnable {    INT X = 0,Y = 0;    公共无效的start(){
        的setSize(500,500);
        的setBackground(Color.BLACK);
        新的Thread(本)。开始();
    }    公共无效的run(){
        而(真){
            尝试{
                更新();
                视频下载(50);            }赶上(InterruptedException的前){            }
        }
    }    公共无效更新(){
        X + = 5;
        Y + = 6;
        重绘();
    }    公共无效漆(图形E){
        super.paint(E);
        Graphics2D的G =(Graphics2D的)电子;
        g.setColor(Color.BLUE);
        g.fillOval(X,Y,20,20);    }
}


旁注


  • 为什么首先使用小程序。如果必须,为什么要使用AWT Applet的,而不是摇摆 JApplet的?时间升级。

下面是我怎么想的重做的Swing中的整个事情,使用Swing的定时,而不是一个环和视频下载,你应该做的。

 进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.SwingUtilities中;
进口javax.swing.Timer中;公共类圆继承JPanel {
    私有静态最终诠释D_W = 500;
    私有静态最终诠释D_H = 500;    INT X = 0;
    INT Y = 0;
    公共圈(){
        的setBackground(Color.BLACK);        定时器定时器=新定时器(50,新的ActionListener(){
            公共无效的actionPerformed(ActionEvent的五){
                X + = 5;
                Y + = 5;
                重绘();
            }
        });
        timer.start();
    }    @覆盖
    保护无效paintComponent(图形G){
        super.paintComponent方法(G);
        g.setColor(Color.BLUE);
        g.fillOval(X,Y,20,20);    }    @覆盖
    公共尺寸的get preferredSize(){
        返回新的Dimension(D_W,D_H);
    }    公共静态无效的主要(字串[] args){
        SwingUtilities.invokeLater(Runnable的新(){
            公共无效的run(){
                JFrame的帧=新的JFrame();
                frame.add(新圈());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }
}



更新


  

问题是,这是一个JPanel应用程序。我特别想打一个applet在网页上轻松使用。


您仍然可以使用它。只需使用的JPanel。取出的主要方法,而不是小程序,使用JApplet的,只是添加的JPanel你的小程序。简单的作为。

 进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口javax.swing.JApplet中;
进口javax.swing.JPanel中;
进口javax.swing.Timer中;公共类CircleApplet扩展JApplet的{    @覆盖
    公共无效的init(){
        添加(新圈());
    }    公共类圆继承JPanel {        私有静态最终诠释D_W = 500;
        私有静态最终诠释D_H = 500;        INT X = 0;
        INT Y = 0;        公共圈(){
            的setBackground(Color.BLACK);            定时器定时器=新定时器(50,新的ActionListener(){
                公共无效的actionPerformed(ActionEvent的五){
                    X + = 5;
                    Y + = 5;
                    重绘();
                }
            });
            timer.start();
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            g.setColor(Color.BLUE);
            g.fillOval(X,Y,20,20);        }        @覆盖
        公共尺寸的get preferredSize(){
            返回新的Dimension(D_W,D_H);
        }    }
}

I've just moved over from Pygame so Java 2D in an applet is a little new to me, especially when it comes to repainting the screen. In pygame you can simply do display.fill([1,1,1]) but how do I do this in an applet in Java? I understand the use of repaint() but that doesn't clear the screen - any moving object is not 'removed' from the screen so you just get a long line of painted circles.

Here's my code that I've been testing with:

package circles;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;

public class circles extends Applet implements Runnable {
    private static final long serialVersionUID = -6945236773451552299L;
    static Random r = new Random();

    String msg = "Click to play!";
    static int w = 800, h = 800;

    int[] txtPos = { (w/2)-50,(h/2)-50 };
    int[] radiusRange = { 5,25 };
    int[] circles;
    static int[] posRange;

    int x = 0, y = 0;
    int radius = 0;
    int cursorRadius = 10;

    boolean game = false;

    public static int[] pos() {
        int side = r.nextInt(5-1)+1;
        switch(side) {
            case 1:
                posRange = new int[]{ 1,r.nextInt(w),r.nextInt((h+40)-h)+h,r.nextInt(270-90)+90 };
                break;
            case 2:
                posRange = new int[]{ 2,r.nextInt((w+40)-w)+w,r.nextInt(h),r.nextInt(270-90)+90 };
                break;
            case 3:
                posRange = new int[]{ 3,r.nextInt(w),r.nextInt(40)-40,r.nextInt(180) };
                break;
            case 4:
                posRange = new int[]{ 4,r.nextInt(40)-40,r.nextInt(h),r.nextInt(180) };
                break;
        }
        System.out.println(side);
        return posRange;
    }
    public void start() {
        setSize(500,500);
        setBackground(Color.BLACK);
        new Thread(this).start();
    }

    public void run() {

    }
    public void update(Graphics g) {
        paint(g);
    }

    public void paint(Graphics e) {
        Graphics2D g = (Graphics2D) e;

        if(System.currentTimeMillis()%113==0) {
            x+=1;
            y+=1;
        }

        g.setColor(Color.BLUE);
        g.fillOval(x,y,20,20);

        repaint();
    }
}

解决方案

  1. You need to call super.paint(g); in your paint method, as to not leave paint artifacts.

  2. Never call repaint() from inside the paint method

  3. Don't explicitly call paint, as you do in update(), when you mean to call reapaint()

  4. just update the x and y values from inside the update() method, then call repaint()

  5. You don't need to take a Graphics argument in update()

  6. You need to call update() somewhere repeatedly in a loop, as it updates the x and y and reapint()s

  7. If your class is going to be a Runnable, then you should put some code in the run() method. That's probably where you should have your loop


import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class circles extends Applet implements Runnable {

    int x = 0, y = 0;

    public void start() {
        setSize(500, 500);
        setBackground(Color.BLACK);
        new Thread(this).start();
    }

    public void run() {
        while (true) {
            try {
                update();
                Thread.sleep(50);

            } catch (InterruptedException ex) {

            }
        }
    }

    public void update() {
        x += 5;
        y += 6;
        repaint();
    }

    public void paint(Graphics e) {
        super.paint(e);
        Graphics2D g = (Graphics2D) e;
        g.setColor(Color.BLUE);
        g.fillOval(x, y, 20, 20);

    }
}


Side Notes

  • Why use Applets in the first place. If you must, why use AWT Applet and not Swing JApplet? Time for an upgrade.

Here's how I'd redo the whole thing in Swing, using a Swing Timer instead of a loop and Thread.sleep, as you should be doing.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Circle extends JPanel{
    private static final int D_W = 500;
    private static final int D_H = 500;

    int x = 0;
    int y = 0;
    public Circle() {
        setBackground(Color.BLACK);

        Timer timer = new Timer(50, new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                x += 5;
                y += 5;
                repaint();
            }
        });
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillOval(x, y, 20, 20);

    }

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new Circle());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}



UPDATE

"Problem is, that's a JPANEL application. I specifically want to make an applet easily usable on a web page. "

You can still use it. Just use the JPanel. Take out the main method, and instead of Applet, use a JApplet and just add the JPanel to your applet. Easy as that.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JPanel;
import javax.swing.Timer;

public class CircleApplet extends JApplet {

    @Override
    public void init() {
        add(new Circle());
    }

    public class Circle extends JPanel {

        private static final int D_W = 500;
        private static final int D_H = 500;

        int x = 0;
        int y = 0;

        public Circle() {
            setBackground(Color.BLACK);

            Timer timer = new Timer(50, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    x += 5;
                    y += 5;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLUE);
            g.fillOval(x, y, 20, 20);

        }

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

    }
}

这篇关于Java小程序重新绘制一个圆形运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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