Added a boss fight and the grappling hook.

This commit is contained in:
josua 2019-09-20 12:32:48 +10:00
parent 51ece50ac0
commit 26d55ab6ca
28 changed files with 714 additions and 37 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

View File

@ -1,6 +1,7 @@
package shootergame.display;
import shootergame.Main;
import shootergame.display.bossbar.BossBars;
import shootergame.entity.player.EntityPlayer;
import shootergame.init.Textures;
import shootergame.inventory.Inventory;
@ -139,6 +140,9 @@ public class DisplayRenderUI
GlHelpers.popMatrix();
}
// Render the boss bars
BossBars.render();
// Render the loaded menu
Main.menu.render();
}

View File

@ -0,0 +1,53 @@
package shootergame.display.bossbar;
import java.util.ArrayList;
import shootergame.init.Textures;
import shootergame.util.gl.GlHelpers;
import shootergame.util.gl.texture.TextureReference;
public class BossBars
{
private static final ArrayList<IBossBar> bossbars = new ArrayList<IBossBar>();
public static void register(IBossBar bossbar) {
bossbars.add(bossbar);
}
public static void render()
{
TextureReference health_fg = Textures.UI_HEALTH_FG;
TextureReference health_bg = Textures.UI_HEALTH_BG;
ArrayList<IBossBar> toRemove = new ArrayList<IBossBar>();
// Render the boss bars
int i = 0;
for(IBossBar bossbar : bossbars)
{
double max_health = bossbar.maxHealth();
double a = 1 - (bossbar.getHealth() / max_health);
GlHelpers.begin();
health_bg.texCoord(0, 1); GlHelpers.vertex2(-3.2, 8.5 - i);
health_bg.texCoord(0, 0); GlHelpers.vertex2(-3.2, 9.0 - i);
health_bg.texCoord(1, 0); GlHelpers.vertex2(3.2, 9.0 - i);
health_bg.texCoord(1, 1); GlHelpers.vertex2(3.2, 8.5 - i);
health_fg.texCoord(0, 1); GlHelpers.vertex2(-3.2, 8.5 - i);
health_fg.texCoord(0, 0); GlHelpers.vertex2(-3.2, 9.0 - i);
health_fg.texCoord(1-a, 0); GlHelpers.vertex2(3.2-a*6.4, 9.0 - i);
health_fg.texCoord(1-a, 1); GlHelpers.vertex2(3.2-a*6.4, 8.5 - i);
GlHelpers.end();
i += 1;
if(!bossbar.displayBossBar()) {
toRemove.add(bossbar);
}
}
for(IBossBar bossbar : toRemove) {
bossbars.remove(toRemove);
}
}
}

View File

@ -0,0 +1,9 @@
package shootergame.display.bossbar;
import shootergame.entity.EntityAlive;
public interface IBossBar extends EntityAlive
{
public String getName();
public boolean displayBossBar();
}

View File

@ -242,7 +242,7 @@ public class Entity implements ITransparentObject
@Override
public void MainLoopUpdate() {
if(!Main.game_paused) {
moveTowards(angle, a[0]/100.0);
moveTowards(Math.toRadians(angle) + 180, a[0]/100.0);
a[0] -= a[0] / 100.0;
}
}

View File

@ -1,5 +1,7 @@
package shootergame.entity;
import shootergame.world.layer.Layer;
public interface EntityAlive
{
public void addHealth(double amount);
@ -10,4 +12,7 @@ public interface EntityAlive
public double maxHealth();
public void setHealth(double health);
public int bloodParticles();
public default void onDeath(Layer layer) {
}
}

View File

