A basic screen using MVC, illustrating activities which are delegated to the base class.
public class CargoScreen extends View { | |
private VisList<ItemEntry> lstItems; | |
private VisImage imgItem; | |
private VisTextArea txtDescription; | |
private VisTextButton btnBack; | |
public CargoScreen(Controller parent, Model model) { | |
super(parent, model); | |
// Initialize the image | |
imgItem = new VisImage(); | |
imgItem.setSize(ui.getWidth() / 2, ui.getWidth() / 2); // TODO: Refactor to world size. | |
// Create the item list | |
lstItems = new VisList<>(); | |
lstItems.addListener(new ChangeListener() { | |
@Override | |
public void changed(ChangeEvent event, Actor actor) { | |
updateSelection(lstItems.getSelected()); | |
} | |
}); | |
// Create the description field | |
txtDescription = new VisTextArea(); | |
txtDescription.setDisabled(true); | |
// Add a "back" button | |
btnBack = makeNavButton("Back", StationScreen.class); | |
// Create the layout | |
VisTable tblLayout = new VisTable(); | |
tblLayout.columnDefaults(0).pad(10f); | |
tblLayout.columnDefaults(1).pad(10f); | |
tblLayout.setFillParent(true); | |
tblLayout.add(imgItem).size(ui.getWidth() / 2); | |
tblLayout.add(new VisScrollPane(lstItems)).fillY(); | |
tblLayout.row(); | |
tblLayout.add(txtDescription).size(ui.getWidth() / 2, 100.0f); | |
tblLayout.add(btnBack).expandX().fillX(); | |
ui.addActor(tblLayout); | |
} | |
@Override | |
public void init() { | |
// Refresh the player data | |
Array<ItemEntry> items = new Array<>(); | |
world.getPlayer().getInventory().forEach(i -> items.add(new ItemEntry(i.key, i.value))); | |
items.sort(new ItemEntry.ItemEntryComparator()); | |
lstItems.setItems(items); | |
updateSelection(lstItems.getSelected()); | |
} | |
/** | |
* Flush all stateful data. | |
*/ | |
@Override | |
public void hide() { | |
super.hide(); | |
lstItems.clear(); | |
updateSelection(lstItems.getSelected()); | |
} | |
private void updateSelection(ItemEntry selected) { | |
imgItem.setDrawable(controller.getManagedTexture(selected.getType().getImage())); | |
txtDescription.setText(selected.getType().getDescription()); | |
} | |
} |
public class Controller extends Game { | |
private ObjectMap<Class<? extends View>, View> screens = new ObjectMap<>(); | |
private boolean debugOn = false; | |
private AssetManager assetManager; | |
private Model world; | |
// libGDX Game Methods // | |
@Override | |
public void create () { | |
// Load the UI first | |
VisUI.load(); | |
// Initialize the asset manager | |
assetManager = new AssetManager(); | |
assetManager.load(ATLAS_NAME, TextureAtlas.class); | |
assetManager.finishLoading(); | |
// Handle any debugging settings | |
this.setDebugOn(false); | |
world = new Model(); | |
// Load the screens | |
loadScreens(); | |
this.changeScreen(MainMenuScreen.class); | |
} | |
@Override | |
public void dispose () { | |
// Dispose of the view | |
setScreen(null); | |
screens.forEach((e) -> e.value.dispose()); | |
screens.clear(); | |
if(VisUI.isLoaded()) VisUI.dispose(); | |
// Dispose of the model | |
world.dispose(); | |
// Dispose of any other resources | |
assetManager.dispose(); | |
} | |
/** | |
* Convenience method to safely load textures. If the texture isn't found, a blank one is created and the error is logged. | |
* @param imageName The name of the image that is being looked up. | |
* @return | |
*/ | |
public TextureRegionDrawable getManagedTexture(String imageName) { | |
try { | |
return new TextureRegionDrawable(assetManager.get(ATLAS_NAME, TextureAtlas.class).findRegion(imageName)); | |
} catch(Exception e) { | |
Gdx.app.error(getClass().getCanonicalName(), "Couldn't get managed texture.", e); | |
return getEmptyTexture(); | |
} | |
} | |
public TextureRegionDrawable getEmptyTexture() { | |
return new TextureRegionDrawable(new TextureRegion(new Texture(new Pixmap(1,1, Pixmap.Format.RGBA8888)))); | |
} | |
// Real Game Methods // | |
/** | |
* Create a new game, starting with the story screen | |
*/ | |
public void newGame() { | |
world.startNewGame(this); | |
this.changeScreen(IntroScreen.class); | |
} | |
// === Debug Logic === // | |
public boolean isDebugOn() { | |
return debugOn; | |
} | |
public Controller setDebugOn(boolean on) { | |
this.debugOn = on; | |
Gdx.app.setLogLevel(on ? Application.LOG_DEBUG : Application.LOG_INFO); | |
return this; | |
} | |
// === Screen Management === // | |
public void changeScreen(Class<? extends View> key) { | |
this.setScreen(screens.get(key)); | |
handle(new GameEvent("SCREEN_CHANGE").set("SCREEN", screens.get(key))); | |
} | |
public void loadScreens() { | |
screens.put(CargoScreen.class, new CargoScreen(this)); | |
screens.put(DepartureScreen.class, new DepartureScreen(this)); | |
screens.put(IntroScreen.class, new IntroScreen(this)); | |
screens.put(MainMenuScreen.class, new MainMenuScreen(this)); | |
screens.put(NewGameScreen.class, new NewGameScreen(this)); | |
screens.put(StationScreen.class, new StationScreen(this)); | |
screens.put(TradeScreen.class, new TradeScreen(this)); | |
screens.put(ClanScreen.class, new ClanScreen(this)); | |
} | |
} |
public class Model { | |
private Galaxy galaxy; | |
private Player player; | |
private boolean active = false; | |
/** | |
* Start a new game. | |
*/ | |
public void startNewGame(Controller controller) { // TODO: Clean up magic screens | |
this.galaxy = GalaxyFactory.get().make(); | |
this.player = new Player(new ObjectIntMap<>(), galaxy.getStations().get("Homeworld"), galaxy.getStations().get("Homeworld")); | |
this.player.getQuests().add(new QuestFactory().make("INTRO_QUEST", controller, this)); | |
this.active = true; | |
} | |
public void dispose() { } | |
// === Getters / Setters === // | |
public Player getPlayer() { | |
return player; | |
} | |
public Galaxy getGalaxy() { return galaxy; } | |
public boolean isActive() { | |
return active; | |
} | |
} |
public abstract class BaseScreen implements Screen { | |
protected GameController controller; | |
protected GameWorld world; | |
protected Stage ui; | |
public BaseScreen(GameController controller, GameWorld world) { | |
this.controller = controller; | |
this.world = world; | |
ui = new Stage(new ScreenViewport()); | |
} | |
// === Lifecycle Methods === // | |
@Override | |
final public void show() { | |
// Set Debug Mode | |
ui.setDebugAll(controller.isDebugOn()); | |
// Map the controller | |
InputMultiplexer input = new InputMultiplexer(); | |
input.addProcessor(ui); | |
// Add an input processor to toggle debug mode via F3. | |
input.addProcessor(new DebugProcessor(ui, controller)); | |
Gdx.input.setInputProcessor(input); | |
// Screen-specific initialization | |
init(); | |
} | |
public void init() { } | |
@Override | |
final public void render(float delta) { | |
Gdx.gl.glClearColor(0, 0, 0, 1); | |
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); | |
draw(delta); | |
if(ui != null) { | |
ui.act(delta); | |
ui.draw(); | |
} | |
} | |
/** | |
* Override this sucker to implement any custom drawing | |
* @param delta The number of seconds that have passed since the last frame. | |
*/ | |
public void draw(float delta) {} | |
@Override public void resize(int width, int height) { | |
ui.getViewport().update(width, height); | |
} | |
@Override public void dispose() { | |
if(ui != null) ui.dispose(); | |
ui = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment