Implemented shield hit effects and bullet absorption and powered rturret

This commit is contained in:
Anuken 2017-11-28 01:00:59 -05:00
parent c0d28eca65
commit 63d8aed9a5
13 changed files with 115 additions and 25 deletions

View File

@ -79,8 +79,7 @@ project(":core") {
apply plugin: "java"
dependencies {
compile 'com.github.Anuken:ucore:d43f3b48ec'
//compile fileTree(dir: '../core/lib', include: '*.jar')
// compile 'com.github.Anuken:ucore:61c43bf'
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-ai:1.8.1"
}

View File

@ -3,6 +3,9 @@ precision mediump float;
precision mediump int;
#endif
#define MAX_HITS 64
#define HIT_RADIUS 12.0
uniform sampler2D u_texture;
uniform vec4 u_color;
@ -10,6 +13,8 @@ uniform vec2 u_texsize;
uniform float u_time;
uniform float u_scaling;
uniform vec2 u_offset;
uniform int u_hitamount;
uniform vec3 u_hits[MAX_HITS];
varying vec4 v_color;
varying vec2 v_texCoord;
@ -49,8 +54,19 @@ void main() {
}
color.a = 0.18;
for(int i = 0; i < u_hitamount; i ++){
vec3 hit = u_hits[i];
float rad = hit.z * HIT_RADIUS;
float fract = 1.0 - hit.z;
if(abs(distance(vec2(hit.x, hit.y), coords - u_texsize/2.0) - rad) < 1.0){
color = mix(color, u_color* vec4(si, si, si, 1.0), (1.0 * fract));
color.a = 0.18 + 0.82 *fract;
}
}
}
gl_FragColor = color;
}
}

View File

