Myszka nie w środku

Myszka nie w środku
N4
  • Rejestracja:około 13 lat
  • Ostatnio:ponad 12 lat
  • Postów:193
0

Witam wszystkich! Powracam w wielkim stylu (czyt. z trzecim problemem w ciągu ostatniego tygodnia)!

Stworzyłem klasę testową, która miała za zadanie centrować myszkę. Po każdym przesunięciu myszy, kursor wracał z powrotem na środek ekranu (później zrobię "zniknięty" kursor, więc gapienie się na niego nie będzie takie wkurzające). Dzięki centrowaniu kursora, można przesuwać myszkę w jedną stronę aż się zepsuje w nieskończoność. Spacją wyłącza i włącza się centrowanie. Aby wykryć, czy naprawdę wykonuję jakiś ruch, tło przesuwa się w tym samym kierunku, co kursor, ale nie powinien się centrować. Zamiast tego, gdy jest włączone centrowanie kursora, obrazek drga tak samo jak kursor. Gdy centrowanie jest wyłączone, wszystko działa poprawnie, ale wtedy kursor (jak było zaplanowane) zatrzymuje się na krawędzi ekranu, zaś dalej się obraz nie przesuwa.
Jedyny mój problem w tej klasie polega na tym, dlaczego we włączonym trybie centrowania (tryb domyślny) obraz centruje się razem z kursorem. Klasa programu MouseTest:

Kopiuj
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.SwingUtilities;
import test.GameCore;

public class MouseTest extends GameCore implements MouseMotionListener, KeyListener {
    public static void main(String[] args) {
        new MouseTest().run();
    }
    private Image bgImage;
    private Robot robot;
    private Point mouseLocation;
    private Point centerLocation;
    private Point imageLocation;
    private boolean relativeMouseMode;
    private boolean isRecentering;
    public void init() {
        super.init();
        mouseLocation = new Point();
        centerLocation = new Point();
        imageLocation = new Point();
        relativeMouseMode = true;
        isRecentering = false;
        try {
            robot = new Robot();
            recenterMouse();
            mouseLocation.x = centerLocation.x;
            mouseLocation.y = centerLocation.y;
        }
        catch (AWTException ex) {
            System.out.println("AWT Exception. Nie można utworzyć obiektu Robot.");
        }
        Window window = screen.getFullScreenWindow();
        window.addMouseMotionListener(this);
        window.addKeyListener(this);
        bgImage = loadImage("src/images/background.jpg");
    }
    public synchronized void draw(Graphics2D g) {
        int w = screen.getWidth();
        int h = screen.getHeight();
        //upewnij się, że położenie jest prawidłowe
        imageLocation.x %= w;
        imageLocation.y %= h;
        if (imageLocation.x < 0) imageLocation.x += w;
        if (imageLocation.y < 0) imageLocation.y += h;
        //narysowanie rysunku w czterech miejscach, co spowoduje pokrycie nim całego ekranu
        int x = imageLocation.x;
        int y = imageLocation.y;
        g.drawImage(bgImage, x, y, null);
        g.drawImage(bgImage, x-w, y, null);
        g.drawImage(bgImage, x, y-h, null);
        g.drawImage(bgImage, x-w, y-h, null);
        //ustawienia rysowania
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.drawString("Naciśnij spację, by zmienić tryb myszy", 5, FONT_SIZE);
        g.drawString("Naciśnij Escape, aby zakończyć", 5, FONT_SIZE*2);
    }
    //zastosowanie klasy Robot do ustawienia wskaźnika myszy na środku ekranu (może nie działać na rzadkich systemach)
    private synchronized void recenterMouse() {
        Window window = screen.getFullScreenWindow();
        if (robot != null && window.isShowing()) {
            centerLocation.x = window.getWidth() / 2;
            centerLocation.y = window.getHeight() / 2;
            SwingUtilities.convertPointToScreen(centerLocation, window);
            isRecentering = true;
            robot.mouseMove(centerLocation.x, centerLocation.y);
        }
    }
    //Następne dwie metody - z interfejsu MouseMotionListener
    public void mouseDragged(MouseEvent e) {
        mouseMoved(e);
    }
    public synchronized void mouseMoved(MouseEvent e) {
        //zdarzenie centrowania wskaźnika myszy - ignorowanie
        if (isRecentering && centerLocation.x == e.getX() && centerLocation.x == e.getY()) isRecentering = false;
        else {
            int dx = e.getX() - mouseLocation.x;
            int dy = e.getY() - mouseLocation.y;
            imageLocation.x += dx;
            imageLocation.y += dy;
            //centrowanie wskaźnika myszy
            if (relativeMouseMode) {
                recenterMouse();
            }
        }
        mouseLocation.x = e.getX();
        mouseLocation.y = e.getY();
    }
    //Następne 3 metody - z interfejsu KeyListener
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            //zakończenie programu
            stop();
        }
        else if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            //zmiana trybu myszy
            relativeMouseMode = !relativeMouseMode;
        }
    }
    public void keyReleased(KeyEvent e) {
        //ignoruj
    }
    public void keyTyped(KeyEvent e) {
        //ignoruj
    }
}

