Files
shattered-pixel-dungeon-web…/src/com/shatteredpixel/shatteredpixeldungeon/effects/Speck.java
2014-10-11 16:46:52 -04:00

434 lines
9.5 KiB
Java

/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* 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 3 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 com.shatteredpixel.shatteredpixeldungeon.effects;
import android.annotation.SuppressLint;
import android.util.FloatMath;
import android.util.SparseArray;
import com.watabou.noosa.Game;
import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.particles.Emitter;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.watabou.utils.PointF;
import com.watabou.utils.Random;
public class Speck extends Image {
public static final int HEALING = 0;
public static final int STAR = 1;
public static final int LIGHT = 2;
public static final int QUESTION = 3;
public static final int UP = 4;
public static final int SCREAM = 5;
public static final int BONE = 6;
public static final int WOOL = 7;
public static final int ROCK = 8;
public static final int NOTE = 9;
public static final int CHANGE = 10;
public static final int HEART = 11;
public static final int BUBBLE = 12;
public static final int STEAM = 13;
public static final int COIN = 14;
public static final int DISCOVER = 101;
public static final int EVOKE = 102;
public static final int MASTERY = 103;
public static final int KIT = 104;
public static final int RATTLE = 105;
public static final int JET = 106;
public static final int TOXIC = 107;
public static final int PARALYSIS = 108;
public static final int DUST = 109;
public static final int STENCH = 110;
public static final int FORGE = 111;
private static final int SIZE = 7;
private int type;
private float lifespan;
private float left;
private static TextureFilm film;
private static SparseArray<Emitter.Factory> factories = new SparseArray<Emitter.Factory>();
public Speck() {
super();
texture( Assets.SPECKS );
if (film == null) {
film = new TextureFilm( texture, SIZE, SIZE );
}
origin.set( SIZE / 2f );
}
public void reset( int index, float x, float y, int type ) {
revive();
this.type = type;
switch (type) {
case DISCOVER:
frame( film.get( LIGHT ) );
break;
case EVOKE:
case MASTERY:
case KIT:
case FORGE:
frame( film.get( STAR ) );
break;
case RATTLE:
frame( film.get( BONE ) );
break;
case JET:
case TOXIC:
case PARALYSIS:
case DUST:
case STENCH:
frame( film.get( STEAM ) );
break;
default:
frame( film.get( type ) );
}
this.x = x - origin.x;
this.y = y - origin.y;
resetColor();
scale.set( 1 );
speed.set( 0 );
acc.set( 0 );
angle = 0;
angularSpeed = 0;
switch (type) {
case HEALING:
speed.set( 0, -20 );
lifespan = 1f;
break;
case STAR:
speed.polar( Random.Float( 2 * 3.1415926f ), Random.Float( 128 ) );
acc.set( 0, 128 );
angle = Random.Float( 360 );
angularSpeed = Random.Float( -360, +360 );
lifespan = 1f;
break;
case FORGE:
speed.polar( Random.Float( -3.1415926f, 0 ), Random.Float( 64 ) );
acc.set( 0, 128 );
angle = Random.Float( 360 );
angularSpeed = Random.Float( -360, +360 );
lifespan = 0.51f;
break;
case EVOKE:
speed.polar( Random.Float( -3.1415926f, 0 ), 50 );
acc.set( 0, 50 );
angle = Random.Float( 360 );
angularSpeed = Random.Float( -180, +180 );
lifespan = 1f;
break;
case KIT:
speed.polar( index * 3.1415926f / 5, 50 );
acc.set( -speed.x, -speed.y );
angle = index * 36;
angularSpeed = 360;
lifespan = 1f;
break;
case MASTERY:
speed.set( Random.Int( 2 ) == 0 ? Random.Float( -128, -64 ) : Random.Float( +64, +128 ), 0 );
angularSpeed = speed.x < 0 ? -180 : +180;
acc.set( -speed.x, 0 );
lifespan = 0.5f;
break;
case LIGHT:
angle = Random.Float( 360 );
angularSpeed = 90;
lifespan = 1f;
break;
case DISCOVER:
angle = Random.Float( 360 );
angularSpeed = 90;
lifespan = 0.5f;
am = 0;
break;
case QUESTION:
lifespan = 0.8f;
break;
case UP:
speed.set( 0, -20 );
lifespan = 1f;
break;
case SCREAM:
lifespan = 0.9f;
break;
case BONE:
lifespan = 0.2f;
speed.polar( Random.Float( 2 * 3.1415926f ), 24 / lifespan );
acc.set( 0, 128 );
angle = Random.Float( 360 );
angularSpeed = 360;
break;
case RATTLE:
lifespan = 0.5f;
speed.set( 0, -200 );
acc.set( 0, -2 * speed.y / lifespan );
angle = Random.Float( 360 );
angularSpeed = 360;
break;
case WOOL:
lifespan = 0.5f;
speed.set( 0, -50 );
angle = Random.Float( 360 );
angularSpeed = Random.Float( -360, +360 );
break;
case ROCK:
angle = Random.Float( 360 );
angularSpeed = Random.Float( -360, +360 );
scale.set( Random.Float( 1, 2 ) );
speed.set( 0, 64 );
lifespan = 0.2f;
y -= speed.y * lifespan;
break;
case NOTE:
angularSpeed = Random.Float( -30, +30 );
speed.polar( (angularSpeed - 90) * PointF.G2R, 30 );
lifespan = 1f;
break;
case CHANGE:
angle = Random.Float( 360 );
speed.polar( (angle - 90) * PointF.G2R, Random.Float( 4, 12 ) );
lifespan = 1.5f;
break;
case HEART:
speed.set( Random.Int( -10, +10 ), -40 );
angularSpeed = Random.Float( -45, +45 );
lifespan = 1f;
break;
case BUBBLE:
speed.set( 0, -15 );
scale.set( Random.Float( 0.8f, 1 ) );
lifespan = Random.Float( 0.8f, 1.5f );
break;
case STEAM:
speed.y = -Random.Float( 20, 30 );
angularSpeed = Random.Float( +180 );
angle = Random.Float( 360 );
lifespan = 1f;
break;
case JET:
speed.y = +32;
acc.y = -64;
angularSpeed = Random.Float( 180, 360 );
angle = Random.Float( 360 );
lifespan = 0.5f;
break;
case TOXIC:
hardlight( 0x50FF60 );
angularSpeed = 30;
angle = Random.Float( 360 );
lifespan = Random.Float( 1f, 3f );
break;
case PARALYSIS:
hardlight( 0xFFFF66 );
angularSpeed = -30;
angle = Random.Float( 360 );
lifespan = Random.Float( 1f, 3f );
break;
case DUST:
hardlight( 0xFFFF66 );
angle = Random.Float( 360 );
speed.polar( Random.Float( 2 * 3.1415926f ), Random.Float( 16, 48 ) );
lifespan = 0.5f;
break;
case STENCH:
hardlight( 0x003300 );
angularSpeed = -30;
angle = Random.Float( 360 );
lifespan = Random.Float( 1f, 3f );
break;
case COIN:
speed.polar( -PointF.PI * Random.Float( 0.3f, 0.7f ), Random.Float( 48, 96 ) );
acc.y = 256;
lifespan = -speed.y / acc.y * 2;
break;
}
left = lifespan;
}
@SuppressLint("FloatMath")
@Override
public void update() {
super.update();
left -= Game.elapsed;
if (left <= 0) {
kill();
} else {
float p = 1 - left / lifespan; // 0 -> 1
switch (type) {
case STAR:
case FORGE:
scale.set( 1 - p );
am = p < 0.2f ? p * 5f : (1 - p) * 1.25f;
break;
case KIT:
case MASTERY:
am = 1 - p * p;
break;
case EVOKE:
case HEALING:
am = p < 0.5f ? 1 : 2 - p * 2;
break;
case LIGHT:
am = scale.set( p < 0.2f ? p * 5f : (1 - p) * 1.25f ).x;
break;
case DISCOVER:
am = 1 - p;
scale.set( (p < 0.5f ? p : 1 - p) * 2 );
break;
case QUESTION:
scale.set( (float)(Math.sqrt( p < 0.5f ? p : 1 - p ) * 3) );
break;
case UP:
scale.set( (float)(Math.sqrt( p < 0.5f ? p : 1 - p ) * 2) );
break;
case SCREAM:
am = (float)Math.sqrt( (p < 0.5f ? p : 1 - p) * 2f );
scale.set( p * 7 );
break;
case BONE:
case RATTLE:
am = p < 0.9f ? 1 : (1 - p) * 10;
break;
case ROCK:
am = p < 0.2f ? p * 5 : 1 ;
break;
case NOTE:
am = 1 - p * p;
break;
case WOOL:
scale.set( 1 - p );
break;
case CHANGE:
am = (float)FloatMath.sqrt( (p < 0.5f ? p : 1 - p) * 2);
scale.y = (1 + p) * 0.5f;
scale.x = scale.y * FloatMath.cos( left * 15 );
break;
case HEART:
scale.set( 1 - p );
am = 1 - p * p;
break;
case BUBBLE:
am = p < 0.2f ? p * 5 : 1;
break;
case STEAM:
case TOXIC:
case PARALYSIS:
case DUST:
am = p < 0.5f ? p : 1 - p;
scale.set( 1 + p * 2 );
break;
case STENCH:
am = (p < 0.5f ? p : 1 - p) * 2;
scale.set( 1 + p * 2 );
break;
case JET:
am = (p < 0.5f ? p : 1 - p) * 2;
scale.set( p * 1.5f );
break;
case COIN:
scale.x = FloatMath.cos( left * 5 );
rm = gm = bm = (Math.abs( scale.x ) + 1) * 0.5f;
am = p < 0.9f ? 1 : (1 - p) * 10;
break;
}
}
}
public static Emitter.Factory factory( final int type ) {
Emitter.Factory factory = factories.get( type );
if (factory == null) {
factory = new Emitter.Factory() {
@Override
public void emit ( Emitter emitter, int index, float x, float y ) {
Speck p = (Speck)emitter.recycle( Speck.class );
p.reset( index, x, y, type );
}
};
factories.put( type, factory );
}
return factory;
}
}