@ -0,0 +1,226 @@
package shootergame.entity;
import shootergame.Main;
import shootergame.display.Camera;
import shootergame.display.bossbar.BossBars;
import shootergame.display.bossbar.IBossBar;
import shootergame.init.Items;
import shootergame.init.Textures;
import shootergame.time.GameTimer;
import shootergame.util.gl.texture.TextureReference;
import shootergame.util.math.ItemStack;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.random.OpenSimplexNoise;
import shootergame.util.math.random.RandomHelpers;
import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec3d;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class EntityBoss extends EntityVertical implements IBossBar
{
private boolean moving = false;
private boolean firing = false;
private double max_health = 25000;
private double health = max_health;
private int bullet_frequency = 0;
private int spawn_frequency = 0;
private OpenSimplexNoise noise_gun;
private OpenSimplexNoise noise_walk;
private OpenSimplexNoise noise_spawn;
public EntityBoss(Vec2d pos) {
super(null, new Vec2d(4, 4));
this.isSolid = true;
this.goThroughSolid = false;
this.crossUnWalkable = false;
this.hitbox = 1;
this.noise_gun = new OpenSimplexNoise(rand.nextLong());
this.noise_walk = new OpenSimplexNoise(rand.nextLong());
this.noise_spawn = new OpenSimplexNoise(rand.nextLong());
Main.player.gun_level = 4;
Main.player.defence_level = 4;
Main.player.getInventory().setItem(new ItemStack(Items.HEALTH_POTION, 100, (byte)50), 0);
Main.player.getInventory().setItem(new ItemStack(Items.TNT, 100, (byte)10), 1);
Main.player.getInventory().setItem(new ItemStack(Items.GRAPPLING_HOOK, 100, (byte)2), 2);
BossBars.register(this);
}
@Override
public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer);
double angle = Math.atan2(pos.x - Main.player.pos.x, pos.y - Main.player.pos.y);
this.angle = Math.toDegrees(angle) + 180;
if(this.noise_spawn.eval(GameTimer.getTime() / 5000.0, 0) > 0.2) {
if(spawn_frequency == 0) {
EntityZombie zombie = new EntityZombie();
int r = 2;
zombie.pos = this.pos.add(new Vec2d(
RandomHelpers.randrange(rand, -r, r),
RandomHelpers.randrange(rand, -r, r)));
layer.spawnEntity(zombie);
spawn_frequency = 50;
}
spawn_frequency -= 1;
}
if(this.noise_gun.eval(GameTimer.getTime() / 5000.0, 0) > 0 && !Main.player.dead && !Main.player.in_animation) {
if(bullet_frequency == 0)
{
Vec2d gun_offset = MathHelpers.moveTowards2(1, Math.toRadians(90 + this.angle));
Vec3d pos1 = new Vec3d(pos.x + gun_offset.x, pos.y + gun_offset.y, 1);
double distance_1 = pos1.distance(new Vec3d(pos.x, pos.y, pos1.z));
double angle1_0 = Math.toDegrees(Math.atan2(
pos1.x - Main.player.pos.x, pos1.y - Main.player.pos.y)) + 180;
double angle1_1 = Math.toDegrees(Math.atan2(distance_1, pos1.z - 1)) - 90;
Vec3d pos2 = new Vec3d(pos.x - gun_offset.x, pos.y - gun_offset.y, 1);
double distance_2 = pos2.distance(new Vec3d(pos.x, pos.y, pos2.z));
double angle2_0 = Math.toDegrees(Math.atan2(pos2.x - Main.player.pos.x, pos2.y - Main.player.pos.y)) + 180;
double angle2_1 = Math.toDegrees(Math.atan2(distance_2, pos2.z - 1)) - 90;
layer.spawnEntity(new EntityBullet(pos.add(gun_offset), this, angle1_0, 20, 5, 1000
).withHeight(angle1_1, pos1.z));
layer.spawnEntity(new EntityBullet(pos.subtract(gun_offset), this, angle2_0, 20, 5, 1000
).withHeight(angle2_1, pos2.z));
bullet_frequency = 10;
}
bullet_frequency -= 1;
}
if(this.noise_gun.eval(GameTimer.getTime() / 5000.0, 0) > -0.2) {
this.firing = true;
}
else {
this.firing = false;
}
if(this.noise_walk.eval(GameTimer.getTime() / 5000.0, 0) > -0.4) {
this.moveForward();
this.moving = true;
}
else {
this.moving = false;
}
}
@Override
public void render(Vec2d pos, Camera camera, TextureReference tex, Vec2d size)
{
// Get the boss texture
if(moving && firing) {
tex = Textures.ENTITY_BOSS_WALKING_AND_FIRING;
} else if(moving) {
tex = Textures.ENTITY_BOSS_WALKING;
} else if(firing) {
tex = Textures.ENTITY_BOSS_FIRING;
} else {
tex = Textures.ENTITY_BOSS_IDLE;
}
// Call render
super.render(pos, camera, tex, size);
}
@Override
public void addHealth(double amount) {
this.health += amount;
}
@Override
public void removeHealth(double amount) {
this.health -= amount;
}
@Override
public double getHealth() {
return health;
}
@Override
public void resetHealth() {
this.health = max_health;
}
@Override
public void clearHealth() {
this.health = 0;
}
@Override
public double maxHealth() {
return max_health;
}
@Override
public void setHealth(double health) {
this.health = health;
}
@Override
public int bloodParticles() {
return 5;
}
@Override
public String getName() {
return "Final Boss";
}
@Override
public boolean displayBossBar() {
return health >= 0;
}
@Override
public void moveTowards(double angle) {
this.moveTowards(angle, 0.02);
}
@Override
public void moveBackward() {
this.moveBackward(0.02);
}
@Override
public void moveForward() {
this.moveForward(0.02);
}
@Override
public void onDeath(Layer layer) {
IBossBar.super.onDeath(layer);
/*
Drop some powerful loot
*/
// Pick level 5 defence or level 5 gun upgrade
ItemStack stack;
if(rand.nextBoolean()) {
stack = new ItemStack(Items.DEFENCE_UPGRADE, 1, (byte)6);
} else {
stack = new ItemStack(Items.GUN_UPGRADE, 1, (byte)6);
}
// Spawn the loot
layer.spawnEntity(new EntityItem(pos.copy(), stack));
layer.spawnEntity(new EntityItem(pos.copy(), new ItemStack(
Items.HEALTH_POTION, RandomHelpers.randrange(rand, 20), (byte)50)));
layer.spawnEntity(new EntityItem(pos.copy(), new ItemStack(
Items.AMMO, RandomHelpers.randrange(rand, 200), (byte)50)));
layer.spawnEntity(new EntityItem(pos.copy(), new ItemStack(Items.GRAPPLING_HOOK, 1, (byte)2)));
}
}

