Search in sources :

Example 1 with DrawableBatch

use of com.agorria.shootandmove.graphics.DrawableBatch 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);
}
Also used : Color(com.agorria.shootandmove.graphics.Color) Drawable(com.agorria.shootandmove.graphics.Drawable) ArrayList(java.util.ArrayList) FloatBuffer(java.nio.FloatBuffer) SuppressLint(android.annotation.SuppressLint) TextureAtlas(com.agorria.shootandmove.graphics.TextureAtlas) DrawableBatch(com.agorria.shootandmove.graphics.DrawableBatch) ShortBuffer(java.nio.ShortBuffer)

Example 2 with DrawableBatch

use of com.agorria.shootandmove.graphics.DrawableBatch 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;
}
Also used : DrawableRectangle(com.agorria.shootandmove.graphics.DrawableRectangle) MenuMain(com.agorria.shootandmove.menu.MenuMain) MenuCredits(com.agorria.shootandmove.menu.MenuCredits) Drawable(com.agorria.shootandmove.graphics.Drawable) ArrayList(java.util.ArrayList) MenuPlay(com.agorria.shootandmove.menu.MenuPlay) DrawableRectangle(com.agorria.shootandmove.graphics.DrawableRectangle) Rectangle(com.agorria.shootandmove.math.Rectangle) MenuEnding(com.agorria.shootandmove.menu.MenuEnding) MenuOptions(com.agorria.shootandmove.menu.MenuOptions) MenuIntro(com.agorria.shootandmove.menu.MenuIntro) TextureAtlas(com.agorria.shootandmove.graphics.TextureAtlas) MenuHelp(com.agorria.shootandmove.menu.MenuHelp) DrawableBatch(com.agorria.shootandmove.graphics.DrawableBatch)

Example 3 with DrawableBatch

use of com.agorria.shootandmove.graphics.DrawableBatch 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);
    }
}
Also used : Color(com.agorria.shootandmove.graphics.Color) Drawable(com.agorria.shootandmove.graphics.Drawable) ArrayList(java.util.ArrayList) Menu(com.agorria.shootandmove.menu.Menu) DrawableBatch(com.agorria.shootandmove.graphics.DrawableBatch)

Example 4 with DrawableBatch

use of com.agorria.shootandmove.graphics.DrawableBatch in project ShootAndRun by IonAgorria.

the class World method load.

/**
 * Loads level as current world
 *
 * @param level to load
 * @param clear state
 */
