io.flob.blackheart.Level.java Source code

Java tutorial

Introduction

Here is the source code for io.flob.blackheart.Level.java

Source

/*
 *    ______     __         ______     ______     __  __     __  __     ______     ______     ______     ______  
 *   /\  == \   /\ \       /\  __ \   /\  ___\   /\ \/ /    /\ \_\ \   /\  ___\   /\  __ \   /\  == \   /\__  _\ 
 *   \ \  __<   \ \ \____  \ \  __ \  \ \ \____  \ \  _"-.  \ \  __ \  \ \  __\   \ \  __ \  \ \  __<   \/_/\ \/ 
 *    \ \_____\  \ \_____\  \ \_\ \_\  \ \_____\  \ \_\ \_\  \ \_\ \_\  \ \_____\  \ \_\ \_\  \ \_\ \_\    \ \_\ 
 *     \/_____/   \/_____/   \/_/\/_/   \/_____/   \/_/\/_/   \/_/\/_/   \/_____/   \/_/\/_/   \/_/ /_/     \/_/ 
 * 
 *      (August 10th-17th 2013) 
 *      <http://7dfps.calvert.io>
 *
 *      blackheart
 *      Copyright (c) 2013 Robert Calvert <http://robert.calvert.io>
 *
 *      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 2 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 io.flob.blackheart;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector3f;

/**
 *
 * @author rob
 */
public final class Level {

    public static final float grid_size = 1f;
    public static final float texture_bleed_offset = 0.0004f;
    private float floorblood_offset = texture_bleed_offset;
    private float floorblood_offset_bump = 0.0001f;
    public final StateGame _game;
    public final MobBarry _barry;
    private Armoury _start_armoury;
    public ArrayList<ILevelObject> objects_static;
    public ArrayList<ILevelObject> objects_dynamic;
    private final HUD _hud;
    public Statistics _statistics;
    private int display_list = -1;
    private boolean display_list_dirty;
    private int level_number = 1;

    public Level(StateGame game) throws Exception {
        _game = game;
        _barry = new MobBarry(this, new Vector3f(0, 0, 0));
        _hud = new HUD(this);
        load(level_number);
    }

    private void load(int number) throws Exception {
        if (number > _game.number_of_levels) {
            _game._statistics.merge(_statistics);
            _game._core.state(_game._core._game_winner);
        } else {
            _game._core.state(_game);
            level_number = number;
            load_objects();
            _start_armoury = _barry._armoury.clone();
            _barry.yaw(-_barry.yaw());
            _barry.pitch(-_barry.pitch());
            _barry.health(_barry.health_maximum());
            _statistics = new Statistics();
        }
    }

    public int number() {
        return level_number;
    }

    public void complete() throws Exception {
        _game._statistics.merge(_statistics);
        load(level_number + 1);
    }

    public void reload() throws Exception {
        _barry._armoury = _start_armoury;
        load(level_number);
    }

    public void level_editor_refresh() throws Exception {
        if (Misc.running_in_IDE()) {
            Vector3f position = new Vector3f(_barry.position());
            load_objects();
            _barry.position(position);
        }
    }

    private void load_objects() throws Exception {
        floorblood_offset = texture_bleed_offset;
        objects_static = new ArrayList<ILevelObject>();
        objects_dynamic = new ArrayList<ILevelObject>();
        load_layer(1); // Floor
        load_layer(0); // Middle
        load_layer(-1); // Ceiling
        display_list_dirty = true;
    }