View File

@ -21,7 +21,10 @@ public class EntityBullet extends EntityParticle
private double damage;
private int breakchance;
public EntityBullet(Vec2d pos, Entity parent, double angle, double damage, int breakchance) {
private double height = 0.2;
private double height_angle = 0;
public EntityBullet(Vec2d pos, Entity parent, double angle, double damage, int breakchance, int despawn_time) {
super(0.2, 0.4);
// Store some specified values
@ -30,17 +33,39 @@ public class EntityBullet extends EntityParticle
this.parent = parent;
this.damage = damage;
this.breakchance = breakchance;
this.time = despawn_time;
// Play the gun sound
Sounds.GUN.play(new Vec3d(pos.x, pos.y, 0.4), 2);
}
public EntityBullet withHeight(double angle, double height) {
this.height_angle = angle;
this.height = height;
return this;
}
@Override
public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer);
// Move forward in the bullets angle, very quickly
this.moveForward(0.2);
Vec3d pos3 = MathHelpers.moveTowards3(0.2, new Vec2d(Math.toRadians(this.angle),
Math.toRadians(this.height_angle))).add(
new Vec3d(pos.x, pos.y, height));
height = pos3.z;
if(moveIsLegal(new Vec2d(pos3.x, pos.y))) {
pos.x = pos3.x;
} if(moveIsLegal(new Vec2d(pos.x, pos3.x))) {
pos.y = pos3.y;
}
if(height < 0 || height > 16) {
kill();
return;
}
chunk = layer.getChunk(pos);
// Is the bullets new position intersecting a solid object
@ -79,10 +104,10 @@ public class EntityBullet extends EntityParticle
}
// Loop over the nearby entities
for(Entity e : layer.getNearbyEntities(pos, 0.5))
for(Entity e : layer.getNearbyEntities(pos, 1))
{
// Is this entity alive and not the parent
if(e instanceof EntityAlive && e != parent)
if(e instanceof EntityAlive && e != parent && e.pos.squareDistance(this.pos) < e.hitbox)
{
// Get the alive entity
EntityAlive ea = (EntityAlive)e;
@ -107,10 +132,10 @@ public class EntityBullet extends EntityParticle
}
}
// Increase time
time++;
// Decrease time
time -= 1;
if(time > 60) {
if(time <= 0) {
chunk.killEntity(this);
}
}
@ -123,6 +148,9 @@ public class EntityBullet extends EntityParticle
MathHelpers.floor(pos.x), MathHelpers.floor(pos.y)));
GlHelpers.color3(1 * light, 0.8 * light, 0.3 * light);
// Set the height
this.setHeight(height);
// Call super
super.render(pos, camera);
GlHelpers.color3(1, 1, 1);