Klasa ta dziedziczy po klasie GameCore z paczki test:

Kopiuj
package test;

import graphic.ScreenManager;
import java.awt.*;
import javax.swing.ImageIcon;

public abstract class GameCore {
    protected static final int FONT_SIZE = 24;
    private static final DisplayMode POSSIBLE_MODES[] = {
        new DisplayMode(2560, 2048, 32, 0),//Najwyższa rozdzielczość dla ekranu 5:4
        new DisplayMode(2560, 2048, 16, 0),//jw. mniej kolorów
        new DisplayMode(2048, 1536, 32, 0),//Najwyższa rozdzielczość dla ekranu 4:3
        new DisplayMode(2048, 1536, 16, 0),//jw. mniej kolorów
        new DisplayMode(1920, 1200, 32, 0),//Najwyższa rozdzielczość dla ekranu 16:10
        new DisplayMode(1920, 1200, 16, 0),//jw. mniej kolorów
        new DisplayMode(1600, 900, 32, 0),//Najwyższa rozdzielczość dla ekranu 16:9
        new DisplayMode(1600, 900, 16, 0),//jw. mniej kolorów
        new DisplayMode(1280, 1024, 32, 0),//Optymalna dla 5:4
        new DisplayMode(1280, 1024, 16, 0),//jw. mniej kolorów
        new DisplayMode(1024, 768, 32, 0),//Optymalna dla 4:3
        new DisplayMode(1024, 768, 32, 0),//jw. mniej kolorów
        new DisplayMode(320, 240, 8, 0)//standard ratunkowy - rozdzielczość 4:3 o najniższym poziomie, 256 kolorów 
    };
    private boolean isRunning;
    protected ScreenManager screen;
    
    //metoda informująca pętlę gry, że należy zakończyć pracę
    public void stop() {
        isRunning = false;
    }
    
    //wywołanie init() i gameLoop()
    public void run() {
        try {
            init();
            gameLoop();
        }
        finally {
            screen.restoreScreen();
        }
    }
    
    
    //ustawia tryb pełnoekranowy i inicjuje obiekty
    public void init() {
        screen = new ScreenManager();
        DisplayMode displayMode = screen.findFirstCompatibleMode(POSSIBLE_MODES);
        screen.setFullScreen(displayMode);
        
        Window window = screen.getFullScreenWindow();
        window.setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE));
        window.setBackground(Color.blue);
        window.setForeground(Color.white);
        
        isRunning = true;
    }
    
    public Image loadImage(String fileName) {
        return new ImageIcon(fileName).getImage();
    }
    
    //uruchamia pętlę gry, działającą aż do wywołania stop()
    public void gameLoop() {
        long startTime = System.currentTimeMillis();
        long currTime = startTime;
        Graphics2D g = screen.getGraphics();
        while (isRunning) {
            long elapsedTime = System.currentTimeMillis() - currTime;
            currTime += elapsedTime;
            //aktualizacja sprite
            update(elapsedTime);
            //narysowanie i aktualizacja zawartości ekranu
            draw(g);
            screen.update();
            //chwila przerwy
            try {
                Thread.sleep(20);
            }
            catch (InterruptedException ex) {}
        }
    }
    
    public void update(long elapsedTime) {
        //Nic nie wykonuj
    }
    //rysowanie na ekranie. Klasy pochodne muszą dziedziczyć tą metodę.
    public abstract void draw(Graphics2D g);
}

