diff --git a/core/assets/Fragment.frag b/core/assets/Fragment.frag index 74b22d3..4cc1b04 100644 --- a/core/assets/Fragment.frag +++ b/core/assets/Fragment.frag @@ -40,6 +40,10 @@ void main() { brightest = brightest + dis2Light2 - brightest * dis2Light2; } texColor.rgb = texColor.rgb * (sin(pow(brightest, 10) * M_PI / 2)); + + //apply torchlight tint + texColor.b = texColor.b * 0.7; + texColor.g = texColor.g * 0.9; //final color gl_FragColor = texColor * vColor; } diff --git a/core/assets/env.png b/core/assets/env.png index 4dcaac0..6edb7ef 100644 Binary files a/core/assets/env.png and b/core/assets/env.png differ diff --git a/core/assets/testmap.tmx b/core/assets/testmap.tmx index bedb038..3df5062 100644 --- a/core/assets/testmap.tmx +++ b/core/assets/testmap.tmx @@ -1,5 +1,5 @@ - + @@ -167,7 +167,6 @@ - @@ -183,6 +182,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -369,47 +410,160 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/com/toasted/chuck/ChuckGame.java b/core/src/com/toasted/chuck/ChuckGame.java index ea9a4ba..35f0d32 100644 --- a/core/src/com/toasted/chuck/ChuckGame.java +++ b/core/src/com/toasted/chuck/ChuckGame.java @@ -29,7 +29,7 @@ public class ChuckGame extends ApplicationAdapter implements InputProcessor{ Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); level.draw(graphics); -// System.out.println("FPS:" + Gdx.graphics.getFramesPerSecond()); + System.out.println("FPS:" + Gdx.graphics.getFramesPerSecond()); } diff --git a/core/src/com/toasted/chuck/Graphics.java b/core/src/com/toasted/chuck/Graphics.java index f32cd30..1182a60 100644 --- a/core/src/com/toasted/chuck/Graphics.java +++ b/core/src/com/toasted/chuck/Graphics.java @@ -5,7 +5,9 @@ import java.util.ArrayList; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; @@ -24,7 +26,7 @@ public class Graphics { final float orthoScale = orthoX / (float)getWidth(); public float lightValueMultiplier = 1f; // for testing fade out private static int MAX_LIGHTS = 50; - + private static Texture textureMap; ShaderProgram shader = new ShaderProgram(VERTEX, FRAGMENT); public Graphics(){ cam = new OrthographicCamera(); @@ -77,17 +79,26 @@ public class Graphics { if(lights.size() > MAX_LIGHTS){ // if there are too many to do } else { - shader.setUniformi("u_actualLights", lights.size()); - shader.setUniformf("u_ambientLight", Light.VAL_AMBIENT); + int loc = shader.getUniformLocation("u_lightCoord[0]"); int locIn = shader.getUniformLocation("u_lightIntensity[0]"); + int nullLights = 0; for(int i = 0;i < lights.size();i++){ - + if(lights.get(i) == null || !lights.get(i).isEmitting()){ + nullLights++; + continue; + } Vector3 v3 = cam.project(new Vector3(lights.get(i).getX(), lights.get(i).getY(), 0)); Vector2 v = new Vector2(v3.x, v3.y); shader.setUniformf(loc + i, v); shader.setUniformf(locIn + i, lights.get(i).getIntensity() * lightValueMultiplier); } + shader.setUniformi("u_actualLights", lights.size() - nullLights); + shader.setUniformf("u_ambientLight", Light.VAL_AMBIENT); } } + public static TextureRegion getSubTexture(int i){ + if(textureMap == null) textureMap = new Texture("env.png"); + return new TextureRegion(textureMap, (i % 8) * 16, (i / 8) * 16, 16, 16); + } } diff --git a/core/src/com/toasted/chuck/Level.java b/core/src/com/toasted/chuck/Level.java index f4eef1f..25b9b2c 100644 --- a/core/src/com/toasted/chuck/Level.java +++ b/core/src/com/toasted/chuck/Level.java @@ -15,8 +15,10 @@ import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import com.toasted.chuck.entities.Entity; +import com.toasted.chuck.entities.EntityBat; import com.toasted.chuck.entities.EntityBox; import com.toasted.chuck.entities.EntityPlayer; +import com.toasted.chuck.entities.EntityPressurePad; import com.toasted.chuck.entities.EntityTorch; public class Level { @@ -36,7 +38,7 @@ public class Level { zSorter = new Comparator(){ public int compare(Entity arg0, Entity arg1) { - return (int) Math.signum(arg1.getY() - arg0.getY()); + return (int) Math.signum(arg1.getZSortValue() - arg0.getZSortValue()); } @@ -132,12 +134,19 @@ public class Level { Vector2 t = new Vector2(); t = r.getCenter(t); Entity newEntity = null; - if(o.getProperties().get("type").equals("torch")){ + String type = (String) o.getProperties().get("type"); + if(type.equals("torch")){ newEntity = new EntityTorch(t.x - r.getWidth() / 2, t.y - r.getHeight() / 2); } - if(o.getProperties().get("type").equals("box")){ + if(type.equals("box")){ newEntity = new EntityBox(t.x - r.getWidth() / 2, t.y - r.getHeight() / 2); } + if(type.equals("pressurePad")){ + newEntity = new EntityPressurePad(t.x - r.getWidth() / 2, t.y - r.getHeight() / 2); + } + if(type.equals("bat")){ + newEntity = new EntityBat(r.x, r.y); + } if(listToAdd == null){ spawnEntity(newEntity); } else { diff --git a/core/src/com/toasted/chuck/Light.java b/core/src/com/toasted/chuck/Light.java index ce01412..9b6f17d 100644 --- a/core/src/com/toasted/chuck/Light.java +++ b/core/src/com/toasted/chuck/Light.java @@ -9,6 +9,7 @@ public class Light { private static Vector2 tmp = new Vector2(); private Vector2 position; private float intensity = 1; + private boolean isEmitting = true; public Light(float x, float y, float intensity){ position = new Vector2(x, y); this.intensity = intensity; @@ -28,5 +29,13 @@ public class Light { public float getIntensity(){ return intensity; } - + public void setIntensity(float value){ + intensity = value; + } + public boolean isEmitting(){ + return isEmitting; + } + public void setEmitting(boolean state){ + isEmitting = state; + } } diff --git a/core/src/com/toasted/chuck/entities/Entity.java b/core/src/com/toasted/chuck/entities/Entity.java index 4909135..5fb76fd 100644 --- a/core/src/com/toasted/chuck/entities/Entity.java +++ b/core/src/com/toasted/chuck/entities/Entity.java @@ -16,12 +16,22 @@ public abstract class Entity { protected float flyLength; protected boolean isChuckable = true; protected boolean shouldDrawSelf = true; + protected boolean isHostile = false; + protected float stunTimer = 0; protected float weight = 0; //used for destruction capabilities and pressure plate triggering public Entity(){ + } + public Entity(float x, float y){ + position = new Vector2(x, y); + collision = new Rectangle(x, y, 16, 16); } public abstract void update(float delta, Level lvl); protected Rectangle doCollisions(float delta, ArrayList collisions){ + if(stunTimer > 0) { + stunTimer -= delta; + return null; + } Rectangle collidedWith = null; position.x += velocity.x * delta; @@ -87,4 +97,10 @@ public abstract class Entity { public EntityController getController(){ return controller; } + public float getZSortValue(){ + return getY(); + } + public void stun(float duration){ + this.stunTimer = duration; + } } diff --git a/core/src/com/toasted/chuck/entities/EntityBat.java b/core/src/com/toasted/chuck/entities/EntityBat.java new file mode 100644 index 0000000..a9a8f5e --- /dev/null +++ b/core/src/com/toasted/chuck/entities/EntityBat.java @@ -0,0 +1,48 @@ +package com.toasted.chuck.entities; + +import java.util.Random; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Rectangle; +import com.toasted.chuck.Graphics; +import com.toasted.chuck.Level; + +public class EntityBat extends Entity{ + private static final float MOVE_SPEED = 40f; + private TextureRegion[] animation = new TextureRegion[]{Graphics.getSubTexture(20), Graphics.getSubTexture(21)}; + private float timeToPickNextDirection = 0f; + private float animationSpeed = .05f; + private float animationTimer = animationSpeed; + + private int animationFrame = 0; + private Random rand = new Random(); + + public EntityBat(float x, float y){ + super(x, y); + isChuckable = false; + isHostile = true; + } + + public void update(float delta, Level lvl) { + Rectangle collide = doCollisions(delta, lvl.getCollisions()); + //wandering ai + timeToPickNextDirection -= delta; + if(timeToPickNextDirection <= 0 || collide != null){ + float nextDirection = rand.nextFloat(); + timeToPickNextDirection = rand.nextFloat() * 1.5f; + velocity.x = (float)Math.cos(nextDirection * Math.PI * 2f) * MOVE_SPEED; + velocity.y = (float)Math.sin(nextDirection * Math.PI * 2f) * MOVE_SPEED; + } + animationTimer -= delta; + if(animationTimer <= 0){ + animationTimer = animationSpeed; + animationFrame++; + } + + } + + public void draw(Graphics g) { + g.getBatch().draw(animation[animationFrame % 2], getX(), getY()); + } + +} diff --git a/core/src/com/toasted/chuck/entities/EntityBox.java b/core/src/com/toasted/chuck/entities/EntityBox.java index 8b0ae62..d9b9130 100644 --- a/core/src/com/toasted/chuck/entities/EntityBox.java +++ b/core/src/com/toasted/chuck/entities/EntityBox.java @@ -12,10 +12,7 @@ public class EntityBox extends Entity{ Texture shadow = new Texture("shadow.png"); public EntityBox(float x, float y){ - super(); - position.x = x; - position.y = y; - collision = new Rectangle(x, y, 16, 16); + super(x, y); weight = 1; } public void update(float delta, Level lvl) { @@ -31,6 +28,16 @@ public class EntityBox extends Entity{ lvl.revealSecretRoom(layerOpened); } } + if(flyLength > 0){ + //can hit enemies while in air + for(Entity e: lvl.getEntities()){ + if(e.isHostile && e.collision.overlaps(collision)){ + velocity.x = 0; + velocity.y = 0; + e.stun(4f); + } + } + } } public void draw(Graphics g) { diff --git a/core/src/com/toasted/chuck/entities/EntityPressurePad.java b/core/src/com/toasted/chuck/entities/EntityPressurePad.java new file mode 100644 index 0000000..ae55a12 --- /dev/null +++ b/core/src/com/toasted/chuck/entities/EntityPressurePad.java @@ -0,0 +1,62 @@ +package com.toasted.chuck.entities; + +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.toasted.chuck.Graphics; +import com.toasted.chuck.Level; +import com.toasted.chuck.Light; +import com.toasted.chuck.LightEmitter; + +public class EntityPressurePad extends Entity implements LightEmitter{ + + private final float TRIGGER_WEIGHT = .75f; + + + private TextureRegion art = Graphics.getSubTexture(16); + private TextureRegion pressed = Graphics.getSubTexture(24); + private Light indicator; + private boolean depressed = false; + public EntityPressurePad(float x, float y){ + super(x, y); + indicator = new Light(x + collision.width / 2, y + collision.height / 2, 2f); + + indicator.setEmitting(false); + isChuckable = false; + + } + @Override + public void update(float delta, Level lvl) { + boolean foundTrigger = false; + for(Entity e: lvl.getEntities()){ + if(e.weight > TRIGGER_WEIGHT && e.flyLength <= 0){ + if(e.collision.overlaps(collision)){ + foundTrigger = true; + break; + } + } + } + if(foundTrigger) { +// indicator.setEmitting(true); + depressed = true; + } else { + depressed = false; +// indicator.setEmitting(false); + } + } + + @Override + public void draw(Graphics g) { + g.getBatch().draw(depressed ? pressed : art, position.x, position.y); + + } + public float getZSortValue(){ + return super.getZSortValue() + 1000000; + } + @Override + public Light getLight() { + return indicator; + } + +} diff --git a/core/src/com/toasted/chuck/entities/EntityTorch.java b/core/src/com/toasted/chuck/entities/EntityTorch.java index ee36d86..875fa4c 100644 --- a/core/src/com/toasted/chuck/entities/EntityTorch.java +++ b/core/src/com/toasted/chuck/entities/EntityTorch.java @@ -1,5 +1,7 @@ package com.toasted.chuck.entities; +import java.util.Random; + import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.toasted.chuck.Graphics; @@ -9,7 +11,20 @@ import com.toasted.chuck.LightEmitter; public class EntityTorch extends EntityBox implements LightEmitter{ private Light emitter; - private TextureRegion torch = new TextureRegion(new Texture("env.png"),0, 23, 16, 16); + private TextureRegion torch = new TextureRegion(new Texture("env.png"),0, 16, 16, 16); + private Random rand = new Random(); + private static TextureRegion[] torchFrames = new TextureRegion[]{ + Graphics.getSubTexture(8), + Graphics.getSubTexture(25), + Graphics.getSubTexture(26), + Graphics.getSubTexture(27), + Graphics.getSubTexture(28), + }; + private int currentFrame = 0; + private float flickerSpeed = .1f; + private float frameTimer = flickerSpeed; + private static final float FLICKER = .07f; + public EntityTorch(float x, float y) { super(x, y); emitter = new Light(x + collision.width / 2, y + collision.height / 2, .3f); @@ -24,6 +39,20 @@ public class EntityTorch extends EntityBox implements LightEmitter{ @Override public void update(float delta, Level lvl) { super.update(delta, lvl); + + //try flickering light + emitter.setIntensity((rand.nextFloat() * FLICKER + (1f-FLICKER)) * .3f); + frameTimer -= delta; + if(frameTimer <= 0){ + frameTimer = flickerSpeed; + int newFrame; + do { + newFrame = rand.nextInt(5); + } while(newFrame == currentFrame); + currentFrame = newFrame; + } + + //follow the torch emitter.getPosition().set(position).add(collision.width / 2, 3 * collision.height / 4); } @@ -34,8 +63,11 @@ public class EntityTorch extends EntityBox implements LightEmitter{ } float flyPerc = (Math.max(flyLength, 0) / .5f); if(flyPerc > 0) - g.getBatch().draw(torch, position.x +dx, position.y + (float)Math.abs(Math.cos((1 - flyPerc) * (Math.PI * 3f / 4f) - (Math.PI / 4f))) * 15 + dy); - else g.getBatch().draw(torch, position.x + dx, position.y + dy); + g.getBatch().draw(getFrame(), position.x +dx, position.y + (float)Math.abs(Math.cos((1 - flyPerc) * (Math.PI * 3f / 4f) - (Math.PI / 4f))) * 15 + dy); + else g.getBatch().draw(getFrame(), position.x + dx, position.y + dy); + } + private TextureRegion getFrame(){ + return torchFrames[currentFrame]; } }