View File

@ -0,0 +1,88 @@
package shootergame.entity;
import shootergame.Main;
import shootergame.display.Camera;
import shootergame.entity.player.EntityPlayer;
import shootergame.init.Layers;
import shootergame.init.Textures;
import shootergame.util.gl.GlHelpers;
import shootergame.util.math.vec.Vec2d;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
import shootergame.world.layer.layergen.LayerGenRememberPlayerPos;
public class EntityGrapplingHook extends EntityVertical
{
private int layerId;
private double height;
private Entity entity;
public EntityGrapplingHook(Vec2d pos, int layerId, Entity entity) {
super(Textures.ENTITY_GRAPPLING_HOOK, new Vec2d(1, 16));
this.layerId = layerId;
this.height = -16;
this.entity = entity;
this.pos = pos;
if(entity instanceof EntityPlayer) {
EntityPlayer ep = (EntityPlayer)entity;
ep.in_animation = true;
}
}
@Override
public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer);
if(entity instanceof EntityHeight) {
EntityHeight ea = (EntityHeight)entity;
if(height >= -8)
{
double h = ea.getHeight();
ea.setHeight(h + 0.02);
if(entity instanceof EntityPlayer) {
EntityPlayer ep = (EntityPlayer)entity;
ep.moving = true;
}
if(h >= 8)
{
ea.setHeight(0);
Main.world.setLayer(Layers.getLayer(layerId));
if(entity instanceof EntityPlayer)
{
EntityPlayer ep = (EntityPlayer)entity;
ep.in_animation = false;
ep.moving = false;
}
if(layer instanceof LayerGenRememberPlayerPos) {
LayerGenRememberPlayerPos lgrpp = (LayerGenRememberPlayerPos)layer;
entity.pos = lgrpp.getPlayerPos();
}
kill();
return;
}
}
else {
height += 0.05;
}
}
}
@Override
public void render(Vec2d pos, Camera camera) {
GlHelpers.pushMatrix();
GlHelpers.translate(0, 0, height);
super.render(pos, camera);
GlHelpers.popMatrix();
}
}

View File

@ -0,0 +1,7 @@
package shootergame.entity;
public interface EntityHeight
{
public double getHeight();
public void setHeight(double height);
}

View File

@ -24,6 +24,10 @@ public class EntityParticle extends Entity
this.size = size;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public void tick(Chunk chunk, Layer layer) {
super.tick(chunk, layer);

View File

@ -44,7 +44,7 @@ public class EntityZombie extends EntityVertical implements EntityAlive
this.angle += noise_movement.eval(time, 0)*80;
this.moveForward();
if(noise_gun_fire.eval(time, 0) > 0)
if(noise_gun_fire.eval(time, 0) > 0 && !Main.player.dead && !Main.player.in_animation)
{
gun_interval += 1;
gun_interval %= 10;
@ -58,7 +58,7 @@ public class EntityZombie extends EntityVertical implements EntityAlive
// Fire the gun
int d = (int)(1 + gun_level / 5.0);
int b = (int)(1 - gun_level / 5.0);
layer.spawnEntity(new EntityBullet(pos.copy(), this, angle_gun, 20*d*d, 5*b*b));
layer.spawnEntity(new EntityBullet(pos.copy(), this, angle_gun, 20*d*d, 5*b*b, 60));
}
}
@ -72,7 +72,7 @@ public class EntityZombie extends EntityVertical implements EntityAlive
}
@Override
public void moveBackward(double speed) {
public void moveBackward() {
super.moveBackward(0.06);
}

View File

@ -6,6 +6,7 @@ import shootergame.display.Camera;
import shootergame.entity.Entity;
import shootergame.entity.EntityAlive;
import shootergame.entity.EntityBullet;
import shootergame.entity.EntityHeight;
import shootergame.entity.EntityInventory;
import shootergame.entity.EntityItem;
import shootergame.entity.EntityVertical;
@ -20,7 +21,7 @@ import shootergame.util.math.vec.Vec2i;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class EntityPlayer extends EntityVertical implements EntityAlive, EntityInventory
public class EntityPlayer extends EntityVertical implements EntityAlive, EntityInventory, EntityHeight
{
public boolean MOVE_FORWARD = false;
public boolean MOVE_BACKWARD = false;
@ -185,7 +186,7 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
int d = (int)(1 + gun_level / 4.0);
int b = (int)(1 + gun_level / 4.0);
Main.world.getLayer().spawnEntity(new EntityBullet(pos.copy(), this, angle + this.angle,
20*d*d, 5/b));
20*d*d, 5/b, 60));
}
}
@ -262,4 +263,14 @@ public class EntityPlayer extends EntityVertical implements EntityAlive, EntityI
public int bloodParticles() {
return 5;
}
@Override
public double getHeight() {
return height;
}
@Override
public void setHeight(double height) {
this.height = height;
}
}

