Converted ShatteredPD to Build from Gradle
Major Changes: - Shattered now builds effortlessly either from gradle CLI or android studio - Much better dependency management through gradle (although it's not really used atm) - Separate PD-classes repo is now SPD-classes module within main repo
This commit is contained in:
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.glwrap.Quad;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.RectF;
|
||||
|
||||
public class BitmapText extends Visual {
|
||||
|
||||
protected String text;
|
||||
protected Font font;
|
||||
|
||||
protected float[] vertices = new float[16];
|
||||
protected FloatBuffer quads;
|
||||
|
||||
public int realLength;
|
||||
|
||||
protected boolean dirty = true;
|
||||
|
||||
public BitmapText() {
|
||||
this( "", null );
|
||||
}
|
||||
|
||||
public BitmapText( Font font ) {
|
||||
this( "", font );
|
||||
}
|
||||
|
||||
public BitmapText( String text, Font font ) {
|
||||
super( 0, 0, 0, 0 );
|
||||
|
||||
this.text = text;
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
text = null;
|
||||
font = null;
|
||||
vertices = null;
|
||||
quads = null;
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateMatrix() {
|
||||
// "origin" field is ignored
|
||||
Matrix.setIdentity( matrix );
|
||||
Matrix.translate( matrix, x, y );
|
||||
Matrix.scale( matrix, scale.x, scale.y );
|
||||
Matrix.rotate( matrix, angle );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
super.draw();
|
||||
|
||||
NoosaScript script = NoosaScript.get();
|
||||
|
||||
font.texture.bind();
|
||||
|
||||
if (dirty) {
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
script.camera( camera() );
|
||||
|
||||
script.uModel.valueM4( matrix );
|
||||
script.lighting(
|
||||
rm, gm, bm, am,
|
||||
ra, ga, ba, aa );
|
||||
script.drawQuadSet( quads, realLength );
|
||||
|
||||
}
|
||||
|
||||
protected void updateVertices() {
|
||||
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
|
||||
quads = Quad.createSet( text.length() );
|
||||
realLength = 0;
|
||||
|
||||
int length = text.length();
|
||||
for (int i=0; i < length; i++) {
|
||||
RectF rect = font.get( text.charAt( i ) );
|
||||
|
||||
if (rect == null) {
|
||||
rect=null;
|
||||
}
|
||||
float w = font.width( rect );
|
||||
float h = font.height( rect );
|
||||
|
||||
vertices[0] = width;
|
||||
vertices[1] = 0;
|
||||
|
||||
vertices[2] = rect.left;
|
||||
vertices[3] = rect.top;
|
||||
|
||||
vertices[4] = width + w;
|
||||
vertices[5] = 0;
|
||||
|
||||
vertices[6] = rect.right;
|
||||
vertices[7] = rect.top;
|
||||
|
||||
vertices[8] = width + w;
|
||||
vertices[9] = h;
|
||||
|
||||
vertices[10] = rect.right;
|
||||
vertices[11] = rect.bottom;
|
||||
|
||||
vertices[12] = width;
|
||||
vertices[13] = h;
|
||||
|
||||
vertices[14] = rect.left;
|
||||
vertices[15] = rect.bottom;
|
||||
|
||||
quads.put( vertices );
|
||||
realLength++;
|
||||
|
||||
width += w + font.tracking;
|
||||
if (h > height) {
|
||||
height = h;
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
width -= font.tracking;
|
||||
}
|
||||
|
||||
dirty = false;
|
||||
|
||||
}
|
||||
|
||||
public void measure() {
|
||||
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
|
||||
int length = text.length();
|
||||
for (int i=0; i < length; i++) {
|
||||
RectF rect = font.get( text.charAt( i ) );
|
||||
|
||||
float w = font.width( rect );
|
||||
float h = font.height( rect );
|
||||
|
||||
width += w + font.tracking;
|
||||
if (h > height) {
|
||||
height = h;
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
width -= font.tracking;
|
||||
}
|
||||
}
|
||||
|
||||
public float baseLine() {
|
||||
return font.baseLine * scale.y;
|
||||
}
|
||||
|
||||
public Font font() {
|
||||
return font;
|
||||
}
|
||||
|
||||
public void font( Font value ) {
|
||||
font = value;
|
||||
}
|
||||
|
||||
public String text() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void text( String str ) {
|
||||
text = str;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public static class Font extends TextureFilm {
|
||||
|
||||
public static final String LATIN_FULL =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F";
|
||||
|
||||
public SmartTexture texture;
|
||||
|
||||
public float tracking = 0;
|
||||
public float baseLine;
|
||||
|
||||
public float lineHeight;
|
||||
|
||||
protected Font( SmartTexture tx ) {
|
||||
super( tx );
|
||||
|
||||
texture = tx;
|
||||
}
|
||||
|
||||
public Font( SmartTexture tx, int width, String chars ) {
|
||||
this( tx, width, tx.height, chars );
|
||||
}
|
||||
|
||||
public Font( SmartTexture tx, int width, int height, String chars ) {
|
||||
super( tx );
|
||||
|
||||
texture = tx;
|
||||
|
||||
int length = chars.length();
|
||||
|
||||
float uw = (float)width / tx.width;
|
||||
float vh = (float)height / tx.height;
|
||||
|
||||
float left = 0;
|
||||
float top = 0;
|
||||
float bottom = vh;
|
||||
|
||||
for (int i=0; i < length; i++) {
|
||||
RectF rect = new RectF( left, top, left += uw, bottom );
|
||||
add( chars.charAt( i ), rect );
|
||||
if (left >= 1) {
|
||||
left = 0;
|
||||
top = bottom;
|
||||
bottom += vh;
|
||||
}
|
||||
}
|
||||
|
||||
lineHeight = baseLine = height;
|
||||
}
|
||||
|
||||
protected void splitBy( Bitmap bitmap, int height, int color, String chars ) {
|
||||
|
||||
int length = chars.length();
|
||||
|
||||
int width = bitmap.getWidth();
|
||||
float vHeight = (float)height / bitmap.getHeight();
|
||||
|
||||
int pos;
|
||||
int line = 0;
|
||||
|
||||
spaceMeasuring:
|
||||
for (pos=0; pos < width; pos++) {
|
||||
for (int j=0; j < height; j++) {
|
||||
if (bitmap.getPixel( pos, j ) != color) {
|
||||
break spaceMeasuring;
|
||||
}
|
||||
}
|
||||
}
|
||||
add( ' ', new RectF( 0, 0, (float)pos / width, vHeight-0.01f ) );
|
||||
|
||||
int separator = pos;
|
||||
|
||||
for (int i=0; i < length; i++) {
|
||||
|
||||
char ch = chars.charAt( i );
|
||||
if (ch == ' ') {
|
||||
continue;
|
||||
} else {
|
||||
|
||||
boolean found;
|
||||
|
||||
do{
|
||||
if (separator >= width) {
|
||||
line += height;
|
||||
separator = 0;
|
||||
}
|
||||
found = false;
|
||||
for (int j=line; j < line + height; j++) {
|
||||
if (bitmap.getPixel( separator, j ) != color) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) separator++;
|
||||
} while (!found);
|
||||
int start = separator;
|
||||
|
||||
do {
|
||||
if (++separator >= width) {
|
||||
line += height;
|
||||
separator = start = 0;
|
||||
if (line + height >= bitmap.getHeight())
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
for (int j=line; j < line + height; j++) {
|
||||
if (bitmap.getPixel( separator, j ) != color) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!found);
|
||||
|
||||
add( ch, new RectF( (float)start / width, (float)line / bitmap.getHeight(), (float)separator / width, (float)line / bitmap.getHeight() + vHeight) );
|
||||
separator++;
|
||||
}
|
||||
}
|
||||
|
||||
lineHeight = baseLine = height( frames.get( chars.charAt( 0 ) ) );
|
||||
}
|
||||
|
||||
public static Font colorMarked( Bitmap bmp, int color, String chars ) {
|
||||
Font font = new Font( TextureCache.get( bmp ) );
|
||||
font.splitBy( bmp, bmp.getHeight(), color, chars );
|
||||
return font;
|
||||
}
|
||||
|
||||
public static Font colorMarked( Bitmap bmp, int height, int color, String chars ) {
|
||||
Font font = new Font( TextureCache.get( bmp ) );
|
||||
font.splitBy( bmp, height, color, chars );
|
||||
return font;
|
||||
}
|
||||
|
||||
public RectF get( char ch ) {
|
||||
if (frames.containsKey( ch )){
|
||||
return super.get( ch );
|
||||
} else {
|
||||
return super.get( '?' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.watabou.glwrap.Quad;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class BitmapTextMultiline extends BitmapText {
|
||||
|
||||
public int maxWidth = Integer.MAX_VALUE;
|
||||
|
||||
protected static final Pattern PARAGRAPH = Pattern.compile( "\n" );
|
||||
protected static final Pattern WORD = Pattern.compile( "\\s+" );
|
||||
|
||||
protected float spaceSize;
|
||||
|
||||
public int nLines = 0;
|
||||
|
||||
public boolean[] mask;
|
||||
|
||||
public BitmapTextMultiline( Font font ) {
|
||||
this( "", font );
|
||||
}
|
||||
|
||||
public BitmapTextMultiline( String text, Font font ) {
|
||||
super( text, font );
|
||||
spaceSize = font.width( font.get( ' ' ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateVertices() {
|
||||
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
|
||||
quads = Quad.createSet( text.length() );
|
||||
realLength = 0;
|
||||
|
||||
// This object controls lines breaking
|
||||
SymbolWriter writer = new SymbolWriter();
|
||||
|
||||
// Word size
|
||||
PointF metrics = new PointF();
|
||||
|
||||
String paragraphs[] = PARAGRAPH.split( text );
|
||||
|
||||
// Current character (used in masking)
|
||||
int pos = 0;
|
||||
|
||||
for (int i=0; i < paragraphs.length; i++) {
|
||||
|
||||
String[] words = WORD.split( paragraphs[i] );
|
||||
|
||||
for (int j=0; j < words.length; j++) {
|
||||
|
||||
String word = words[j];
|
||||
if (word.length() == 0) {
|
||||
// This case is possible when there are
|
||||
// several spaces coming along
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
getWordMetrics( word, metrics );
|
||||
writer.addSymbol( metrics.x, metrics.y );
|
||||
|
||||
int length = word.length();
|
||||
float shift = 0; // Position in pixels relative to the beginning of the word
|
||||
|
||||
for (int k=0; k < length; k++) {
|
||||
RectF rect = font.get( word.charAt( k ) );
|
||||
|
||||
float w = font.width( rect );
|
||||
float h = font.height( rect );
|
||||
|
||||
if (mask == null || mask[pos]) {
|
||||
vertices[0] = writer.x + shift;
|
||||
vertices[1] = writer.y;
|
||||
|
||||
vertices[2] = rect.left;
|
||||
vertices[3] = rect.top;
|
||||
|
||||
vertices[4] = writer.x + shift + w;
|
||||
vertices[5] = writer.y;
|
||||
|
||||
vertices[6] = rect.right;
|
||||
vertices[7] = rect.top;
|
||||
|
||||
vertices[8] = writer.x + shift + w;
|
||||
vertices[9] = writer.y + h;
|
||||
|
||||
vertices[10] = rect.right;
|
||||
vertices[11] = rect.bottom;
|
||||
|
||||
vertices[12] = writer.x + shift;
|
||||
vertices[13] = writer.y + h;
|
||||
|
||||
vertices[14] = rect.left;
|
||||
vertices[15] = rect.bottom;
|
||||
|
||||
quads.put( vertices );
|
||||
realLength++;
|
||||
}
|
||||
|
||||
shift += w + font.tracking;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
writer.addSpace( spaceSize );
|
||||
}
|
||||
|
||||
writer.newLine( 0, font.lineHeight );
|
||||
}
|
||||
|
||||
nLines = writer.nLines();
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
private void getWordMetrics( String word, PointF metrics ) {
|
||||
|
||||
float w = 0;
|
||||
float h = 0;
|
||||
|
||||
int length = word.length();
|
||||
for (int i=0; i < length; i++) {
|
||||
|
||||
RectF rect = font.get( word.charAt( i ) );
|
||||
w += font.width( rect ) + (w > 0 ? font.tracking : 0);
|
||||
h = Math.max( h, font.height( rect ) );
|
||||
}
|
||||
|
||||
metrics.set( w, h );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void measure() {
|
||||
|
||||
SymbolWriter writer = new SymbolWriter();
|
||||
|
||||
PointF metrics = new PointF();
|
||||
|
||||
String paragraphs[] = PARAGRAPH.split( text );
|
||||
|
||||
for (int i=0; i < paragraphs.length; i++) {
|
||||
|
||||
String[] words = WORD.split( paragraphs[i] );
|
||||
|
||||
for (int j=0; j < words.length; j++) {
|
||||
|
||||
if (j > 0) {
|
||||
writer.addSpace( spaceSize );
|
||||
}
|
||||
String word = words[j];
|
||||
if (word.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
getWordMetrics( word, metrics );
|
||||
writer.addSymbol( metrics.x, metrics.y );
|
||||
}
|
||||
|
||||
writer.newLine( 0, font.lineHeight );
|
||||
}
|
||||
|
||||
width = writer.width;
|
||||
height = writer.height;
|
||||
|
||||
nLines = writer.nLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float baseLine() {
|
||||
return (height - font.lineHeight + font.baseLine) * scale.y;
|
||||
}
|
||||
|
||||
private class SymbolWriter {
|
||||
|
||||
public float width = 0;
|
||||
public float height = 0;
|
||||
|
||||
public int nLines = 0;
|
||||
|
||||
public float lineWidth = 0;
|
||||
public float lineHeight = 0;
|
||||
|
||||
public float x = 0;
|
||||
public float y = 0;
|
||||
|
||||
public void addSymbol( float w, float h ) {
|
||||
if (lineWidth > 0 && lineWidth + font.tracking + w > maxWidth / scale.x) {
|
||||
newLine( w, h );
|
||||
} else {
|
||||
|
||||
x = lineWidth;
|
||||
|
||||
lineWidth += (lineWidth > 0 ? font.tracking : 0) + w;
|
||||
if (h > lineHeight) {
|
||||
lineHeight = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addSpace( float w ) {
|
||||
if (lineWidth > 0 && lineWidth + font.tracking + w > maxWidth / scale.x) {
|
||||
newLine( 0, 0 );
|
||||
} else {
|
||||
|
||||
x = lineWidth;
|
||||
lineWidth += (lineWidth > 0 ? font.tracking : 0) + w;
|
||||
}
|
||||
}
|
||||
|
||||
public void newLine( float w, float h ) {
|
||||
|
||||
height += lineHeight;
|
||||
if (width < lineWidth) {
|
||||
width = lineWidth;
|
||||
}
|
||||
|
||||
lineWidth = w;
|
||||
lineHeight = h;
|
||||
|
||||
x = 0;
|
||||
y = height;
|
||||
|
||||
nLines++;
|
||||
}
|
||||
|
||||
public int nLines() {
|
||||
return x == 0 ? nLines : nLines+1;
|
||||
}
|
||||
}
|
||||
|
||||
public class LineSplitter {
|
||||
|
||||
private ArrayList<BitmapText> lines;
|
||||
|
||||
private StringBuilder curLine;
|
||||
private float curLineWidth;
|
||||
|
||||
private PointF metrics = new PointF();
|
||||
|
||||
private void newLine( String str, float width ) {
|
||||
BitmapText txt = new BitmapText( curLine.toString(), font );
|
||||
txt.scale.set( scale.x );
|
||||
lines.add( txt );
|
||||
|
||||
curLine = new StringBuilder( str );
|
||||
curLineWidth = width;
|
||||
}
|
||||
|
||||
private void append( String str, float width ) {
|
||||
curLineWidth += (curLineWidth > 0 ? font.tracking : 0) + width;
|
||||
curLine.append( str );
|
||||
}
|
||||
|
||||
public ArrayList<BitmapText> split() {
|
||||
|
||||
lines = new ArrayList<>();
|
||||
|
||||
curLine = new StringBuilder();
|
||||
curLineWidth = 0;
|
||||
|
||||
String paragraphs[] = PARAGRAPH.split( text );
|
||||
|
||||
for (int i=0; i < paragraphs.length; i++) {
|
||||
|
||||
String[] words = WORD.split( paragraphs[i] );
|
||||
|
||||
for (int j=0; j < words.length; j++) {
|
||||
|
||||
String word = words[j];
|
||||
if (word.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
getWordMetrics( word, metrics );
|
||||
|
||||
if (curLineWidth > 0 && curLineWidth + font.tracking + metrics.x > maxWidth / scale.x) {
|
||||
newLine( word, metrics.x );
|
||||
} else {
|
||||
append( word, metrics.x );
|
||||
}
|
||||
|
||||
if (curLineWidth > 0 && curLineWidth + font.tracking + spaceSize > maxWidth / scale.x) {
|
||||
newLine( "", 0 );
|
||||
} else {
|
||||
append( " ", spaceSize );
|
||||
}
|
||||
}
|
||||
|
||||
newLine( "", 0 );
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class Camera extends Gizmo {
|
||||
|
||||
protected static ArrayList<Camera> all = new ArrayList<Camera>();
|
||||
|
||||
protected static float invW2;
|
||||
protected static float invH2;
|
||||
|
||||
public static Camera main;
|
||||
|
||||
public float zoom;
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
int screenWidth;
|
||||
int screenHeight;
|
||||
|
||||
public float[] matrix;
|
||||
|
||||
public PointF scroll;
|
||||
public Visual target;
|
||||
|
||||
private float shakeMagX = 10f;
|
||||
private float shakeMagY = 10f;
|
||||
private float shakeTime = 0f;
|
||||
private float shakeDuration = 1f;
|
||||
|
||||
protected float shakeX;
|
||||
protected float shakeY;
|
||||
|
||||
public static Camera reset() {
|
||||
return reset( createFullscreen( 1 ) );
|
||||
}
|
||||
|
||||
public static Camera reset( Camera newCamera ) {
|
||||
|
||||
invW2 = 2f / Game.width;
|
||||
invH2 = 2f / Game.height;
|
||||
|
||||
int length = all.size();
|
||||
for (int i=0; i < length; i++) {
|
||||
all.get( i ).destroy();
|
||||
}
|
||||
all.clear();
|
||||
|
||||
return main = add( newCamera );
|
||||
}
|
||||
|
||||
public static Camera add( Camera camera ) {
|
||||
all.add( camera );
|
||||
return camera;
|
||||
}
|
||||
|
||||
public static Camera remove( Camera camera ) {
|
||||
all.remove( camera );
|
||||
return camera;
|
||||
}
|
||||
|
||||
public static void updateAll() {
|
||||
int length = all.size();
|
||||
for (int i=0; i < length; i++) {
|
||||
Camera c = all.get( i );
|
||||
if (c.exists && c.active) {
|
||||
c.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Camera createFullscreen( float zoom ) {
|
||||
int w = (int)Math.ceil( Game.width / zoom );
|
||||
int h = (int)Math.ceil( Game.height / zoom );
|
||||
return new Camera(
|
||||
(int)(Game.width - w * zoom) / 2,
|
||||
(int)(Game.height - h * zoom) / 2,
|
||||
w, h, zoom );
|
||||
}
|
||||
|
||||
public Camera( int x, int y, int width, int height, float zoom ) {
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.zoom = zoom;
|
||||
|
||||
screenWidth = (int)(width * zoom);
|
||||
screenHeight = (int)(height * zoom);
|
||||
|
||||
scroll = new PointF();
|
||||
|
||||
matrix = new float[16];
|
||||
Matrix.setIdentity( matrix );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
target = null;
|
||||
matrix = null;
|
||||
}
|
||||
|
||||
public void zoom( float value ) {
|
||||
zoom( value,
|
||||
scroll.x + width / 2,
|
||||
scroll.y + height / 2 );
|
||||
}
|
||||
|
||||
public void zoom( float value, float fx, float fy ) {
|
||||
|
||||
zoom = value;
|
||||
width = (int)(screenWidth / zoom);
|
||||
height = (int)(screenHeight / zoom);
|
||||
|
||||
focusOn( fx, fy );
|
||||
}
|
||||
|
||||
public void resize( int width, int height ) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
screenWidth = (int)(width * zoom);
|
||||
screenHeight = (int)(height * zoom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
if (target != null) {
|
||||
focusOn( target );
|
||||
}
|
||||
|
||||
if ((shakeTime -= Game.elapsed) > 0) {
|
||||
float damping = shakeTime / shakeDuration;
|
||||
shakeX = Random.Float( -shakeMagX, +shakeMagX ) * damping;
|
||||
shakeY = Random.Float( -shakeMagY, +shakeMagY ) * damping;
|
||||
} else {
|
||||
shakeX = 0;
|
||||
shakeY = 0;
|
||||
}
|
||||
|
||||
updateMatrix();
|
||||
}
|
||||
|
||||
public PointF center() {
|
||||
return new PointF( width / 2, height / 2 );
|
||||
}
|
||||
|
||||
public boolean hitTest( float x, float y ) {
|
||||
return x >= this.x && y >= this.y && x < this.x + screenWidth && y < this.y + screenHeight;
|
||||
}
|
||||
|
||||
public void focusOn( float x, float y ) {
|
||||
scroll.set( x - width / 2, y - height / 2 );
|
||||
}
|
||||
|
||||
public void focusOn( PointF point ) {
|
||||
focusOn( point.x, point.y );
|
||||
}
|
||||
|
||||
public void focusOn( Visual visual ) {
|
||||
focusOn( visual.center() );
|
||||
}
|
||||
|
||||
public PointF screenToCamera( int x, int y ) {
|
||||
return new PointF(
|
||||
(x - this.x) / zoom + scroll.x,
|
||||
(y - this.y) / zoom + scroll.y );
|
||||
}
|
||||
|
||||
public Point cameraToScreen( float x, float y ) {
|
||||
return new Point(
|
||||
(int)((x - scroll.x) * zoom + this.x),
|
||||
(int)((y - scroll.y) * zoom + this.y));
|
||||
}
|
||||
|
||||
public float screenWidth() {
|
||||
return width * zoom;
|
||||
}
|
||||
|
||||
public float screenHeight() {
|
||||
return height * zoom;
|
||||
}
|
||||
|
||||
protected void updateMatrix() {
|
||||
|
||||
/* Matrix.setIdentity( matrix );
|
||||
Matrix.translate( matrix, -1, +1 );
|
||||
Matrix.scale( matrix, 2f / G.width, -2f / G.height );
|
||||
Matrix.translate( matrix, x, y );
|
||||
Matrix.scale( matrix, zoom, zoom );
|
||||
Matrix.translate( matrix, scroll.x, scroll.y );*/
|
||||
|
||||
matrix[0] = +zoom * invW2;
|
||||
matrix[5] = -zoom * invH2;
|
||||
|
||||
matrix[12] = -1 + x * invW2 - (scroll.x + shakeX) * matrix[0];
|
||||
matrix[13] = +1 - y * invH2 - (scroll.y + shakeY) * matrix[5];
|
||||
|
||||
}
|
||||
|
||||
public void shake( float magnitude, float duration ) {
|
||||
shakeMagX = shakeMagY = magnitude;
|
||||
shakeTime = shakeDuration = duration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
|
||||
public class ColorBlock extends Image implements Resizable {
|
||||
|
||||
public ColorBlock( float width, float height, int color ) {
|
||||
super( TextureCache.createSolid( color ) );
|
||||
scale.set( width, height );
|
||||
origin.set( 0, 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void size( float width, float height ) {
|
||||
scale.set( width, height );
|
||||
}
|
||||
|
||||
@Override
|
||||
public float width() {
|
||||
return scale.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float height() {
|
||||
return scale.y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import com.watabou.glscripts.Script;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.input.Keys;
|
||||
import com.watabou.input.Touchscreen;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.BitmapCache;
|
||||
import com.watabou.utils.SystemTime;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.media.AudioManager;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
|
||||
public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTouchListener {
|
||||
|
||||
public static Game instance;
|
||||
|
||||
// Actual size of the screen
|
||||
public static int width;
|
||||
public static int height;
|
||||
|
||||
// Density: mdpi=1, hdpi=1.5, xhdpi=2...
|
||||
public static float density = 1;
|
||||
|
||||
public static String version;
|
||||
public static int versionCode;
|
||||
|
||||
// Current scene
|
||||
protected Scene scene;
|
||||
// New scene we are going to switch to
|
||||
protected Scene requestedScene;
|
||||
// true if scene switch is requested
|
||||
protected boolean requestedReset = true;
|
||||
// callback to perform logic during scene change
|
||||
protected SceneChangeCallback onChange;
|
||||
// New scene class
|
||||
protected Class<? extends Scene> sceneClass;
|
||||
|
||||
// Current time in milliseconds
|
||||
protected long now;
|
||||
// Milliseconds passed since previous update
|
||||
protected long step;
|
||||
|
||||
public static float timeScale = 1f;
|
||||
public static float elapsed = 0f;
|
||||
public static float timeTotal = 0f;
|
||||
|
||||
protected GLSurfaceView view;
|
||||
protected SurfaceHolder holder;
|
||||
|
||||
// Accumulated touch events
|
||||
protected ArrayList<MotionEvent> motionEvents = new ArrayList<MotionEvent>();
|
||||
|
||||
// Accumulated key events
|
||||
protected ArrayList<KeyEvent> keysEvents = new ArrayList<KeyEvent>();
|
||||
|
||||
public Game( Class<? extends Scene> c ) {
|
||||
super();
|
||||
sceneClass = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate( Bundle savedInstanceState ) {
|
||||
super.onCreate( savedInstanceState );
|
||||
|
||||
BitmapCache.context = TextureCache.context = instance = this;
|
||||
|
||||
DisplayMetrics m = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics( m );
|
||||
density = m.density;
|
||||
|
||||
try {
|
||||
version = getPackageManager().getPackageInfo( getPackageName(), 0 ).versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
version = "???";
|
||||
}
|
||||
try {
|
||||
versionCode = getPackageManager().getPackageInfo( getPackageName(), 0 ).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
versionCode = 0;
|
||||
}
|
||||
|
||||
setVolumeControlStream( AudioManager.STREAM_MUSIC );
|
||||
|
||||
view = new GLSurfaceView( this );
|
||||
view.setEGLContextClientVersion( 2 );
|
||||
view.setEGLConfigChooser( 5, 6, 5, 0, 0, 0 );
|
||||
view.setRenderer( this );
|
||||
view.setOnTouchListener( this );
|
||||
setContentView( view );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
now = 0;
|
||||
view.onResume();
|
||||
|
||||
Music.INSTANCE.resume();
|
||||
Sample.INSTANCE.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (scene != null) {
|
||||
scene.pause();
|
||||
}
|
||||
|
||||
view.onPause();
|
||||
Script.reset();
|
||||
|
||||
Music.INSTANCE.pause();
|
||||
Sample.INSTANCE.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
destroyGame();
|
||||
|
||||
Music.INSTANCE.mute();
|
||||
Sample.INSTANCE.reset();
|
||||
}
|
||||
|
||||
@SuppressLint({ "Recycle", "ClickableViewAccessibility" })
|
||||
@Override
|
||||
public boolean onTouch( View view, MotionEvent event ) {
|
||||
synchronized (motionEvents) {
|
||||
motionEvents.add( MotionEvent.obtain( event ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown( int keyCode, KeyEvent event ) {
|
||||
|
||||
if (keyCode != Keys.BACK &&
|
||||
keyCode != Keys.MENU) {
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (motionEvents) {
|
||||
keysEvents.add( event );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp( int keyCode, KeyEvent event ) {
|
||||
|
||||
if (keyCode != Keys.BACK &&
|
||||
keyCode != Keys.MENU) {
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (motionEvents) {
|
||||
keysEvents.add( event );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawFrame( GL10 gl ) {
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SystemTime.tick();
|
||||
long rightNow = SystemTime.now;
|
||||
step = (now == 0 ? 0 : rightNow - now);
|
||||
now = rightNow;
|
||||
|
||||
step();
|
||||
|
||||
NoosaScript.get().resetCamera();
|
||||
GLES20.glScissor( 0, 0, width, height );
|
||||
GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );
|
||||
draw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged( GL10 gl, int width, int height ) {
|
||||
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
|
||||
if (height != Game.height || width != Game.width) {
|
||||
|
||||
Game.width = width;
|
||||
Game.height = height;
|
||||
|
||||
resetScene();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated( GL10 gl, EGLConfig config ) {
|
||||
GLES20.glEnable( GL10.GL_BLEND );
|
||||
// For premultiplied alpha:
|
||||
// GLES20.glBlendFunc( GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA );
|
||||
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
GLES20.glEnable( GL10.GL_SCISSOR_TEST );
|
||||
|
||||
TextureCache.reload();
|
||||
RenderedText.reloadCache();
|
||||
}
|
||||
|
||||
protected void destroyGame() {
|
||||
if (scene != null) {
|
||||
scene.destroy();
|
||||
scene = null;
|
||||
}
|
||||
|
||||
//instance = null;
|
||||
}
|
||||
|
||||
public static void resetScene() {
|
||||
switchScene( instance.sceneClass );
|
||||
}
|
||||
|
||||
public static void switchScene(Class<? extends Scene> c) {
|
||||
switchScene(c, null);
|
||||
}
|
||||
|
||||
public static void switchScene(Class<? extends Scene> c, SceneChangeCallback callback) {
|
||||
instance.sceneClass = c;
|
||||
instance.requestedReset = true;
|
||||
instance.onChange = callback;
|
||||
}
|
||||
|
||||
public static Scene scene() {
|
||||
return instance.scene;
|
||||
}
|
||||
|
||||
protected void step() {
|
||||
|
||||
if (requestedReset) {
|
||||
requestedReset = false;
|
||||
|
||||
try {
|
||||
requestedScene = sceneClass.newInstance();
|
||||
switchScene();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
protected void draw() {
|
||||
scene.draw();
|
||||
}
|
||||
|
||||
protected void switchScene() {
|
||||
|
||||
Camera.reset();
|
||||
|
||||
if (scene != null) {
|
||||
scene.destroy();
|
||||
}
|
||||
scene = requestedScene;
|
||||
if (onChange != null) onChange.beforeCreate();
|
||||
scene.create();
|
||||
if (onChange != null) onChange.afterCreate();
|
||||
onChange = null;
|
||||
|
||||
Game.elapsed = 0f;
|
||||
Game.timeScale = 1f;
|
||||
Game.timeTotal = 0f;
|
||||
}
|
||||
|
||||
protected void update() {
|
||||
Game.elapsed = Game.timeScale * step * 0.001f;
|
||||
Game.timeTotal += Game.elapsed;
|
||||
|
||||
synchronized (motionEvents) {
|
||||
Touchscreen.processTouchEvents( motionEvents );
|
||||
motionEvents.clear();
|
||||
}
|
||||
synchronized (keysEvents) {
|
||||
Keys.processTouchEvents( keysEvents );
|
||||
keysEvents.clear();
|
||||
}
|
||||
|
||||
scene.update();
|
||||
Camera.updateAll();
|
||||
}
|
||||
|
||||
public static void vibrate( int milliseconds ) {
|
||||
((Vibrator)instance.getSystemService( VIBRATOR_SERVICE )).vibrate( milliseconds );
|
||||
}
|
||||
|
||||
public interface SceneChangeCallback{
|
||||
void beforeCreate();
|
||||
void afterCreate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
public class Gizmo {
|
||||
|
||||
public boolean exists;
|
||||
public boolean alive;
|
||||
public boolean active;
|
||||
public boolean visible;
|
||||
|
||||
public Group parent;
|
||||
|
||||
public Camera camera;
|
||||
|
||||
public Gizmo() {
|
||||
exists = true;
|
||||
alive = true;
|
||||
active = true;
|
||||
visible = true;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
parent = null;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
alive = false;
|
||||
exists = false;
|
||||
}
|
||||
|
||||
// Not exactly opposite to "kill" method
|
||||
public void revive() {
|
||||
alive = true;
|
||||
exists = true;
|
||||
}
|
||||
|
||||
public Camera camera() {
|
||||
if (camera != null) {
|
||||
return camera;
|
||||
} else if (parent != null) {
|
||||
return parent.camera();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
if (parent == null) {
|
||||
return visible;
|
||||
} else {
|
||||
return visible && parent.isVisible();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
if (parent == null) {
|
||||
return active;
|
||||
} else {
|
||||
return active && parent.isActive();
|
||||
}
|
||||
}
|
||||
|
||||
public void killAndErase() {
|
||||
kill();
|
||||
if (parent != null) {
|
||||
parent.erase( this );
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (parent != null) {
|
||||
parent.remove( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Group extends Gizmo {
|
||||
|
||||
protected ArrayList<Gizmo> members;
|
||||
|
||||
// Accessing it is a little faster,
|
||||
// than calling members.getSize()
|
||||
public int length;
|
||||
|
||||
public static boolean freezeEmitters = false;
|
||||
|
||||
public Group() {
|
||||
members = new ArrayList<Gizmo>();
|
||||
length = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null) {
|
||||
g.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
members.clear();
|
||||
members = null;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null && g.exists && g.active
|
||||
//functionality for the freezing of emitters(particle effects), effects are given a second
|
||||
//from load to get started so they aren't frozen before anything is generated.
|
||||
&& !(freezeEmitters && Game.timeTotal > 1f && g instanceof Emitter)) {
|
||||
g.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null && g.exists && g.visible) {
|
||||
g.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kill() {
|
||||
// A killed group keeps all its members,
|
||||
// but they get killed too
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null && g.exists) {
|
||||
g.kill();
|
||||
}
|
||||
}
|
||||
|
||||
super.kill();
|
||||
}
|
||||
|
||||
public int indexOf( Gizmo g ) {
|
||||
return members.indexOf( g );
|
||||
}
|
||||
|
||||
public Gizmo add( Gizmo g ) {
|
||||
|
||||
if (g.parent == this) {
|
||||
return g;
|
||||
}
|
||||
|
||||
if (g.parent != null) {
|
||||
g.parent.remove( g );
|
||||
}
|
||||
|
||||
// Trying to find an empty space for a new member
|
||||
for (int i=0; i < length; i++) {
|
||||
if (members.get( i ) == null) {
|
||||
members.set( i, g );
|
||||
g.parent = this;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
members.add( g );
|
||||
g.parent = this;
|
||||
length++;
|
||||
return g;
|
||||
}
|
||||
|
||||
public Gizmo addToFront( Gizmo g){
|
||||
|
||||
if (g.parent == this) {
|
||||
return g;
|
||||
}
|
||||
|
||||
if (g.parent != null) {
|
||||
g.parent.remove( g );
|
||||
}
|
||||
|
||||
// Trying to find an empty space for a new member
|
||||
// starts from the front and never goes over a none-null element
|
||||
for (int i=length-1; i >= 0; i--) {
|
||||
if (members.get( i ) == null) {
|
||||
if (i == 0 || members.get(i - 1) != null) {
|
||||
members.set(i, g);
|
||||
g.parent = this;
|
||||
return g;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
members.add( g );
|
||||
g.parent = this;
|
||||
length++;
|
||||
return g;
|
||||
}
|
||||
|
||||
public Gizmo addToBack( Gizmo g ) {
|
||||
|
||||
if (g.parent == this) {
|
||||
sendToBack( g );
|
||||
return g;
|
||||
}
|
||||
|
||||
if (g.parent != null) {
|
||||
g.parent.remove( g );
|
||||
}
|
||||
|
||||
if (members.get( 0 ) == null) {
|
||||
members.set( 0, g );
|
||||
g.parent = this;
|
||||
return g;
|
||||
}
|
||||
|
||||
members.add( 0, g );
|
||||
g.parent = this;
|
||||
length++;
|
||||
return g;
|
||||
}
|
||||
|
||||
public Gizmo recycle( Class<? extends Gizmo> c ) {
|
||||
|
||||
Gizmo g = getFirstAvailable( c );
|
||||
if (g != null) {
|
||||
|
||||
return g;
|
||||
|
||||
} else if (c == null) {
|
||||
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
||||
try {
|
||||
return add( c.newInstance() );
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fast removal - replacing with null
|
||||
public Gizmo erase( Gizmo g ) {
|
||||
int index = members.indexOf( g );
|
||||
|
||||
if (index != -1) {
|
||||
members.set( index, null );
|
||||
g.parent = null;
|
||||
return g;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Real removal
|
||||
public Gizmo remove( Gizmo g ) {
|
||||
if (members.remove( g )) {
|
||||
length--;
|
||||
g.parent = null;
|
||||
return g;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Gizmo replace( Gizmo oldOne, Gizmo newOne ) {
|
||||
int index = members.indexOf( oldOne );
|
||||
if (index != -1) {
|
||||
members.set( index, newOne );
|
||||
newOne.parent = this;
|
||||
oldOne.parent = null;
|
||||
return newOne;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Gizmo getFirstAvailable( Class<? extends Gizmo> c ) {
|
||||
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null && !g.exists && ((c == null) || g.getClass() == c)) {
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int countLiving() {
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null && g.exists && g.alive) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public int countDead() {
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null && !g.alive) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public Gizmo random() {
|
||||
if (length > 0) {
|
||||
return members.get( (int)(Math.random() * length) );
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i=0; i < length; i++) {
|
||||
Gizmo g = members.get( i );
|
||||
if (g != null) {
|
||||
g.parent = null;
|
||||
}
|
||||
}
|
||||
members.clear();
|
||||
length = 0;
|
||||
}
|
||||
|
||||
public Gizmo bringToFront( Gizmo g ) {
|
||||
if (members.contains( g )) {
|
||||
members.remove( g );
|
||||
members.add( g );
|
||||
return g;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Gizmo sendToBack( Gizmo g ) {
|
||||
if (members.contains( g )) {
|
||||
members.remove( g );
|
||||
members.add( 0, g );
|
||||
return g;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.glwrap.Quad;
|
||||
|
||||
public class Image extends Visual {
|
||||
|
||||
public SmartTexture texture;
|
||||
protected RectF frame;
|
||||
|
||||
public boolean flipHorizontal;
|
||||
public boolean flipVertical;
|
||||
|
||||
protected float[] vertices;
|
||||
protected FloatBuffer verticesBuffer;
|
||||
|
||||
protected boolean dirty;
|
||||
|
||||
public Image() {
|
||||
super( 0, 0, 0, 0 );
|
||||
|
||||
vertices = new float[16];
|
||||
verticesBuffer = Quad.create();
|
||||
}
|
||||
|
||||
public Image( Image src ) {
|
||||
this();
|
||||
copy( src );
|
||||
}
|
||||
|
||||
public Image( Object tx ) {
|
||||
this();
|
||||
texture( tx );
|
||||
}
|
||||
|
||||
public Image( Object tx, int left, int top, int width, int height ) {
|
||||
this( tx );
|
||||
frame( texture.uvRect( left, top, left + width, top + height ) );
|
||||
}
|
||||
|
||||
public void texture( Object tx ) {
|
||||
texture = tx instanceof SmartTexture ? (SmartTexture)tx : TextureCache.get( tx );
|
||||
frame( new RectF( 0, 0, 1, 1 ) );
|
||||
}
|
||||
|
||||
public void frame( RectF frame ) {
|
||||
this.frame = frame;
|
||||
|
||||
width = frame.width() * texture.width;
|
||||
height = frame.height() * texture.height;
|
||||
|
||||
updateFrame();
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
public void frame( int left, int top, int width, int height ) {
|
||||
frame( texture.uvRect( left, top, left + width, top + height ) );
|
||||
}
|
||||
|
||||
public RectF frame() {
|
||||
return new RectF( frame );
|
||||
}
|
||||
|
||||
public void copy( Image other ) {
|
||||
texture = other.texture;
|
||||
frame = new RectF( other.frame );
|
||||
|
||||
width = other.width;
|
||||
height = other.height;
|
||||
|
||||
updateFrame();
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
protected void updateFrame() {
|
||||
|
||||
if (flipHorizontal) {
|
||||
vertices[2] = frame.right;
|
||||
vertices[6] = frame.left;
|
||||
vertices[10] = frame.left;
|
||||
vertices[14] = frame.right;
|
||||
} else {
|
||||
vertices[2] = frame.left;
|
||||
vertices[6] = frame.right;
|
||||
vertices[10] = frame.right;
|
||||
vertices[14] = frame.left;
|
||||
}
|
||||
|
||||
if (flipVertical) {
|
||||
vertices[3] = frame.bottom;
|
||||
vertices[7] = frame.bottom;
|
||||
vertices[11] = frame.top;
|
||||
vertices[15] = frame.top;
|
||||
} else {
|
||||
vertices[3] = frame.top;
|
||||
vertices[7] = frame.top;
|
||||
vertices[11] = frame.bottom;
|
||||
vertices[15] = frame.bottom;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
protected void updateVertices() {
|
||||
|
||||
vertices[0] = 0;
|
||||
vertices[1] = 0;
|
||||
|
||||
vertices[4] = width;
|
||||
vertices[5] = 0;
|
||||
|
||||
vertices[8] = width;
|
||||
vertices[9] = height;
|
||||
|
||||
vertices[12] = 0;
|
||||
vertices[13] = height;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
super.draw();
|
||||
|
||||
NoosaScript script = NoosaScript.get();
|
||||
|
||||
texture.bind();
|
||||
|
||||
script.camera( camera() );
|
||||
|
||||
script.uModel.valueM4( matrix );
|
||||
script.lighting(
|
||||
rm, gm, bm, am,
|
||||
ra, ga, ba, aa );
|
||||
|
||||
if (dirty) {
|
||||
verticesBuffer.position( 0 );
|
||||
verticesBuffer.put( vertices );
|
||||
dirty = false;
|
||||
}
|
||||
script.drawQuad( verticesBuffer );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
public class MovieClip extends Image {
|
||||
|
||||
protected Animation curAnim;
|
||||
protected int curFrame;
|
||||
protected float frameTimer;
|
||||
protected boolean finished;
|
||||
|
||||
public boolean paused = false;
|
||||
|
||||
public Listener listener;
|
||||
|
||||
public MovieClip() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MovieClip( Object tx ) {
|
||||
super( tx );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
if (!paused) {
|
||||
updateAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean looping(){
|
||||
return curAnim != null && curAnim.looped;
|
||||
}
|
||||
|
||||
protected void updateAnimation() {
|
||||
if (curAnim != null && curAnim.delay > 0 && (curAnim.looped || !finished)) {
|
||||
|
||||
int lastFrame = curFrame;
|
||||
|
||||
frameTimer += Game.elapsed;
|
||||
while (frameTimer > curAnim.delay) {
|
||||
frameTimer -= curAnim.delay;
|
||||
if (curFrame == curAnim.frames.length - 1) {
|
||||
if (curAnim.looped) {
|
||||
curFrame = 0;
|
||||
}
|
||||
finished = true;
|
||||
if (listener != null) {
|
||||
listener.onComplete( curAnim );
|
||||
// This check can probably be removed
|
||||
if (curAnim == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
curFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
if (curFrame != lastFrame) {
|
||||
frame( curAnim.frames[curFrame] );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void play( Animation anim ) {
|
||||
play( anim, false );
|
||||
}
|
||||
|
||||
public void play( Animation anim, boolean force ) {
|
||||
|
||||
if (!force && (curAnim != null) && (curAnim == anim) && (curAnim.looped || !finished)) {
|
||||
return;
|
||||
}
|
||||
|
||||
curAnim = anim;
|
||||
curFrame = 0;
|
||||
finished = false;
|
||||
|
||||
frameTimer = 0;
|
||||
|
||||
if (anim != null) {
|
||||
frame( anim.frames[curFrame] );
|
||||
}
|
||||
}
|
||||
|
||||
public static class Animation {
|
||||
|
||||
public float delay;
|
||||
public RectF[] frames;
|
||||
public boolean looped;
|
||||
|
||||
public Animation( int fps, boolean looped ) {
|
||||
this.delay = 1f / fps;
|
||||
this.looped = looped;
|
||||
}
|
||||
|
||||
public Animation frames( RectF... frames ) {
|
||||
this.frames = frames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Animation frames( TextureFilm film, Object... frames ) {
|
||||
this.frames = new RectF[frames.length];
|
||||
for (int i=0; i < frames.length; i++) {
|
||||
this.frames[i] = film.get( frames[i] );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Animation clone() {
|
||||
return new Animation( Math.round( 1 / delay ), looped ).frames( frames );
|
||||
}
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onComplete( Animation anim );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Quad;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
public class NinePatch extends Visual {
|
||||
|
||||
public SmartTexture texture;
|
||||
|
||||
protected float[] vertices;
|
||||
protected FloatBuffer verticesBuffer;
|
||||
|
||||
protected RectF outterF;
|
||||
protected RectF innerF;
|
||||
|
||||
protected int marginLeft;
|
||||
protected int marginRight;
|
||||
protected int marginTop;
|
||||
protected int marginBottom;
|
||||
|
||||
protected float nWidth;
|
||||
protected float nHeight;
|
||||
|
||||
protected boolean flipHorizontal;
|
||||
protected boolean flipVertical;
|
||||
|
||||
public NinePatch( Object tx, int margin ) {
|
||||
this( tx, margin, margin, margin, margin );
|
||||
}
|
||||
|
||||
public NinePatch( Object tx, int left, int top, int right, int bottom ) {
|
||||
this( tx, 0, 0, 0, 0, left, top, right, bottom );
|
||||
}
|
||||
|
||||
public NinePatch( Object tx, int x, int y, int w, int h, int margin ) {
|
||||
this( tx, x, y, w, h, margin, margin, margin, margin );
|
||||
}
|
||||
|
||||
public NinePatch( Object tx, int x, int y, int w, int h, int left, int top, int right, int bottom ) {
|
||||
super( 0, 0, 0, 0 );
|
||||
|
||||
texture = TextureCache.get( tx );
|
||||
w = w == 0 ? texture.width : w;
|
||||
h = h == 0 ? texture.height : h;
|
||||
|
||||
nWidth = width = w;
|
||||
nHeight = height = h;
|
||||
|
||||
vertices = new float[16];
|
||||
verticesBuffer = Quad.createSet( 9 );
|
||||
|
||||
marginLeft = left;
|
||||
marginRight = right;
|
||||
marginTop = top;
|
||||
marginBottom= bottom;
|
||||
|
||||
outterF = texture.uvRect( x, y, x + w, y + h );
|
||||
innerF = texture.uvRect( x + left, y + top, x + w - right, y + h - bottom );
|
||||
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
protected void updateVertices() {
|
||||
|
||||
verticesBuffer.position( 0 );
|
||||
|
||||
float right = width - marginRight;
|
||||
float bottom = height - marginBottom;
|
||||
|
||||
float outleft = flipHorizontal ? outterF.right : outterF.left;
|
||||
float outright = flipHorizontal ? outterF.left : outterF.right;
|
||||
float outtop = flipVertical ? outterF.bottom : outterF.top;
|
||||
float outbottom = flipVertical ? outterF.top : outterF.bottom;
|
||||
|
||||
float inleft = flipHorizontal ? innerF.right : innerF.left;
|
||||
float inright = flipHorizontal ? innerF.left : innerF.right;
|
||||
float intop = flipVertical ? innerF.bottom : innerF.top;
|
||||
float inbottom = flipVertical ? innerF.top : innerF.bottom;
|
||||
|
||||
Quad.fill( vertices,
|
||||
0, marginLeft, 0, marginTop, outleft, inleft, outtop, intop );
|
||||
verticesBuffer.put( vertices );
|
||||
Quad.fill( vertices,
|
||||
marginLeft, right, 0, marginTop, inleft, inright, outtop, intop );
|
||||
verticesBuffer.put( vertices );
|
||||
Quad.fill( vertices,
|
||||
right, width, 0, marginTop, inright, outright, outtop, intop );
|
||||
verticesBuffer.put( vertices );
|
||||
|
||||
Quad.fill( vertices,
|
||||
0, marginLeft, marginTop, bottom, outleft, inleft, intop, inbottom );
|
||||
verticesBuffer.put( vertices );
|
||||
Quad.fill( vertices,
|
||||
marginLeft, right, marginTop, bottom, inleft, inright, intop, inbottom );
|
||||
verticesBuffer.put( vertices );
|
||||
Quad.fill( vertices,
|
||||
right, width, marginTop, bottom, inright, outright, intop, inbottom );
|
||||
verticesBuffer.put( vertices );
|
||||
|
||||
Quad.fill( vertices,
|
||||
0, marginLeft, bottom, height, outleft, inleft, inbottom, outbottom );
|
||||
verticesBuffer.put( vertices );
|
||||
Quad.fill( vertices,
|
||||
marginLeft, right, bottom, height, inleft, inright, inbottom, outbottom );
|
||||
verticesBuffer.put( vertices );
|
||||
Quad.fill( vertices,
|
||||
right, width, bottom, height, inright, outright, inbottom, outbottom );
|
||||
verticesBuffer.put( vertices );
|
||||
}
|
||||
|
||||
public int marginLeft() {
|
||||
return marginLeft;
|
||||
}
|
||||
|
||||
public int marginRight() {
|
||||
return marginRight;
|
||||
}
|
||||
|
||||
public int marginTop() {
|
||||
return marginTop;
|
||||
}
|
||||
|
||||
public int marginBottom() {
|
||||
return marginBottom;
|
||||
}
|
||||
|
||||
public int marginHor() {
|
||||
return marginLeft + marginRight;
|
||||
}
|
||||
|
||||
public int marginVer() {
|
||||
return marginTop + marginBottom;
|
||||
}
|
||||
|
||||
public float innerWidth() {
|
||||
return width - marginLeft - marginRight;
|
||||
}
|
||||
|
||||
public float innerHeight() {
|
||||
return height - marginTop - marginBottom;
|
||||
}
|
||||
|
||||
public float innerRight() {
|
||||
return width - marginRight;
|
||||
}
|
||||
|
||||
public float innerBottom() {
|
||||
return height - marginBottom;
|
||||
}
|
||||
|
||||
public void flipHorizontal(boolean value) {
|
||||
flipHorizontal = value;
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
public void flipVertical(boolean value) {
|
||||
flipVertical = value;
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
public void size( float width, float height ) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
super.draw();
|
||||
|
||||
NoosaScript script = NoosaScript.get();
|
||||
|
||||
texture.bind();
|
||||
|
||||
script.camera( camera() );
|
||||
|
||||
script.uModel.valueM4( matrix );
|
||||
script.lighting(
|
||||
rm, gm, bm, am,
|
||||
ra, ga, ba, aa );
|
||||
|
||||
script.drawQuadSet( verticesBuffer, 9 );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
|
||||
import com.watabou.glscripts.Script;
|
||||
import com.watabou.glwrap.Attribute;
|
||||
import com.watabou.glwrap.Quad;
|
||||
import com.watabou.glwrap.Uniform;
|
||||
|
||||
public class NoosaScript extends Script {
|
||||
|
||||
public Uniform uCamera;
|
||||
public Uniform uModel;
|
||||
public Uniform uTex;
|
||||
public Uniform uColorM;
|
||||
public Uniform uColorA;
|
||||
public Attribute aXY;
|
||||
public Attribute aUV;
|
||||
|
||||
private Camera lastCamera;
|
||||
|
||||
public NoosaScript() {
|
||||
|
||||
super();
|
||||
compile( shader() );
|
||||
|
||||
uCamera = uniform( "uCamera" );
|
||||
uModel = uniform( "uModel" );
|
||||
uTex = uniform( "uTex" );
|
||||
uColorM = uniform( "uColorM" );
|
||||
uColorA = uniform( "uColorA" );
|
||||
aXY = attribute( "aXYZW" );
|
||||
aUV = attribute( "aUV" );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use() {
|
||||
|
||||
super.use();
|
||||
|
||||
aXY.enable();
|
||||
aUV.enable();
|
||||
|
||||
}
|
||||
|
||||
public void drawElements( FloatBuffer vertices, ShortBuffer indices, int size ) {
|
||||
|
||||
vertices.position( 0 );
|
||||
aXY.vertexPointer( 2, 4, vertices );
|
||||
|
||||
vertices.position( 2 );
|
||||
aUV.vertexPointer( 2, 4, vertices );
|
||||
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, size, GLES20.GL_UNSIGNED_SHORT, indices );
|
||||
|
||||
}
|
||||
|
||||
public void drawQuad( FloatBuffer vertices ) {
|
||||
|
||||
vertices.position( 0 );
|
||||
aXY.vertexPointer( 2, 4, vertices );
|
||||
|
||||
vertices.position( 2 );
|
||||
aUV.vertexPointer( 2, 4, vertices );
|
||||
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE, GLES20.GL_UNSIGNED_SHORT, Quad.getIndices( 1 ) );
|
||||
|
||||
}
|
||||
|
||||
public void drawQuadSet( FloatBuffer vertices, int size ) {
|
||||
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
vertices.position( 0 );
|
||||
aXY.vertexPointer( 2, 4, vertices );
|
||||
|
||||
vertices.position( 2 );
|
||||
aUV.vertexPointer( 2, 4, vertices );
|
||||
|
||||
GLES20.glDrawElements(
|
||||
GLES20.GL_TRIANGLES,
|
||||
Quad.SIZE * size,
|
||||
GLES20.GL_UNSIGNED_SHORT,
|
||||
Quad.getIndices( size ) );
|
||||
|
||||
}
|
||||
|
||||
public void lighting( float rm, float gm, float bm, float am, float ra, float ga, float ba, float aa ) {
|
||||
uColorM.value4f( rm, gm, bm, am );
|
||||
uColorA.value4f( ra, ga, ba, aa );
|
||||
}
|
||||
|
||||
public void resetCamera() {
|
||||
lastCamera = null;
|
||||
}
|
||||
|
||||
public void camera( Camera camera ) {
|
||||
if (camera == null) {
|
||||
camera = Camera.main;
|
||||
}
|
||||
if (camera != lastCamera && camera.matrix != null) {
|
||||
lastCamera = camera;
|
||||
uCamera.valueM4( camera.matrix );
|
||||
|
||||
GLES20.glScissor(
|
||||
camera.x,
|
||||
Game.height - camera.screenHeight - camera.y,
|
||||
camera.screenWidth,
|
||||
camera.screenHeight );
|
||||
}
|
||||
}
|
||||
|
||||
public static NoosaScript get() {
|
||||
return Script.use( NoosaScript.class );
|
||||
}
|
||||
|
||||
|
||||
protected String shader() {
|
||||
return SHADER;
|
||||
}
|
||||
|
||||
private static final String SHADER =
|
||||
|
||||
"uniform mat4 uCamera;" +
|
||||
"uniform mat4 uModel;" +
|
||||
"attribute vec4 aXYZW;" +
|
||||
"attribute vec2 aUV;" +
|
||||
"varying vec2 vUV;" +
|
||||
"void main() {" +
|
||||
" gl_Position = uCamera * uModel * aXYZW;" +
|
||||
" vUV = aUV;" +
|
||||
"}" +
|
||||
|
||||
"//\n" +
|
||||
|
||||
"precision mediump float;" +
|
||||
"varying vec2 vUV;" +
|
||||
"uniform sampler2D uTex;" +
|
||||
"uniform vec4 uColorM;" +
|
||||
"uniform vec4 uColorA;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = texture2D( uTex, vUV ) * uColorM + uColorA;" +
|
||||
"}";
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
|
||||
public class PseudoPixel extends Image {
|
||||
|
||||
public PseudoPixel() {
|
||||
super( TextureCache.createSolid( 0xFFFFFFFF ) );
|
||||
}
|
||||
|
||||
public PseudoPixel( float x, float y, int color ) {
|
||||
|
||||
this();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
color( color );
|
||||
}
|
||||
|
||||
public void size( float w, float h ) {
|
||||
scale.set( w, h );
|
||||
}
|
||||
|
||||
public void size( float value ) {
|
||||
scale.set( value );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.glwrap.Texture;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RenderedText extends Image {
|
||||
|
||||
private static Canvas canvas = new Canvas();
|
||||
private static Paint painter = new Paint();
|
||||
|
||||
private static Typeface font;
|
||||
|
||||
//this is basically a LRU cache. capacity is determined by character count, not entry count.
|
||||
//will attempt to clear oldest, not in use entires until there are 500 characters stored.
|
||||
//FIXME: Caching based on words is very inefficient for every language but chinese.
|
||||
private static LinkedHashMap<String, CachedText> textCache =
|
||||
new LinkedHashMap<String, CachedText>(700, 0.75f, true){
|
||||
private int cachedChars = 0;
|
||||
private final int MAX_CACHED = 500;
|
||||
|
||||
@Override
|
||||
public CachedText put(String key, CachedText value) {
|
||||
cachedChars += value.length;
|
||||
CachedText added = super.put(key, value);
|
||||
runGC();
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedText remove(Object key) {
|
||||
CachedText removed = super.remove(key);
|
||||
if (removed != null) {
|
||||
cachedChars-= removed.length;
|
||||
removed.texture.delete();
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
cachedChars = 0;
|
||||
}
|
||||
|
||||
private void runGC(){
|
||||
Iterator<Map.Entry<String, CachedText>> it = this.entrySet().iterator();
|
||||
while (cachedChars > MAX_CACHED && it.hasNext()){
|
||||
CachedText cached = it.next().getValue();
|
||||
if (cached.activeTexts.isEmpty()) it.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private int size;
|
||||
private String text;
|
||||
private CachedText cache;
|
||||
|
||||
public RenderedText( ){
|
||||
text = null;
|
||||
}
|
||||
|
||||
public RenderedText( int size ){
|
||||
text = null;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public RenderedText(String text, int size){
|
||||
this.text = text;
|
||||
this.size = size;
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
public void text( String text ){
|
||||
this.text = text;
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
public String text(){
|
||||
return text;
|
||||
}
|
||||
|
||||
public void size( int size ){
|
||||
this.size = size;
|
||||
render();
|
||||
}
|
||||
|
||||
public float baseLine(){
|
||||
return size * scale.y;
|
||||
}
|
||||
|
||||
private void render(){
|
||||
if ( text == null || text.equals("") ) {
|
||||
text = "";
|
||||
width=height=0;
|
||||
visible = false;
|
||||
return;
|
||||
} else {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
if (cache != null)
|
||||
cache.activeTexts.remove(this);
|
||||
|
||||
String key = "text:" + size + " " + text;
|
||||
if (textCache.containsKey(key)){
|
||||
cache = textCache.get(key);
|
||||
texture = cache.texture;
|
||||
frame(cache.rect);
|
||||
cache.activeTexts.add(this);
|
||||
} else {
|
||||
|
||||
painter.setTextSize(size);
|
||||
painter.setAntiAlias(true);
|
||||
|
||||
if (font != null) {
|
||||
painter.setTypeface(font);
|
||||
} else {
|
||||
painter.setTypeface(Typeface.DEFAULT);
|
||||
}
|
||||
|
||||
//paint outer strokes
|
||||
painter.setARGB(0xff, 0, 0, 0);
|
||||
painter.setStyle(Paint.Style.STROKE);
|
||||
painter.setStrokeWidth(size / 5f);
|
||||
|
||||
int right = (int)(painter.measureText(text)+ (size/5f));
|
||||
int bottom = (int)(-painter.ascent() + painter.descent()+ (size/5f));
|
||||
|
||||
//bitmap has to be in a power of 2 for some devices (as we're using openGL methods to render to texture)
|
||||
Bitmap bitmap = Bitmap.createBitmap(Integer.highestOneBit(right)*2, Integer.highestOneBit(bottom)*2, Bitmap.Config.ARGB_4444);
|
||||
bitmap.eraseColor(0x00000000);
|
||||
|
||||
canvas.setBitmap(bitmap);
|
||||
canvas.drawText(text, (size/10f), size, painter);
|
||||
|
||||
//paint inner text
|
||||
painter.setARGB(0xff, 0xff, 0xff, 0xff);
|
||||
painter.setStyle(Paint.Style.FILL);
|
||||
|
||||
canvas.drawText(text, (size/10f), size, painter);
|
||||
|
||||
texture = new SmartTexture(bitmap, Texture.NEAREST, Texture.CLAMP, true);
|
||||
|
||||
RectF rect = texture.uvRect(0, 0, right, bottom);
|
||||
frame(rect);
|
||||
|
||||
cache = new CachedText();
|
||||
cache.rect = rect;
|
||||
cache.texture = texture;
|
||||
cache.length = text.length();
|
||||
cache.activeTexts = new HashSet<>();
|
||||
cache.activeTexts.add(this);
|
||||
textCache.put("text:" + size + " " + text, cache);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateMatrix() {
|
||||
super.updateMatrix();
|
||||
//the y value is set at the top of the character, not at the top of accents.
|
||||
Matrix.translate( matrix, 0, -Math.round((baseLine()*0.15f)/scale.y) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (cache != null)
|
||||
cache.activeTexts.remove(this);
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
public static void clearCache(){
|
||||
for (CachedText cached : textCache.values()){
|
||||
cached.texture.delete();
|
||||
}
|
||||
textCache.clear();
|
||||
}
|
||||
|
||||
public static void reloadCache(){
|
||||
for (CachedText txt : textCache.values()){
|
||||
txt.texture.reload();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFont(String asset){
|
||||
font = Typeface.createFromAsset(Game.instance.getAssets(), asset);
|
||||
clearCache();
|
||||
}
|
||||
|
||||
private class CachedText{
|
||||
public SmartTexture texture;
|
||||
public RectF rect;
|
||||
public int length;
|
||||
public HashSet<RenderedText> activeTexts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
public interface Resizable {
|
||||
|
||||
public void size( float width, float height );
|
||||
public float width();
|
||||
public float height();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.input.Keys;
|
||||
import com.watabou.utils.Signal;
|
||||
|
||||
public class Scene extends Group {
|
||||
|
||||
private Signal.Listener<Keys.Key> keyListener;
|
||||
|
||||
public void create() {
|
||||
Keys.event.add( keyListener = new Signal.Listener<Keys.Key>() {
|
||||
@Override
|
||||
public void onSignal( Keys.Key key ) {
|
||||
if (Game.instance != null && key.pressed) {
|
||||
switch (key.code) {
|
||||
case Keys.BACK:
|
||||
onBackPressed();
|
||||
break;
|
||||
case Keys.MENU:
|
||||
onMenuPressed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Keys.event.remove( keyListener );
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Camera camera() {
|
||||
return Camera.main;
|
||||
}
|
||||
|
||||
protected void onBackPressed() {
|
||||
Game.instance.finish();
|
||||
}
|
||||
|
||||
protected void onMenuPressed() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.glwrap.Texture;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
public class SkinnedBlock extends Image {
|
||||
|
||||
protected float scaleX;
|
||||
protected float scaleY;
|
||||
|
||||
protected float offsetX;
|
||||
protected float offsetY;
|
||||
|
||||
public boolean autoAdjust = false;
|
||||
|
||||
public SkinnedBlock( float width, float height, Object tx ) {
|
||||
super( tx );
|
||||
|
||||
texture.wrap( Texture.REPEAT, Texture.REPEAT );
|
||||
|
||||
size( width, height );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frame( RectF frame ) {
|
||||
scaleX = 1;
|
||||
scaleY = 1;
|
||||
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
|
||||
super.frame( new RectF( 0, 0, 1, 1 ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFrame() {
|
||||
|
||||
if (autoAdjust) {
|
||||
while (offsetX > texture.width) {
|
||||
offsetX -= texture.width;
|
||||
}
|
||||
while (offsetX < -texture.width) {
|
||||
offsetX += texture.width;
|
||||
}
|
||||
while (offsetY > texture.height) {
|
||||
offsetY -= texture.height;
|
||||
}
|
||||
while (offsetY < -texture.height) {
|
||||
offsetY += texture.height;
|
||||
}
|
||||
}
|
||||
|
||||
float tw = 1f / texture.width;
|
||||
float th = 1f / texture.height;
|
||||
|
||||
float u0 = offsetX * tw;
|
||||
float v0 = offsetY * th;
|
||||
float u1 = u0 + width * tw / scaleX;
|
||||
float v1 = v0 + height * th / scaleY;
|
||||
|
||||
vertices[2] = u0;
|
||||
vertices[3] = v0;
|
||||
|
||||
vertices[6] = u1;
|
||||
vertices[7] = v0;
|
||||
|
||||
vertices[10] = u1;
|
||||
vertices[11] = v1;
|
||||
|
||||
vertices[14] = u0;
|
||||
vertices[15] = v1;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void offsetTo( float x, float y ) {
|
||||
offsetX = x;
|
||||
offsetY = y;
|
||||
updateFrame();
|
||||
}
|
||||
|
||||
public void offset( float x, float y ) {
|
||||
offsetX += x;
|
||||
offsetY += y;
|
||||
updateFrame();
|
||||
}
|
||||
|
||||
public float offsetX() {
|
||||
return offsetX;
|
||||
}
|
||||
|
||||
public float offsetY() {
|
||||
return offsetY;
|
||||
}
|
||||
|
||||
public void scale( float x, float y ) {
|
||||
scaleX = x;
|
||||
scaleY = y;
|
||||
updateFrame();
|
||||
}
|
||||
|
||||
public void size( float w, float h ) {
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
updateFrame();
|
||||
updateVertices();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
public class TextureFilm {
|
||||
|
||||
private static final RectF FULL = new RectF( 0, 0, 1, 1 );
|
||||
|
||||
private int texWidth;
|
||||
private int texHeight;
|
||||
|
||||
protected HashMap<Object,RectF> frames = new HashMap<Object, RectF>();
|
||||
|
||||
public TextureFilm( Object tx ) {
|
||||
|
||||
SmartTexture texture = TextureCache.get( tx );
|
||||
|
||||
texWidth = texture.width;
|
||||
texHeight = texture.height;
|
||||
|
||||
add( null, FULL );
|
||||
}
|
||||
|
||||
public TextureFilm( SmartTexture texture, int width ) {
|
||||
this( texture, width, texture.height );
|
||||
}
|
||||
|
||||
public TextureFilm( Object tx, int width, int height ) {
|
||||
|
||||
SmartTexture texture = TextureCache.get( tx );
|
||||
|
||||
texWidth = texture.width;
|
||||
texHeight = texture.height;
|
||||
|
||||
float uw = (float)width / texWidth;
|
||||
float vh = (float)height / texHeight;
|
||||
int cols = texWidth / width;
|
||||
int rows = texHeight / height;
|
||||
|
||||
for (int i=0; i < rows; i++) {
|
||||
for (int j=0; j < cols; j++) {
|
||||
RectF rect = new RectF( j * uw, i * vh, (j+1) * uw, (i+1) * vh );
|
||||
add( i * cols + j, rect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TextureFilm( TextureFilm atlas, Object key, int width, int height ) {
|
||||
|
||||
texWidth = atlas.texWidth;
|
||||
texHeight = atlas.texHeight;
|
||||
|
||||
RectF patch = atlas.get( key );
|
||||
|
||||
float uw = (float)width / texWidth;
|
||||
float vh = (float)height / texHeight;
|
||||
int cols = (int)(width( patch ) / width);
|
||||
int rows = (int)(height( patch ) / height);
|
||||
|
||||
for (int i=0; i < rows; i++) {
|
||||
for (int j=0; j < cols; j++) {
|
||||
RectF rect = new RectF( j * uw, i * vh, (j+1) * uw, (i+1) * vh );
|
||||
rect.offset( patch.left, patch.top );
|
||||
add( i * cols + j, rect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add( Object id, RectF rect ) {
|
||||
frames.put( id, rect );
|
||||
}
|
||||
|
||||
public RectF get( Object id ) {
|
||||
return frames.get( id );
|
||||
}
|
||||
|
||||
public float width( RectF frame ) {
|
||||
return frame.width() * texWidth;
|
||||
}
|
||||
|
||||
public float height( RectF frame ) {
|
||||
return frame.height() * texHeight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Quad;
|
||||
import com.watabou.utils.Rect;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
public class Tilemap extends Visual {
|
||||
|
||||
protected SmartTexture texture;
|
||||
protected TextureFilm tileset;
|
||||
|
||||
protected int[] data;
|
||||
protected int mapWidth;
|
||||
protected int mapHeight;
|
||||
protected int size;
|
||||
|
||||
private float cellW;
|
||||
private float cellH;
|
||||
|
||||
protected float[] vertices;
|
||||
protected FloatBuffer quads;
|
||||
|
||||
public Rect updated;
|
||||
|
||||
public Tilemap( Object tx, TextureFilm tileset ) {
|
||||
|
||||
super( 0, 0, 0, 0 );
|
||||
|
||||
this.texture = TextureCache.get( tx );
|
||||
this.tileset = tileset;
|
||||
|
||||
RectF r = tileset.get( 0 );
|
||||
cellW = tileset.width( r );
|
||||
cellH = tileset.height( r );
|
||||
|
||||
vertices = new float[16];
|
||||
|
||||
updated = new Rect();
|
||||
}
|
||||
|
||||
public void map( int[] data, int cols ) {
|
||||
|
||||
this.data = data;
|
||||
|
||||
mapWidth = cols;
|
||||
mapHeight = data.length / cols;
|
||||
size = mapWidth * mapHeight;
|
||||
|
||||
width = cellW * mapWidth;
|
||||
height = cellH * mapHeight;
|
||||
|
||||
quads = Quad.createSet( size );
|
||||
|
||||
updated.set( 0, 0, mapWidth, mapHeight );
|
||||
}
|
||||
|
||||
protected void updateVertices() {
|
||||
|
||||
float y1 = cellH * updated.top;
|
||||
float y2 = y1 + cellH;
|
||||
|
||||
for (int i=updated.top; i < updated.bottom; i++) {
|
||||
|
||||
float x1 = cellW * updated.left;
|
||||
float x2 = x1 + cellW;
|
||||
|
||||
int pos = i * mapWidth + updated.left;
|
||||
quads.position( 16 * pos );
|
||||
|
||||
for (int j=updated.left; j < updated.right; j++) {
|
||||
|
||||
RectF uv = tileset.get( data[pos++] );
|
||||
|
||||
vertices[0] = x1;
|
||||
vertices[1] = y1;
|
||||
|
||||
vertices[2] = uv.left;
|
||||
vertices[3] = uv.top;
|
||||
|
||||
vertices[4] = x2;
|
||||
vertices[5] = y1;
|
||||
|
||||
vertices[6] = uv.right;
|
||||
vertices[7] = uv.top;
|
||||
|
||||
vertices[8] = x2;
|
||||
vertices[9] = y2;
|
||||
|
||||
vertices[10] = uv.right;
|
||||
vertices[11] = uv.bottom;
|
||||
|
||||
vertices[12] = x1;
|
||||
vertices[13] = y2;
|
||||
|
||||
vertices[14] = uv.left;
|
||||
vertices[15] = uv.bottom;
|
||||
|
||||
quads.put( vertices );
|
||||
|
||||
x1 = x2;
|
||||
x2 += cellW;
|
||||
|
||||
}
|
||||
|
||||
y1 = y2;
|
||||
y2 += cellH;
|
||||
}
|
||||
|
||||
updated.setEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
|
||||
super.draw();
|
||||
|
||||
NoosaScript script = NoosaScript.get();
|
||||
|
||||
texture.bind();
|
||||
|
||||
script.uModel.valueM4( matrix );
|
||||
script.lighting(
|
||||
rm, gm, bm, am,
|
||||
ra, ga, ba, aa );
|
||||
|
||||
if (!updated.isEmpty()) {
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
script.camera( camera );
|
||||
script.drawQuadSet( quads, size );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.input.Touchscreen;
|
||||
import com.watabou.input.Touchscreen.Touch;
|
||||
import com.watabou.utils.Signal;
|
||||
|
||||
public class TouchArea extends Visual implements Signal.Listener<Touchscreen.Touch> {
|
||||
|
||||
// Its target can be toucharea itself
|
||||
public Visual target;
|
||||
|
||||
protected Touchscreen.Touch touch = null;
|
||||
|
||||
//if true, this TouchArea will always block input, even when it is inactive
|
||||
public boolean blockWhenInactive = false;
|
||||
|
||||
public TouchArea( Visual target ) {
|
||||
super( 0, 0, 0, 0 );
|
||||
this.target = target;
|
||||
|
||||
Touchscreen.event.add( this );
|
||||
}
|
||||
|
||||
public TouchArea( float x, float y, float width, float height ) {
|
||||
super( x, y, width, height );
|
||||
this.target = this;
|
||||
|
||||
visible = false;
|
||||
|
||||
Touchscreen.event.add( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignal( Touch touch ) {
|
||||
|
||||
boolean hit = touch != null && target.overlapsScreenPoint( (int)touch.current.x, (int)touch.current.y );
|
||||
|
||||
if (!isActive()) {
|
||||
if (hit && blockWhenInactive) Touchscreen.event.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
|
||||
if (touch.down || touch == this.touch) Touchscreen.event.cancel();
|
||||
|
||||
if (touch.down) {
|
||||
|
||||
if (this.touch == null) {
|
||||
this.touch = touch;
|
||||
}
|
||||
onTouchDown( touch );
|
||||
|
||||
} else {
|
||||
|
||||
onTouchUp( touch );
|
||||
|
||||
if (this.touch == touch) {
|
||||
this.touch = null;
|
||||
onClick( touch );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (touch == null && this.touch != null) {
|
||||
onDrag( this.touch );
|
||||
}
|
||||
|
||||
else if (this.touch != null && !touch.down) {
|
||||
onTouchUp( touch );
|
||||
this.touch = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void onTouchDown( Touch touch ) {
|
||||
}
|
||||
|
||||
protected void onTouchUp( Touch touch ) {
|
||||
}
|
||||
|
||||
protected void onClick( Touch touch ) {
|
||||
}
|
||||
|
||||
protected void onDrag( Touch touch ) {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
touch = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Touchscreen.event.remove( this );
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa;
|
||||
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.utils.GameMath;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class Visual extends Gizmo {
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float width;
|
||||
public float height;
|
||||
|
||||
public PointF scale;
|
||||
public PointF origin;
|
||||
|
||||
protected float[] matrix;
|
||||
|
||||
public float rm;
|
||||
public float gm;
|
||||
public float bm;
|
||||
public float am;
|
||||
public float ra;
|
||||
public float ga;
|
||||
public float ba;
|
||||
public float aa;
|
||||
|
||||
public PointF speed;
|
||||
public PointF acc;
|
||||
|
||||
public float angle;
|
||||
public float angularSpeed;
|
||||
|
||||
public Visual( float x, float y, float width, float height ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
scale = new PointF( 1, 1 );
|
||||
origin = new PointF();
|
||||
|
||||
matrix = new float[16];
|
||||
|
||||
resetColor();
|
||||
|
||||
speed = new PointF();
|
||||
acc = new PointF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
updateMotion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
updateMatrix();
|
||||
}
|
||||
|
||||
protected void updateMatrix() {
|
||||
Matrix.setIdentity( matrix );
|
||||
Matrix.translate( matrix, x, y );
|
||||
Matrix.translate( matrix, origin.x, origin.y );
|
||||
if (angle != 0) {
|
||||
Matrix.rotate( matrix, angle );
|
||||
}
|
||||
if (scale.x != 1 || scale.y != 1) {
|
||||
Matrix.scale( matrix, scale.x, scale.y );
|
||||
}
|
||||
Matrix.translate( matrix, -origin.x, -origin.y );
|
||||
}
|
||||
|
||||
public PointF point() {
|
||||
return new PointF( x, y );
|
||||
}
|
||||
|
||||
public PointF point( PointF p ) {
|
||||
x = p.x;
|
||||
y = p.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
public Point point( Point p ) {
|
||||
x = p.x;
|
||||
y = p.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
public PointF center() {
|
||||
return new PointF( x + width / 2, y + height / 2 );
|
||||
}
|
||||
|
||||
public PointF center( PointF p ) {
|
||||
x = p.x - width / 2;
|
||||
y = p.y - height / 2;
|
||||
return p;
|
||||
}
|
||||
|
||||
public float width() {
|
||||
return width * scale.x;
|
||||
}
|
||||
|
||||
public float height() {
|
||||
return height * scale.y;
|
||||
}
|
||||
|
||||
protected void updateMotion() {
|
||||
|
||||
float elapsed = Game.elapsed;
|
||||
|
||||
float d = (GameMath.speed( speed.x, acc.x ) - speed.x) / 2;
|
||||
speed.x += d;
|
||||
x += speed.x * elapsed;
|
||||
speed.x += d;
|
||||
|
||||
d = (GameMath.speed( speed.y, acc.y ) - speed.y) / 2;
|
||||
speed.y += d;
|
||||
y += speed.y * elapsed;
|
||||
speed.y += d;
|
||||
|
||||
angle += angularSpeed * elapsed;
|
||||
}
|
||||
|
||||
public void alpha( float value ) {
|
||||
am = value;
|
||||
aa = 0;
|
||||
}
|
||||
|
||||
public float alpha() {
|
||||
return am + aa;
|
||||
}
|
||||
|
||||
public void invert() {
|
||||
rm = gm = bm = -1f;
|
||||
ra = ga = ba = +1f;
|
||||
}
|
||||
|
||||
public void lightness( float value ) {
|
||||
if (value < 0.5f) {
|
||||
rm = gm = bm = value * 2f;
|
||||
ra = ga = ba = 0;
|
||||
} else {
|
||||
rm = gm = bm = 2f - value * 2f;
|
||||
ra = ga = ba = value * 2f - 1f;
|
||||
}
|
||||
}
|
||||
|
||||
public void brightness( float value ) {
|
||||
rm = gm = bm = value;
|
||||
}
|
||||
|
||||
public void tint( float r, float g, float b, float strength ) {
|
||||
rm = gm = bm = 1f - strength;
|
||||
ra = r * strength;
|
||||
ga = g * strength;
|
||||
ba = b * strength;
|
||||
}
|
||||
|
||||
public void tint( int color, float strength ) {
|
||||
rm = gm = bm = 1f - strength;
|
||||
ra = ((color >> 16) & 0xFF) / 255f * strength;
|
||||
ga = ((color >> 8) & 0xFF) / 255f * strength;
|
||||
ba = (color & 0xFF) / 255f * strength;
|
||||
}
|
||||
|
||||
//color must include an alpha component (e.g. 0x80FF0000 for red at 0.5 strength)
|
||||
public void tint( int color ) {
|
||||
tint( color & 0xFFFFFF, ((color >> 24) & 0xFF) / (float)0xFF);
|
||||
}
|
||||
|
||||
public void color( float r, float g, float b ) {
|
||||
rm = gm = bm = 0;
|
||||
ra = r;
|
||||
ga = g;
|
||||
ba = b;
|
||||
}
|
||||
|
||||
public void color( int color ) {
|
||||
color( ((color >> 16) & 0xFF) / 255f, ((color >> 8) & 0xFF) / 255f, (color & 0xFF) / 255f );
|
||||
}
|
||||
|
||||
public void hardlight( float r, float g, float b ) {
|
||||
ra = ga = ba = 0;
|
||||
rm = r;
|
||||
gm = g;
|
||||
bm = b;
|
||||
}
|
||||
|
||||
public void hardlight( int color ) {
|
||||
hardlight( (color >> 16) / 255f, ((color >> 8) & 0xFF) / 255f, (color & 0xFF) / 255f );
|
||||
}
|
||||
|
||||
public void resetColor() {
|
||||
rm = gm = bm = am = 1;
|
||||
ra = ga = ba = aa = 0;
|
||||
}
|
||||
|
||||
public boolean overlapsPoint( float x, float y ) {
|
||||
return x >= this.x && x < this.x + width * scale.x && y >= this.y && y < this.y + height * scale.y;
|
||||
}
|
||||
|
||||
public boolean overlapsScreenPoint( int x, int y ) {
|
||||
Camera c = camera();
|
||||
|
||||
if (c == null) return false;
|
||||
|
||||
PointF p = c.screenToCamera( x, y );
|
||||
return overlapsPoint( p.x, p.y );
|
||||
}
|
||||
|
||||
// true if its bounding box intersects its camera's bounds
|
||||
public boolean isVisible() {
|
||||
Camera c = camera();
|
||||
|
||||
if (c == null) return false;
|
||||
|
||||
float cx = c.scroll.x;
|
||||
float cy = c.scroll.y;
|
||||
float w = width();
|
||||
float h = height();
|
||||
return x + w >= cx && y + h >= cy && x < cx + c.width && y < cy + c.height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.audio;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
|
||||
public enum Music implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
private MediaPlayer player;
|
||||
|
||||
private String lastPlayed;
|
||||
private boolean looping;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
public void play( String assetName, boolean looping ) {
|
||||
|
||||
if (isPlaying() && lastPlayed.equals( assetName )) {
|
||||
return;
|
||||
}
|
||||
|
||||
stop();
|
||||
|
||||
lastPlayed = assetName;
|
||||
this.looping = looping;
|
||||
|
||||
if (!enabled || assetName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
AssetFileDescriptor afd = Game.instance.getAssets().openFd( assetName );
|
||||
|
||||
player = new MediaPlayer();
|
||||
player.setAudioStreamType( AudioManager.STREAM_MUSIC );
|
||||
player.setDataSource( afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength() );
|
||||
player.setOnPreparedListener( this );
|
||||
player.setOnErrorListener( this );
|
||||
player.prepareAsync();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
player.release();
|
||||
player = null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void mute() {
|
||||
lastPlayed = null;
|
||||
stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepared( MediaPlayer player ) {
|
||||
player.start();
|
||||
player.setLooping(looping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onError( MediaPlayer mp, int what, int extra ) {
|
||||
if (player != null) {
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (player != null) {
|
||||
player.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (player != null) {
|
||||
player.start();
|
||||
player.setLooping(looping);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (player != null) {
|
||||
player.stop();
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void volume( float value ) {
|
||||
if (player != null) {
|
||||
player.setVolume( value, value );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return player != null && player.isPlaying();
|
||||
}
|
||||
|
||||
public void enable( boolean value ) {
|
||||
enabled = value;
|
||||
if (isPlaying() && !value) {
|
||||
stop();
|
||||
} else
|
||||
if (!isPlaying() && value) {
|
||||
play( lastPlayed, looping );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.audio;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.content.res.AssetManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.SoundPool;
|
||||
|
||||
public enum Sample implements SoundPool.OnLoadCompleteListener {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public static final int MAX_STREAMS = 8;
|
||||
|
||||
protected SoundPool pool =
|
||||
new SoundPool( MAX_STREAMS, AudioManager.STREAM_MUSIC, 0 );
|
||||
|
||||
protected HashMap<Object, Integer> ids =
|
||||
new HashMap<>();
|
||||
|
||||
private boolean enabled = true;
|
||||
private float volume = 1f;
|
||||
|
||||
private LinkedList<String> loadingQueue = new LinkedList<>();
|
||||
|
||||
public void reset() {
|
||||
|
||||
ids.clear();
|
||||
loadingQueue = new LinkedList<>();
|
||||
pool.release();
|
||||
|
||||
pool = new SoundPool( MAX_STREAMS, AudioManager.STREAM_MUSIC, 0 );
|
||||
pool.setOnLoadCompleteListener( this );
|
||||
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (pool != null) {
|
||||
pool.autoPause();
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (pool != null) {
|
||||
pool.autoResume();
|
||||
}
|
||||
}
|
||||
|
||||
public void load( String... assets ) {
|
||||
|
||||
for (String asset : assets) {
|
||||
loadingQueue.add( asset );
|
||||
}
|
||||
loadNext();
|
||||
}
|
||||
|
||||
private void loadNext() {
|
||||
final String asset = loadingQueue.poll();
|
||||
if (asset != null) {
|
||||
if (!ids.containsKey( asset )) {
|
||||
try {
|
||||
pool.setOnLoadCompleteListener( new SoundPool.OnLoadCompleteListener() {
|
||||
@Override
|
||||
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
|
||||
loadNext();
|
||||
}
|
||||
} );
|
||||
|
||||
AssetManager manager = Game.instance.getAssets();
|
||||
AssetFileDescriptor fd = manager.openFd( asset );
|
||||
int streamID = pool.load( fd, 1 ) ;
|
||||
ids.put( asset, streamID );
|
||||
fd.close();
|
||||
} catch (IOException e) {
|
||||
loadNext();
|
||||
} catch (NullPointerException e) {
|
||||
// Do nothing (stop loading sounds)
|
||||
}
|
||||
} else {
|
||||
loadNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unload( Object src ) {
|
||||
|
||||
if (ids.containsKey( src )) {
|
||||
|
||||
pool.unload( ids.get( src ) );
|
||||
ids.remove( src );
|
||||
}
|
||||
}
|
||||
|
||||
public int play( Object id ) {
|
||||
return play( id, 1 );
|
||||
}
|
||||
|
||||
public int play( Object id, float volume ) {
|
||||
return play( id, volume, volume, 1 );
|
||||
}
|
||||
|
||||
public int play( Object id, float leftVolume, float rightVolume, float rate ) {
|
||||
if (enabled && ids.containsKey( id )) {
|
||||
return pool.play( ids.get( id ), leftVolume*volume, rightVolume*volume, 0, 0, rate );
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void enable( boolean value ) {
|
||||
enabled = value;
|
||||
}
|
||||
|
||||
public void volume( float value ) {
|
||||
this.volume = value;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadComplete( SoundPool soundPool, int sampleId, int status ) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.particles;
|
||||
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.noosa.Image;
|
||||
import com.watabou.noosa.particles.Emitter;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class BitmaskEmitter extends Emitter {
|
||||
|
||||
// DON'T USE WITH COMPLETELY TRANSPARENT IMAGES!!!
|
||||
|
||||
private SmartTexture map;
|
||||
private int mapW;
|
||||
private int mapH;
|
||||
|
||||
public BitmaskEmitter( Image target ) {
|
||||
super();
|
||||
|
||||
this.target = target;
|
||||
|
||||
map = target.texture;
|
||||
mapW = map.bitmap.getWidth();
|
||||
mapH = map.bitmap.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void emit( int index ) {
|
||||
|
||||
RectF frame = ((Image)target).frame();
|
||||
float ofsX = frame.left * mapW;
|
||||
float ofsY = frame.top * mapH;
|
||||
|
||||
float x, y;
|
||||
do {
|
||||
x = Random.Float( frame.width() ) * mapW;
|
||||
y = Random.Float( frame.height() ) * mapH;
|
||||
} while ((map.bitmap.getPixel( (int)(x + ofsX), (int)(y + ofsY) ) & 0x000000FF) == 0);
|
||||
|
||||
factory.emit( this, index,
|
||||
target.x + x * target.scale.x,
|
||||
target.y + y * target.scale.y );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.particles;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Group;
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.utils.PointF;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class Emitter extends Group {
|
||||
|
||||
protected boolean lightMode = false;
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float width;
|
||||
public float height;
|
||||
|
||||
protected Visual target;
|
||||
public boolean fillTarget = true;
|
||||
|
||||
protected float interval;
|
||||
protected int quantity;
|
||||
|
||||
public boolean on = false;
|
||||
|
||||
public boolean autoKill = true;
|
||||
|
||||
protected int count;
|
||||
protected float time;
|
||||
|
||||
protected Factory factory;
|
||||
|
||||
public void pos( float x, float y ) {
|
||||
pos( x, y, 0, 0 );
|
||||
}
|
||||
|
||||
public void pos( PointF p ) {
|
||||
pos( p.x, p.y, 0, 0 );
|
||||
}
|
||||
|
||||
public void pos( float x, float y, float width, float height ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
target = null;
|
||||
}
|
||||
|
||||
public void pos( Visual target ) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void pos( Visual target, float x, float y, float width, float height ) {
|
||||
pos(x, y, width, height);
|
||||
pos(target);
|
||||
}
|
||||
|
||||
public void burst( Factory factory, int quantity ) {
|
||||
start( factory, 0, quantity );
|
||||
}
|
||||
|
||||
public void pour( Factory factory, float interval ) {
|
||||
start( factory, interval, 0 );
|
||||
}
|
||||
|
||||
public void start( Factory factory, float interval, int quantity ) {
|
||||
|
||||
this.factory = factory;
|
||||
this.lightMode = factory.lightMode();
|
||||
|
||||
this.interval = interval;
|
||||
this.quantity = quantity;
|
||||
|
||||
count = 0;
|
||||
time = Random.Float( interval );
|
||||
|
||||
on = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
if (on) {
|
||||
time += Game.elapsed;
|
||||
while (time > interval) {
|
||||
time -= interval;
|
||||
emit( count++ );
|
||||
if (quantity > 0 && count >= quantity) {
|
||||
on = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (autoKill && countLiving() == 0) {
|
||||
kill();
|
||||
}
|
||||
|
||||
super.update();
|
||||
}
|
||||
|
||||
protected void emit( int index ) {
|
||||
if (target == null) {
|
||||
factory.emit(
|
||||
this,
|
||||
index,
|
||||
x + Random.Float( width ),
|
||||
y + Random.Float( height ) );
|
||||
} else {
|
||||
if (fillTarget) {
|
||||
factory.emit(
|
||||
this,
|
||||
index,
|
||||
target.x + Random.Float( target.width ),
|
||||
target.y + Random.Float( target.height ) );
|
||||
} else {
|
||||
factory.emit(
|
||||
this,
|
||||
index,
|
||||
target.x + x + Random.Float( width ),
|
||||
target.y + y + Random.Float( height ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (lightMode) {
|
||||
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE );
|
||||
super.draw();
|
||||
GLES20.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
|
||||
} else {
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
abstract public static class Factory {
|
||||
|
||||
abstract public void emit( Emitter emitter, int index, float x, float y );
|
||||
|
||||
public boolean lightMode() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.particles;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.PseudoPixel;
|
||||
|
||||
public class PixelParticle extends PseudoPixel {
|
||||
|
||||
protected float size;
|
||||
|
||||
protected float lifespan;
|
||||
protected float left;
|
||||
|
||||
public PixelParticle() {
|
||||
super();
|
||||
|
||||
origin.set( +0.5f );
|
||||
}
|
||||
|
||||
public void reset( float x, float y, int color, float size, float lifespan ) {
|
||||
revive();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
color( color );
|
||||
size( this.size = size );
|
||||
|
||||
this.left = this.lifespan = lifespan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
if ((left -= Game.elapsed) <= 0) {
|
||||
kill();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Shrinking extends PixelParticle {
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
size( size * left / lifespan );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.tweeners;
|
||||
|
||||
import com.watabou.noosa.Visual;
|
||||
|
||||
public class AlphaTweener extends Tweener {
|
||||
|
||||
public Visual image;
|
||||
|
||||
public float start;
|
||||
public float delta;
|
||||
|
||||
public AlphaTweener( Visual image, float alpha, float time ) {
|
||||
super( image, time );
|
||||
|
||||
this.image = image;
|
||||
start = image.alpha();
|
||||
delta = alpha - start;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateValues( float progress ) {
|
||||
image.alpha( start + delta * progress );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.tweeners;
|
||||
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class CameraScrollTweener extends Tweener {
|
||||
|
||||
public Camera camera;
|
||||
|
||||
public PointF start;
|
||||
public PointF end;
|
||||
|
||||
public CameraScrollTweener( Camera camera, PointF pos, float time ) {
|
||||
super( camera, time );
|
||||
|
||||
this.camera = camera;
|
||||
start = camera.scroll;
|
||||
end = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateValues( float progress ) {
|
||||
camera.scroll = PointF.inter( start, end, progress );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.tweeners;
|
||||
|
||||
public class Delayer extends Tweener {
|
||||
|
||||
public Delayer() {
|
||||
super( null, 0 );
|
||||
}
|
||||
|
||||
public Delayer( float time ) {
|
||||
super( null, time );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateValues( float progress ) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.tweeners;
|
||||
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class PosTweener extends Tweener {
|
||||
|
||||
public Visual visual;
|
||||
|
||||
public PointF start;
|
||||
public PointF end;
|
||||
|
||||
public PosTweener( Visual visual, PointF pos, float time ) {
|
||||
super( visual, time );
|
||||
|
||||
this.visual = visual;
|
||||
start = visual.point();
|
||||
end = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateValues( float progress ) {
|
||||
visual.point( PointF.inter( start, end, progress ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.tweeners;
|
||||
|
||||
import com.watabou.noosa.Visual;
|
||||
import com.watabou.utils.PointF;
|
||||
|
||||
public class ScaleTweener extends Tweener {
|
||||
|
||||
public Visual visual;
|
||||
|
||||
public PointF start;
|
||||
public PointF end;
|
||||
|
||||
public ScaleTweener( Visual visual, PointF scale, float time ) {
|
||||
super( visual, time );
|
||||
|
||||
this.visual = visual;
|
||||
start = visual.scale;
|
||||
end = scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateValues( float progress ) {
|
||||
visual.scale = PointF.inter( start, end, progress );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.tweeners;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.Gizmo;
|
||||
|
||||
abstract public class Tweener extends Gizmo {
|
||||
|
||||
public Gizmo target;
|
||||
|
||||
public float interval;
|
||||
public float elapsed;
|
||||
|
||||
public Listener listener;
|
||||
|
||||
public Tweener( Gizmo target, float interval ) {
|
||||
super();
|
||||
|
||||
this.target = target;
|
||||
this.interval = interval;
|
||||
|
||||
elapsed = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
elapsed += Game.elapsed;
|
||||
if (elapsed >= interval) {
|
||||
updateValues( 1 );
|
||||
onComplete();
|
||||
kill();
|
||||
} else {
|
||||
updateValues( elapsed / interval );
|
||||
}
|
||||
}
|
||||
|
||||
protected void onComplete() {
|
||||
if (listener != null) {
|
||||
listener.onComplete( this );
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected void updateValues( float progress );
|
||||
|
||||
public static interface Listener {
|
||||
void onComplete( Tweener tweener );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.ui;
|
||||
|
||||
import com.watabou.input.Touchscreen.Touch;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.TouchArea;
|
||||
|
||||
public class Button extends Component {
|
||||
|
||||
public static float longClick = 1f;
|
||||
|
||||
protected TouchArea hotArea;
|
||||
|
||||
protected boolean pressed;
|
||||
protected float pressTime;
|
||||
|
||||
protected boolean processed;
|
||||
|
||||
@Override
|
||||
protected void createChildren() {
|
||||
hotArea = new TouchArea( 0, 0, 0, 0 ) {
|
||||
@Override
|
||||
protected void onTouchDown(Touch touch) {
|
||||
pressed = true;
|
||||
pressTime = 0;
|
||||
processed = false;
|
||||
Button.this.onTouchDown();
|
||||
};
|
||||
@Override
|
||||
protected void onTouchUp(Touch touch) {
|
||||
pressed = false;
|
||||
Button.this.onTouchUp();
|
||||
};
|
||||
@Override
|
||||
protected void onClick( Touch touch ) {
|
||||
if (!processed) {
|
||||
Button.this.onClick();
|
||||
}
|
||||
};
|
||||
};
|
||||
add( hotArea );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
hotArea.active = visible;
|
||||
|
||||
if (pressed) {
|
||||
if ((pressTime += Game.elapsed) >= longClick) {
|
||||
pressed = false;
|
||||
if (onLongClick()) {
|
||||
|
||||
hotArea.reset();
|
||||
processed = true;
|
||||
onTouchUp();
|
||||
|
||||
Game.vibrate( 50 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void onTouchDown() {};
|
||||
protected void onTouchUp() {};
|
||||
protected void onClick() {};
|
||||
|
||||
protected boolean onLongClick() {
|
||||
return false;
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void layout() {
|
||||
hotArea.x = x;
|
||||
hotArea.y = y;
|
||||
hotArea.width = width;
|
||||
hotArea.height = height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.ui;
|
||||
|
||||
public class CheckBox extends Button {
|
||||
|
||||
protected boolean checked;
|
||||
|
||||
public boolean checked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void checked( boolean value ) {
|
||||
if (checked != value) {
|
||||
checked = value;
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateState() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
checked( !checked );
|
||||
onChange();
|
||||
}
|
||||
|
||||
protected void onChange() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2016 Evan Debenham
|
||||
*
|
||||
* 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.watabou.noosa.ui;
|
||||
|
||||
import com.watabou.noosa.Group;
|
||||
|
||||
public class Component extends Group {
|
||||
|
||||
protected float x;
|
||||
protected float y;
|
||||
protected float width;
|
||||
protected float height;
|
||||
|
||||
public Component() {
|
||||
super();
|
||||
createChildren();
|
||||
}
|
||||
|
||||
public Component setPos( float x, float y ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
layout();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Component setSize( float width, float height ) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
layout();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Component setRect( float x, float y, float width, float height ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
layout();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean inside( float x, float y ) {
|
||||
return x >= this.x && y >= this.y && x < this.x + width && y < this.y + height;
|
||||
}
|
||||
|
||||
public void fill( Component c ) {
|
||||
setRect( c.x, c.y, c.width, c.height );
|
||||
}
|
||||
|
||||
public float left() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float right() {
|
||||
return x + width;
|
||||
}
|
||||
|
||||
public float centerX() {
|
||||
return x + width / 2;
|
||||
}
|
||||
|
||||
public float top() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float bottom() {
|
||||
return y + height;
|
||||
}
|
||||
|
||||
public float centerY() {
|
||||
return y + height / 2;
|
||||
}
|
||||
|
||||
public float width() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public float height() {
|
||||
return height;
|
||||
}
|
||||
|
||||
protected void createChildren() {
|
||||
}
|
||||
|
||||
protected void layout() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user