While Schleife bleibt hängen

  • Themenstarter Themenstarter OomarsmanoO
  • Beginndatum Beginndatum
O

OomarsmanoO

Gast
Hallo, ich bin noch ziemlicher Anfänger in Java und hab jetzt mal ein kleines Programm geschrieben, in dem das Objekt durch Tastatursteuerung auf dem Bildschirm bewegt werden soll und dabei die Animation abspielen soll! Leider bleibt er in der While-Schleife hängen(Zeile 85 in der main-class), warum? Wie könnte ich es lösen?
Danke schon mal im Voraus! 🙂

Meine main-class:
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;

public class mainclass extends core implements MouseMotionListener, KeyListener{

	private Image sprite;
	private Point image;
	private animation a;
	private boolean right;
	private boolean left;
	private boolean up;
	private boolean down;
	
	public static void main(String[] args) {
		new mainclass().run();
	}

	public void init(){
		super.init();
		Window w = s.getFullScreenWindow();
		w.addMouseMotionListener(this);
		w.addKeyListener(this);
		Image x = new ImageIcon("C:\\Users\\Julian\\Desktop\\workspace\\eclipse\\Animation\\src\\a.png").getImage(); //C:\\Users\\Julian\\Desktop\\workspace\\eclipse\\Animation\\src\\a.png
		Image y = new ImageIcon("C:\\Users\\Julian\\Desktop\\workspace\\eclipse\\Animation\\src\\b.png").getImage();
		a = new animation();
		a.addScene(x, 250);
		a.addScene(y, 250);
		image = new Point(200,200);
	}
	
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
			stop();
			e.consume();
		}
		if(e.getKeyCode() == KeyEvent.VK_RIGHT){
			
			right=true;
	                animate();
			e.consume();
		}
		if(e.getKeyCode() == KeyEvent.VK_LEFT){
			left=true;
		}
		if(e.getKeyCode() == KeyEvent.VK_UP){
			up=true;
		}
		if(e.getKeyCode() == KeyEvent.VK_DOWN){
			down=true;
		}
		
	}
	
	

	public void keyReleased(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_RIGHT){
			right=false;
		}
		if(e.getKeyCode() == KeyEvent.VK_LEFT){
			left=false;
		}
		if(e.getKeyCode() == KeyEvent.VK_UP){
			up=false;
		}
		if(e.getKeyCode() == KeyEvent.VK_DOWN){
			down=false;
		}
		
	}

	public void keyTyped(KeyEvent e) {}

	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseMoved(MouseEvent e) {
	}
	
	public void animate(){
		long startingTime = System.currentTimeMillis();
		long cumTime = startingTime;
		while(right){
				
			long timePassed = System.currentTimeMillis() - cumTime;
			cumTime += timePassed;
			a.update(timePassed);
			try{
				Thread.sleep(20);
			}catch(Exception ex){System.out.println("error");}
		}
	}

	public void draw(Graphics2D g) {
		int x = image.x;
		int y = image.y;
		Window w = s.getFullScreenWindow();
		g.setColor(w.getBackground());
		g.fillRect(0, 0, s.getWidth(), s.getHeight());
		if (right){
			image.x += 5;
		}
		if (left){
			image.x -= 5;
		}
		if (up){
			image.y -= 5;
		}
		if (down){
			image.y += 5;
		}
		g.drawImage(a.getImage(), x, y, null);
		
	}

}

Die Core-class:
Java:
import java.awt.*;
import javax.swing.*;

public abstract class core {

	private static DisplayMode modes[] ={
		new DisplayMode(1366,768,32,0),
		new DisplayMode(800,600,32,0),
		new DisplayMode(800,600,24,0),
		new DisplayMode(800,600,16,0),
		new DisplayMode(640,480,32,0),
		new DisplayMode(640,480,24,0),
		new DisplayMode(640,480,16,0),
	};
	
	private boolean running;
	protected screen2 s;
	
	//stop method
	public void stop(){
		running = false;
	}
	
	//call init and gameloop
	public void run(){
		try{
			init();
			gameLoop();
		}finally{
			s.restoreScreen();
		}
		
	}
	
	//sets to fullscreen
	public void init(){
		s = new screen2();
		DisplayMode dm = s.findFirstCompatibleMode(modes);
		s.setFullScreen(dm);
		
		Window w = s.getFullScreenWindow();
		w.setFont(new Font("Arial", Font.PLAIN, 20));
		w.setBackground(Color.GRAY);
		w.setForeground(Color.WHITE);
		running = true;
	}
	
	//main gameloop
	public void gameLoop(){
		long startTime = System.currentTimeMillis();
		long cumTime = startTime;
		
		while (running){
			long timePassed = System.currentTimeMillis() - cumTime;
			cumTime += timePassed;
			update(timePassed);
			
			Graphics2D g = s.getGraphics();
			draw(g);
			g.dispose();
			s.update();
			try{
				Thread.sleep(20);
			}catch (Exception ex){}
		}
	}
	
	//update animation
	public void update(long timePassed){
	}
	
	//draws to screen
	public abstract void draw(Graphics2D g);
}

Und meine screen class:

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

public class screen2 {
	
	private GraphicsDevice vc;
	
	//give vc access to monitor
	public screen2(){
		GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
		vc = e.getDefaultScreenDevice();
	}
	
	//get compatible dm
	public DisplayMode[] getCompatibleDisplayModes(){
		return vc.getDisplayModes();
	}
	
	//Compare dm with vc-dm and see, if the match
	public DisplayMode findFirstCompatibleMode(DisplayMode modes[]){
		DisplayMode goodModes[] = vc.getDisplayModes();
		for(int x=0; x<modes.length; x++){
			for(int y=0; y<goodModes.length; y++){
				if (displayModesMatch(modes[x], goodModes[y])){
					return modes[x];
				}
			}
		}
		return null;
	}
	