View File

@ -5,6 +5,7 @@ import shootergame.items.ItemAmmo;
import shootergame.items.ItemDefenceUpgrade;
import shootergame.items.ItemEmpty;
import shootergame.items.ItemFlare;
import shootergame.items.ItemGrapplingHook;
import shootergame.items.ItemGunUpgrade;
import shootergame.items.ItemHealthPotion;
import shootergame.items.ItemLantern;
@ -20,4 +21,5 @@ public class Items
public static final Item TNT = new ItemTnt("tnt");
public static final Item LANTERN = new ItemLantern("lantern");
public static final Item FLARE = new ItemFlare("flare");
public static final Item GRAPPLING_HOOK = new ItemGrapplingHook("grappling_hook");
}

View File

@ -4,10 +4,11 @@ import java.util.ArrayList;
import java.util.Random;
import shootergame.Main;
import shootergame.util.math.vec.Vec2d;
import shootergame.world.World;
import shootergame.world.layer.Layer;
import shootergame.world.layer.layergen.LayerGenBossArena;
import shootergame.world.layer.layergen.LayerGenCaves;
import shootergame.world.layer.layergen.LayerGenEarth;
import shootergame.world.layer.layergen.LayerGenLavaCaves;
public class Layers
@ -17,7 +18,7 @@ public class Layers
public static void init(long seed)
{
// Create all the layers
EARTH = new Layer(new Random(seed), new LayerGenEarth(), 0);
EARTH = new Layer(new Random(seed), new LayerGenBossArena(), 0);
CAVES = new Layer(new Random(seed), new LayerGenCaves(), 1);
LAVA_CAVES = new Layer(new Random(seed), new LayerGenLavaCaves(), 2);

View File

@ -40,6 +40,33 @@ public class Textures
public static final TextureReference TILE_CHEST = texmap.getTextureReference(2, 3, 4, 5);
public static final TextureReference ENTITY_FLARE = texmap.getTextureReference(6, 7, 15, 16);
public static final TextureReference ENTITY_DUMMY = texmap.getTextureReference(7, 8, 15, 16);
public static final TextureReference TILE_BOSS_PORTAL = texmap.getTextureReference(18, 20, 0, 2);
public static final TextureReference ITEM_GRAPPLING_HOOK = texmap.getTextureReference(18, 19, 2, 3);
public static final TextureReference ENTITY_GRAPPLING_HOOK = texmap.getTextureReference(17, 18, 0, 16);
public static final AnimationReference ENTITY_BOSS_IDLE = new AnimationReference(50,
texmap.getTextureReference(20, 22, 0, 2),
texmap.getTextureReference(22, 24, 0, 2),
texmap.getTextureReference(24, 26, 0, 2),
texmap.getTextureReference(26, 28, 0, 2));
public static final AnimationReference ENTITY_BOSS_FIRING = new AnimationReference(50,
texmap.getTextureReference(20, 22, 2, 4),
texmap.getTextureReference(22, 24, 2, 4),
texmap.getTextureReference(24, 26, 2, 4),
texmap.getTextureReference(26, 28, 2, 4));
public static final AnimationReference ENTITY_BOSS_WALKING = new AnimationReference(50,
texmap.getTextureReference(20, 22, 4, 6),
texmap.getTextureReference(22, 24, 4, 6),
texmap.getTextureReference(24, 26, 4, 6),
texmap.getTextureReference(26, 28, 4, 6));
public static final AnimationReference ENTITY_BOSS_WALKING_AND_FIRING = new AnimationReference(50,
texmap.getTextureReference(20, 22, 6, 8),
texmap.getTextureReference(22, 24, 6, 8),
texmap.getTextureReference(24, 26, 6, 8),
texmap.getTextureReference(26, 28, 6, 8));
public static final AnimationReference TILE_LANTERN = new AnimationReference(10,
texmap.getTextureReference(8, 9, 15, 16),

View File

@ -17,6 +17,7 @@ import shootergame.tiles.TileStone;
import shootergame.tiles.TileTree;
import shootergame.tiles.TileVoid;
import shootergame.tiles.TileWall;
import shootergame.tiles.TileWallUnbreakable;
import shootergame.tiles.TileWater;
import shootergame.tiles.TileWaterFlow;
@ -40,4 +41,5 @@ public class Tiles
public static final Tile LADDER_UP = new TileLadderUp("ladder_up");
public static final Tile CHEST = new TileChest("chest");
public static final Tile LANTERN = new TileLantern("lantern");
public static final Tile WALL_UNBREAKABLE = new TileWallUnbreakable("wall_unbreakable");
}

View File

@ -22,4 +22,9 @@ public class ItemFlare extends Item
layer.spawnEntity(new EntityFlare(entity.pos.copy(), entity.angle));
}
@Override
public String getName(short meta) {
return "Flare";
}
}