    private void load_layer(int layer) throws Exception {
        BufferedImage _objects;
        if (Misc.running_in_IDE()) {
            FileInputStream file = new FileInputStream(Path.base() + "../src/io/flob/" + About.title + "/level/"
                    + level_number + "/" + layer + ".png");
            _objects = ImageIO.read(new BufferedInputStream(file));
        } else {
            _objects = ImageIO.read(new BufferedInputStream(
                    getClass().getResourceAsStream("level/" + level_number + "/" + layer + ".png")));
        }
        for (int z = 0; z < (_objects.getHeight()); z++) {
            for (int x = 0; x < (_objects.getWidth()); x++) {
                int rgb = _objects.getRGB(x, z);
                Vector3f position = new Vector3f(x * Level.grid_size, layer, z * Level.grid_size);
                if (rgb == 0) {
                    continue;
                } else {
                    if (layer == -1) {
                        // Floor
                        if (rgb == -5086909) {
                            objects_static.add(new FloorWood(this, position));
                        } else if (rgb == -12040120) {
                            objects_static.add(new FloorLift(this, position));
                        } else if (rgb == -6984636) {
                            objects_static.add(new FloorLightWood(this, position));
                        } else if (rgb == -12365488) {
                            objects_static.add(new FloorDarkGrey(this, position));
                        } else {
                            Output.error("Level.load_layer(" + layer + ") - Unknow rgb(" + rgb + ")");
                        }
                    } else if (layer == 0) {
                        // Play area
                        if (rgb == -1) {
                            _barry.position(position);
                        } else if (rgb == -4737179) {
                            objects_dynamic.add(new MobPistol(this, position));
                        } else if (rgb == -8499253) {
                            objects_dynamic.add(new MobShotgun(this, position));
                        } else if (rgb == -11185590) {
                            objects_dynamic.add(new MobPrisoner(this, position));
                        } else if (rgb == -8479931) {
                            objects_dynamic.add(new MobZombie(this, position));
                        } else if (rgb == -6127072) {
                            objects_dynamic.add(new MobMachinegun(this, position));
                        } else if (rgb == -12422803) {
                            objects_static.add(new WallBlue(this, position));
                        } else if (rgb == -9345719) {
                            objects_static.add(new WallBluePainting(this, position));
                        } else if (rgb == -10854049) {
                            objects_dynamic.add(new WallSecretBlue(this, position));
                        } else if (rgb == -13679032) {
                            objects_dynamic.add(new DoorBlue(this, position, true));
                        } else if (rgb == -10580589) {
                            objects_dynamic.add(new DoorBlue(this, position, false));
                        } else if (rgb == -12829636) {
                            objects_dynamic.add(new DoorLift(this, position, true));
                        } else if (rgb == -12831178) {
                            objects_dynamic.add(new DoorLift(this, position, false));
                        } else if (rgb == -7325383) {
                            objects_static.add(new WallRed(this, position));
                        } else if (rgb == -12365488) {
                            objects_static.add(new WallGrey(this, position));
                        } else if (rgb == -12434885) {
                            objects_dynamic.add(new WindowBars(this, position, true));
                        } else if (rgb == -10921648) {
                            objects_dynamic.add(new WindowBars(this, position, false));
                        } else if (rgb == -2044210) {
                            objects_dynamic.add(new CollectableHealth(this, position));
                        } else if (rgb == -1387165) {
                            objects_dynamic.add(new CollectableGold(this, position));
                        } else if (rgb == -5881278) {
                            objects_dynamic.add(new WallSecretRed(this, position));
                        } else if (rgb == -14140101) {
                            objects_dynamic.add(new WallSecretGrey(this, position));
                        } else if (rgb == -10461088) {
                            objects_static.add(new WallLiftPanel(this, position));
                        } else if (rgb == -9740706) {
                            objects_static.add(new WallLiftPanelInactive(this, position));
                        } else if (rgb == -8816263) {
                            objects_static.add(new WallLiftSides(this, position));
                        } else if (rgb == -6337203) {
                            objects_static.add(new WallRedDeadInside1(this, position));
                        } else if (rgb == -4107180) {
                            objects_static.add(new WallRedDeadInside2(this, position));
                        } else {
                            Output.error("Level.load_layer(" + layer + ") - Unknow rgb(" + rgb + ")");
                        }

                    } else if (layer == 1) {
                        // Ceiling
                        if (rgb == -9078165) {
                            objects_static.add(new CeilingLightGrey(this, position));
                        } else if (rgb == -12040120) {
                            objects_static.add(new CeilingLift(this, position));
                        } else if (rgb == -12365488) {
                            objects_static.add(new CeilingDarkGrey(this, position));
                        } else {
                            Output.error("Level.load_layer(" + layer + ") - Unknow rgb(" + rgb + ")");
                        }
                    }
                }
            }
        }
    }

    private void load_display_list() throws Exception {
        display_list = GL11.glGenLists(1);
        GL11.glNewList(display_list, GL11.GL_COMPILE);
        for (int count = 0; count < objects_static.size(); count++) {
            objects_static.get(count).tick();
        }
        GL11.glEndList();
        display_list_dirty = false;
    }

