use of com.agorria.shootandmove.graphics.Drawable in project ShootAndRun by IonAgorria.
the class GameView method createBatch.
/**
* Creates batch for current drawables in queue, this clears queue.
*
* @param slot to set batch
* @param mode to use
* @param drawables to draw in the batch
* @param camera location when drawing
* @param rotation of camera when drawing
* @param color to set when drawing
* @return batch created
*/
public DrawableBatch createBatch(DrawableBatch.SLOT slot, DrawableBatch.MODE mode, List<Drawable> drawables, Vector3f camera, Vector3f rotation, Color color) {
// Vertices calculation
int vertexCount = 0;
for (Drawable drawable : drawables) {
vertexCount += drawable.getVertexCount();
}
// Create buffers
FloatBuffer positionBuffer = Utilities.getDirectByteBuffer(vertexCount * Constants.STRIDE_POSITION).asFloatBuffer();
FloatBuffer texCoordBuffer = Utilities.getDirectByteBuffer(vertexCount * Constants.STRIDE_TEXCOORD).asFloatBuffer();
// Fill buffers with each drawable
TextureAtlas.Atlas atlas = null;
int i = 0;
int indicesCount = 0;
List<short[]> indicesList = new ArrayList<>();
for (Drawable drawable : drawables) {
float[] positions = drawable.getVertexPositions();
positionBuffer.put(positions);
texCoordBuffer.put(drawable.getVertexTexCoords());
short[] indices = drawable.getVertexIndices(i);
indicesCount += indices.length;
indicesList.add(indices);
// Increment indices index
i += positions.length / Constants.FLOATS_PER_POSITION;
// Check atlas is the same
TextureAtlas.Atlas drawableAtlas = drawable.getAtlas();
if (atlas == null) {
atlas = drawableAtlas;
} else if (atlas != drawableAtlas) {
throw new RuntimeException("This batch uses " + atlas + " but drawable has " + drawableAtlas);
}
}
// Create indices buffer
ShortBuffer indicesBuffer = Utilities.getDirectByteBuffer(indicesCount * 2).asShortBuffer();
for (short[] indices : indicesList) {
indicesBuffer.put(indices);
}
// Reset positions for reading
positionBuffer.position(0);
texCoordBuffer.position(0);
indicesBuffer.position(0);
// Create and return batch
return new DrawableBatch(slot, mode, camera, rotation, new Color(color), atlas, positionBuffer, texCoordBuffer, indicesBuffer, indicesCount);
}
use of com.agorria.shootandmove.graphics.Drawable in project ShootAndRun by IonAgorria.
the class AnimatedEntity method update.
/**
* Updates entity, called from world
* Advances entity animation
*/
@Override
public void update(float delta) {
super.update(delta);
Drawable drawable = getDrawable();
animation.update(delta);
drawable.setTextureRegion(animation.getCurrentFrame());
}
use of com.agorria.shootandmove.graphics.Drawable in project ShootAndRun by IonAgorria.
the class GameThread method run.
/**
* Called from thread when starts
*/
@Override
public void run() {
// Initializes stuff
lastTime = System.currentTimeMillis();
world = new World(gameView);
// Main loop
while (running.get()) {
long sleep = Constants.THREAD_SLEEP;
// Check if we are not in pause
if (!paused) {
// Calculate delta and store last time
long time = System.currentTimeMillis();
float delta = (time - lastTime) / 1000.0f;
lastTime = time;
// Checks if UI requests a game state
GameState requestedState = gameUI.getRequestedGameState();
if (requestedState != null) {
setGameState(requestedState);
}
// Get player
Player player = null;
if (gameState != GameState.Menu && world != null) {
player = world.getPlayer();
}
// Check active state
float gyroscope = gameUI.getGyroscope();
if (gameState == GameState.Active) {
// Check if player is dead
if (player == null || player.isDestroyed()) {
setGameState(GameState.Lost);
}
// Check if level is requested
Integer requestedLevel = world.getRequestedLevel();
if (requestedLevel != null) {
world.setRequestedLevel(null);
// Check if is ending or normal level
if (requestedLevel > Constants.LEVEL_COUNT) {
setGameState(GameState.Menu);
gameUI.setCurrentMenu(MenuEnding.class);
} else {
SharedPreferences preferences = gameView.getPreferences();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(Constants.PREFERENCES_KEY_LEVEL, requestedLevel);
editor.apply();
setLevel(requestedLevel, false);
}
}
// Check if we are still active
if (requestedLevel == null && gameState == GameState.Active) {
// Update just the player
if (player != null) {
player.update(Constants.GAME_DELTA, gameUI.getButtons(), gameUI.getJoystick(), gameUI.isGyroscopeEnabled() ? gyroscope : 0f);
}
// Update and draw world
world.update(Constants.GAME_DELTA);
// Show any message
String message = world.getMessage();
if (message != null) {
gameUI.showText(message);
}
}
}
// Game UI update and draw
gameUI.update(delta);
gameUI.draw(gameView, player);
// Debug draw
if (Constants.DEBUG_MODE) {
// Draw FPS
List<Drawable> drawables = new ArrayList<>();
String text = String.format(Locale.getDefault(), "U %.1f", 1f / delta);
if (player != null) {
Vector3f pos = player.getPosition();
text += String.format(Locale.getDefault(), " X %.1f", pos.x);
text += String.format(Locale.getDefault(), " Z %.1f", pos.z);
text += String.format(Locale.getDefault(), " D %.1f", player.getDirection());
text += String.format(Locale.getDefault(), " G %.1f", gyroscope);
}
if (world != null) {
text += String.format(Locale.getDefault(), " R %d", world.getRobots());
}
gameView.drawText(drawables, 0, 0, 0, 0.05f, text);
gameView.submitBatch(gameView.createBatchOrthographic(DrawableBatch.SLOT.DebugUI, drawables, Color.WHITE));
}
// Check if view should be rendered
gameView.checkShouldRender();
// Calculate how much to sleep
sleep = Constants.GAME_SLEEP;
sleep -= System.currentTimeMillis() - time;
}
// Sleep thread
if (0 < sleep) {
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
Log.d(TAG, "Game loop sleep interrupted");
}
}
}
}
use of com.agorria.shootandmove.graphics.Drawable in project ShootAndRun by IonAgorria.
the class GameUI method sizeChanged.
/**
* Called when size of view is changed
*
* @param width in pixes
* @param height in pixels
*/
public void sizeChanged(GameView view, int width, int height) {
Log.d(TAG, "sizeChanged " + width + "x" + height);
this.viewWidth = width == 0 ? 1 : width;
this.viewHeight = height == 0 ? 1 : height;
this.aspect = viewWidth / viewHeight;
// Create non scaled background and submit
TextureAtlas sprite128 = view.getTextureAtlas(TextureAtlas.Atlas.Sprite128);
List<Drawable> backgrounds = new ArrayList<>();
backgrounds.add(new DrawableRectangle(aspect / 2f - 1f, 0, 1f, 1f, sprite128.getRegion(0, 0).copy().flip(false, true)));
backgrounds.add(new DrawableRectangle(aspect / 2f, 0, 1f, 1f, sprite128.getRegion(0, 0)));
DrawableBatch batch = view.createBatchOrthographic(DrawableBatch.SLOT.Background, backgrounds, Color.WHITE);
view.submitBatch(batch);
// Generate menus
menuMap.put(MenuMain.class, new MenuMain(this, view));
menuMap.put(MenuHelp.class, new MenuHelp(this, view));
menuMap.put(MenuPlay.class, new MenuPlay(this, view));
menuMap.put(MenuIntro.class, new MenuIntro(this, view));
menuMap.put(MenuEnding.class, new MenuEnding(this, view));
menuMap.put(MenuCredits.class, new MenuCredits(this, view));
menuMap.put(MenuOptions.class, new MenuOptions(this, view));
// Generate control drawables
TextureAtlas atlas = view.getTextureAtlas(TextureAtlas.Atlas.Sprite32);
gameDrawables.clear();
float controlSize = CONTROLS_SIZE / 2;
// Joystick
joystickRectangle = new Rectangle(CONTROLS_PADDING, CONTROLS_PADDING, controlSize * 2, controlSize * 2);
gameDrawables.add(new DrawableRectangle(joystickRectangle, atlas.getRegion(14, 0)));
// Shoot
gameDrawables.add(new DrawableRectangle(aspect - controlSize - CONTROLS_PADDING, CONTROLS_PADDING + controlSize, controlSize, controlSize, atlas.getRegion(14, 1)));
// Prev
gameDrawables.add(new DrawableRectangle(aspect - controlSize * 2 - CONTROLS_PADDING, CONTROLS_PADDING, controlSize, controlSize, atlas.getRegion(15, 0)));
// Next
gameDrawables.add(new DrawableRectangle(aspect - controlSize - CONTROLS_PADDING, CONTROLS_PADDING, controlSize, controlSize, // Flip side
atlas.getRegion(15, 0).copy().flip(true, false)));
// Cross
gameDrawables.add(new DrawableRectangle(aspect / 2f - CROSS_SIZE / 2f, 0.5f - CROSS_SIZE / 2f, CROSS_SIZE, CROSS_SIZE, atlas.getRegion(8, 1)));
// Health
float playerSpace = aspect * PLAYER_SPACE;
float playerPadding = (1f - PLAYER_PADDING) - PLAYER_SIZE;
gameDrawables.add(new DrawableRectangle(aspect / 2 - playerSpace - PLAYER_SIZE, playerPadding, PLAYER_SIZE, PLAYER_SIZE, atlas.getRegion(4, 2).copy().setSizeCentered(20, 20)));
// Movement
movementDrawables = new Drawable[] { new DrawableRectangle(aspect - controlSize * 2 - CONTROLS_PADDING, CONTROLS_PADDING + controlSize, controlSize, controlSize, atlas.getRegion(15, 1)), new DrawableRectangle(aspect - controlSize * 2 - CONTROLS_PADDING, CONTROLS_PADDING + controlSize, controlSize, controlSize, atlas.getRegion(15, 2)) };
// Death drawables
deathDrawables = new Drawable[] { new DrawableRectangle(0, 0, aspect, 1f, atlas.getRegion(14, 2)), new DrawableRectangle(0, 0, aspect, 1f, atlas.getRegion(13, 2)), new DrawableRectangle(0, 0, aspect, 1f, atlas.getRegion(12, 2)) };
// Set flag
requireDraw = true;
}
use of com.agorria.shootandmove.graphics.Drawable in project ShootAndRun by IonAgorria.
the class GameUI method draw.
/**
* Draws the UI if required
*
* @param view of game
* @param player instance
*/
void draw(GameView view, Player player) {
if (player != null) {
requireDraw |= player.hasChanged();
}
if (requireDraw) {
requireDraw = false;
List<Drawable> drawables = new ArrayList<>();
// Draw death overlay
if (player != null) {
int health = player.getCurrentHealth();
if (health <= 50)
drawables.add(deathDrawables[0]);
if (health <= 25)
drawables.add(deathDrawables[1]);
}
// Draw UI per state
Color color = null;
String text = null;
if (currentGameState == GameState.Menu) {
// Draw current menu
color = Color.WHITE;
Menu menu = menuMap.get(currentMenu);
if (menu != null) {
menu.draw(view, drawables);
}
} else if (currentGameState == GameState.Active) {
color = Color.GRAY_LIGHT_50;
drawables.addAll(gameDrawables);
// Movement mode
if (movementDrawables != null) {
drawables.add(movementDrawables[movementMode ? 1 : 0]);
}
// Add player stuff
if (player != null) {
Weapon weapon = player.getWeapon();
Drawable weaponDrawable = weapon.getDrawable();
float playerPadding = (1 - PLAYER_PADDING) - PLAYER_SIZE;
float middle = aspect / 2f;
// Draw player health
int health = player.getCurrentHealth();
view.drawText(drawables, middle, playerPadding, 0, PLAYER_SIZE, false, false, String.valueOf(health));
// Draw weapon
weaponDrawable.getPosition().set(middle - PLAYER_SIZE - PLAYER_SPACE, playerPadding - PLAYER_SIZE - PLAYER_SPACE, 0);
weaponDrawable.getSize().set(PLAYER_SIZE, PLAYER_SIZE, 0);
drawables.add(weaponDrawable);
// Draw weapon ammo
view.drawText(drawables, middle, playerPadding - PLAYER_SIZE - PLAYER_SPACE, 0, PLAYER_SIZE, false, false, String.valueOf(weapon.getShots()));
}
} else if (currentGameState == GameState.Lost) {
color = Color.RED;
drawables.add(deathDrawables[2]);
text = view.getText(R.string.lost);
} else if (currentGameState == GameState.Pause) {
color = Color.GRAY_LIGHT_50;
text = view.getText(R.string.paused);
}
// Add text
if (text != null) {
String[] lines = Utilities.getTextLines(text);
int textWidth = Utilities.getTextWidth(lines) + 2;
float charWidth = aspect / textWidth;
view.drawText(drawables, aspect / 2f, 0.5f, charWidth, 0, true, true, lines);
}
// Draw slow text if any
if (slowTextElement != null) {
slowTextElement.onDraw(view, drawables);
}
// Send drawables to batch if any
if (drawables.isEmpty()) {
view.clearBatches(DrawableBatch.SLOT.UI);
} else {
DrawableBatch batch = view.createBatchOrthographic(DrawableBatch.SLOT.UI, drawables, color);
view.submitBatch(batch);
}
}
if (vibrate) {
vibrate = false;
view.vibrate(Constants.VIBRATE_UI);
}
}
Aggregations