View File

@ -0,0 +1,37 @@
package shootergame.items;
import shootergame.Main;
import shootergame.entity.Entity;
import shootergame.entity.EntityGrapplingHook;
import shootergame.init.Layers;
import shootergame.init.Textures;
import shootergame.util.math.ItemStack;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.vec.Vec2d;
import shootergame.world.World;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class ItemGrapplingHook extends Item
{
public ItemGrapplingHook(String id) {
super(id);
this.texture = Textures.ITEM_GRAPPLING_HOOK;
}
@Override
public String getName(short meta) {
return "Grappling Hook";
}
@Override
public void onAction(ItemStack stack, Layer layer, Chunk chunk, Entity entity) {
super.onAction(stack, layer, chunk, entity);
Vec2d pos = entity.pos.add(MathHelpers.moveTowards2(0.01, Math.toRadians(entity.angle)));
layer.spawnEntity(new EntityGrapplingHook(pos, stack.meta, entity));
}
}

View File

@ -28,4 +28,9 @@ public class ItemLantern extends Item
}
}
@Override
public String getName(short meta) {
return "Lantern";
}
}

View File

@ -0,0 +1,12 @@
package shootergame.tiles;
public class TileWallUnbreakable extends TileWall
{
public TileWallUnbreakable(String id) {
super(id);
this.unbreakable = true;
}
}

View File

@ -25,10 +25,10 @@ public class VerticalRender
// Render the tile
GlHelpers.begin();
tex.texCoord(1, 1); GlHelpers.vertex3(0.5-w, 0.5, 0);
tex.texCoord(0, 1); GlHelpers.vertex3(0.5+w, 0.5, 0);
tex.texCoord(0, 0); GlHelpers.vertex3(0.5+w, 0.5, h);
tex.texCoord(1, 0); GlHelpers.vertex3(0.5-w, 0.5, h);
tex.texCoord(0, 1); GlHelpers.vertex3(0.5-w, 0.5, 0);
tex.texCoord(1, 1); GlHelpers.vertex3(0.5+w, 0.5, 0);
tex.texCoord(1, 0); GlHelpers.vertex3(0.5+w, 0.5, h);
tex.texCoord(0, 0); GlHelpers.vertex3(0.5-w, 0.5, h);
GlHelpers.end();
// Pop the matrix

