Swing + Java2D Sichtfeld bewegen verhält sich träge

Mappenz

Bekanntes Mitglied
Hi,

ich stelle ein zweidimensionales Array graphisch dar. Der Benutzer kann den Ausschnitt des Arrays der angezeigt wird ändern, indem er mit gedrückter Maustaste über das JFrame zieht.

Hier der Code:
Gui.Java
Java:
package gui;

import gamestuff.Board;
import gamestuff.MovableObstacle;
import gamestuff.Obstacle;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

public class Gui extends Component implements MouseMotionListener, MouseListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Point leftUpperCorner = new Point(0, 0);
    private Point mousePressed;
    private int displayHight = 500;
    private int displayWidth = 500;

    public void createAndShowGUI() {
	JFrame frame = new JFrame("Game");
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	addMouseMotionListener(this);
	addMouseListener(this);
	frame.add(this);
	Dimension size = new Dimension(displayWidth, displayHight);
	frame.setSize(size);
	//Display the window
	//        frame.pack();
	frame.setVisible(true);
    }

    public void paint(Graphics g) {
	Graphics2D g2 = (Graphics2D) g;
	int gameHight = 10;
	int gameWidth = 10;
	
	
	Board board = new Board(gameHight, gameWidth);
	board.setObstacleAt(0, 0, new MovableObstacle());
	board.setObstacleAt(2, 3, new Obstacle());
	Obstacle obstacle = null;
	int offsetX = (int) (leftUpperCorner.getX() % 100); 
	int offsetY = (int) (leftUpperCorner.getY() % 100); 
	
	for(int i = 0; i < (displayHight / 100) + 1; i++) {
	    for(int j = 0; j < (displayWidth / 100) + 1; j++) {
		if((int) (leftUpperCorner.getY() / 100) + i < board.getLength() && 
			(int) (leftUpperCorner.getX() / 100) + j < board.getHight() 
			&& (leftUpperCorner.getY() / 100) + i >= 0 && 
			(int) (leftUpperCorner.getX() / 100) + j >= 0) {
		    
		    obstacle = board.getObstacleAt((int) (leftUpperCorner.getY() / 100) + i,
			    (int) (leftUpperCorner.getX() / 100) + j);
		    if(obstacle == null) {
			g2.drawRect((j * 100) - offsetX, (i * 100) - offsetY, 90, 90);
		    } else if ( obstacle.getClass().equals(MovableObstacle.class)) {
			g2.fill3DRect((j * 100) - offsetX, (i * 100) - offsetY, 90, 90, true);
		    } else {
			g2.fillRect((j * 100) - offsetX, (i * 100) - offsetY, 90, 90);
		    }		    
		}
		
	    }
	}
    }

    @Override
    public void mouseDragged(MouseEvent e) {
	leftUpperCorner.setLocation(leftUpperCorner.getX() - (mousePressed.getX() - e.getX()) / 10,
		leftUpperCorner.getY() - (mousePressed.getY() - e.getY()) / 10);
	repaint();
	System.out.println(leftUpperCorner);
    }
 

    @Override
    public void mouseMoved(MouseEvent e) {
	// TODO Auto-generated method stub
	
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {
	// TODO Auto-generated method stub
	
    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
	// TODO Auto-generated method stub
	
    }

    @Override
    public void mouseExited(MouseEvent arg0) {
	// TODO Auto-generated method stub
	
    }

    @Override
    public void mousePressed(MouseEvent arg0) {
	mousePressed = arg0.getPoint();
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
	// TODO Auto-generated method stub
	
    }
}

Main.java
Java:
import gui.Gui;


public class Main {
    final static Gui gui = new Gui();

    /**
     * @param args
     */
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                gui.createAndShowGUI();
                System.out.println("Gui start");
              
            }
        });

    }
}

Board.java
Java:
/**
 * 
 */
package gamestuff;

/**
 * @author m
 *
 */
public class Board {
    Obstacle[][] obstacles;
    
    public Board(int hight, int width) {
	this.obstacles = new Obstacle[hight][width];
    }
    public int getHight() {
	return this.obstacles[0].length;
    }
    public int getLength() {
	return this.obstacles.length;
    }
    
    public Obstacle getObstacleAt(int hight, int width) {
	return this.obstacles[hight][width];
    }
    public boolean setObstacleAt(int hight, int width, Obstacle obstacle) {
	this.obstacles[width][hight] = obstacle;
	return true;
    }
    
}
Obstacle.java
Java:
/**
 * 
 */
package gamestuff;

/**
 * @author m
 *
 */
public class Obstacle {

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "OBST";
    }
}
MovableObstacle.java
Java:
package gamestuff;

public class MovableObstacle extends Obstacle {

}

Das Problem ist dass wenn man in einem Zug erst in die eine Richtung dann in die Entgegengesetze zieht der Richtungswechsel auf dem Bildschirm nicht sofort dargestellt wird.
 
Hmgl... Hab's nicht getestet oder compiliert, aber beim Überfliegen sah das, was da in mouseDragged gemacht wird, etwas seltsam aus. Sollte nicht bei jedem Bewegen der Maus direkt eine neue Position gesetzt werden (die NICHT von der vorherigen abhängt?)
 
Für jeden Mauszug bekomme ich viele Aufrufe an MouseDragged. Ich möchte die linke obere Ecke verschieben. Dazu ist es doch nötig, eine Distanz zwischen der alten Position und der neuen Position des Cursers zu berechnen und sie von der Ecke abzuziehen. Verstehe ich deine Antwort falsch? Kann ich das Kompilieren und Ausführen für euch einfacher machen?
 
Ja, aber die "alte" Position ändert sich ja bei jedem mouseDragged. Falls du die Karte einfach "an einem Punkt festhalten" willst, würde es sowas hier tun
Java:
    @Override
    public void mouseDragged(MouseEvent e) {
        leftUpperCorner.setLocation(
            leftUpperCorner.getX() + (mousePressed.getX() - e.getX()),
            leftUpperCorner.getY() + (mousePressed.getY() - e.getY()));
        repaint();
        System.out.println(leftUpperCorner);
        mousePressed.setLocation(e.getPoint()); 
        // TODO "mousePressed" umbenennen in "previousMousePosition"
    }

BTW: Wenn alles in eine Datei geklatscht ist, ist es einfacher, es schnell rauszukopieren und zu starten (aber zumindest hat hier nichts gefehlt oder so).

Ansonsten: In dem Code sind einige ziemliche Schnitzer. Im Moment wird in der "paint", d.h. bei JEDEM Neuzeichnen, das "board" neu erstellt. Abgesehen davon sollte man eher von JComponent erben und paintComponent überschreiben ( Malen in Swing Teil 1: der grundlegende Mechanismus ? Byte-Welt Wiki ), und ... das Zeichnen der Rechtecke sieht nicht gerade "geschickt" aus, aber ... naja...
 

Zurück
Oben