void load(Integer level, boolean clear) {
    // Store player relative data if any
    float playerDirection = Constants.HALF_PI;
    Vector3f playerPreviousPosition = null;
    if (clear) {
        playerPosition = null;
        walked = 0;
    }
    if (!clear && player != null) {
        playerDirection = player.getDirection();
        playerPreviousPosition = player.getPreviousPosition().sub(player.getPosition(), new Vector3f());
    }
    // Reset stuff
    cameraPosition = new Vector3f(0, 0, 0);
    cameraRotation = new Vector3f(0, 0, 0);
    batches.clear();
    entities.clear();
    entitiesNext.clear();
    collisions.clear();
    doors.clear();
    player = null;
    requestedLevel = null;
    robots = 0;
    // Use loader if none or different name
    if (level == null) {
        throw new RuntimeException("No level to load");
    }
    if (loader == null || !level.equals(loader.level)) {
        loader = new WorldLoader(level, view);
    }
    // Load the world collisions
    collisions.addAll(loader.collisions);
    // Load world entities from spawns
    entities.clear();
    for (WorldLoader.EntitySpawn spawn : loader.entities) {
        Vector3f position = new Vector3f(spawn.position);
        Vector3f size = spawn.size == null ? null : new Vector3f(spawn.size);
        switch(spawn.name) {
            case "Player":
                // Restore old player position
                if (playerPosition != null) {
                    position.add(playerPosition);
                }
                player = new Player(this, position, playerDirection);
                // Restore old previous position
                if (playerPreviousPosition != null) {
                    player.getPosition().add(playerPreviousPosition, player.getPreviousPosition());
                }
                entities.add(player);
                break;
            case "Robot":
                entities.add(new Robot(this, position, spawn.type));
                robots++;
                break;
            case "Pistol":
                entities.add(new Item(this, position, Item.ItemType.Pistol));
                break;
            case "Plasma":
                entities.add(new Item(this, position, Item.ItemType.Plasma));
                break;
            case "Missile":
                entities.add(new Item(this, position, Item.ItemType.Missile));
                break;
            case "Health":
                entities.add(new Item(this, position, Item.ItemType.Health));
                break;
            case "Door":
                Door door = new Door(this, position, size, spawn.type);
                entities.add(door);
                doors.add(door);
                break;
            case "LockedDoor":
                LockedDoor lockedDoor = new LockedDoor(this, position, size, spawn.type);
                entities.add(lockedDoor);
                doors.add(lockedDoor);
                break;
            case "Warp":
                entities.add(new Warp(this, position, spawn.type));
                break;
            default:
                throw new IllegalArgumentException("Unknown object name");
        }
    }
    // Update camera before batch
    updateCamera();
    // Create the batch, use depth as world has no transparency
    DrawableBatch batch = view.createBatch(DrawableBatch.SLOT.World, DrawableBatch.MODE.PerspectiveDepth, loader.planes, cameraPosition, cameraRotation, Color.WHITE);
    view.submitBatch(batch);
    batches.add(batch);
}
Also used : Warp(com.agorria.shootandmove.entities.Warp) Player(com.agorria.shootandmove.entities.Player) LockedDoor(com.agorria.shootandmove.entities.LockedDoor) Door(com.agorria.shootandmove.entities.Door) Item(com.agorria.shootandmove.entities.Item) Vector3f(com.agorria.shootandmove.math.Vector3f) LockedDoor(com.agorria.shootandmove.entities.LockedDoor) DrawableBatch(com.agorria.shootandmove.graphics.DrawableBatch) Robot(com.agorria.shootandmove.entities.Robot)

Example 5 with DrawableBatch

use of com.agorria.shootandmove.graphics.DrawableBatch in project ShootAndRun by IonAgorria.

the class World method update.

/**
 * Updates the world
 *
 * @param delta time since last update
 */
