Problem z płynnością animacji

Odpowiedz Nowy wątek
2013-04-28 20:14

Rejestracja: 6 lat temu

Ostatnio: 4 lata temu

0

Dzieńdoberek, po dość długim czasie wróciłem do programowania i na rozgrzewkę postanowiłem napisać sobie program, w którym kółko lata od ściany do ściany i się odbija. Wszystko ładnie, pięknie, ale niepłynnie. Bawiłem się delayem i "długością skoku" na jeden raz, ale nie pomogło. Zauważyłem dziwną rzecz - kiedy latam kursorem nad okienkiem, to działa płynnie, a kiedy tylko przestanę albo z niego zjadę, to kółko znowu zaczyna skakać. Pracuję na Ubuntu 12.04 LTS.

Klasa App:

import javax.swing.*;

public class App extends JFrame {

    public App() {
        setSize(800, 600);
        setVisible(true);
        setLocationRelativeTo(null);
        Anim anim = new Anim();
        add(anim);
        anim.StartAnim();
    }

    public static void main(String [] args) {
        new App();
    }

}

Klasa Anim:

import java.awt.*;
import javax.swing.*;
public class Anim extends JPanel {

    int x = 30, y = 30, dx = 1, dy = 3, delay = 10;

    public void StartAnim() {
        while(true) {
            if(x + 30 > getWidth() || x < 0)
                dx =- dx;
            if(y + 30 > getHeight() || y < 0)
                dy =- dy;

            x+=dx;
            y+=dy;

            repaint();
            try{ 
                Thread.sleep(delay);
            } catch(InterruptedException e) { System.out.println("IE e!"); }
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.red);
        g2d.fillOval(x, y, 30, 30);
    }
}

Pozostało 580 znaków

HeHeuszki
2013-04-28 21:35
HeHeuszki
1

Welcome to java, and have a nice day!

Pozostało 580 znaków

2013-04-28 23:21

Rejestracja: 10 lat temu

Ostatnio: 1 rok temu

0

Robisz sleep() w wątku EDT, czyli wątku obsługi zdarzeń, dlatego aplikacja 'zamarza'. Wszystkie długotrwałe czynności powinny być wykonywane w osobnych wątkach. A w sytuacji takiej jak Twoja najlepiej będzie wykorzystać Timer

Zapewne masz rację, ale pod windowsem oryginalny kod i kod z animacją w nowym wątku działają identycznie. @Purchawek, brakuje w klasie App instrukcji setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);. - bogdans 2013-04-28 23:27
A co defaultCloseOperation ma wspólnego z przycinaniem GUI? Jeżeli na windowsie działa poprawnie to dość dziwne i nie logiczne niestety. - airborn 2013-04-29 00:32
Nic, po prostu wskazałem na usterkę. - bogdans 2013-04-29 06:30

Pozostało 580 znaków

2013-04-28 23:28
Moderator

Rejestracja: 6 lat temu

Ostatnio: 4 lata temu

0

Chodzi o coś takiego?

App:

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;

public class App extends JFrame {

    private static class Anim extends JPanel {      
        int x = 50, y = 50, dx = 5, dy = 3;

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            if(x + 50 > getWidth() || x < 0)
                dx=-dx;
            if(y + 50 > getHeight() || y < 0)
                dy=-dy;

            x+=dx;
            y+=dy;
            g2d.fillOval(x, y, 50, 50);
        }
    }
    public App()
    {
        setSize(500, 400);
        setLocationRelativeTo(null);
        Anim panel = new Anim();
        add(panel);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        new Watek(panel);
    }

    public static void main(String[] args) {
        new App();
    }

}

Watek:

import java.awt.Component;

public class Watek implements Runnable {
    private final Component c;
    int delay = 10;
        public Watek(Component c) {
            this.c = c;
            (new Thread(this, "F")).start();
        }

    public void run() {
        while(true) {
            c.repaint();
            try {
                Thread.sleep(delay);
            } catch (Exception e) {
                System.out.println("Exception!");
            }
        }
    }
}

Pozostało 580 znaków

2013-04-28 23:30

Rejestracja: 11 lat temu

Ostatnio: 3 minuty temu

0

Raczej o coś takiego:

        public void StartAnim() {
            ActionListener task = new ActionListener()
            {
                public void actionPerformed(ActionEvent ae)
                {
                        if(x + 30 > getWidth() || x < 0)
                                dx =- dx;
                        if(y + 30 > getHeight() || y < 0)
                                dy =- dy;

                        x+=dx;
                        y+=dy;

                        repaint();              
                }
            };
            Timer timer = new Timer(delay,task);
            timer.start();
        }

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2013-04-28 23:38
Moderator

Rejestracja: 6 lat temu

Ostatnio: 4 lata temu

0

Bogdans, zrobiłem tak, by wykorzystać Twoją metodę i działa tak jak poprzednio :/
Może to nie jest wina samego programu? Bo jak pisałem na Windowsie to takich dziwactw z kursorem nie miałem.

edytowany 1x, ostatnio: Purchawek, 2013-04-28 23:43

Pozostało 580 znaków

2013-04-28 23:45
Moderator

Rejestracja: 11 lat temu

Ostatnio: 3 minuty temu

0

A jaką masz Javę? po linuksach pęta się jakaś java nie oraclowska, Swing działa na niej źle.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2013-04-28 23:53

Rejestracja: 6 lat temu

Ostatnio: 4 lata temu

0

java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

Pozostało 580 znaków

2013-04-29 00:01

Rejestracja: 11 lat temu

Ostatnio: 3 minuty temu

0

Wygląda na Oracle.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell

Pozostało 580 znaków

2013-04-29 00:29

Rejestracja: 10 lat temu

Ostatnio: 1 rok temu

0

Jak na chwilę obecną wygląda Twój kod? Porównaj go z tym poniżej, który u mnie na Ubuntu zachowuje się jak należy.

package app;

import java.awt.Graphics;
import java.awt.Graphics2D;
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 App {

    public static void main(String[] args) {
        new App();
    }
    private JFrame frame;
    private PaintingPanel panel;

    public App() {
        frame = new JFrame();
        frame.setSize(500, 500);

        panel = new PaintingPanel();
        frame.add(panel);

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.setVisible(true);
            }
        });
        Timer t = new Timer(10, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                panel.update();
            }
        });
        t.start();
    }

    class PaintingPanel extends JPanel {

        int x = 50, y = 50, dx = 5, dy = 3;

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;

            g2d.fillOval(x, y, 50, 50);
        }

        public void update() {
            if (x + 50 > getWidth() || x < 0) {
                dx = -dx;
            }
            if (y + 50 > getHeight() || y < 0) {
                dy = -dy;
            }

            x += dx;
            y += dy;
            repaint();
        }
    }
}
edytowany 1x, ostatnio: airborn, 2013-04-29 00:29

Pozostało 580 znaków

2013-04-29 01:19

Rejestracja: 7 lat temu

Ostatnio: 1 tydzień temu

dodaj do metody paintComponent:
Toolkit.getDefaultToolkit().sync();
Podobno rozwiązuje problemy z płynnością animacji na linuxie - profilaktycznie i ja dodałem ją u siebie, choć nie miałem żadnych problemów - arch 64 bit


Limitations are limitless

> ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
edytowany 2x, ostatnio: hcubyc, 2013-04-29 01:21
O, ciekawe, faktycznie na niektórych systemach mocno pomaga. Dzięki :) - airborn 2013-04-29 10:32

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0