Java tutorial
/******************************************************************************* * Copyright 2011 See AUTHORS.libgdx file. * 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 net.onedaybeard.keyflection.demo; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.InputMultiplexer; import com.badlogic.gdx.backends.lwjgl.LwjglApplication; import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Image; 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.utils.Array; import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.Scaling; import net.onedaybeard.keyflection.CommandController; import net.onedaybeard.keyflection.KeyflectionInputListener; import net.onedaybeard.keyflection.KeyflectionInputProcessor; import net.onedaybeard.keyflection.annotation.Command; import net.onedaybeard.keyflection.annotation.Shortcut; public class DemoUI implements ApplicationListener { private static final int NUM_GROUPS = 5; private static final int NUM_SPRITES = (int) Math.sqrt(400 / NUM_GROUPS); private static final float SPACING = 5; ShapeRenderer renderer; Stage stage; Stage ui; Texture texture; Texture uiTexture; BitmapFont font; boolean rotateSprites = false; boolean scaleSprites = false; float angle; Array<Image> images = new Array<Image>(); float scale = 1; float vScale = 1; Label fps; Label hint; private Color background; private boolean drawHud = true; private StageKeys stageActions; private Table overlay; public static void main(String[] args) { LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); cfg.title = "keyflection-demo"; cfg.useGL20 = false; cfg.width = 1024; cfg.height = 768; new LwjglApplication(new DemoUI(), cfg); } @Override public void create() { background = new Color(0.2f, 0.2f, 0.2f, 1f); texture = new Texture(Gdx.files.internal("data/badlogicsmall.jpg")); texture.setFilter(TextureFilter.Linear, TextureFilter.Linear); font = new BitmapFont(Gdx.files.internal("data/font.fnt"), false); stageActions = new StageKeys(); stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); float loc = (NUM_SPRITES * (32 + SPACING) - SPACING) / 2; for (int i = 0; i < NUM_GROUPS; i++) { Group group = new Group(); group.setX((float) Math.random() * (stage.getWidth() - NUM_SPRITES * (32 + SPACING))); group.setY((float) Math.random() * (stage.getHeight() - NUM_SPRITES * (32 + SPACING))); group.setOrigin(loc, loc); fillGroup(group, texture); stage.addActor(group); } uiTexture = new Texture(Gdx.files.internal("data/ui.png")); uiTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); ui = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); ui.addListener(new KeyflectionInputListener(stageActions)); Image blend = new Image(new TextureRegion(uiTexture, 0, 0, 64, 32)); blend.setAlign(Align.center); blend.setScaling(Scaling.none); blend.addListener(new InputListener() { public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { stageActions.toggleBlending(); return true; } }); blend.setY(ui.getHeight() - 64); Image rotate = new Image(new TextureRegion(uiTexture, 64, 0, 64, 32)); rotate.setAlign(Align.center); rotate.setScaling(Scaling.none); rotate.addListener(new InputListener() { public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { stageActions.toggleRotation(); return true; } }); rotate.setPosition(64, blend.getY()); Image scale = new Image(new TextureRegion(uiTexture, 64, 32, 64, 32)); scale.setAlign(Align.center); scale.setScaling(Scaling.none); scale.addListener(new InputListener() { public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { stageActions.toggleScaling(); return true; } }); scale.setPosition(128, blend.getY()); ui.addActor(blend); ui.addActor(rotate); ui.addActor(scale); hint = new Label("Press F1 to see keyboard shortcuts.", new Label.LabelStyle(font, Color.WHITE)); hint.setPosition(10, 45); hint.setColor(0, 1, 0, 1); ui.addActor(hint); fps = new Label("fps: 0", new Label.LabelStyle(font, Color.WHITE)); fps.setPosition(10, 30); fps.setColor(0, 1, 0, 1); ui.addActor(fps); renderer = new ShapeRenderer(); InputMultiplexer multiplexer = new InputMultiplexer(); multiplexer.addProcessor(new KeyflectionInputProcessor(new GlobalKeys())); multiplexer.addProcessor(stage); multiplexer.addProcessor(ui); Gdx.input.setInputProcessor(multiplexer); } private void fillGroup(Group group, Texture texture) { float advance = 32 + SPACING; for (int y = 0; y < NUM_SPRITES * advance; y += advance) for (int x = 0; x < NUM_SPRITES * advance; x += advance) { Image img = new Image(new TextureRegion(texture)); img.setAlign(Align.center); img.setScaling(Scaling.none); img.setBounds(x, y, 32, 32); img.setOrigin(16, 16); group.addActor(img); images.add(img); } } @Override public void render() { Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); Gdx.gl.glClearColor(background.r, background.g, background.b, 1); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); if (Gdx.input.isTouched()) { Vector2 stageCoords = Vector2.tmp; stage.screenToStageCoordinates(stageCoords.set(Gdx.input.getX(), Gdx.input.getY())); Actor actor = stage.hit(stageCoords.x, stageCoords.y, true); if (actor instanceof Image) ((Image) actor).setColor((float) Math.random(), (float) Math.random(), (float) Math.random(), 0.5f + 0.5f * (float) Math.random()); } Array<Actor> actors = stage.getActors(); int len = actors.size; if (rotateSprites) { for (int i = 0; i < len; i++) actors.get(i).rotate(Gdx.graphics.getDeltaTime() * 10); } scale += vScale * Gdx.graphics.getDeltaTime(); if (scale > 1) { scale = 1; vScale = -vScale; } if (scale < 0.5f) { scale = 0.5f; vScale = -vScale; } len = images.size; for (int i = 0; i < len; i++) { Image img = images.get(i); if (rotateSprites) img.rotate(-40 * Gdx.graphics.getDeltaTime()); else img.setRotation(0); if (scaleSprites) { img.setScale(scale); } else { img.setScale(1); } img.invalidate(); } stage.draw(); renderer.begin(ShapeType.Point); renderer.setColor(1, 0, 0, 1); len = actors.size; for (int i = 0; i < len; i++) { Group group = (Group) actors.get(i); renderer.point(group.getX() + group.getOriginX(), group.getY() + group.getOriginY(), 0); } renderer.end(); if (drawHud) { fps.setText("fps: " + Gdx.graphics.getFramesPerSecond() + ", actors " + images.size + ", groups " + actors.size); ui.draw(); } } @Override public void dispose() { // ui.dispose(); // FIXME: crashes, somehow - maybe an OSX or nightlies issue? renderer.dispose(); texture.dispose(); uiTexture.dispose(); font.dispose(); } @Override public void pause() { } @Override public void resize(int arg0, int arg1) { } @Override public void resume() { } protected class StageKeys implements CommandController { @Command(name = "toggle UI", description = "hides/shows the UI", bindings = @Shortcut(Keys.H)) public void toggleHidingHud() { drawHud = !drawHud; } @Command(name = "randomize background", description = "colors...", bindings = { @Shortcut({ Keys.SHIFT_LEFT, Keys.R }), @Shortcut({ Keys.SHIFT_RIGHT, Keys.R }) }) public void randomizeBackground() { background.r = MathUtils.random(1f); background.g = MathUtils.random(1f); background.b = MathUtils.random(1f); } @Command(name = "toggle scaling", description = "toggles sprite scaling", bindings = @Shortcut(Keys.S)) public void toggleScaling() { scaleSprites = !scaleSprites; } @Command(name = "toggle rotation", description = "toggles sprite rotation", bindings = @Shortcut(Keys.R)) public void toggleRotation() { rotateSprites = !rotateSprites; } @Command(name = "toggle blend", description = "toggles blending", bindings = @Shortcut(Keys.B)) public void toggleBlending() { if (stage.getSpriteBatch().isBlendingEnabled()) stage.getSpriteBatch().disableBlending(); else stage.getSpriteBatch().enableBlending(); } } protected class GlobalKeys implements CommandController { @Command(name = "exit", description = "exit the demo", bindings = { @Shortcut(Keys.ESCAPE), @Shortcut({ Keys.CONTROL_LEFT, Keys.Q }), @Shortcut({ Keys.SHIFT_LEFT, Keys.Q }) }) public void exit() { try { dispose(); } catch (GdxRuntimeException e) { e.printStackTrace(); } finally { Gdx.app.exit(); } } @Command(name = "toggle help", description = "show/hide shortcut keys overview", bindings = @Shortcut(Keys.F1)) public void toggleHelp() { if (overlay == null) { overlay = new CommandOverlay().createOverlay(); overlay.setX(ui.getWidth() - overlay.getWidth()); } if (overlay.hasParent()) overlay.remove(); else ui.addActor(overlay); } } }