    public void tick() throws Exception {

        if (display_list_dirty) {
            load_display_list();
        }

        ByteBuffer temp = ByteBuffer.allocateDirect(16);
        temp.order(ByteOrder.nativeOrder());
        float fog_colour[] = new float[] { 0f, 0f, 0f, 0f };
        GL11.glFogi(GL11.GL_FOG_MODE, GL11.GL_EXP);
        temp.asFloatBuffer().put(fog_colour).flip();
        GL11.glFog(GL11.GL_FOG_COLOR, temp.asFloatBuffer());
        GL11.glFogf(GL11.GL_FOG_DENSITY, 0.25f);
        GL11.glHint(GL11.GL_FOG_HINT, GL11.GL_DONT_CARE);
        GL11.glFogf(GL11.GL_FOG_START, 0);
        GL11.glFogf(GL11.GL_FOG_END, 200);

        _barry.tick();

        try {
            Collections.sort(objects_dynamic, this.sort_objects);
        } catch (Exception ex) {
            Output.error(ex.getMessage());
        }

        if (Debug.collision_boxs) {
            _game._core._display.flush_texture();
            for (int count = 0; count < objects_static.size(); count++) {
                if (objects_static.get(count) instanceof ICollidable) {
                    ICollidable objcet = (ICollidable) objects_static.get(count);
                    objcet.collision_box().render();
                }
            }
            for (int count = 0; count < objects_dynamic.size(); count++) {
                if (objects_dynamic.get(count) instanceof ICollidable) {
                    ICollidable objcet = (ICollidable) objects_dynamic.get(count);
                    objcet.collision_box().render();
                }
            }
            _barry.collision_box().render();
            _barry.ray_picker().collision_box().render();
        }

        GL11.glPushMatrix();
        _game._core._texture.game_atlas.bind();
        if (_game.anaglyph()) {
            GL11.glTranslatef(1 * 0.03f, 0, 0);
            GL11.glColorMask(true, false, false, true);
        }
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glCallList(display_list);
        for (int count = 0; count < objects_dynamic.size(); count++) {
            objects_dynamic.get(count).tick();
        }
        GL11.glEnd();
        if (_game.anaglyph()) {
            GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
            GL11.glColorMask(false, true, true, true);
            GL11.glTranslatef(-1 * 0.03f, 0, 0);
            GL11.glBegin(GL11.GL_QUADS);
            GL11.glCallList(display_list);
            for (int count = 0; count < objects_dynamic.size(); count++) {
                objects_dynamic.get(count)._render();
            }
            GL11.glEnd();
            GL11.glColorMask(true, true, true, true);
        }
        GL11.glPopMatrix();

        for (int count = 0; count < objects_dynamic.size(); count++) {
            if (objects_dynamic.get(count).IRemove()) {
                objects_dynamic.remove(count);
            }
        }

        _hud.tick();

        if (_barry.health() <= 0) {
            _game._core.state(_game._core._game_dead);
        }
    }

    private Comparator<ILevelObject> sort_objects = new Comparator<ILevelObject>() {
        @Override
        public int compare(ILevelObject object1, ILevelObject object2) {
            Double distance1 = object1.player_distance();
            Double distance2 = object2.player_distance();
            // Always push FloorBloods back in the distance stack so that they are rendered first
            if (object1 instanceof FloorBlood) {
                distance1 = distance2 + 0.1f;
            }
            if (object2 instanceof FloorBlood) {
                distance2 = distance1 + 0.1f;
            }
            // Always push IDoors back in the distance stack so that they are rendered first
            // This is behind the FloorBloods
            if (object1 instanceof IDoor) {
                distance1 = distance2 + 0.1f;
            }
            if (object2 instanceof IDoor) {
                distance2 = distance1 + 0.1f;
            }
            return distance2.compareTo(distance1);
        }
    };

    public void _render() throws Exception {
        // assume the texture is already bound
        _barry._look_through();
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glCallList(display_list);
        for (int count = 0; count < objects_dynamic.size(); count++) {
            objects_dynamic.get(count)._render();
        }
        GL11.glEnd();
    }

    public ICollidable collision(ICollidable what) {
        if (Debug.no_clip) {
            if (what.equals(_barry)) {
                return null;
            }
        }
        for (int count = 0; count < objects_static.size(); count++) {
            if (objects_static.get(count) instanceof ICollidable) {
                ICollidable with = (ICollidable) objects_static.get(count);
                if (what != with) {
                    if (what.collision_box().intersects(with.collision_box())) {
                        return with;
                    }
                }
            }
        }
        for (int count = 0; count < objects_dynamic.size(); count++) {
            if (objects_dynamic.get(count) instanceof ICollidable) {
                ICollidable with = (ICollidable) objects_dynamic.get(count);
                if (what != with) {
                    if (what.collision_box().intersects(with.collision_box())) {
                        if (what.equals(_barry)) {
                            if (with instanceof MobPrisoner) {
                                MobPrisoner _object = (MobPrisoner) with;
                                if (_object.following()) {
                                    return null;
                                }
                            }
                        }
                        return with;
                    }
                }
            }
        }
        if (what != _barry) {
            if (what.collision_box().intersects(_barry.collision_box())) {
                return _barry;
            }
        }
        return null;
    }

    // Used to stack the layers better
    // May not work well on some cards.....
    public float floorblood_offset() {
        floorblood_offset += floorblood_offset_bump;
        return floorblood_offset;
    }
}