/**
*
*/
package com.szuppe.jakub.view;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import javax.swing.SwingUtilities;
import com.szuppe.jakub.common.Acceleration2D;
import com.szuppe.jakub.common.Coordinates2D;
import com.szuppe.jakub.common.SpeedVector2D;
import com.szuppe.jakub.config.view.ViewConfig;
import com.szuppe.jakub.events.*;
import com.szuppe.jakub.mockups.*;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
/**
* Widok gry "Vaus".
*
* @author Jakub Szuppe <j.szuppe at gmail.com>
*
*/
/**
* @author Jakub Szuppe <j.szuppe at gmail.com>
*
*/
public class View implements Runnable
{
/** Obecny stan widoku. **/
@SuppressWarnings("unused")
private ViewState viewState;
/** Konfiguracja widoku. */
private final ViewConfig viewConfig;
/** Główne okno. */
private final MainFrame mainFrame;
/** Kolejka blokująca zdarzeń, do której wkładamy zdarzenia. */
private final BlockingQueue<AppEvent> eventsBlockingQueue;
/**
* Tworzy widok na podstawie pliku konfiguracyjnego
* oraz z podaną kolejką blokującą zdarzeń.
*
* @param eventsBlockingQueue
*/
public View(final BlockingQueue<AppEvent> eventsBlockingQueue)
{
try
{
XStream xStream = new XStream();
URL urlToModelConfig = getClass().getResource("/com/szuppe/jakub/resources/viewConfig.xml");
this.viewConfig = (ViewConfig)xStream.fromXML(urlToModelConfig);
// change AWTEventListener to RepeatingReleasedEventsFixer
RepeatingReleasedEventsFixer.install();
this.eventsBlockingQueue = eventsBlockingQueue;
this.viewState = ViewState.START_MENU;
this.mainFrame = new MainFrame(viewConfig.getMainFrameConfig(), eventsBlockingQueue);
} catch (XStreamException | NullPointerException e)
{
// Brak pliku konfiguracyjnego.
throw new RuntimeException(e);
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
mainFrame.setVisible(true);
}
/**
* Uruchamia widok.
*/
public void init()
{
SwingUtilities.invokeLater(this);
}
/**
* Rozpoczyna grę. Przejście z menu do planszy gry.
*
*/
public void startGame(final GameMockup gameMockup)
{
final GameMockup correctedGameMockup = correctGameMockup(gameMockup);
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
viewState = ViewState.GAME;
mainFrame.startGame(eventsBlockingQueue, correctedGameMockup);
mainFrame.revalidate();
mainFrame.repaint();
}
});
} catch (InvocationTargetException e)
{
e.printStackTrace();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
/**
* Kończy grę.
*
* @param playerWon
*/
public void endGame(final boolean playerWon)
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
viewState = ViewState.START_MENU;
mainFrame.endGame(playerWon);
mainFrame.revalidate();
mainFrame.repaint();
}
});
} catch (InvocationTargetException e)
{
e.printStackTrace();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
/**
* @param gameMockup
*/
public void setGameUsingMockup(GameMockup gameMockup)
{
final GameMockup correctedGameMockup = correctGameMockup(gameMockup);
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
mainFrame.setGameUsingMockup(correctedGameMockup);
}
});
} catch (InvocationTargetException e)
{
e.printStackTrace();
throw new RuntimeException(e);
} catch (InterruptedException e)
{
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @param gameMockup
*/
public void setGameUsingMockupAndRevalidate(GameMockup gameMockup)
{
final GameMockup correctedGameMockup = correctGameMockup(gameMockup);
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
mainFrame.setGameUsingMockup(correctedGameMockup);
mainFrame.revalidateGamePanel();
}
});
} catch (InvocationTargetException e)
{
e.printStackTrace();
throw new RuntimeException(e);
} catch (InterruptedException e)
{
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* Poprawia współrzędne, prędkości, przyspieszenia w makiecie.
* Jest to związane z faktem, że widoku zero osi współrzędnych y
* jest na górze i rośnie w dół, a w modelu jest standardowy
* układ współrzędnych.
*
* @param gameMockup - makieta do poprawy.
* @return Poprawioną makietę stanu gry.
*/
private GameMockup correctGameMockup(GameMockup gameMockup)
{
LevelMockup correctedLevelMockup = gameMockup.getLevelMockup();
float levelHeight = correctedLevelMockup.getHeight();
BallMockup correctedBallMockup = correctBallMockup(gameMockup.getBallMockup(), levelHeight);
PaddleMockup correctedPaddleMockup = correctPaddleMockup(gameMockup.getPaddleMockup(), levelHeight);
BricksMockup corrcetedBricksMockup = correctBricksMockup(gameMockup.getBricksMockup(), levelHeight);
GameMockup correctedGameMockup = new GameMockup(correctedBallMockup, correctedPaddleMockup,
correctedLevelMockup, corrcetedBricksMockup, gameMockup.getPlayerMockup());
return correctedGameMockup;
}
/**
* Poprawia współrzędne, prędkości, przyspieszenia w makiecie.
* Jest to związane z faktem, że widoku zero osi współrzędnych y
* jest na górze i rośnie w dół, a w modelu jest standardowy
* układ współrzędnych.
*
*
* @param bricksMockup - makieta do poprawy.
* @param levelHeight - maksymalna wartość y, tj. wysokość planszy.
* @return Poprawioną makietę.
*/
private BricksMockup correctBricksMockup(BricksMockup bricksMockup, float levelHeight)
{
BricksMockup correctedBricksMockup = new BricksMockup();
List<BrickMockup> bricksList = bricksMockup.getBricksList();
for (BrickMockup brickMockup : bricksList)
{
Coordinates2D correctedCoordinates = new Coordinates2D(brickMockup.getX(), levelHeight - brickMockup.getY());
correctedBricksMockup.add(new BrickMockup(correctedCoordinates, brickMockup.getBrickType()));
}
return correctedBricksMockup;
}
/**
* Poprawia współrzędne, prędkości, przyspieszenia w makiecie.
* Jest to związane z faktem, że widoku zero osi współrzędnych y
* jest na górze i rośnie w dół, a w modelu jest standardowy
* układ współrzędnych.
*
*
* @param paddleMockup - makieta do poprawy.
* @param levelHeight - maksymalna wartość y, tj. wysokość planszy.
* @return Poprawioną makietę.
*/
private PaddleMockup correctPaddleMockup(PaddleMockup paddleMockup, float levelHeight)
{
Coordinates2D correctedPaddleCoordinates = new Coordinates2D(paddleMockup.getX(), levelHeight
- paddleMockup.getY());
SpeedVector2D correctedSpeed = paddleMockup.getSpeed();
correctedSpeed.reverseYSpeed();
Acceleration2D correctedAcceleration = paddleMockup.getRetardation();
correctedAcceleration.reverseYAcc();
PaddleMockup correctedPaddleMockup = new PaddleMockup(correctedPaddleCoordinates, correctedSpeed,
correctedAcceleration);
return correctedPaddleMockup;
}
/**
* Poprawia współrzędne, prędkości, przyspieszenia w makiecie.
* Jest to związane z faktem, że widoku zero osi współrzędnych y
* jest na górze i rośnie w dół, a w modelu jest standardowy
* układ współrzędnych.
*
*
* @param ballMockup - makieta do poprawy.
* @param levelHeight - maksymalna wartość y, tj. wysokość planszy.
* @return Poprawioną makietę.
*/
private BallMockup correctBallMockup(BallMockup ballMockup, float levelHeight)
{
Coordinates2D correctedBallCoordinates = new Coordinates2D(ballMockup.getX(), levelHeight - ballMockup.getY());
SpeedVector2D correctedSpeed = ballMockup.getSpeed();
correctedSpeed.reverseYSpeed();
Acceleration2D correctedAcceleration = ballMockup.getAcceleration();
correctedAcceleration.reverseYAcc();
BallMockup correctedBallMockup = new BallMockup(correctedBallCoordinates, ballMockup.getRadius(),
correctedSpeed, correctedAcceleration);
return correctedBallMockup;
}
}