View File

@ -33,12 +33,14 @@ public class Chunk
public ArrayList<Entity> entities = new ArrayList<Entity>();
private Layer layer;
private Vec2i c_pos;
public boolean dirty;
public Chunk(Layer layer, Vec2i c_pos, Random rand)
{
// Set some specified values
this.layer = layer;
this.c_pos = c_pos;
this.dirty = false;
// Loop over all the tiles in the chunk
for(int i=0;i<CHUNK_INDEX;i++)
@ -109,6 +111,7 @@ public class Chunk
// Kill the entity if it should be dead and continue to the next loop iteration
if(ea.getHealth() < 0) {
ea.onDeath(layer);
entities.remove(i);
continue;
}
@ -145,6 +148,7 @@ public class Chunk
// Set the back tile
this.tiles_back[id] = tile.tile;
this.tiles_back_meta[id] = tile.meta;
this.dirty = true;
}
public void setFrontTile(TileState tile, Vec2i pos)
@ -163,6 +167,7 @@ public class Chunk
// Set the front tile
this.tiles_front[id] = tile.tile;
this.tiles_front_meta[id] = tile.meta;
this.dirty = true;
}
public TileState getBackTile(Vec2i pos)
@ -206,6 +211,7 @@ public class Chunk
public void breakBackTile(Vec2i pos)
{
TileState ts = getBackTile(pos);
this.dirty = true;
if(!ts.tile.unbreakable) {
setBackTile(layer.layergen.getTileDestroyed(), pos);
@ -215,6 +221,19 @@ public class Chunk
}
}
public void breakFrontTile(Vec2i pos)
{
TileState ts = getFrontTile(pos);
this.dirty = true;
if(!ts.tile.unbreakable) {
setFrontTile(Tiles.VOID.getDefaultState(), pos);
for(int i=0;i<20;i++) {
spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts));
}
}
}
public double getLightLevel(int id) {
return tiles_lighting[id] / (double)Byte.MAX_VALUE;
}
@ -245,18 +264,6 @@ public class Chunk
setLightLevel(light, id);
}
public void breakFrontTile(Vec2i pos)
{
TileState ts = getFrontTile(pos);
if(!ts.tile.unbreakable) {
setFrontTile(Tiles.VOID.getDefaultState(), pos);
for(int i=0;i<20;i++) {
spawnEntity(new ParticleBreak(new Vec2d(pos.x+0.5, pos.y+0.5), ts));
}
}
}
public void killEntity(Entity e) {
entities.remove(e);
}

View File

@ -3,6 +3,7 @@ package shootergame.world.layer;
import java.util.ArrayList;
import java.util.Random;
import bdf.types.BdfObject;
import shootergame.Main;
import shootergame.display.Camera;
import shootergame.entity.Entity;
@ -18,6 +19,7 @@ import shootergame.world.layer.layergen.LayerGen;
public class Layer
{
public Map2D<Chunk> chunks;
private Map2D<Chunk> dirty_chunks;
public LayerGen layergen;
private Random rand;
private long seed;
@ -30,6 +32,7 @@ public class Layer
this.seed = rand.nextLong();
this.rand = new Random();
this.chunks = new Map2D<Chunk>(layergen);
this.dirty_chunks = new Map2D<Chunk>(layergen);
this.id = id;
}
@ -54,6 +57,7 @@ public class Layer
{
// Tick every entity and every tile in every loaded chunk
for(Map2DElement<Chunk> e : chunks) {
layergen.tickLayer(this, e.o);
e.o.tickEntities();
e.o.tickRandomly();
}
@ -158,16 +162,34 @@ public class Layer
}
public void loadChunk(Vec2i pos)
{
// Has the chunk been saved for later
if(dirty_chunks.contains(pos)) {
chunks.set(pos, dirty_chunks.get(pos));
}
else
{
// Create a unique seed specific to this chunk
long cseed = new Random(pos.x).nextLong() + new Random(pos.y).nextLong() + seed;
// Create and generate the chunk
Chunk chunk = new Chunk(this, pos, rand);
chunks.set(pos, chunk);
layergen.generateChunk(chunk, this, seed, new Random(cseed), pos);
chunk.dirty = false;
}
}
public void unloadChunk(Vec2i pos) {
public void unloadChunk(Vec2i pos)
{
// Store the chunk if its a dirty chunk
Chunk chunk = chunks.get(pos);
if(chunk.dirty) {
dirty_chunks.set(pos, chunk);
}
// Remove the chunk
chunks.remove(pos);
}

View File

@ -19,4 +19,7 @@ public abstract class LayerGen implements IMap2D<Chunk>
public Chunk getEmpty(Vec2i pos) {
return Chunk.CHUNK_EMPTY;
}
public void tickLayer(Layer layer, Chunk chunk) {
}
}