void update(float delta) {
    // Update entities except player
    List<Entity> entitiesCollision = new ArrayList<>();
    for (Entity entity : entities) {
        // This removes entity as is not added to next list
        if (entity.isDestroyed()) {
            removedEntity(entity);
            continue;
        }
        // Update entity
        entity.update(delta);
        // Add to next
        entitiesNext.add(entity);
        if (entity.getCollision() != null) {
            entitiesCollision.add(entity);
        }
    }
    // Check if collides with world
    for (Entity entity : entitiesCollision) {
        for (Rectangle collision : collisions) {
            if (!entity.ignoreCollisionWorld(collision) && entity.checkCollision(collision)) {
                boolean unhandled = entity.handleCollisionWorld(collision);
                if (unhandled) {
                    Vector2f vector = entity.resolveCollision(collision);
                    if (vector != null) {
                        entity.getPosition().add(vector.x, 0, vector.y);
                        entity.updateAfterPosition();
                    }
                }
            }
        }
    }
    // Check if entities collide
    for (Iterator<Entity> iterator = entitiesCollision.iterator(); iterator.hasNext(); ) {
        Entity entity = iterator.next();
        // Check other entities
        for (Entity other : entitiesCollision) {
            CollisionInterface otherCollision = other.getCollision();
            if (entity != other && !(entity.ignoreCollisionEntity(other) || other.ignoreCollisionEntity(entity)) && entity.checkCollision(otherCollision)) {
                boolean entityUnhandled = entity.handleCollisionEntity(other) && !other.ignoreCollisionResolution(entity);
                boolean otherUnhandled = other.handleCollisionEntity(entity) && !entity.ignoreCollisionResolution(other);
                if (entityUnhandled) {
                    Vector2f vector = entity.resolveCollision(otherCollision);
                    if (vector != null) {
                        if (otherUnhandled) {
                            // Handle both by distributing equally at opposing direction
                            vector.mul(0.5f);
                            other.getPosition().add(-vector.x, 0, -vector.y);
                            other.updateAfterPosition();
                        }
                        // Handle entity
                        entity.getPosition().add(vector.x, 0, vector.y);
                        entity.updateAfterPosition();
                    }
                } else if (otherUnhandled) {
                    // Only handle other
                    Vector2f vector = other.resolveCollision(entity.getCollision());
                    if (vector != null) {
                        other.getPosition().add(vector.x, 0, vector.y);
                        other.updateAfterPosition();
                    }
                }
            }
        }
        // Remove entity as we have checked it
        iterator.remove();
    }
    // Remove entities that are destroyed and get drawables
    List<Drawable> entitiesDrawable = new ArrayList<>();
    for (Iterator<Entity> iterator = entitiesNext.iterator(); iterator.hasNext(); ) {
        Entity entity = iterator.next();
        if (entity.isDestroyed()) {
            // Remove entity
            removedEntity(entity);
            iterator.remove();
        } else {
            // Add to draw
            Drawable drawable = entity.getDrawable();
            if (drawable != null) {
                entitiesDrawable.add(drawable);
            }
        }
    }
    // Set the current entities from next
    entities.clear();
    entities = entitiesNext;
    entitiesNext = new ArrayList<>();
    // Update camera
    if (player != null && !player.isDestroyed()) {
        updateCamera();
    }
    // Submit batch to draw entities
    DrawableBatch batch = view.createBatch(DrawableBatch.SLOT.Entities, DrawableBatch.MODE.PerspectiveDepthBlend, entitiesDrawable, cameraPosition, cameraRotation, Color.WHITE);
    view.submitBatch(batch);
}
Also used : Entity(com.agorria.shootandmove.entities.Entity) Vector2f(com.agorria.shootandmove.math.Vector2f) ArrayList(java.util.ArrayList) Rectangle(com.agorria.shootandmove.math.Rectangle) CollisionInterface(com.agorria.shootandmove.math.CollisionInterface) Drawable(com.agorria.shootandmove.graphics.Drawable) DrawableBatch(com.agorria.shootandmove.graphics.DrawableBatch)

Aggregations

DrawableBatch (com.agorria.shootandmove.graphics.DrawableBatch)5 Drawable (com.agorria.shootandmove.graphics.Drawable)4 ArrayList (java.util.ArrayList)4 Color (com.agorria.shootandmove.graphics.Color)2 TextureAtlas (com.agorria.shootandmove.graphics.TextureAtlas)2 Rectangle (com.agorria.shootandmove.math.Rectangle)2 SuppressLint (android.annotation.SuppressLint)1 Door (com.agorria.shootandmove.entities.Door)1 Entity (com.agorria.shootandmove.entities.Entity)1 Item (com.agorria.shootandmove.entities.Item)1 LockedDoor (com.agorria.shootandmove.entities.LockedDoor)1 Player (com.agorria.shootandmove.entities.Player)1 Robot (com.agorria.shootandmove.entities.Robot)1 Warp (com.agorria.shootandmove.entities.Warp)1 DrawableRectangle (com.agorria.shootandmove.graphics.DrawableRectangle)1 CollisionInterface (com.agorria.shootandmove.math.CollisionInterface)1 Vector2f (com.agorria.shootandmove.math.Vector2f)1 Vector3f (com.agorria.shootandmove.math.Vector3f)1 Menu (com.agorria.shootandmove.menu.Menu)1 MenuCredits (com.agorria.shootandmove.menu.MenuCredits)1