Zaś ta klasa wymaga do działania klasy ScreenManager z paczki graphic:

Kopiuj
package graphic;


import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;

public class ScreenManager
{
	private GraphicsDevice device;
	
	public ScreenManager()
	{
		GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
		device = environment.getDefaultScreenDevice();
	}
        
        public DisplayMode[] getCompatibleModes() {
            return device.getDisplayModes();
        }
        
        public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
            DisplayMode goodModes[] = device.getDisplayModes();
            for (int i = 0; i < modes.length; i++) {
                for (int j = 0; j <goodModes.length; j++) {
                    if (displayModesMatch(modes[i], goodModes[j])) {
                        return modes[i];
                    }
                }
            }
            
            return null;
        }
	
	public DisplayMode getCurrentDisplayMode() {
            return device.getDisplayMode();
        }
        
        public boolean displayModesMatch(DisplayMode mode1, DisplayMode mode2) {
            if (mode1.getWidth() != mode2.getWidth() || mode1.getHeight() != mode2.getHeight()) return false;
            if (mode1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && mode2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && mode1.getBitDepth() != mode2.getBitDepth()) return false;
            if (mode1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && mode2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && mode1.getRefreshRate() != mode2.getRefreshRate()) return false;
            return true;
        }
        
        public void setFullScreen(DisplayMode displayMode) {
            final JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setUndecorated(true);
            frame.setIgnoreRepaint(true);
            frame.setResizable(false);
            
            device.setFullScreenWindow(frame);
            
            if (displayMode != null && device.isDisplayChangeSupported()) {
                try {
                    device.setDisplayMode(displayMode);
                }
                catch (IllegalArgumentException ex) {}
                //poprawka dla systemu MacOS X:
                frame.setSize(displayMode.getWidth(), displayMode.getHeight());
                }
                
                try {
                    EventQueue.invokeAndWait(new Runnable() {
                        public void run() {
                            frame.createBufferStrategy(2);
                        }
                    });
                }
                catch (InterruptedException | InvocationTargetException ex) {
                    //ignorowanie
                }
        }
        
        public Graphics2D getGraphics() {
            Window window = device.getFullScreenWindow();
            if (window != null) {
                BufferStrategy strategy = window.getBufferStrategy();
                return (Graphics2D)strategy.getDrawGraphics();
            }
            else return null;
        }
        
        public void update() {
            Window window = device.getFullScreenWindow();
            if (window != null) {
                BufferStrategy strategy = window.getBufferStrategy();
                if (!strategy.contentsLost()) strategy.show();
            }
            //naprawa problemu z kolejką zdarzeń w Linux
            Toolkit.getDefaultToolkit().sync();
        }
        
        public JFrame getFullScreenWindow() {
            return (JFrame)device.getFullScreenWindow();
        }
        
        public int getWidth() {
            Window window = device.getFullScreenWindow();
            if (window != null) return window.getWidth();
            else return 0;
                }
        public int getHeight() {
            Window window = device.getFullScreenWindow();
            if (window != null) return window.getHeight();
            else return 0;
                }
        
        public BufferedImage createCompatibleImage(int w, int h, int transparancy) {
            Window window = device.getFullScreenWindow();
            if (window != null) {
                GraphicsConfiguration gc = window.getGraphicsConfiguration();
                return gc.createCompatibleImage(w, h, transparancy);
            }
            return null;
        }

    public void restoreScreen() {
        Window window = device.getFullScreenWindow();
            if (window != null) window.dispose();
            device.setFullScreenWindow(null);
    }
}

Plik graficzny w tle może być dowolnym plikiem, ja w czasie testów korzystam z http://www.sendspace.pl/file/371867fe3e4f05adca7eb46

Gdy włączycie program, poruszajcie myszką, a następnie wciśnijcie spację i jeszcze raz poruszajcie myszką. Przed naciśnięciem spacji powinny być te same efekty, co po wciśnięciu, ale kursor powinien wracać na środek, a obraz powinien się przesuwać tylko wtedy, gdy ja przesuwam myszką.


...
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)