View File

@ -0,0 +1,109 @@
package shootergame.world.layer.layergen;
import java.util.Random;
import shootergame.entity.EntityBoss;
import shootergame.entity.player.EntityPlayer;
import shootergame.init.Tiles;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.TileState;
import shootergame.util.math.random.RandomHelpers;
import shootergame.util.math.vec.Vec2d;
import shootergame.util.math.vec.Vec2i;
import shootergame.world.chunk.Chunk;
import shootergame.world.layer.Layer;
public class LayerGenBossArena extends LayerGen implements LayerGenRememberPlayerPos
{
private final Vec2i center = new Vec2i(0, 0);
private final int size = 10;
private Vec2d player_pos = new Vec2d(0, 0);
@Override
public void generateChunk(Chunk chunk, Layer layer, long seed, Random rand, Vec2i pos)
{
// Fill with stone
for(int i=0;i<Chunk.CHUNK_INDEX;i++) {
chunk.setBackTile(getTileDestroyed(), i);
}
for(int x=0;x<16;x++) {
for(int y=0;y<16;y++)
{
// Get the tile position
Vec2i tpos = new Vec2i(pos.x * 16 + x, pos.y * 16 + y);
// Arena walls
if(tpos.squareDistance(center) > size) {
chunk.setBackTile(Tiles.WALL_UNBREAKABLE.getDefaultState(), tpos);
}
else if(tpos.squareDistance(center) == size)
{
// Arena decoration wall
if(MathHelpers.positive(tpos.x) == MathHelpers.positive(tpos.y)) {
chunk.setBackTile(Tiles.WALL_UNBREAKABLE.getDefaultState(), tpos);
}
// Arena lava well
else {
chunk.setFrontTile(Tiles.LAVA.getDefaultState(), tpos);
}
}
// Arena lava well
else if(
MathHelpers.positive(tpos.x) > size - 2 &&
MathHelpers.positive(tpos.y) > size - 2) {
chunk.setFrontTile(Tiles.LAVA.getDefaultState(), tpos);
}
if(tpos.x == 0 && tpos.y == 0) {
chunk.spawnEntity(new EntityBoss(new Vec2d(0, 0)));
}
}
}
int t = 16;
for(int i=0;i<t;i++)
{
Vec2i lava_flow_pos = new Vec2i(
RandomHelpers.randrange(rand, 16),
RandomHelpers.randrange(rand, 16));
if(
chunk.getFrontTile(lava_flow_pos).tile == Tiles.VOID &&
chunk.getBackTile(lava_flow_pos).tile == getTileDestroyed().tile) {
chunk.setFrontTile(Tiles.LAVA_FLOW.getDefaultState(), lava_flow_pos);
}
}
}
@Override
public void spawnEntities(Layer layer, Random rand) {
// TODO Auto-generated method stub
}
@Override
public TileState getTileDestroyed() {
return Tiles.STONE.getDefaultState();
}
@Override
public double getLightLevel() {
return 0;
}
@Override
public Vec2d getPlayerPos() {
return player_pos;
}
@Override
public void spawnPlayer(EntityPlayer player) {
this.player_pos = player.pos.copy();
player.pos = new Vec2d(0, 0);
}
}

View File

@ -0,0 +1,10 @@
package shootergame.world.layer.layergen;
import shootergame.entity.player.EntityPlayer;
import shootergame.util.math.vec.Vec2d;
public interface LayerGenRememberPlayerPos
{
public Vec2d getPlayerPos();
public void spawnPlayer(EntityPlayer player);
}