/*
Point & Hit: A fast paced Android game
Copyright (C) 2015 Marien Raat
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jmstudios.pointandhit;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.Align;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
public class TutorialScreen
implements Screen, InputProcessor {
public enum TutorialState { Calibrating, Step1, Step2, Done };
OneShotGame game;
SpriteBatch batch;
ShapeRenderer shapeRenderer;
UserPointer userPointer;
TargetManager targetManager;
Vector2 screenSize;
BitmapFont textFont;
TutorialState state;
boolean automatic;
// Calibration
float roll, pitch, azimuth;
int frames;
float calibrationTimeLeft
, calibrationTime = 0.1f;
Label.LabelStyle infoLabelStyle
, tapToLabelStyle;
// Step 1
float scale;
Stage step1Stage;
Table step1Table;
CharSequence tiltInfo = "Tilt your phone to move the white pointer."
, tapInfo = "Tap the screen to shoot."
, tapToContinue = "Tap the screen to continue...";
Label step1TiltInfo, step1TapInfo, step1TapToContinue;
// Step 2
Stage step2Stage;
Table step2Table;
CharSequence objectiveInfo = "Shoot the targets before they dissapear."
, shootToContinueInfo = "Shoot a target to continue...";
Label step2ObjectiveInfo, step2ShootToContinue;
// Done
Stage doneStage;
Table doneTable;
CharSequence endMessage = "That's all. Have fun!"
, tapToPlay = "Tap to play...";
Label doneEndMessage, doneTapToInfo;
public TutorialScreen(final OneShotGame game, boolean automatic) {
this.game = game;
this.automatic = automatic;
this.scale = game.scale;
batch = new SpriteBatch();
shapeRenderer = new ShapeRenderer();
screenSize = new Vector2(Gdx.graphics.getWidth()
, Gdx.graphics.getHeight());
textFont = new BitmapFont(Gdx.files.internal("fonts/deja_vu_sans_medium.fnt"));
textFont.setScale(scale);
infoLabelStyle = new Label.LabelStyle(textFont, Color.WHITE);
tapToLabelStyle = new Label.LabelStyle(textFont, Color.LIGHT_GRAY);
// Step 1
float padding = 50 * scale;
step1Stage = new Stage();
step1Table = new Table();
step1Table.setFillParent(true);
step1Table.align(Align.bottomLeft);
step1TiltInfo = new Label(tiltInfo, infoLabelStyle);
step1TiltInfo.setWrap(true);
step1TiltInfo.setWidth(screenSize.x - padding * 2);
step1TiltInfo.setAlignment(Align.center);
step1TapInfo = new Label(tapInfo, infoLabelStyle);
step1TapInfo.setWrap(true);
step1TapInfo.setWidth(screenSize.x - padding * 2);
step1TapInfo.setAlignment(Align.center);
step1TapToContinue = new Label(tapToContinue, tapToLabelStyle);
step1TapToContinue.setWrap(true);
step1TapToContinue.setWidth(screenSize.x - padding * 2);
step1TapToContinue.setAlignment(Align.center);
step1Table.defaults().pad(padding);
step1Table.add(step1TiltInfo)
.width(screenSize.x - padding * 2);
step1Table.row();
step1Table.add(step1TapInfo)
.width(screenSize.x - padding * 2);
step1Table.row();
step1Table.add(step1TapToContinue)
.width(screenSize.x - padding * 2);
step1Stage.addActor(step1Table);
// Step 2
step2Stage = new Stage();
step2Table = new Table();
step2Table.setFillParent(true);
step2Table.align(Align.bottomLeft);
step2ObjectiveInfo = new Label(objectiveInfo, infoLabelStyle);
step2ObjectiveInfo.setWrap(true);
step2ObjectiveInfo.setWidth(screenSize.x - padding * 2);
step2ObjectiveInfo.setAlignment(Align.center);
step2ShootToContinue = new Label(shootToContinueInfo, tapToLabelStyle);
step2ShootToContinue.setWrap(true);
step2ShootToContinue.setWidth(screenSize.x - padding * 2);
step2ShootToContinue.setAlignment(Align.center);
step2Table.defaults().pad(padding);
step2Table.add(step2ObjectiveInfo)
.width(screenSize.x - padding * 2);
step2Table.row();
step2Table.add(step2ShootToContinue)
.width(screenSize.x - padding * 2);
step2Stage.addActor(step2Table);
// Done
doneStage = new Stage();
doneTable = new Table();
doneTable.setFillParent(true);
doneTable.align(Align.left);
doneEndMessage = new Label(endMessage, infoLabelStyle);
doneEndMessage.setWrap(true);
doneEndMessage.setWidth(screenSize.x - padding * 2);
doneEndMessage.setAlignment(Align.center);
if (automatic) {
tapToPlay = "Tap to finish...";
}
doneTapToInfo = new Label(tapToPlay, tapToLabelStyle);
doneTapToInfo.setWrap(true);
doneTapToInfo.setWidth(screenSize.x - padding * 2);
doneTapToInfo.setAlignment(Align.center);
doneTable.defaults().pad(padding);
doneTable.add(doneEndMessage)
.width(screenSize.x - padding * 2);
doneTable.row();
doneTable.add(doneTapToInfo)
.width(screenSize.x - padding * 2);
doneStage.addActor(doneTable);
}
@Override
public void show() {
Gdx.input.setInputProcessor(this);
Gdx.input.setCatchBackKey(true);
userPointer = new UserPointer((int) (screenSize.x / 40), screenSize
, game.preferences);
targetManager = new TargetManager(3f, (int) (screenSize.x * 0.255f)
, screenSize, userPointer, null);
// Calibration
roll = Gdx.input.getRoll();
pitch = Gdx.input.getPitch();
azimuth = Gdx.input.getAzimuth();
frames = 1;
calibrationTimeLeft = calibrationTime;
state = TutorialState.Calibrating;
// Tutorial has been done
game.preferences.putBoolean("tutorial", true);
game.preferences.flush();
}
@Override
public void render(float delta) {
if (state == TutorialState.Calibrating) {
clearScreen();
updateCalibrations();
}
else if (state == TutorialState.Step1) {
userPointer.update();
clearScreen();
shapeRenderer.begin(ShapeType.Filled);
userPointer.draw(shapeRenderer
, targetManager.currentTheme);
shapeRenderer.end();
step1Stage.act();
step1Stage.draw();
}
else if (state == TutorialState.Step2) {
userPointer.update();
targetManager.update();
clearScreen();
shapeRenderer.begin(ShapeType.Filled);
targetManager.draw(shapeRenderer);
userPointer.draw(shapeRenderer, targetManager.currentTheme);
shapeRenderer.end();
batch.begin();
targetManager.draw(batch);
batch.end();
step2Stage.act();
step2Stage.draw();
if (targetManager.score > 0) {
startDone();
}
}
else if (state == TutorialState.Done) {
clearScreen();
doneStage.act();
doneStage.draw();
}
}
public void clearScreen() {
Color backgroundColor = targetManager.currentTheme
.background;
Gdx.gl.glClearColor(backgroundColor.r
, backgroundColor.g
, backgroundColor.b, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
public void updateCalibrations() {
roll += Gdx.input.getRoll();
pitch += Gdx.input.getPitch();
azimuth += Gdx.input.getAzimuth();
frames++;
calibrationTimeLeft -= Gdx.graphics.getDeltaTime();
if (calibrationTimeLeft < 0) {
userPointer.calibrate(roll / frames
, pitch / frames
, azimuth / frames);
startStep1();
}
}
public void startStep1() {
state = TutorialState.Step1;
}
public void startStep2() {
state = TutorialState.Step2;
}
public void startDone() {
state = TutorialState.Done;
}
@Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
@Override
public void hide() {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
@Override
public boolean keyDown(int keycode) {
if (keycode == Keys.BACK) {
if (state == TutorialState.Calibrating
|| state == TutorialState.Step1
|| state == TutorialState.Done) {
game.setScreen(game.mainMenu);
} else if (state == TutorialState.Step2) {
startStep1();
}
return true;
}
return false;
}
@Override
public boolean keyUp(int keycode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if (state == TutorialState.Step1) {
startStep2();
return true;
}
if (state == TutorialState.Step2) {
targetManager.screenTouchDown();
}
if (state == TutorialState.Done) {
if (automatic) {
game.setScreen(game.mainMenu);
} else {
game.setScreen(game.getGameScreen());
}
}
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}