	//get current dm
	public DisplayMode getCurrentDisplayMode(){
		return vc.getDisplayMode();
	}
	
	//compare displaymodes
	public boolean displayModesMatch(DisplayMode m1, DisplayMode m2){
		if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()){
			return false;
		}
		if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()){
			return false;
		}
		if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m2.getRefreshRate() != m2.getRefreshRate()){
			return false;
		}
		
		return true;
	}
	
	//make frame fullscreen
	public void setFullScreen (DisplayMode dm){
		JFrame f = new JFrame();
		f.setUndecorated(true);
		f.setIgnoreRepaint(true);
		f.setResizable(true);
		vc.setFullScreenWindow(f);
		
		if(dm != null && vc.isDisplayChangeSupported()){
			try{
				vc.setDisplayMode(dm);
			}catch(Exception e){}
		}
		
		f.createBufferStrategy(2);
	}
	
	//set graphics object = this
	public Graphics2D getGraphics(){
		Window w = vc.getFullScreenWindow();
		if (w != null){
			BufferStrategy s = w.getBufferStrategy();
			return (Graphics2D)s.getDrawGraphics();
		}
		else
			return null;
	}
	
	//updates Display
	public void update(){
		Window w = vc.getFullScreenWindow();
		if (w != null){
			BufferStrategy s = w.getBufferStrategy();
			if(!s.contentsLost()){
				s.show();
			}
		}
	}
	
	//return fullscreenwindow
	public Window getFullScreenWindow(){
		return vc.getFullScreenWindow();
	}
	
	public int getWidth(){
		Window w = vc.getFullScreenWindow();
		if (w != null){
			return w.getWidth();
		}
		else{
			return 0;
		}
	}
	
	public int getHeight(){
		Window w = vc.getFullScreenWindow();
		if (w != null){
			return w.getHeight();
		}
		else{
			return 0;
		}
	}
	
	//get out of fullscreen
	public void restoreScreen(){
		Window w = vc.getFullScreenWindow();
		if (w != null){
			w.dispose();
		}
		vc.setFullScreenWindow(null);
	}
	
	//create image compatible with monitor
	public BufferedImage createCompatibleImage(int w, int h, int t){
		Window win = vc.getFullScreenWindow();
		if (win != null){
			GraphicsConfiguration gc = win.getGraphicsConfiguration();
			return gc.createCompatibleImage(w, h, t);
		}
		return null;
	}
	
}
 
Zuletzt bearbeitet von einem Moderator:
weil dein animate() im AWTEvent-Thread läuft, dadurch werden keine weiteren Events verarbeitet und right bleibt auf ewig true.
Du solltest für die Animation lieber einen Thread verwenden.
 
Danke für die schnelle Antwort 🙂
Sorry, wenn ich mich ein bisschen blöd anstelle, aber wie mache ich das, also wo muss ich das
Thread() = new Thread(); einfügen? is der Code so überhaupt richtig? Danke 🙂
 
Java:
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
Ist dir eigtl. klar, dass cumTime und timePassed immer gleich groß sind? Ich bin mir nicht sicher, ob das von dir beabsichtigt ist...

EDIT: ups, Fehler bemerkt... cumTime ist immer genau die letzte Systemzeit... naja, bissl umständlich sind die beiden Zeilen zumindest...
 
Zuletzt bearbeitet:
[ot]ja lol - wie hier schon Variablen benannt werden.... zu geil... lieber nicht in einem englischen Forum posten[/ot]

ansonstne bin ich beeindruckt was ein "ziemlicher Anfaenger" so schon fuer code hinhaut - ohne zu wissen ob er richtig ist ;-) ... muss wohl meine Definition von "ziemlicher Anfaenger" aendern.
 
aber wie mache ich das, also wo muss ich das
Thread() = new Thread(); einfügen?
Mhn naja den Thread starten und am besen ein Runnable Objekt mitgeben das dann im Thread ausgeführt wird. Kann mit einer Annonymen innern Klasse so aussehn...

Java:
public class Test {

    public static void main(String[] args) {
        System.out.println("Mache was");
        
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println("ich bim im Thread");
                try {
                    Thread.sleep(2000);
                }
                catch (InterruptedException e) { }
                System.out.println("noch immer im Thread - cumTime ist vorbei");
                System.out.println("Thread jetzt erst fertig");
            }
        }).start();
        
        System.out.println("ich bin schon vorm Thread fertig");
        
        
    }

}
Wichtig, den Thread mit start starten und nicht run ausführen... Kannst ja mal das start gegen run austauschen und schaun was passiert. Dann wirds klar wozu ein Thread gut ist...
 
Leider bleibt er in der While-Schleife hängen(Zeile 85 in der main-class), warum? Wie könnte ich es lösen?

Ganz einfach indem du die Variable "right" innerhalb der Schleife veränderst ;-)
(Oder machst du das irgendwo in den Tiefen von a.update()? - dann müsste ich mit dir aber ein ernstes Wörtchen über die Verwendung globaler Variablen reden)
 
Juhu, es funktioniert endlich 🙂
[OT]und die variable cumTime hab ich aus nem ENGLISCHEN Tutorial 😀[/OT]
und ich hab das alles so stückchenweise aus den game-development-tutorials von thenewboston, daher so "fortschrittlicher" code, aber wie gesagt, das is nur zusammengeflickt...
und die variable während der while schleife ändern geht auch nicht, da das dann so komisch stockt, aber ja, das wäre auch eine Lösung gewesen 🙂
Auf jeden Fall danke für die Hilfe 😛
 

Neue Themen


Zurück
Oben