Java tutorial
/* * Copyright (C) 2017 by Sebastian Hasait (sebastian at hasait dot de) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.hasait.tanks.app.common; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Supplier; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.Preferences; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.TextField; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Align; import de.hasait.tanks.app.common.model.GameConfig; import de.hasait.tanks.app.common.model.PlayerConfig; import de.hasait.tanks.util.common.Abstract2DScreen; import de.hasait.tanks.util.common.Util; import de.hasait.tanks.util.common.input.ConfiguredAction; import de.hasait.tanks.util.common.input.ConfiguredActionFactory; import de.hasait.tanks.util.common.input.GdxInputKeyPressedAction; /** * */ public class MainMenuScreen extends Abstract2DScreen<TanksScreenContext> { private static final String PREFKEY__ROOM_NAME = "roomName"; private static final String PREFKEY__PLAYER_CONFIG = "playerConfig"; private final InputProcessor _inputProcessor = new InputAdapter() { @Override public boolean keyUp(final int keycode) { if (keycode == Input.Keys.ESCAPE) { Gdx.app.exit(); } return super.keyUp(keycode); } }; private final AtomicReference<ConfiguredActionFactory> _configuredActionFactory = new AtomicReference<>(); private final TextField _roomNameField; private final List<TextField> _playerNameFields = new ArrayList<>(); private final TextButton _connectButton; private boolean _connect; public MainMenuScreen(final TanksScreenContext pContext) { super(pContext, 800, 600); setBackgroundColor(new Color(0.0f, 0.0f, 0.2f, 1.0f)); addInputProcessor(_inputProcessor); final Table layout = addLayout(); layout.setFillParent(true); layout.defaults().pad(5.0f).align(Align.left).fill(); final Label titleLabel = createLabel("Welcome to Tanks", 2.0f); layout.add(titleLabel).colspan(2).padBottom(20.0f); final Preferences preferences = obtainPreferences(); layout.row(); layout.add(createLabel("Room")); _roomNameField = createTextField(preferences.getString(PREFKEY__ROOM_NAME, "Default")); layout.add(_roomNameField); for (int i = 0; i < 2; i++) { layout.row(); layout.add(createLabel("Player " + (i + 1))); final TextField playerNameField = createTextField(); layout.add(playerNameField); _playerNameFields.add(playerNameField); PlayerConfig playerConfig = null; final String preferencesString = preferences.getString(PREFKEY__PLAYER_CONFIG + i); if (!Util.isEmpty(preferencesString)) { try { playerConfig = (PlayerConfig) Util.serializeFromString(preferencesString); Gdx.app.log("PlayerConfig", "Read for player " + i); } catch (final RuntimeException pE) { Gdx.app.error("PlayerConfig", "Cannot read for player " + i, pE); } } if (playerConfig == null) { Gdx.app.log("PlayerConfig", "New for player " + i); playerConfig = new PlayerConfig(); if (i == 0) { playerConfig.setName("Player " + (i + 1)); setActionSet1(playerConfig); } else if (i == 1) { setActionSet2(playerConfig); } } playerNameField.setText(playerConfig.getName()); playerNameField.setUserObject(playerConfig); layout.add(actionConfig("Fire", playerConfig::getFire, playerConfig::setFire)); layout.row(); layout.add(createLabel(Util.EMPTY)); layout.add(actionConfig("Move Forward", playerConfig::getMoveForward, playerConfig::setMoveForward)); layout.add(actionConfig("Move Backward", playerConfig::getMoveBackward, playerConfig::setMoveBackward)); layout.row(); layout.add(createLabel(Util.EMPTY)); layout.add(actionConfig("Rotate Left", playerConfig::getRotateLeft, playerConfig::setRotateLeft)); layout.add(actionConfig("Rotate Right", playerConfig::getRotateRight, playerConfig::setRotateRight)); layout.row(); layout.add(createLabel(Util.EMPTY)); layout.add(actionConfig("Turret Left", playerConfig::getTurrentRotateLeft, playerConfig::setTurrentRotateLeft)); layout.add(actionConfig("Turret Right", playerConfig::getTurrentRotateRight, playerConfig::setTurrentRotateRight)); } layout.row(); _connectButton = createTextButton("Connect"); layout.add(_connectButton).colspan(2); _connectButton.addListener(pEvent -> { if (pEvent instanceof ChangeListener.ChangeEvent) { _connect = true; } return false; }); } @Override protected void renderInternal(final float pDelta) { final ConfiguredActionFactory configuredActionFactory = _configuredActionFactory.get(); if (configuredActionFactory != null) { drawText(0, ">>> Waiting for action <<<", AlignH.CENTER, AlignV.TOP); if (configuredActionFactory.isFinished()) { _configuredActionFactory.set(null); } } if (_connect) { _connect = false; final String roomName = _roomNameField.getText(); if (Util.isBlank(roomName)) { return; } final Preferences preferences = obtainPreferences(); preferences.putString(PREFKEY__ROOM_NAME, roomName); final GameConfig config = new GameConfig(); config.setRoomName(roomName); config.setWishPiecesX(40); config.setWishPiecesY(24); for (int i = 0; i < _playerNameFields.size(); i++) { final TextField playerNameField = _playerNameFields.get(i); final String playerName = playerNameField.getText(); if (Util.isBlank(playerName)) { continue; } final PlayerConfig playerConfig = (PlayerConfig) playerNameField.getUserObject(); playerConfig.setName(playerName.trim()); config.getPlayers().add(playerConfig); preferences.putString(PREFKEY__PLAYER_CONFIG + i, Util.serializeToString(playerConfig)); } if (config.getPlayers().isEmpty()) { return; } preferences.flush(); setScreen(new ConnectingScreen(getContext(), config)); } } private Label actionConfig(final String pTitle, final Supplier<ConfiguredAction> pActionSupplier, final Consumer<ConfiguredAction> pActionConsumer) { final Label label = createLabel(pTitle); final Consumer<ConfiguredAction> actionConsumer = pAction -> { label.setText(pTitle + ": " + pAction); pActionConsumer.accept(pAction); }; actionConsumer.accept(pActionSupplier.get()); label.addListener(new ClickListener() { @Override public void clicked(final InputEvent pEvent, final float pX, final float pY) { if (_configuredActionFactory.compareAndSet(null, new ConfiguredActionFactory())) { _configuredActionFactory.get().init(actionConsumer); } } }); return label; } private Preferences obtainPreferences() { return Gdx.app.getPreferences("tanks-config"); } private void setActionSet1(final PlayerConfig pPlayerConfig) { pPlayerConfig.setMoveForward(new GdxInputKeyPressedAction(Input.Keys.W)); pPlayerConfig.setMoveBackward(new GdxInputKeyPressedAction(Input.Keys.S)); pPlayerConfig.setRotateLeft(new GdxInputKeyPressedAction(Input.Keys.A)); pPlayerConfig.setRotateRight(new GdxInputKeyPressedAction(Input.Keys.D)); pPlayerConfig.setTurrentRotateLeft(new GdxInputKeyPressedAction(Input.Keys.Q)); pPlayerConfig.setTurrentRotateRight(new GdxInputKeyPressedAction(Input.Keys.E)); pPlayerConfig.setFire(new GdxInputKeyPressedAction(Input.Keys.SPACE)); } private void setActionSet2(final PlayerConfig pPlayerConfig) { pPlayerConfig.setMoveForward(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_5)); pPlayerConfig.setMoveBackward(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_2)); pPlayerConfig.setRotateLeft(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_1)); pPlayerConfig.setRotateRight(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_3)); pPlayerConfig.setTurrentRotateLeft(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_4)); pPlayerConfig.setTurrentRotateRight(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_6)); pPlayerConfig.setFire(new GdxInputKeyPressedAction(Input.Keys.NUMPAD_0)); } }