@ -42,7 +42,7 @@ public class Vars{
//whether to draw chunk borders
public static boolean debugChunks = false;
//whether turrets have infinite ammo (only with debug)
public static boolean infiniteAmmo = true;
public static boolean infiniteAmmo = false;
//whether to show paths of enemies
public static boolean showPaths = true;
//number of save slots-- increasing may lead to layout issues

View File

@ -59,9 +59,12 @@ public class Control extends Module{
float respawntime;
public Control(){
if(Mindustry.args.contains("-debug", false)){
if(Mindustry.args.contains("-debug", false))
Vars.debug = true;
}
if(Mindustry.args.contains("-profile", false))
Vars.profile = true;
if(Mindustry.args.contains("-debugGL", false))
Vars.debugGL = true;
UCore.log("Total blocks loaded: " + Block.getAllBlocks().size);

View File

@ -11,6 +11,7 @@ import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.profiling.GLProfiler;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.FloatArray;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
@ -39,6 +40,8 @@ public class Renderer extends RendererModule{
int targetscale = baseCameraScale;
int chunksize = 32;
Cache[][] floorCache;
FloatArray shieldHits = new FloatArray();
float shieldHitDuration = 18f;
public Renderer() {
Core.cameraScale = baseCameraScale;
@ -127,6 +130,10 @@ public class Renderer extends RendererModule{
drawDefault();
Profiler.end("draw");
if(Profiler.updating())
Profiler.getTimes().put("draw", Profiler.getTimes().get("draw")
- Profiler.getTimes().get("blockDraw")
- Profiler.getTimes().get("entityDraw"));
if(Vars.debug && Vars.debugGL && Timers.get("profile", 60)){
UCore.log("shaders: " + GLProfiler.shaderSwitches, "calls: " + GLProfiler.drawCalls, "bindings: " + GLProfiler.textureBindings, "vertices: " + GLProfiler.vertexCount.average);
@ -195,11 +202,26 @@ public class Renderer extends RendererModule{
}
void drawShield(){
for(int i = 0; i < shieldHits.size/3; i ++){
//float x = hits.get(i*3+0);
//float y = hits.get(i*3+1);
float time = shieldHits.get(i*3+2);
time += Timers.delta() / shieldHitDuration;
shieldHits.set(i*3 + 2, time);
if(time >= 1f){
shieldHits.removeRange(i*3, i*3 + 2);
i --;
}
}
Texture texture = Graphics.getSurface("shield").texture();
Shaders.shield.color.set(Color.SKY);
Tmp.tr2.setRegion(texture);
Shaders.shield.region = Tmp.tr2;
Shaders.shield.hits = shieldHits;
Graphics.end();
Graphics.shader(Shaders.shield);
@ -211,6 +233,10 @@ public class Renderer extends RendererModule{
Graphics.end();
Graphics.beginCam();
}
public void addShieldHit(float x, float y){
shieldHits.addAll(x, y, 0f);
}
void renderTiles(){
int chunksx = world.width() / chunksize, chunksy = world.height() / chunksize;

View File

@ -1,6 +1,7 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.FloatArray;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
@ -28,7 +29,9 @@ public class Shaders{
}
public static class Shield extends Shader{
public static final int MAX_HITS = 3*64;
public Color color = new Color();
public FloatArray hits;
public Shield(){
super("shield", "default");
@ -38,6 +41,8 @@ public class Shaders{
public void apply(){
float scale = Settings.getBool("pixelate") ? 1 : Core.cameraScale / Core.camera.zoom;
float scaling = Core.cameraScale / 4f / Core.camera.zoom;
shader.setUniform3fv("u_hits[0]", hits.items, 0, Math.min(hits.size, MAX_HITS));
shader.setUniformi("u_hitamount", Math.min(hits.size, MAX_HITS)/3);
shader.setUniformf("u_color", color);
shader.setUniformf("u_time", Timers.time());
shader.setUniformf("u_scaling", scaling);

View File

@ -1,7 +1,10 @@
package io.anuke.mindustry.entities.effect;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Interpolation;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock;
import io.anuke.ucore.core.Draw;
@ -14,6 +17,8 @@ import io.anuke.ucore.util.Mathf;
public class Shield extends Entity{
public boolean active;
public boolean hitPlayers = true;
private float uptime = 0f;
private final Tile tile;
//TODO
@ -30,11 +35,14 @@ public class Shield extends Entity{
@Override
public void update(){
float alpha = 0.1f;
Interpolation interp = Interpolation.fade;
if(active){
uptime += Timers.delta() / 90f;
uptime = interp.apply(uptime, 1f, alpha * Timers.delta());
}else{
uptime -= Timers.delta() / 60f;
if(uptime < 0)
uptime = interp.apply(uptime, 0f, alpha * Timers.delta());
if(uptime <= 0.05f)
remove();
}
uptime = Mathf.clamp(uptime);
@ -46,14 +54,14 @@ public class Shield extends Entity{
ShieldBlock block = (ShieldBlock)tile.block();
Entities.getNearby(x, y, block.shieldRadius * 2*uptime + 10, entity->{
if(entity instanceof BulletEntity){
BulletEntity bullet = (BulletEntity)entity;
Entities.getNearby(Entities.getGroup(Bullet.class), x, y, block.shieldRadius * 2*uptime + 10, entity->{
BulletEntity bullet = (BulletEntity)entity;
if((bullet.owner instanceof Enemy || hitPlayers)){
float dst = entity.distanceTo(this);
if(Math.abs(dst - block.shieldRadius) < 2){
bullet.velocity.scl(-1);
if(dst < drawRadius()/2f){
((ShieldBlock)tile.block()).handleBullet(tile, bullet);
}
}
});
@ -65,10 +73,7 @@ public class Shield extends Entity{
return;
}
ShieldBlock block = (ShieldBlock)tile.block();
float rad = block.shieldRadius*2 + Mathf.sin(Timers.time(), 25f, 2f);
rad *= uptime;
float rad = drawRadius();
Graphics.surface("shield", false);
Draw.color(Color.ROYAL);
@ -78,6 +83,11 @@ public class Shield extends Entity{
Graphics.surface();
}
float drawRadius(){
ShieldBlock block = (ShieldBlock)tile.block();
return (block.shieldRadius*2 + Mathf.sin(Timers.time(), 25f, 2f)) * uptime;
}
public void removeDelay(){
active = false;
}

View File

@ -163,6 +163,7 @@ public class HudFragment implements Fragment{
}
public void updateItems(){
itemtable.clear();
itemtable.left();
@ -183,6 +184,7 @@ public class HudFragment implements Fragment{
}
public void fadeRespawn(boolean in){
respawntable.addAction(Actions.color(in ? new Color(0, 0, 0, 0.3f) : Color.CLEAR, 0.3f));
}
}

View File

@ -41,6 +41,12 @@ public class PowerTurret extends Turret implements PowerAcceptor{
Draw.dashcircle(tile.worldx() + offset.x, tile.worldy() + offset.y, range);
Draw.reset();
drawPowerBar(tile);
}
public void drawPowerBar(Tile tile){
Vector2 offset = getPlaceOffset();
PowerTurretEntity entity = tile.entity();
float fract = (float)entity.power / powerCapacity;

View File

@ -36,7 +36,9 @@ public class RepairTurret extends PowerTurret{
@Override
public void update(Tile tile){
TurretEntity entity = tile.entity();
PowerTurretEntity entity = tile.entity();
if(entity.power < powerUsed) return;
if(Timers.get(entity, "blocktarget", targetInterval)){
entity.blockTarget = Vars.world.findTileTarget(tile.worldx(), tile.worldy(), tile, range, true);
@ -51,6 +53,8 @@ public class RepairTurret extends PowerTurret{
if(entity.blockTarget.health > entity.blockTarget.health)
entity.blockTarget.health = entity.blockTarget.maxhealth;
entity.power -= powerUsed;
}
}
}
@ -60,6 +64,8 @@ public class RepairTurret extends PowerTurret{
Draw.color("green");
Draw.dashcircle(tile.worldx(), tile.worldy(), range);
Draw.reset();
drawPowerBar(tile);
}
@Override

View File

@ -1,17 +1,20 @@
package io.anuke.mindustry.world.blocks.types.defense;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.PowerBlock;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.BulletEntity;
public class ShieldBlock extends PowerBlock{
private static boolean debugShield = false;
public float shieldRadius = 40f;
public float powerDrain = 0.005f;
public float powerPerDamage = 0.1f;
public ShieldBlock(String name) {
super(name);
voltage = powerDrain;
@ -23,18 +26,18 @@ public class ShieldBlock extends PowerBlock{
if(entity.shield == null){
entity.shield = new Shield(tile);
if(debugShield)
if(Vars.infiniteAmmo && Vars.debug)
entity.shield.add();
}
if(entity.power > powerDrain * Timers.delta()){
if(entity.power > powerPerDamage){
if(!entity.shield.active && entity.power > powerDrain * Timers.delta() * 10f){
entity.shield.add();
}
entity.power -= powerDrain * Timers.delta();
}else{
if(entity.shield.active && !debugShield){
if(entity.shield.active && !(Vars.infiniteAmmo && Vars.debug)){
entity.shield.removeDelay();
}
}
@ -45,6 +48,20 @@ public class ShieldBlock extends PowerBlock{
public TileEntity getEntity(){
return new ShieldEntity();
}
public void handleBullet(Tile tile, BulletEntity bullet){
ShieldEntity entity = tile.entity();
if(entity.power < bullet.getDamage() * powerPerDamage){
return;
}
bullet.remove();
Effects.effect(Fx.laserhit, bullet);
Vars.renderer.addShieldHit(bullet.x, bullet.y);
entity.power -= bullet.getDamage() * powerPerDamage;
}
static class ShieldEntity extends PowerEntity{
Shield shield;

Binary file not shown.

Binary file not shown.