Init der fehlenden Dateien
This commit is contained in:
parent
3324056634
commit
8c24604447
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,9 @@
|
||||
.gradle
|
||||
/app/*.apk
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
/app/build
|
@ -0,0 +1,13 @@
|
||||
package de.frajul.endlessroll;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
37
app/src/main/assets/levelpacks/Icy Mountains.xml
Normal file
37
app/src/main/assets/levelpacks/Icy Mountains.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<levelPack id="2">
|
||||
<world>ICY_MOUNTAINS</world>
|
||||
<levels class="java.util.ArrayList">
|
||||
<level packId="2" id="1" goalX="0.6333344" startSpeed="0.5" endSpeed="0.5" terrainEdge="-0.6" ceilingEdge="1.0">
|
||||
<terrainTiles class="java.util.ArrayList">
|
||||
<tileData x="-1.7933328" width="2.4133344"/>
|
||||
<tileData x="0.023334444" width="1.2199999"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="java.util.ArrayList">
|
||||
<tileData x="-1.7933328" width="2.4133344"/>
|
||||
<tileData x="0.023334444" width="1.2199999"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList"/>
|
||||
<stars class="java.util.ArrayList">
|
||||
<positionData x="-0.57999986" y="-0.45999992"/>
|
||||
<positionData x="-0.2666666" y="-0.46666658"/>
|
||||
<positionData x="0.033333335" y="-0.4466666"/>
|
||||
</stars>
|
||||
<energy x="0.36666656" y="-0.43333337"/>
|
||||
</level>
|
||||
<level packId="2" id="2" goalX="0.2466674" startSpeed="0.5" endSpeed="0.5" terrainEdge="-0.6" ceilingEdge="1.0">
|
||||
<terrainTiles class="java.util.ArrayList">
|
||||
<tileData x="-1.3766663" width="3.2466674"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="java.util.ArrayList">
|
||||
<tileData x="-1.3766663" width="3.2466674"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList"/>
|
||||
<stars class="java.util.ArrayList">
|
||||
<positionData x="-0.57333314" y="-0.45333323"/>
|
||||
<positionData x="-0.2799999" y="-0.17333329"/>
|
||||
<positionData x="0.006666667" y="-0.45333326"/>
|
||||
</stars>
|
||||
<energy x="-0.29333326" y="-0.45333314"/>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
151
app/src/main/assets/particleEffects/stasis.pe
Normal file
151
app/src/main/assets/particleEffects/stasis.pe
Normal file
@ -0,0 +1,151 @@
|
||||
Untitled
|
||||
- Delay -
|
||||
active: false
|
||||
- Duration -
|
||||
lowMin: 1000.0
|
||||
lowMax: 1000.0
|
||||
- Count -
|
||||
min: 0
|
||||
max: 200
|
||||
- Emission -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 7.0
|
||||
highMax: 7.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Life -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 1100.0
|
||||
highMax: 2000.0
|
||||
relative: false
|
||||
scalingCount: 5
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
scaling3: 1.0
|
||||
scaling4: 1.0
|
||||
timelineCount: 5
|
||||
timeline0: 0.0
|
||||
timeline1: 0.001
|
||||
timeline2: 0.002
|
||||
timeline3: 0.003
|
||||
timeline4: 1.0
|
||||
- Life Offset -
|
||||
active: false
|
||||
- X Offset -
|
||||
active: false
|
||||
- Y Offset -
|
||||
active: false
|
||||
- Spawn Shape -
|
||||
shape: square
|
||||
- Spawn Width -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 200.0
|
||||
highMax: 200.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Spawn Height -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 200.0
|
||||
highMax: 200.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Scale -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 60.0
|
||||
highMax: 30.0
|
||||
relative: false
|
||||
scalingCount: 4
|
||||
scaling0: 1.0
|
||||
scaling1: 0.64705884
|
||||
scaling2: 0.23529412
|
||||
scaling3: 0.0
|
||||
timelineCount: 4
|
||||
timeline0: 0.0
|
||||
timeline1: 0.8630137
|
||||
timeline2: 0.98630136
|
||||
timeline3: 1.0
|
||||
- Velocity -
|
||||
active: true
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 0.0
|
||||
highMax: 60.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Angle -
|
||||
active: true
|
||||
lowMin: 0.0
|
||||
lowMax: 360.0
|
||||
highMin: 60.0
|
||||
highMax: 120.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.56164384
|
||||
timeline2: 0.9931507
|
||||
- Rotation -
|
||||
active: false
|
||||
- Wind -
|
||||
active: false
|
||||
- Gravity -
|
||||
active: false
|
||||
- Tint -
|
||||
colorsCount: 6
|
||||
colors0: 0.047058824
|
||||
colors1: 1.0
|
||||
colors2: 0.93333334
|
||||
colors3: 0.3137255
|
||||
colors4: 0.047058824
|
||||
colors5: 1.0
|
||||
timelineCount: 2
|
||||
timeline0: 0.0
|
||||
timeline1: 1.0
|
||||
- Transparency -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 1.0
|
||||
highMax: 1.0
|
||||
relative: false
|
||||
scalingCount: 5
|
||||
scaling0: 0.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
scaling3: 0.6666667
|
||||
scaling4: 0.0
|
||||
timelineCount: 5
|
||||
timeline0: 0.0
|
||||
timeline1: 0.2
|
||||
timeline2: 0.201
|
||||
timeline3: 0.9246575
|
||||
timeline4: 1.0
|
||||
- Options -
|
||||
attached: false
|
||||
continuous: true
|
||||
aligned: false
|
||||
additive: true
|
||||
behind: false
|
||||
premultipliedAlpha: false
|
||||
- Image Path -
|
||||
particle.png
|
135
app/src/main/assets/particleEffects/test_fire.pe
Normal file
135
app/src/main/assets/particleEffects/test_fire.pe
Normal file
@ -0,0 +1,135 @@
|
||||
Untitled
|
||||
- Delay -
|
||||
active: false
|
||||
- Duration -
|
||||
lowMin: 3000.0
|
||||
lowMax: 3000.0
|
||||
- Count -
|
||||
min: 0
|
||||
max: 200
|
||||
- Emission -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 250.0
|
||||
highMax: 250.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Life -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 500.0
|
||||
highMax: 1000.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 0.3
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.66
|
||||
timeline2: 1.0
|
||||
- Life Offset -
|
||||
active: false
|
||||
- X Offset -
|
||||
active: false
|
||||
- Y Offset -
|
||||
active: false
|
||||
- Spawn Shape -
|
||||
shape: point
|
||||
- Spawn Width -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 0.0
|
||||
highMax: 0.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Spawn Height -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 0.0
|
||||
highMax: 0.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Scale -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 100.0
|
||||
highMax: 100.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Velocity -
|
||||
active: true
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 90.0
|
||||
highMax: 900.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Angle -
|
||||
active: true
|
||||
lowMin: 90.0
|
||||
lowMax: 90.0
|
||||
highMin: 45.0
|
||||
highMax: 135.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 0.0
|
||||
scaling2: 0.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.5
|
||||
timeline2: 1.0
|
||||
- Rotation -
|
||||
active: false
|
||||
- Wind -
|
||||
active: false
|
||||
- Gravity -
|
||||
active: false
|
||||
- Tint -
|
||||
colorsCount: 3
|
||||
colors0: 1.0
|
||||
colors1: 0.12156863
|
||||
colors2: 0.047058824
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Transparency -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 1.0
|
||||
highMax: 1.0
|
||||
relative: false
|
||||
scalingCount: 4
|
||||
scaling0: 0.0
|
||||
scaling1: 1.0
|
||||
scaling2: 0.75
|
||||
scaling3: 0.0
|
||||
timelineCount: 4
|
||||
timeline0: 0.0
|
||||
timeline1: 0.2
|
||||
timeline2: 0.8
|
||||
timeline3: 1.0
|
||||
- Options -
|
||||
attached: false
|
||||
continuous: true
|
||||
aligned: false
|
||||
additive: true
|
||||
behind: false
|
||||
premultipliedAlpha: false
|
||||
- Image Path -
|
||||
particle.png
|
69
app/src/main/java/de/frajul/endlessroll/data/Color.java
Normal file
69
app/src/main/java/de/frajul/endlessroll/data/Color.java
Normal file
@ -0,0 +1,69 @@
|
||||
package de.frajul.endlessroll.data;
|
||||
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class Color {
|
||||
|
||||
private float r, g, b;
|
||||
|
||||
public Color() {
|
||||
}
|
||||
|
||||
public Color(float r, float g, float b) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public Color(Color other) {
|
||||
this.r = other.getR();
|
||||
this.g = other.getG();
|
||||
this.b = other.getB();
|
||||
}
|
||||
|
||||
public Color interpolate(float leftValue, float rightValue, Color color2) {
|
||||
float r = this.r + (color2.r - this.r) * leftValue;
|
||||
float g = this.g + (color2.g - this.g) * leftValue;
|
||||
float b = this.b + (color2.b - this.b) * leftValue;
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
private void mul(float a) {
|
||||
r *= a;
|
||||
g *= a;
|
||||
b *= a;
|
||||
}
|
||||
|
||||
private void add(Color other) {
|
||||
r += other.getR();
|
||||
g += other.getG();
|
||||
b += other.getB();
|
||||
}
|
||||
|
||||
public float getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public void setR(float r) {
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
public float getG() {
|
||||
return g;
|
||||
}
|
||||
|
||||
public void setG(float g) {
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
public float getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public void setB(float b) {
|
||||
this.b = b;
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package de.frajul.endlessroll.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 16.11.2016.
|
||||
*/
|
||||
|
||||
public class SynchronizedArrayList<E> extends ArrayList<E> {
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean add(E object) {
|
||||
return super.add(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(int index, E object) {
|
||||
super.add(index, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(Collection<? extends E> collection) {
|
||||
return super.addAll(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(int index, Collection<? extends E> collection) {
|
||||
return super.addAll(index, collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
super.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object clone() {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void ensureCapacity(int minimumCapacity) {
|
||||
super.ensureCapacity(minimumCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized E get(int index) {
|
||||
return super.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return super.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
return super.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean contains(Object object) {
|
||||
return super.contains(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int indexOf(Object object) {
|
||||
return super.indexOf(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int lastIndexOf(Object object) {
|
||||
return super.lastIndexOf(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized E remove(int index) {
|
||||
return super.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean remove(Object object) {
|
||||
return super.remove(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void removeRange(int fromIndex, int toIndex) {
|
||||
super.removeRange(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized E set(int index, E object) {
|
||||
return super.set(index, object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object[] toArray() {
|
||||
return super.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <T> T[] toArray(T[] contents) {
|
||||
return super.toArray(contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void trimToSize() {
|
||||
super.trimToSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<E> subList(int start, int end) {
|
||||
return super.subList(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean containsAll(Collection<?> collection) {
|
||||
return super.containsAll(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAll(Collection<?> collection) {
|
||||
return super.removeAll(collection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean retainAll(Collection<?> collection) {
|
||||
return super.retainAll(collection);
|
||||
}
|
||||
}
|
101
app/src/main/java/de/frajul/endlessroll/data/Vector.java
Normal file
101
app/src/main/java/de/frajul/endlessroll/data/Vector.java
Normal file
@ -0,0 +1,101 @@
|
||||
package de.frajul.endlessroll.data;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
*/
|
||||
public class Vector {
|
||||
|
||||
public float x, y;
|
||||
|
||||
public Vector() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
public Vector(Vector other) {
|
||||
this(other.x, other.y);
|
||||
}
|
||||
|
||||
public Vector(float x, float y) {
|
||||
set(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Vector(" + x + ", " + y + ")";
|
||||
}
|
||||
|
||||
public Vector set(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float length() {
|
||||
return (float) Math.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
public Vector normalize() {
|
||||
float length = this.length();
|
||||
x /= length;
|
||||
y /= length;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector translate(Vector other) {
|
||||
this.x += other.x;
|
||||
this.y += other.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector translate(float x, float y) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector mul(float z) {
|
||||
x *= z;
|
||||
y *= z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector mul(Vector other) {
|
||||
this.x *= other.x;
|
||||
this.y *= other.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector mul(float x, float y) {
|
||||
this.x *= x;
|
||||
this.y *= y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector negate() {
|
||||
this.x *= -1;
|
||||
this.y *= -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector vectorTo(Vector other) {
|
||||
float x = other.x - this.x;
|
||||
float y = other.y - this.y;
|
||||
return new Vector(x, y);
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.02.2017.
|
||||
*/
|
||||
|
||||
public class AnimatedEntity extends Entity {
|
||||
|
||||
protected Animation animation;
|
||||
|
||||
public AnimatedEntity(Texture texture, Vector position, float width, float height) {
|
||||
super(texture, position, width, height);
|
||||
animation = new Animation();
|
||||
}
|
||||
|
||||
public void update(Timer timer){
|
||||
animation.update(timer);
|
||||
super.setTextureAtlasIndex(animation.getCurrentTexIndex());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 14.12.2015.
|
||||
*/
|
||||
public class Animation {
|
||||
|
||||
private int[] indexSequence = {0, 1, 2, 3};
|
||||
private boolean looping = false;
|
||||
private int requiredDelta = 110;
|
||||
|
||||
private int indexPointer = 0;
|
||||
private boolean stillRunning = true;
|
||||
private long lastSwitchTime = -1;
|
||||
|
||||
public void disable(){
|
||||
stillRunning = false;
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
if (lastSwitchTime == -1) {
|
||||
lastSwitchTime = timer.getCurrentTime();
|
||||
return;
|
||||
}
|
||||
if (stillRunning) {
|
||||
long delta = timer.getCurrentTime() - lastSwitchTime;
|
||||
if (delta >= requiredDelta) {
|
||||
lastSwitchTime = timer.getCurrentTime();
|
||||
indexPointer++;
|
||||
if (!looping && indexPointer == indexSequence.length - 1)
|
||||
stillRunning = false;
|
||||
if (looping && indexPointer == indexSequence.length)
|
||||
indexPointer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentTexIndex() {
|
||||
return indexSequence[indexPointer];
|
||||
}
|
||||
|
||||
public void setIndexSequence(int[] indexSequence) {
|
||||
this.indexSequence = indexSequence;
|
||||
}
|
||||
|
||||
public void setRequiredDelta(int requiredDelta) {
|
||||
this.requiredDelta = requiredDelta;
|
||||
}
|
||||
|
||||
public void setLooping(boolean looping) {
|
||||
this.looping = looping;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import de.frajul.endlessroll.data.SynchronizedArrayList;
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.07.2016.
|
||||
*/
|
||||
public class Background extends SynchronizedArrayList<Entity> {
|
||||
|
||||
private final float PART_WIDTH = 5;
|
||||
private final float HALF_PART_WIDTH = PART_WIDTH / 2;
|
||||
private final float HEIGHT = 2.5f;
|
||||
private Texture texture;
|
||||
|
||||
public Background(Texture texture) {
|
||||
this.texture = texture;
|
||||
super.add(createPart(-HALF_PART_WIDTH));
|
||||
}
|
||||
|
||||
public void changeTexture(Texture texture) {
|
||||
this.texture = texture;
|
||||
synchronized (this) {
|
||||
for (Entity entity : this)
|
||||
entity.setTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
private Entity createPart(float xLeftEdge) {
|
||||
return new Entity(texture, new Vector(xLeftEdge + HALF_PART_WIDTH, (HEIGHT - 2) / 2), PART_WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
public void move(float x, float cameraX) {
|
||||
Vector movement = new Vector(x, 0);
|
||||
synchronized (this) {
|
||||
for (Entity part : this)
|
||||
part.move(movement);
|
||||
}
|
||||
if (!super.isEmpty()) {
|
||||
Entity last = super.get(super.size() - 1);
|
||||
if (last.getRightEdge() - cameraX < 3) {
|
||||
super.add(createPart(last.getRightEdge() - 0.001f));
|
||||
}
|
||||
if (super.get(0).getRightEdge() - cameraX < -3) {
|
||||
super.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resetPosition() {
|
||||
super.clear();
|
||||
super.add(createPart(-HALF_PART_WIDTH));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleEffect;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSource;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
|
||||
/**
|
||||
* Created by Julian on 11.03.2016.
|
||||
*/
|
||||
public enum DestroyEffect {
|
||||
|
||||
EXPLOSION, STAR_EXPLOSION, ENERGY_COLLECT, NONE;
|
||||
|
||||
@Nullable
|
||||
public ParticleSource createEffect(ParticleSystem system, Vector position, Vector size) {
|
||||
if (this == NONE)
|
||||
return null;
|
||||
ParticleSource source = new ParticleSource(position, getEffect(system));
|
||||
source.setSpawnSize(size);
|
||||
return source;
|
||||
}
|
||||
|
||||
private ParticleEffect getEffect(ParticleSystem system) {
|
||||
switch (this) {
|
||||
case EXPLOSION:
|
||||
return system.explosion;
|
||||
case STAR_EXPLOSION:
|
||||
return system.starCollect;
|
||||
case ENERGY_COLLECT:
|
||||
return system.energyCollect;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
113
app/src/main/java/de/frajul/endlessroll/entities/Entity.java
Normal file
113
app/src/main/java/de/frajul/endlessroll/entities/Entity.java
Normal file
@ -0,0 +1,113 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Quad;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.11.2015.
|
||||
*/
|
||||
public class Entity extends Quad {
|
||||
|
||||
private int textureAtlasIndex;
|
||||
private Texture texture;
|
||||
private Vector movement;
|
||||
private float rotation;
|
||||
private float alpha = 1.0f;
|
||||
private boolean destroyed;
|
||||
private DestroyEffect destroyEffect;
|
||||
private Vector maxTexSize;
|
||||
private boolean visible = true;
|
||||
|
||||
public Entity(Texture texture, Vector position, float width, float height) {
|
||||
super(position, width, height);
|
||||
this.texture = texture;
|
||||
this.movement = new Vector();
|
||||
this.maxTexSize = new Vector();
|
||||
}
|
||||
|
||||
public void move(Vector movement) {
|
||||
position.translate(movement);
|
||||
}
|
||||
|
||||
public void rotate(float factor) {
|
||||
rotation += factor;
|
||||
}
|
||||
|
||||
public void setToTerrain(float terrainEdge) {
|
||||
position.y = terrainEdge + height / 2;
|
||||
}
|
||||
|
||||
public void setTopEdge(float y) {
|
||||
position.y = y - height / 2;
|
||||
}
|
||||
|
||||
public Texture getTexture() {
|
||||
return texture;
|
||||
}
|
||||
|
||||
public void setTexture(Texture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public Vector getMovement() {
|
||||
return movement;
|
||||
}
|
||||
|
||||
public void setMovement(Vector movement) {
|
||||
this.movement = movement;
|
||||
}
|
||||
|
||||
public float getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public void setRotation(float rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public void setAlpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
public float getAlpha() {
|
||||
return alpha;
|
||||
}
|
||||
|
||||
public void destroy(DestroyEffect destroyEffect) {
|
||||
this.destroyed = true;
|
||||
this.destroyEffect = destroyEffect;
|
||||
}
|
||||
|
||||
public boolean isDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
public DestroyEffect getDestroyEffect() {
|
||||
return destroyEffect;
|
||||
}
|
||||
|
||||
public void setTextureAtlasIndex(int textureAtlasIndex) {
|
||||
this.textureAtlasIndex = textureAtlasIndex;
|
||||
}
|
||||
|
||||
public int getTextureAtlasIndex() {
|
||||
return textureAtlasIndex;
|
||||
}
|
||||
|
||||
public void setMaxTexSize(Vector maxTexSize) {
|
||||
this.maxTexSize = maxTexSize;
|
||||
}
|
||||
|
||||
public Vector getMaxTexSize() {
|
||||
return maxTexSize;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
}
|
16
app/src/main/java/de/frajul/endlessroll/entities/Goal.java
Normal file
16
app/src/main/java/de/frajul/endlessroll/entities/Goal.java
Normal file
@ -0,0 +1,16 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
|
||||
public class Goal extends Entity {
|
||||
|
||||
public Goal(Texture texture) {
|
||||
super(texture, new Vector(), 0.1f, 3);
|
||||
super.getMaxTexSize().setY(0.2f);
|
||||
}
|
||||
|
||||
public void setGoalX(float goalX) {
|
||||
super.setPosition(new Vector(goalX - 0.05f, 0));
|
||||
}
|
||||
}
|
130
app/src/main/java/de/frajul/endlessroll/entities/Player.java
Normal file
130
app/src/main/java/de/frajul/endlessroll/entities/Player.java
Normal file
@ -0,0 +1,130 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSource;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.tools.PlayerInfluenceTool;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.11.2015.
|
||||
*/
|
||||
public class Player extends Entity {
|
||||
|
||||
private final float ROTATION_SPEED = -400;
|
||||
public final float RADIUS = 0.1f;
|
||||
private final float START_X = -0.9f;
|
||||
private final float SPEED = 0.002f;
|
||||
|
||||
private float startSpeed, endSpeed;
|
||||
private float speed = SPEED;
|
||||
|
||||
private long currentSuperPowerDuration;
|
||||
private boolean hasSuperPower;
|
||||
private long superPowerDuration;
|
||||
private ParticleSource superPowerParticles;
|
||||
|
||||
private ParticleSystem particleSystem;
|
||||
private List<PlayerInfluenceTool> influenceTools = new ArrayList<>();
|
||||
private List<Float> forces = new ArrayList<>();
|
||||
private float gravityForce;
|
||||
|
||||
public Player() {
|
||||
super(PlayerShape.BALL.getTexture(), new Vector(), 0, 0);
|
||||
super.setWidth(RADIUS * 2);
|
||||
super.setHeight(RADIUS * 2);
|
||||
}
|
||||
|
||||
public void startSuperPower(long duration) {
|
||||
this.superPowerDuration = duration;
|
||||
currentSuperPowerDuration = 0;
|
||||
hasSuperPower = true;
|
||||
superPowerParticles = new ParticleSource(
|
||||
new Vector(super.getPosition().x, super.getPosition().y), particleSystem.superPower);
|
||||
superPowerParticles.start();
|
||||
}
|
||||
|
||||
public void init(PlayerShape playerShape, float terrainEdge, float startSpeed, float endSpeed, ParticleSystem particleSystem) {
|
||||
super.setTexture(playerShape.getTexture());
|
||||
super.setToTerrain(terrainEdge);
|
||||
super.getPosition().x = START_X;
|
||||
super.setMovement(new Vector(speed, 0));
|
||||
this.startSpeed = startSpeed;
|
||||
this.endSpeed = endSpeed;
|
||||
setSpeedByProgress(0);
|
||||
this.particleSystem = particleSystem;
|
||||
}
|
||||
|
||||
public void setSpeedByProgress(float progress) {
|
||||
this.speed = ((endSpeed - startSpeed) * progress + startSpeed) * SPEED;
|
||||
super.getMovement().x = speed;
|
||||
}
|
||||
|
||||
public void preMoveUpdate(Timer timer) {
|
||||
if (hasSuperPower && superPowerParticles != null) {
|
||||
currentSuperPowerDuration += timer.getFrameTimeSeconds();
|
||||
hasSuperPower = superPowerDuration >= currentSuperPowerDuration;
|
||||
superPowerParticles.setPosition(new Vector(super.getPosition()));
|
||||
}
|
||||
if (!hasSuperPower && superPowerParticles != null)
|
||||
superPowerParticles.kill();
|
||||
|
||||
for (PlayerInfluenceTool tool : influenceTools)
|
||||
tool.influencePlayerValues(this);
|
||||
|
||||
for (float force : forces)
|
||||
super.getMovement().y += force;
|
||||
super.getMovement().y += gravityForce;
|
||||
}
|
||||
|
||||
public void clearAllForces() {
|
||||
forces.clear();
|
||||
gravityForce = 0;
|
||||
}
|
||||
|
||||
public void manipulateAllForces(float factor) {
|
||||
for (int i = 0; i < forces.size(); i++)
|
||||
forces.set(i, forces.get(i) * factor);
|
||||
gravityForce *= factor * factor;
|
||||
}
|
||||
|
||||
public void postMoveUpdate() {
|
||||
influenceTools.clear();
|
||||
forces.clear();
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
return getPosition().x - START_X;
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public boolean hasSuperPower() {
|
||||
return hasSuperPower;
|
||||
}
|
||||
|
||||
public void addInfluenceTool(PlayerInfluenceTool tool) {
|
||||
influenceTools.add(tool);
|
||||
}
|
||||
|
||||
public void addForce(float force) {
|
||||
forces.add(force);
|
||||
}
|
||||
|
||||
public void setGravityForce(float gravityForce) {
|
||||
this.gravityForce = gravityForce;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(Vector movement) {
|
||||
super.move(movement);
|
||||
rotate(movement.x * ROTATION_SPEED);
|
||||
}
|
||||
|
||||
}
|
44
app/src/main/java/de/frajul/endlessroll/entities/Vertex.java
Normal file
44
app/src/main/java/de/frajul/endlessroll/entities/Vertex.java
Normal file
@ -0,0 +1,44 @@
|
||||
package de.frajul.endlessroll.entities;
|
||||
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
|
||||
/**
|
||||
* Created by Julian on 11.12.2016.
|
||||
*/
|
||||
|
||||
public enum Vertex {
|
||||
|
||||
UL(0, -1, 1), UR(1, 1, 1), BL(3, -1, -1), BR(2, 1, -1);
|
||||
|
||||
private int index;
|
||||
private float x, y;
|
||||
|
||||
Vertex(int index, float x, float y) {
|
||||
this.index = index;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Vertex getNext(boolean clockwise) {
|
||||
int newIndex = index + 1;
|
||||
if (!clockwise)
|
||||
newIndex = index - 1;
|
||||
if (newIndex > 3)
|
||||
newIndex = 0;
|
||||
if (newIndex < 0)
|
||||
newIndex = 3;
|
||||
for (Vertex vertex : values())
|
||||
if (vertex.index == newIndex)
|
||||
return vertex;
|
||||
GameLog.e("No vertex with index " + index + " found!!!");
|
||||
return null;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package de.frajul.endlessroll.entities.collectables;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.AnimatedEntity;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.levels.PositionData;
|
||||
|
||||
public class Energy extends AnimatedEntity {
|
||||
|
||||
private final static float SIZE = 0.3f;
|
||||
|
||||
public Energy(Texture texture, PositionData data) {
|
||||
super(texture, new Vector(data.getX(), data.getY()), SIZE, SIZE);
|
||||
animation.setLooping(true);
|
||||
animation.setRequiredDelta(130);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package de.frajul.endlessroll.entities.collectables;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.levels.PositionData;
|
||||
|
||||
public class Star extends Entity {
|
||||
|
||||
private final static float SIZE = 0.25f;
|
||||
private int index;
|
||||
|
||||
public Star(int index, Texture texture, PositionData data) {
|
||||
super(texture, new Vector(data.getX(), data.getY()), SIZE, SIZE);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package de.frajul.endlessroll.entities.collision;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Circle;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Triangle;
|
||||
|
||||
/**
|
||||
* Created by Julian on 28.02.2016.
|
||||
*/
|
||||
public class CircleTriangleCollisionDetector {
|
||||
|
||||
public boolean circleTriangleCollision(Circle circle, Triangle triangle) {
|
||||
if (circleIntersectingWithTriangleVertices(circle, triangle))
|
||||
return true;
|
||||
|
||||
if (circleCenterInsideTriangle(circle, triangle))
|
||||
return true;
|
||||
|
||||
if (circleIntersectingWithTriangleEdges(circle, triangle))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean circleIntersectingWithTriangleEdges(Circle circle, Triangle triangle) {
|
||||
Vector edge1 = triangle.getVertex1().vectorTo(triangle.getVertex2());
|
||||
Vector edge2 = triangle.getVertex2().vectorTo(triangle.getVertex3());
|
||||
Vector edge3 = triangle.getVertex3().vectorTo(triangle.getVertex1());
|
||||
|
||||
boolean intersectingWithEdge1 = circleIntersectingWithTriangleEdge(circle, triangle.getVertex1(), edge1);
|
||||
boolean intersectingWithEdge2 = circleIntersectingWithTriangleEdge(circle, triangle.getVertex2(), edge2);
|
||||
boolean intersectingWithEdge3 = circleIntersectingWithTriangleEdge(circle, triangle.getVertex3(), edge3);
|
||||
return intersectingWithEdge1 || intersectingWithEdge2 || intersectingWithEdge3;
|
||||
}
|
||||
|
||||
private boolean circleIntersectingWithTriangleEdge(Circle circle, Vector vertex, Vector edge) {
|
||||
Vector vertexToCenter = vertex.vectorTo(circle.getCenter());
|
||||
Vector kVector = new Vector(vertexToCenter).mul(edge);
|
||||
float k = kVector.x + kVector.y;
|
||||
|
||||
if (k > 0) {
|
||||
float length = edge.length();
|
||||
k = k / length;
|
||||
|
||||
if (k < length)
|
||||
if (Math.sqrt(vertexToCenter.x * vertexToCenter.x + vertexToCenter.y * vertexToCenter.y - k * k) <= circle.getRadius())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean circleCenterInsideTriangle(Circle circle, Triangle triangle) {
|
||||
Vector vertex1To2 = triangle.getVertex1().vectorTo(triangle.getVertex2());
|
||||
Vector vertex2To3 = triangle.getVertex2().vectorTo(triangle.getVertex3());
|
||||
Vector vertex3To1 = triangle.getVertex3().vectorTo(triangle.getVertex1());
|
||||
Vector vertex1ToCenter = triangle.getVertex1().vectorTo(circle.getCenter());
|
||||
Vector vertex2ToCenter = triangle.getVertex2().vectorTo(circle.getCenter());
|
||||
Vector vertex3ToCenter = triangle.getVertex3().vectorTo(circle.getCenter());
|
||||
|
||||
boolean centerInsideV1V2 = vertex1To2.y * vertex1ToCenter.x - vertex1To2.x * vertex1ToCenter.y < 0;
|
||||
boolean centerInsideV2V3 = vertex2To3.y * vertex2ToCenter.x - vertex2To3.x * vertex2ToCenter.y < 0;
|
||||
boolean centerInsideV3V1 = vertex3To1.y * vertex3ToCenter.x - vertex3To1.x * vertex3ToCenter.y < 0;
|
||||
|
||||
return centerInsideV1V2 && centerInsideV2V3 && centerInsideV3V1;
|
||||
}
|
||||
|
||||
private boolean circleIntersectingWithTriangleVertices(Circle circle, Triangle triangle) {
|
||||
boolean intersectingWithVertex1 = circleIntersectingWithTriangleVertex(circle, triangle.getVertex1());
|
||||
boolean intersectingWithVertex2 = circleIntersectingWithTriangleVertex(circle, triangle.getVertex2());
|
||||
boolean intersectingWithVertex3 = circleIntersectingWithTriangleVertex(circle, triangle.getVertex3());
|
||||
return intersectingWithVertex1 || intersectingWithVertex2 || intersectingWithVertex3;
|
||||
}
|
||||
|
||||
private boolean circleIntersectingWithTriangleVertex(Circle circle, Vector vertex) {
|
||||
Vector centerToVertex = circle.getCenter().vectorTo(vertex);
|
||||
return centerToVertex.length() <= circle.getRadius();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
package de.frajul.endlessroll.entities.collision;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.EntityCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Circle;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Quad;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Triangle;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
*/
|
||||
public class CollisionDetector {
|
||||
|
||||
private CircleTriangleCollisionDetector triangleDetector;
|
||||
|
||||
public CollisionDetector() {
|
||||
triangleDetector = new CircleTriangleCollisionDetector();
|
||||
}
|
||||
|
||||
public boolean isCircleCircleCollision(Circle c1, Circle c2) {
|
||||
float distance = Math.abs(c1.getCenter().vectorTo(c2.getCenter()).length());
|
||||
float radiusSum = c1.getRadius() + c2.getRadius();
|
||||
return distance < radiusSum;
|
||||
}
|
||||
|
||||
public boolean isCircleQuadCollision(Circle circle, Quad quad) {
|
||||
Vector distance = circle.getCenter().vectorTo(quad.getPosition());
|
||||
distance.x = Math.abs(distance.x);
|
||||
distance.y = Math.abs(distance.y);
|
||||
|
||||
if (distance.x > circle.getRadius() + quad.getWidth() / 2)
|
||||
return false;
|
||||
if (distance.y > circle.getRadius() + quad.getHeight() / 2)
|
||||
return false;
|
||||
|
||||
if (distance.x <= quad.getWidth() / 2)
|
||||
return true;
|
||||
if (distance.y <= quad.getHeight() / 2)
|
||||
return true;
|
||||
|
||||
float cornerDistance_sq = (distance.x - quad.getWidth() / 2) * (distance.x - quad
|
||||
.getWidth() / 2) + (distance.y - quad.getHeight() / 2) * (distance.y - quad
|
||||
.getHeight() / 2);
|
||||
return cornerDistance_sq <= circle.getRadius() * circle.getRadius();
|
||||
}
|
||||
|
||||
public boolean isCircleTriangleCollision(Circle circle, Triangle triangle) {
|
||||
return triangleDetector.circleTriangleCollision(circle, triangle);
|
||||
}
|
||||
|
||||
public boolean isQuadQuadCollision(Quad q1, Quad q2) {
|
||||
float xDistance = Math.abs(q2.getPosition().x - q1.getPosition().x);
|
||||
float yDistance = Math.abs(q2.getPosition().y - q1.getPosition().y);
|
||||
if (xDistance >= q1.getWidth() / 2 + q2.getWidth() / 2)
|
||||
return false;
|
||||
if (yDistance >= q1.getHeight() / 2 + q2.getHeight() / 2)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isQuadTriangleCollision(Quad quad, Triangle triangle) {
|
||||
boolean quadVertex1InTriangle = isVertexInTriangle(
|
||||
new Vector(quad.getLeftEdge(), quad.getTopEdge()), triangle);
|
||||
if (quadVertex1InTriangle)
|
||||
return true;
|
||||
boolean quadVertex2InTriangle = isVertexInTriangle(
|
||||
new Vector(quad.getRightEdge(), quad.getTopEdge()), triangle);
|
||||
if (quadVertex2InTriangle)
|
||||
return true;
|
||||
boolean quadVertex3InTriangle = isVertexInTriangle(
|
||||
new Vector(quad.getRightEdge(), quad.getBottomEdge()), triangle);
|
||||
if (quadVertex3InTriangle)
|
||||
return true;
|
||||
boolean quadVertex4InTriangle = isVertexInTriangle(
|
||||
new Vector(quad.getLeftEdge(), quad.getBottomEdge()), triangle);
|
||||
if (quadVertex4InTriangle)
|
||||
return true;
|
||||
boolean triangleVertex1InQuad = isVertexInQuad(triangle.getVertex1(), quad);
|
||||
if (triangleVertex1InQuad)
|
||||
return true;
|
||||
boolean triangleVertex2InQuad = isVertexInQuad(triangle.getVertex2(), quad);
|
||||
if (triangleVertex2InQuad)
|
||||
return true;
|
||||
boolean triangleVertex3InQuad = isVertexInQuad(triangle.getVertex3(), quad);
|
||||
if (triangleVertex3InQuad)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isTriangleTriangleCollision(Triangle triangle1, Triangle triangle2) {
|
||||
boolean triangle1Vertex1InTriangle2 = isVertexInTriangle(triangle1.getVertex1(), triangle2);
|
||||
if (triangle1Vertex1InTriangle2)
|
||||
return true;
|
||||
boolean triangle1Vertex2InTriangle2 = isVertexInTriangle(triangle1.getVertex2(), triangle2);
|
||||
if (triangle1Vertex2InTriangle2)
|
||||
return true;
|
||||
boolean triangle1Vertex3InTriangle2 = isVertexInTriangle(triangle1.getVertex3(), triangle2);
|
||||
if (triangle1Vertex3InTriangle2)
|
||||
return true;
|
||||
boolean triangle2Vertex1InTriangle1 = isVertexInTriangle(triangle2.getVertex1(), triangle1);
|
||||
if (triangle2Vertex1InTriangle1)
|
||||
return true;
|
||||
boolean triangle2Vertex2InTriangle1 = isVertexInTriangle(triangle2.getVertex2(), triangle1);
|
||||
if (triangle2Vertex2InTriangle1)
|
||||
return true;
|
||||
boolean triangle2Vertex3InTriangle1 = isVertexInTriangle(triangle2.getVertex3(), triangle1);
|
||||
if (triangle2Vertex3InTriangle1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean isVertexInTriangle(Vector vertex, Triangle triangle) {
|
||||
Vector vertex1To2 = triangle.getVertex1().vectorTo(triangle.getVertex2());
|
||||
Vector vertex2To3 = triangle.getVertex2().vectorTo(triangle.getVertex3());
|
||||
Vector vertex3To1 = triangle.getVertex3().vectorTo(triangle.getVertex1());
|
||||
Vector vertex1ToCenter = triangle.getVertex1().vectorTo(vertex);
|
||||
Vector vertex2ToCenter = triangle.getVertex2().vectorTo(vertex);
|
||||
Vector vertex3ToCenter = triangle.getVertex3().vectorTo(vertex);
|
||||
|
||||
boolean centerInsideV1V2 = vertex1To2.y * vertex1ToCenter.x - vertex1To2.x * vertex1ToCenter.y < 0;
|
||||
boolean centerInsideV2V3 = vertex2To3.y * vertex2ToCenter.x - vertex2To3.x * vertex2ToCenter.y < 0;
|
||||
boolean centerInsideV3V1 = vertex3To1.y * vertex3ToCenter.x - vertex3To1.x * vertex3ToCenter.y < 0;
|
||||
|
||||
return centerInsideV1V2 && centerInsideV2V3 && centerInsideV3V1;
|
||||
}
|
||||
|
||||
private boolean isVertexInQuad(Vector vertex, Quad quad) {
|
||||
return vertex.getX() >= quad.getLeftEdge() && vertex.getX() <= quad.getRightEdge() && vertex
|
||||
.getY() >= quad.getBottomEdge() && vertex.getY() <= quad.getTopEdge();
|
||||
}
|
||||
|
||||
|
||||
public EntityCollisionData playerEntityCollision(Player player, Entity entity) {
|
||||
Circle circle = new Circle(player);
|
||||
Quad quad = entity;
|
||||
if (isCircleQuadCollision(circle, quad)) {
|
||||
Edge edge = circleQuadCollisionEdge(circle, player.getMovement(), quad,
|
||||
entity.getMovement());
|
||||
return new EntityCollisionData(entity, edge);
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
private Edge circleQuadCollisionEdge(Circle circle, Vector circleMovement, Quad quad, Vector quadMovement) {
|
||||
Vector relativeMovement = circleMovement.translate(quadMovement);
|
||||
|
||||
//LEFT || TOP || BOTTOM
|
||||
if (relativeMovement.x > 0) {
|
||||
//LEFT || BOTTOM
|
||||
if (relativeMovement.y > 0) {
|
||||
float toLeftDistance = quad.getLeftEdge() - circle.getCenter().x;
|
||||
float actualY = toLeftDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y;
|
||||
if (actualY < quad.getBottomEdge())
|
||||
return Edge.BOTTOM;
|
||||
else
|
||||
return Edge.LEFT;
|
||||
}
|
||||
//LEFT || TOP
|
||||
else if (relativeMovement.y < 0) {
|
||||
float toLeftDistance = quad.getLeftEdge() - circle.getCenter().x;
|
||||
float actualY = toLeftDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y;
|
||||
if (actualY < quad.getTopEdge())
|
||||
return Edge.LEFT;
|
||||
else
|
||||
return Edge.TOP;
|
||||
} else
|
||||
return Edge.LEFT;
|
||||
}
|
||||
//RIGHT || TOP || BOTTOM
|
||||
else if (relativeMovement.x < 0) {
|
||||
//RIGHT || BOTTOM
|
||||
if (relativeMovement.y > 0) {
|
||||
float toRightDistance = quad.getRightEdge() - circle.getCenter().x;
|
||||
float actualY = toRightDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y;
|
||||
if (actualY < quad.getBottomEdge())
|
||||
return Edge.BOTTOM;
|
||||
else
|
||||
return Edge.RIGHT;
|
||||
}
|
||||
//RIGHT || TOP
|
||||
else if (relativeMovement.y < 0) {
|
||||
float toRightDistance = quad.getRightEdge() - circle.getCenter().x;
|
||||
float actualY = toRightDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y;
|
||||
if (actualY < quad.getTopEdge())
|
||||
return Edge.RIGHT;
|
||||
else
|
||||
return Edge.TOP;
|
||||
} else
|
||||
return Edge.RIGHT;
|
||||
} else {
|
||||
if (relativeMovement.y > 0)
|
||||
return Edge.BOTTOM;
|
||||
else if (relativeMovement.y < 0)
|
||||
return Edge.TOP;
|
||||
}
|
||||
return Edge.NONE;
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package de.frajul.endlessroll.entities.collision;
|
||||
|
||||
import de.frajul.endlessroll.entities.DestroyEffect;
|
||||
import de.frajul.endlessroll.entities.Obstacle;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collectables.Energy;
|
||||
import de.frajul.endlessroll.entities.collectables.Star;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.EntityCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.ObstacleCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.PlayerCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.ToolCollisionData;
|
||||
import de.frajul.endlessroll.entities.tools.Tool;
|
||||
import de.frajul.endlessroll.main.game.Game;
|
||||
import de.frajul.endlessroll.main.game.GameScene;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
import de.frajul.endlessroll.main.physics.Physics;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.01.2016.
|
||||
*/
|
||||
public class CollisionManager {
|
||||
|
||||
private Game game;
|
||||
private Player player;
|
||||
private Timer timer;
|
||||
|
||||
public CollisionManager(Game game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
//Check Obstacle always before tool, because at tool, player could be moved etc.
|
||||
public void update(Physics physics, GameScene scene, Timer timer) {
|
||||
physics.checkToolCollision(scene);
|
||||
|
||||
this.player = scene.getPlayer();
|
||||
this.timer = timer;
|
||||
PlayerCollisionData data = physics.getPlayerCollisionData(scene);
|
||||
if (data.isTerrainCollision())
|
||||
checkTerrainCollision(data.getTerrainCollisionData());
|
||||
if (data.isCeilingCollision())
|
||||
checkCeilingCollision(data.getCeilingCollisionData());
|
||||
if (data.isObstacleCollision())
|
||||
checkObstacleCollision(data.getObstacleCollisionData(), player.hasSuperPower());
|
||||
if (data.isToolCollision())
|
||||
checkToolCollision(data.getToolCollisionData());
|
||||
if (data.isStarCollision())
|
||||
game.onStarCollision((Star) data.getStarCollisionData().getEntity());
|
||||
if (data.isEnergyCollision())
|
||||
game.onEnergyCollision((Energy) data.getEnergyCollisionData().getEntity());
|
||||
}
|
||||
|
||||
private void checkTerrainCollision(EntityCollisionData data) {
|
||||
checkEntityCollision(data, -0.01f);
|
||||
if (data.getEdge() != Edge.TOP)
|
||||
game.onGameOver(true);
|
||||
}
|
||||
|
||||
private void checkCeilingCollision(EntityCollisionData data) {
|
||||
checkEntityCollision(data, -0.01f);
|
||||
if (data.getEdge() == Edge.RIGHT || data.getEdge() == Edge.LEFT)
|
||||
game.onGameOver(true);
|
||||
}
|
||||
|
||||
private void checkToolCollision(ToolCollisionData data) {
|
||||
for (Tool tool : data.getTools())
|
||||
tool.onPlayerCollision(player, timer);
|
||||
}
|
||||
|
||||
private void checkObstacleCollision(ObstacleCollisionData data, boolean playerHasSuperpower) {
|
||||
for (EntityCollisionData entityData : data.getCollisions()) {
|
||||
if (playerHasSuperpower) {
|
||||
entityData.getEntity().destroy(DestroyEffect.EXPLOSION);
|
||||
} else {
|
||||
if (entityData.getEdge() != Edge.TOP || ((Obstacle) entityData.getEntity())
|
||||
.isDeadly())
|
||||
game.onGameOver(true);
|
||||
else
|
||||
checkEntityCollision(entityData, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEntityCollision(EntityCollisionData data, float xBounceFactor) {
|
||||
switch (data.getEdge()) {
|
||||
case TOP:
|
||||
player.getMovement().y = 0;
|
||||
player.setToTerrain(data.getEntity().getTopEdge());
|
||||
break;
|
||||
case BOTTOM:
|
||||
player.getMovement().y = 0;
|
||||
player.setTopEdge(data.getEntity().getBottomEdge());
|
||||
break;
|
||||
case LEFT:
|
||||
player.getMovement().x *= xBounceFactor;
|
||||
player.getPosition().x = data.getEntity().getLeftEdge() - player.RADIUS;
|
||||
break;
|
||||
case RIGHT:
|
||||
player.getMovement().x *= xBounceFactor;
|
||||
player.getPosition().x = data.getEntity().getRightEdge() + player.RADIUS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package de.frajul.endlessroll.entities.collision;
|
||||
|
||||
public enum Edge {
|
||||
LEFT, RIGHT, TOP, BOTTOM, NONE;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package de.frajul.endlessroll.entities.collision.collisionData;
|
||||
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.collision.Edge;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.01.2016.
|
||||
*/
|
||||
public class EntityCollisionData {
|
||||
|
||||
private Entity entity;
|
||||
private Edge edge;
|
||||
|
||||
public EntityCollisionData(Entity entity, Edge edge) {
|
||||
this.entity = entity;
|
||||
this.edge = edge;
|
||||
}
|
||||
|
||||
public boolean isCollision() {
|
||||
return entity != null && edge != null;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Edge getEdge() {
|
||||
return edge;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package de.frajul.endlessroll.entities.collision.collisionData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 04.01.2016.
|
||||
*/
|
||||
public class ObstacleCollisionData {
|
||||
|
||||
private List<EntityCollisionData> collisions;
|
||||
|
||||
public ObstacleCollisionData(List<EntityCollisionData> collisions) {
|
||||
this.collisions = collisions;
|
||||
}
|
||||
|
||||
public boolean isCollision() {
|
||||
return collisions.size() > 0;
|
||||
}
|
||||
|
||||
public List<EntityCollisionData> getCollisions() {
|
||||
return collisions;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package de.frajul.endlessroll.entities.collision.collisionData;
|
||||
|
||||
/**
|
||||
* Created by Julian on 05.12.2015.
|
||||
*/
|
||||
public class PlayerCollisionData {
|
||||
|
||||
private EntityCollisionData terrainCollision;
|
||||
private EntityCollisionData ceilingCollision;
|
||||
private ObstacleCollisionData obstacleCollision;
|
||||
private ToolCollisionData toolCollision;
|
||||
private EntityCollisionData starCollision;
|
||||
private EntityCollisionData energyCollision;
|
||||
|
||||
public PlayerCollisionData(EntityCollisionData terrainCollision, EntityCollisionData ceilingCollision, ObstacleCollisionData obstacleCollision, ToolCollisionData toolCollision, EntityCollisionData starCollision, EntityCollisionData energyCollision) {
|
||||
this.terrainCollision = terrainCollision;
|
||||
this.ceilingCollision = ceilingCollision;
|
||||
this.obstacleCollision = obstacleCollision;
|
||||
this.toolCollision = toolCollision;
|
||||
this.starCollision = starCollision;
|
||||
this.energyCollision = energyCollision;
|
||||
}
|
||||
|
||||
public boolean isTerrainCollision() {
|
||||
return terrainCollision.isCollision();
|
||||
}
|
||||
|
||||
public EntityCollisionData getTerrainCollisionData() {
|
||||
return terrainCollision;
|
||||
}
|
||||
|
||||
public boolean isCeilingCollision() {
|
||||
return ceilingCollision.isCollision();
|
||||
}
|
||||
|
||||
public EntityCollisionData getCeilingCollisionData() {
|
||||
return ceilingCollision;
|
||||
}
|
||||
|
||||
public boolean isObstacleCollision() {
|
||||
return obstacleCollision.isCollision();
|
||||
}
|
||||
|
||||
public ObstacleCollisionData getObstacleCollisionData() {
|
||||
return obstacleCollision;
|
||||
}
|
||||
|
||||
public boolean isToolCollision() {
|
||||
return toolCollision.isCollision();
|
||||
}
|
||||
|
||||
public ToolCollisionData getToolCollisionData() {
|
||||
return toolCollision;
|
||||
}
|
||||
|
||||
public boolean isStarCollision() {
|
||||
return starCollision.isCollision();
|
||||
}
|
||||
|
||||
public EntityCollisionData getStarCollisionData() {
|
||||
return starCollision;
|
||||
}
|
||||
|
||||
public boolean isEnergyCollision() {
|
||||
return energyCollision.isCollision();
|
||||
}
|
||||
|
||||
public EntityCollisionData getEnergyCollisionData() {
|
||||
return energyCollision;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package de.frajul.endlessroll.entities.collision.collisionData;
|
||||
|
||||
import de.frajul.endlessroll.entities.tools.Tool;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 21.02.2016.
|
||||
*/
|
||||
public class ToolCollisionData {
|
||||
|
||||
private List<Tool> tools;
|
||||
|
||||
public ToolCollisionData(List<Tool> tools) {
|
||||
this.tools = tools;
|
||||
}
|
||||
|
||||
public boolean isCollision() {
|
||||
return tools.size() > 0;
|
||||
}
|
||||
|
||||
public List<Tool> getTools() {
|
||||
return tools;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package de.frajul.endlessroll.entities.collision.geometry;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
*/
|
||||
public class Circle implements Geometry {
|
||||
|
||||
private Vector center;
|
||||
private float radius;
|
||||
|
||||
public Circle(Player ball) {
|
||||
this(new Vector(ball.getPosition()), ball.getWidth() / 2);
|
||||
}
|
||||
|
||||
public Circle(Vector center, float radius) {
|
||||
this.center = center;
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public Vector getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
public float getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public void setRadius(float radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithCircle(Circle circle, CollisionDetector collisionDetector){
|
||||
return collisionDetector.isCircleCircleCollision(this, circle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithQuad(Quad quad, CollisionDetector collisionDetector){
|
||||
return collisionDetector.isCircleQuadCollision(this, quad);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithTriangle(Triangle triangle, CollisionDetector collisionDetector){
|
||||
return collisionDetector.isCircleTriangleCollision(this, triangle);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package de.frajul.endlessroll.entities.collision.geometry;
|
||||
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
|
||||
/**
|
||||
* Created by Julian on 28.02.2016.
|
||||
*/
|
||||
public interface Geometry {
|
||||
|
||||
boolean isCollisionWithCircle(Circle circle, CollisionDetector collisionDetector);
|
||||
|
||||
boolean isCollisionWithQuad(Quad quad, CollisionDetector collisionDetector);
|
||||
|
||||
boolean isCollisionWithTriangle(Triangle triangle, CollisionDetector collisionDetector);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package de.frajul.endlessroll.entities.collision.geometry;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
*/
|
||||
public class Quad implements Geometry {
|
||||
|
||||
protected Vector position;
|
||||
protected float width, height;
|
||||
|
||||
public Quad(Vector position, float width, float height) {
|
||||
this.position = position;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public float getRightEdge() {
|
||||
return position.x + width / 2;
|
||||
}
|
||||
|
||||
public float getLeftEdge() {
|
||||
return position.x - width / 2;
|
||||
}
|
||||
|
||||
public float getTopEdge() {
|
||||
return position.y + height / 2;
|
||||
}
|
||||
|
||||
public float getBottomEdge() {
|
||||
return position.y - height / 2;
|
||||
}
|
||||
|
||||
public Vector getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(Vector position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(float width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(float height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithCircle(Circle circle, CollisionDetector collisionDetector) {
|
||||
return collisionDetector.isCircleQuadCollision(circle, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithQuad(Quad quad, CollisionDetector collisionDetector) {
|
||||
return collisionDetector.isQuadQuadCollision(this, quad);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithTriangle(Triangle triangle, CollisionDetector collisionDetector) {
|
||||
return collisionDetector.isQuadTriangleCollision(this, triangle);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package de.frajul.endlessroll.entities.collision.geometry;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
import de.frajul.endlessroll.entities.tools.Ramp;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
*/
|
||||
public class Triangle implements Geometry {
|
||||
|
||||
//bottom right
|
||||
private Vector vertex1;
|
||||
//top right
|
||||
private Vector vertex2;
|
||||
//bottom left
|
||||
private Vector vertex3;
|
||||
|
||||
public Triangle(Ramp ramp) {
|
||||
Vector vertex1 = new Vector(ramp.getRightEdge(), ramp.getBottomEdge());
|
||||
Vector vertex2 = new Vector(ramp.getRightEdge(), ramp.getTopEdge());
|
||||
Vector vertex3 = new Vector(ramp.getLeftEdge(), ramp.getBottomEdge());
|
||||
this.vertex1 = vertex1;
|
||||
this.vertex2 = vertex2;
|
||||
this.vertex3 = vertex3;
|
||||
}
|
||||
|
||||
public Triangle(Vector vertex1, Vector vertex2, Vector vertex3) {
|
||||
this.vertex1 = vertex1;
|
||||
this.vertex2 = vertex2;
|
||||
this.vertex3 = vertex3;
|
||||
}
|
||||
|
||||
public Vector getVertex1() {
|
||||
return vertex1;
|
||||
}
|
||||
|
||||
public Vector getVertex2() {
|
||||
return vertex2;
|
||||
}
|
||||
|
||||
public Vector getVertex3() {
|
||||
return vertex3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithCircle(Circle circle, CollisionDetector collisionDetector) {
|
||||
return collisionDetector.isCircleTriangleCollision(circle, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithQuad(Quad quad, CollisionDetector collisionDetector) {
|
||||
return collisionDetector.isQuadTriangleCollision(quad, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionWithTriangle(Triangle triangle, CollisionDetector collisionDetector) {
|
||||
return collisionDetector.isTriangleTriangleCollision(this, triangle);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package de.frajul.endlessroll.entities.particles;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import de.frajul.endlessroll.data.Color;
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class Particle extends Entity {
|
||||
|
||||
private Color color;
|
||||
private Random random;
|
||||
private boolean active;
|
||||
private float maxLife;
|
||||
private float passedLifetime;
|
||||
|
||||
private Timeline scaleTimeline;
|
||||
private Range scale;
|
||||
private Timeline velocityTimeline;
|
||||
private Range velocity;
|
||||
private Timeline angleTimeline;
|
||||
private Range angle;
|
||||
private Timeline rotationTimeline;
|
||||
private Range rotation;
|
||||
private Timeline transparencyTimeline;
|
||||
private TintTimeline tintTimeline;
|
||||
private Timeline windTimeline;
|
||||
private Range wind;
|
||||
private Timeline gravityTimeline;
|
||||
private Range gravity;
|
||||
|
||||
public Particle(Random random) {
|
||||
super(null, new Vector(), 1, 1);
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public void activate(Vector position, float liveValue, ParticleData particleData) {
|
||||
active = true;
|
||||
passedLifetime = 0;
|
||||
super.setPosition(position);
|
||||
maxLife = particleData.getLife().createValue(random, liveValue);
|
||||
scaleTimeline = particleData.getScaleTR().getTimeline();
|
||||
scale = particleData.getScaleTR().getRange().createNormalizedInstance(random);
|
||||
velocityTimeline = particleData.getVelocityTR().getTimeline();
|
||||
velocity = particleData.getVelocityTR().getRange().createNormalizedInstance(random);
|
||||
angleTimeline = particleData.getAngleTR().getTimeline();
|
||||
angle = particleData.getAngleTR().getRange().createNormalizedInstance(random);
|
||||
rotationTimeline = particleData.getRotationTR().getTimeline();
|
||||
rotation = particleData.getRotationTR().getRange().createNormalizedInstance(random);
|
||||
transparencyTimeline = particleData.getTransparencyT();
|
||||
tintTimeline = particleData.getTint();
|
||||
windTimeline = particleData.getWindTR().getTimeline();
|
||||
wind = particleData.getWindTR().getRange().createNormalizedInstance(random);
|
||||
gravityTimeline = particleData.getGravityTR().getTimeline();
|
||||
gravity = particleData.getGravityTR().getRange().createNormalizedInstance(random);
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
if (active) {
|
||||
passedLifetime += timer.getFrameTimeSeconds();
|
||||
if (passedLifetime >= maxLife)
|
||||
active = false;
|
||||
float lifetimePercent = passedLifetime / maxLife;
|
||||
setScale(scale.createValue(random, scaleTimeline.getValueAtTime(lifetimePercent)));
|
||||
setMovement(
|
||||
velocity.createValue(random, velocityTimeline.getValueAtTime(lifetimePercent)),
|
||||
angle.createValue(random, angleTimeline.getValueAtTime(lifetimePercent)),
|
||||
wind.createValue(random, windTimeline.getValueAtTime(lifetimePercent)),
|
||||
gravity.createValue(random, gravityTimeline.getValueAtTime(lifetimePercent)));
|
||||
super.setRotation(-rotation
|
||||
.createValue(random, rotationTimeline.getValueAtTime(lifetimePercent)));
|
||||
super.setAlpha(transparencyTimeline.getValueAtTime(lifetimePercent));
|
||||
setColor(tintTimeline.getValueAtTime(lifetimePercent));
|
||||
}
|
||||
}
|
||||
|
||||
private void setScale(float scale) {
|
||||
super.setWidth(scale * ParticleSystem.TRANSFER_VALUE);
|
||||
super.setHeight(scale * ParticleSystem.TRANSFER_VALUE);
|
||||
}
|
||||
|
||||
private void setMovement(float velocity, float angle, float windStrength, float gravityStrength) {
|
||||
float radians = (float) Math.toRadians(angle);
|
||||
Vector normalMovement = new Vector();
|
||||
normalMovement.setX((float) Math.cos(radians));
|
||||
normalMovement.setY((float) Math.sin(radians));
|
||||
normalMovement.mul(velocity * ParticleSystem.TRANSFER_VALUE);
|
||||
normalMovement.translate(windStrength * ParticleSystem.TRANSFER_VALUE,
|
||||
gravityStrength * ParticleSystem.TRANSFER_VALUE);
|
||||
super.setMovement(normalMovement);
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package de.frajul.endlessroll.entities.particles;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
|
||||
/**
|
||||
* Created by Julian on 03.08.2016.
|
||||
*/
|
||||
public class ParticleData {
|
||||
|
||||
private Range life;
|
||||
private TimelineRange scaleTR;
|
||||
private TimelineRange velocityTR;
|
||||
private TimelineRange angleTR;
|
||||
private TimelineRange rotationTR;
|
||||
private Timeline transparencyT;
|
||||
private TintTimeline tint;
|
||||
private TimelineRange windTR;
|
||||
private TimelineRange gravityTR;
|
||||
|
||||
public ParticleData(Range life, TimelineRange scaleTR, TimelineRange velocityTR, TimelineRange angleTR, TimelineRange rotationTR, Timeline transparencyT, TintTimeline tint, TimelineRange windTR, TimelineRange gravityTR) {
|
||||
this.life = life;
|
||||
this.scaleTR = scaleTR;
|
||||
this.velocityTR = velocityTR;
|
||||
this.angleTR = angleTR;
|
||||
this.rotationTR = rotationTR;
|
||||
this.transparencyT = transparencyT;
|
||||
this.tint = tint;
|
||||
this.windTR = windTR;
|
||||
this.gravityTR = gravityTR;
|
||||
}
|
||||
|
||||
public Range getLife() {
|
||||
return life;
|
||||
}
|
||||
|
||||
public TimelineRange getScaleTR() {
|
||||
return scaleTR;
|
||||
}
|
||||
|
||||
public TimelineRange getVelocityTR() {
|
||||
return velocityTR;
|
||||
}
|
||||
|
||||
public TimelineRange getAngleTR() {
|
||||
return angleTR;
|
||||
}
|
||||
|
||||
public TimelineRange getRotationTR() {
|
||||
return rotationTR;
|
||||
}
|
||||
|
||||
public Timeline getTransparencyT() {
|
||||
return transparencyT;
|
||||
}
|
||||
|
||||
public TintTimeline getTint() {
|
||||
return tint;
|
||||
}
|
||||
|
||||
public TimelineRange getWindTR() {
|
||||
return windTR;
|
||||
}
|
||||
|
||||
public TimelineRange getGravityTR() {
|
||||
return gravityTR;
|
||||
}
|
||||
}
|
@ -0,0 +1,229 @@
|
||||
package de.frajul.endlessroll.entities.particles;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Options;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by Julian on 05.08.2016.
|
||||
*/
|
||||
public class ParticleEffect {
|
||||
|
||||
private TimelineRange life;
|
||||
//Particle Timeline
|
||||
private TimelineRange scale;
|
||||
private TimelineRange velocity;
|
||||
private TimelineRange angle;
|
||||
private TimelineRange rotation;
|
||||
private Timeline transparency;
|
||||
private TintTimeline tint;
|
||||
private TimelineRange wind;
|
||||
private TimelineRange gravity;
|
||||
|
||||
//Source Timeline
|
||||
private Range delay;
|
||||
private Range duration;
|
||||
private TimelineRange emission;
|
||||
private Range xOffset;
|
||||
private Range yOffset;
|
||||
private SpawnShape.Shape spawnShape;
|
||||
private TimelineRange spawnWidth;
|
||||
private TimelineRange spawnHeight;
|
||||
|
||||
private Options options;
|
||||
private Texture texture;
|
||||
private String textureName;
|
||||
|
||||
private Random random;
|
||||
private List<ParticleSource> sources = Collections.synchronizedList(new ArrayList<ParticleSource>());
|
||||
|
||||
public ParticleEffect() {
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
synchronized (sources) {
|
||||
for (ParticleSource source : sources)
|
||||
source.update(timer);
|
||||
}
|
||||
}
|
||||
|
||||
public ParticleData createParticleData() {
|
||||
return new ParticleData(life.getRange(), scale, velocity, angle, rotation, transparency, tint, wind , gravity);
|
||||
}
|
||||
|
||||
public Random getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
public void addSource(ParticleSource source) {
|
||||
sources.add(source);
|
||||
}
|
||||
|
||||
public void setDelay(Range delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public void setDuration(Range duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public void setEmission(TimelineRange emission) {
|
||||
this.emission = emission;
|
||||
}
|
||||
|
||||
public void setLife(TimelineRange life) {
|
||||
this.life = life;
|
||||
}
|
||||
|
||||
public void setxOffset(Range xOffset) {
|
||||
this.xOffset = xOffset;
|
||||
}
|
||||
|
||||
public void setyOffset(Range yOffset) {
|
||||
this.yOffset = yOffset;
|
||||
}
|
||||
|
||||
public void setSpawnShape(SpawnShape.Shape spawnShape) {
|
||||
this.spawnShape = spawnShape;
|
||||
}
|
||||
|
||||
public void setSpawnWidth(TimelineRange spawnWidth) {
|
||||
this.spawnWidth = spawnWidth;
|
||||
}
|
||||
|
||||
public void setSpawnHeight(TimelineRange spawnHeight) {
|
||||
this.spawnHeight = spawnHeight;
|
||||
}
|
||||
|
||||
public void setScale(TimelineRange scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public void setVelocity(TimelineRange velocity) {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
||||
public void setAngle(TimelineRange angle) {
|
||||
this.angle = angle;
|
||||
}
|
||||
|
||||
public void setRotation(TimelineRange rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public void setWind(TimelineRange wind) {
|
||||
this.wind = wind;
|
||||
}
|
||||
|
||||
public void setGravity(TimelineRange gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
public void setTint(TintTimeline tint) {
|
||||
this.tint = tint;
|
||||
}
|
||||
|
||||
public void setTransparency(Timeline transparency) {
|
||||
this.transparency = transparency;
|
||||
}
|
||||
|
||||
public Timeline getTransparency() {
|
||||
return transparency;
|
||||
}
|
||||
|
||||
public TintTimeline getTint() {
|
||||
return tint;
|
||||
}
|
||||
|
||||
public void setOptions(Options options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public void setTexture(Texture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public void setTextureName(String textureName) {
|
||||
this.textureName = textureName;
|
||||
}
|
||||
|
||||
public String getTextureName() {
|
||||
return textureName;
|
||||
}
|
||||
|
||||
public Texture getTexture() {
|
||||
return texture;
|
||||
}
|
||||
|
||||
public Range getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public Range getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public TimelineRange getEmission() {
|
||||
return emission;
|
||||
}
|
||||
|
||||
public Options getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public TimelineRange getWind() {
|
||||
return wind;
|
||||
}
|
||||
|
||||
public TimelineRange getGravity() {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
public Range getxOffset() {
|
||||
return xOffset;
|
||||
}
|
||||
|
||||
public Range getyOffset() {
|
||||
return yOffset;
|
||||
}
|
||||
|
||||
public synchronized List<ParticleSource> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
public TimelineRange getLife() {
|
||||
return life;
|
||||
}
|
||||
|
||||
public SpawnShape.Shape getSpawnShape() {
|
||||
return spawnShape;
|
||||
}
|
||||
|
||||
public TimelineRange getSpawnHeight() {
|
||||
return spawnHeight;
|
||||
}
|
||||
|
||||
public void deleteSources() {
|
||||
synchronized (sources) {
|
||||
for (ParticleSource source : sources)
|
||||
source.kill();
|
||||
sources.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public TimelineRange getSpawnWidth() {
|
||||
return spawnWidth;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,163 @@
|
||||
package de.frajul.endlessroll.entities.particles;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.attributes.Attribute;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.AttributeValueReader;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.ParticleAttributeType;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ImagePath;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Options;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class ParticleReader {
|
||||
|
||||
private Context context;
|
||||
private AttributeValueReader attributeValueReader;
|
||||
|
||||
private List<Attribute> attributes;
|
||||
private Attribute currentAttribute;
|
||||
|
||||
public ParticleReader(Context context) {
|
||||
this.context = context;
|
||||
attributeValueReader = new AttributeValueReader();
|
||||
}
|
||||
|
||||
/**
|
||||
* reads ParticleEffect from *.pe files
|
||||
* !Ignores COUNT, LIFE_OFFSET!
|
||||
*/
|
||||
public ParticleEffect read(String filename) throws Exception {
|
||||
try {
|
||||
attributes = new ArrayList<>();
|
||||
currentAttribute = null;
|
||||
InputStream is = context.getAssets().open(filename);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
line = line.trim();
|
||||
handleLine(line);
|
||||
}
|
||||
reader.close();
|
||||
return createParticleEffect();
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Could not read particleFile: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLine(String line) throws Exception {
|
||||
if (line.startsWith("- ")) {
|
||||
Attribute attrib = ParticleAttributeType.getByInFileTitle(line).createInstance();
|
||||
attributes.add(attrib);
|
||||
currentAttribute = attrib;
|
||||
} else if (currentAttribute != null)
|
||||
attributeValueReader.addValueForAttribute(currentAttribute, line);
|
||||
}
|
||||
|
||||
private ParticleEffect createParticleEffect() throws Exception {
|
||||
ParticleEffect effect = new ParticleEffect();
|
||||
Timeline timeline = null;
|
||||
Range range = null;
|
||||
for (Attribute attribute : attributes) {
|
||||
switch (attribute.getType()) {
|
||||
case DELAY:
|
||||
effect.setDelay((Range) attribute.get(ParticleAttributeValueType.RANGE));
|
||||
break;
|
||||
case DURATION:
|
||||
effect.setDuration((Range) attribute.get(ParticleAttributeValueType.RANGE));
|
||||
break;
|
||||
case COUNT:
|
||||
break;
|
||||
case EMISSION:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setEmission(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case LIFE:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setLife(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case LIFE_OFFSET:
|
||||
break;
|
||||
case X_OFFSET:
|
||||
effect.setxOffset((Range) attribute.get(ParticleAttributeValueType.RANGE));
|
||||
break;
|
||||
case Y_OFFSET:
|
||||
effect.setyOffset((Range) attribute.get(ParticleAttributeValueType.RANGE));
|
||||
break;
|
||||
case SPAWN_SHAPE:
|
||||
effect.setSpawnShape(((SpawnShape) attribute.get(ParticleAttributeValueType.SPAWN_SHAPE)).getShape());
|
||||
break;
|
||||
case SPAWN_WIDTH:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setSpawnWidth(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case SPAWN_HEIGHT:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setSpawnHeight(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case SCALE:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setScale(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case VELOCITY:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setVelocity(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case ANGLE:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setAngle(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case ROTATION:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setRotation(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case WIND:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setWind(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case GRAVITY:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
|
||||
effect.setGravity(new TimelineRange(timeline, range));
|
||||
break;
|
||||
case TINT:
|
||||
effect.setTint((TintTimeline) attribute.get(ParticleAttributeValueType.TINT_TIMELINE));
|
||||
break;
|
||||
case TRANSPARENCY:
|
||||
timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
|
||||
effect.setTransparency(timeline);
|
||||
break;
|
||||
case OPTIONS:
|
||||
effect.setOptions((Options) attribute.get(ParticleAttributeValueType.OPTIONS));
|
||||
break;
|
||||
case IMAGE_PATH:
|
||||
String path = ((ImagePath) attribute.get(ParticleAttributeValueType.IMAGE_PATH)).getImagePath();
|
||||
effect.setTextureName(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
package de.frajul.endlessroll.entities.particles;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
import de.frajul.endlessroll.rendering.Lock;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class ParticleSource {
|
||||
|
||||
private Vector position;
|
||||
private ParticleEffect effect;
|
||||
private Random random;
|
||||
|
||||
private boolean delayManuallySet = false;
|
||||
|
||||
private boolean alife;
|
||||
private float currentDelay;
|
||||
private float lifePercent;
|
||||
private float maxTime = -1;
|
||||
private float passedTime;
|
||||
private float emittPause;
|
||||
private float passedEmittPause;
|
||||
private float passedSecond;
|
||||
|
||||
private Vector spawnSize = null;
|
||||
private ParticleData particleData;
|
||||
private List<Particle> activeParticles = new ArrayList<>();
|
||||
private List<Particle> inactiveParticles = new ArrayList<>();
|
||||
private Lock activeParticleLock = new Lock();
|
||||
|
||||
public ParticleSource(Vector position, ParticleEffect effect) {
|
||||
this.position = position;
|
||||
this.effect = effect;
|
||||
random = effect.getRandom();
|
||||
effect.addSource(this);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
alife = true;
|
||||
if (!delayManuallySet)
|
||||
currentDelay = effect.getDelay().createValue(random, 0);
|
||||
maxTime = effect.getDuration().createValue(random, 0) + currentDelay;
|
||||
passedTime = 0;
|
||||
emittPause = calcEmittPause();
|
||||
passedEmittPause = 0;
|
||||
passedSecond = 0;
|
||||
lifePercent = 0;
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
if (alife) {
|
||||
passedTime += timer.getFrameTimeSeconds();
|
||||
lifePercent = passedTime / maxTime;
|
||||
|
||||
if (passedTime >= currentDelay) {
|
||||
passedEmittPause += timer.getFrameTimeSeconds();
|
||||
while (passedEmittPause >= emittPause) {
|
||||
passedEmittPause -= emittPause;
|
||||
emitt();
|
||||
}
|
||||
|
||||
passedSecond += timer.getFrameTimeSeconds();
|
||||
if (passedSecond >= 1000) {
|
||||
passedSecond -= 1000;
|
||||
calcEmittPause();
|
||||
}
|
||||
}
|
||||
if (passedTime >= maxTime)
|
||||
die();
|
||||
}
|
||||
updateParticles(timer);
|
||||
}
|
||||
|
||||
private void updateParticles(Timer timer) {
|
||||
activeParticleLock.lock();
|
||||
Iterator<Particle> iter = activeParticles.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Particle particle = iter.next();
|
||||
particle.update(timer);
|
||||
if (!particle.isActive()) {
|
||||
inactiveParticles.add(particle);
|
||||
iter.remove();
|
||||
} else {
|
||||
particle.move(
|
||||
new Vector(particle.getMovement()).mul(timer.getFrameTimeSeconds() / 1000));
|
||||
}
|
||||
}
|
||||
activeParticleLock.unlock();
|
||||
}
|
||||
|
||||
private void die() {
|
||||
alife = false;
|
||||
if (effect.getOptions().isContinuous())
|
||||
start();
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
alife = false;
|
||||
}
|
||||
|
||||
public void emitt() {
|
||||
if (particleData == null)
|
||||
particleData = effect.createParticleData();
|
||||
float xOff = effect.getxOffset().createValue(random, 0) * ParticleSystem.TRANSFER_VALUE;
|
||||
float yOff = effect.getyOffset().createValue(random, 0) * ParticleSystem.TRANSFER_VALUE;
|
||||
if (effect.getSpawnShape() == SpawnShape.Shape.SQUARE || effect.getSpawnShape() == SpawnShape.Shape.LINE) {
|
||||
float width, height;
|
||||
if (spawnSize == null) {
|
||||
width = effect.getSpawnWidth().getRange().createValue(random,
|
||||
effect.getSpawnWidth().getTimeline().getValueAtTime(lifePercent));
|
||||
height = effect.getSpawnHeight().getRange().createValue(random,
|
||||
effect.getSpawnHeight().getTimeline().getValueAtTime(lifePercent));
|
||||
} else {
|
||||
width = spawnSize.getX() / ParticleSystem.TRANSFER_VALUE;
|
||||
height = spawnSize.getY() / ParticleSystem.TRANSFER_VALUE;
|
||||
}
|
||||
xOff += (random.nextFloat() * width - width * 0.5f) * ParticleSystem.TRANSFER_VALUE;
|
||||
yOff += (random.nextFloat() * height - height * 0.5f) * ParticleSystem.TRANSFER_VALUE;
|
||||
}
|
||||
setUpParticle(new Vector(position).translate(xOff, yOff));
|
||||
}
|
||||
|
||||
private Particle setUpParticle(Vector position) {
|
||||
Particle particle;
|
||||
if (inactiveParticles.size() > 0)
|
||||
particle = inactiveParticles.remove(0);
|
||||
else
|
||||
particle = new Particle(random);
|
||||
|
||||
particle.activate(position, effect.getLife().getTimeline().getValueAtTime(lifePercent),
|
||||
particleData);
|
||||
activeParticleLock.lock();
|
||||
activeParticles.add(particle);
|
||||
activeParticleLock.unlock();
|
||||
return particle;
|
||||
}
|
||||
|
||||
private float calcEmittPause() {
|
||||
float emittedPerSecond = effect.getEmission().getRange().createValue(random,
|
||||
effect.getEmission().getTimeline().getValueAtTime(passedTime / maxTime));
|
||||
return 1000 / emittedPerSecond;
|
||||
}
|
||||
|
||||
public Lock getActiveParticleLock() {
|
||||
return activeParticleLock;
|
||||
}
|
||||
|
||||
public List<Particle> getActiveParticles() {
|
||||
return activeParticles;
|
||||
}
|
||||
|
||||
public void setSpawnSize(Vector spawnSize) {
|
||||
this.spawnSize = spawnSize;
|
||||
}
|
||||
|
||||
public void setPosition(Vector position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void setDelayMS(float delay) {
|
||||
currentDelay = delay;
|
||||
delayManuallySet = true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package de.frajul.endlessroll.entities.particles;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import de.frajul.endlessroll.entities.textures.TextureLoader;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class ParticleSystem {
|
||||
|
||||
public static final float TRANSFER_VALUE = 0.002f;
|
||||
public final ParticleEffect stasis;
|
||||
public final ParticleEffect testFire;
|
||||
public final ParticleEffect colorChange;
|
||||
public final ParticleEffect explosion;
|
||||
public final ParticleEffect magnet;
|
||||
public final ParticleEffect starCollect;
|
||||
public final ParticleEffect energyCollect;
|
||||
public final ParticleEffect firework;
|
||||
public final ParticleEffect superPower;
|
||||
private ParticleEffect[] effects;
|
||||
|
||||
private TextureLoader textureLoader;
|
||||
|
||||
public ParticleSystem(Context context) throws Exception {
|
||||
this.textureLoader = new TextureLoader(context);
|
||||
ParticleReader reader = new ParticleReader(context);
|
||||
stasis = reader.read("particleEffects/stasis.pe");
|
||||
testFire = reader.read("particleEffects/test_fire.pe");
|
||||
colorChange = reader.read("particleEffects/colorChange.pe");
|
||||
explosion = reader.read("particleEffects/explosion.pe");
|
||||
magnet = reader.read("particleEffects/magnet.pe");
|
||||
starCollect = reader.read("particleEffects/collectStar.pe");
|
||||
energyCollect = reader.read("particleEffects/collectEnergy.pe");
|
||||
firework = reader.read("particleEffects/firework.pe");
|
||||
superPower = reader.read("particleEffects/superPower.pe");
|
||||
|
||||
effects = new ParticleEffect[]{stasis, testFire,colorChange, explosion, magnet, starCollect, energyCollect, firework, superPower};
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
synchronized (effects) {
|
||||
for (ParticleEffect effect : effects)
|
||||
effect.update(timer);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadTextures() throws Exception {
|
||||
synchronized (effects) {
|
||||
for (ParticleEffect effect : effects)
|
||||
effect.setTexture(
|
||||
textureLoader.loadTexture("particleEffects/" + effect.getTextureName()));
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAllSources() {
|
||||
synchronized (effects) {
|
||||
for (ParticleEffect effect : effects) {
|
||||
effect.deleteSources();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized ParticleEffect[] getEffects() {
|
||||
return effects;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValue;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class Attribute {
|
||||
|
||||
private ParticleAttributeType type;
|
||||
private List<ParticleAttributeValue> values = new ArrayList<>();
|
||||
|
||||
public Attribute(ParticleAttributeType type, ParticleAttributeValueType... valueTypes) {
|
||||
this.type = type;
|
||||
for (ParticleAttributeValueType valueType : valueTypes)
|
||||
values.add(valueType.createInstance());
|
||||
}
|
||||
|
||||
public ParticleAttributeValue get(ParticleAttributeValueType valueType) throws Exception {
|
||||
for (ParticleAttributeValue v : values)
|
||||
if (v.getType() == valueType)
|
||||
return v;
|
||||
throw new Exception("ParticleAttributeValue with type: " + valueType + " does not exist in Attribute " + type);
|
||||
}
|
||||
|
||||
public ParticleAttributeType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ImagePath;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Options;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class AttributeValueReader {
|
||||
|
||||
public void addValueForAttribute(Attribute attribute, String line) throws Exception {
|
||||
//RANGE
|
||||
if (line.startsWith("lowMin:") || line.startsWith("min:"))
|
||||
((Range) attribute.get(ParticleAttributeValueType.RANGE)).setLowMin(parseFloat(line));
|
||||
else if (line.startsWith("lowMax:") || line.startsWith("max:"))
|
||||
((Range) attribute.get(ParticleAttributeValueType.RANGE)).setLowMax(parseFloat(line));
|
||||
else if (line.startsWith("highMin:"))
|
||||
((Range) attribute.get(ParticleAttributeValueType.RANGE)).setHighMin(parseFloat(line));
|
||||
else if (line.startsWith("highMax:"))
|
||||
((Range) attribute.get(ParticleAttributeValueType.RANGE)).setHighMax(parseFloat(line));
|
||||
//TIMELINE
|
||||
else if (!line.startsWith("scalingCount") && line.startsWith("scaling"))
|
||||
((Timeline) attribute.get(ParticleAttributeValueType.TIMELINE)).setValueOfPoint(parseTimeLineIndex("scaling", line), parseFloat(line));
|
||||
else if (!line.startsWith("timelineCount") && line.startsWith("timeline") && attribute.getType() != ParticleAttributeType.TINT)
|
||||
((Timeline) attribute.get(ParticleAttributeValueType.TIMELINE)).setTimeOfPoint(parseTimeLineIndex("timeline", line), parseFloat(line));
|
||||
//TINT_TIMELINE
|
||||
else if (!line.startsWith("colorsCount") && line.startsWith("colors")) {
|
||||
int index = parseTimeLineIndex("colors", line);
|
||||
((TintTimeline) attribute.get(ParticleAttributeValueType.TINT_TIMELINE)).setValueOfPoint((int) (index / 3f), index % 3, parseFloat(line));
|
||||
} else if (!line.startsWith("timelineCount") && line.startsWith("timeline") && attribute.getType() == ParticleAttributeType.TINT)
|
||||
((TintTimeline) attribute.get(ParticleAttributeValueType.TINT_TIMELINE)).setTimeOfPoint(parseTimeLineIndex("timeline", line), parseFloat(line));
|
||||
//SPAWN_SHAPE
|
||||
else if (line.startsWith("shape:"))
|
||||
((SpawnShape) attribute.get(ParticleAttributeValueType.SPAWN_SHAPE)).setShape(SpawnShape.Shape.byName(parseString(line)));
|
||||
//OPTIONS
|
||||
else if (line.startsWith("attached:"))
|
||||
((Options) attribute.get(ParticleAttributeValueType.OPTIONS)).setAttached(parseBoolean(line));
|
||||
else if (line.startsWith("continuous:"))
|
||||
((Options) attribute.get(ParticleAttributeValueType.OPTIONS)).setContinuous(parseBoolean(line));
|
||||
else if (line.startsWith("aligned:"))
|
||||
((Options) attribute.get(ParticleAttributeValueType.OPTIONS)).setAligned(parseBoolean(line));
|
||||
else if (line.startsWith("additive:"))
|
||||
((Options) attribute.get(ParticleAttributeValueType.OPTIONS)).setAdditive(parseBoolean(line));
|
||||
else if (line.startsWith("behind:"))
|
||||
((Options) attribute.get(ParticleAttributeValueType.OPTIONS)).setBehind(parseBoolean(line));
|
||||
else if (line.startsWith("premultipliedAlpha:"))
|
||||
((Options) attribute.get(ParticleAttributeValueType.OPTIONS)).setPremultipliedAlpha(parseBoolean(line));
|
||||
//IMAGE PATH
|
||||
else if (attribute.getType() == ParticleAttributeType.IMAGE_PATH)
|
||||
((ImagePath) attribute.get(ParticleAttributeValueType.IMAGE_PATH)).setImagePath(line);
|
||||
}
|
||||
|
||||
private int parseTimeLineIndex(String start, String line) throws Exception {
|
||||
String asString = line.split(start)[1].split(":")[0];
|
||||
return Integer.parseInt(asString);
|
||||
}
|
||||
|
||||
private float parseFloat(String line) throws Exception {
|
||||
String asString = line.split(" ")[1];
|
||||
return Float.parseFloat(asString);
|
||||
}
|
||||
|
||||
private String parseString(String line) throws Exception {
|
||||
return line.split(" ")[1];
|
||||
}
|
||||
|
||||
private boolean parseBoolean(String line) throws Exception {
|
||||
String asString = line.split(" ")[1];
|
||||
return Boolean.parseBoolean(asString);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
|
||||
|
||||
public enum ParticleAttributeType {
|
||||
NONE(""),
|
||||
DELAY("Delay", ParticleAttributeValueType.RANGE),
|
||||
DURATION("Duration", ParticleAttributeValueType.RANGE),
|
||||
COUNT("Count", ParticleAttributeValueType.RANGE),
|
||||
EMISSION("Emission", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
LIFE("Life", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
LIFE_OFFSET("Life Offset", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
X_OFFSET("X Offset", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
Y_OFFSET("Y Offset", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
SPAWN_SHAPE("Spawn Shape", ParticleAttributeValueType.SPAWN_SHAPE),
|
||||
SPAWN_WIDTH("Spawn Width", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
SPAWN_HEIGHT("Spawn Height", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
SCALE("Scale", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
VELOCITY("Velocity", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
ANGLE("Angle", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
ROTATION("Rotation", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
WIND("Wind", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
GRAVITY("Gravity", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
TINT("Tint", ParticleAttributeValueType.TINT_TIMELINE),
|
||||
TRANSPARENCY("Transparency", ParticleAttributeValueType.RANGE, ParticleAttributeValueType.TIMELINE),
|
||||
OPTIONS("Options", ParticleAttributeValueType.OPTIONS),
|
||||
IMAGE_PATH("Image Path", ParticleAttributeValueType.IMAGE_PATH);
|
||||
|
||||
private String name;
|
||||
private ParticleAttributeValueType[] valueTypes;
|
||||
|
||||
ParticleAttributeType(String name, ParticleAttributeValueType... valueTypes) {
|
||||
this.name = name;
|
||||
this.valueTypes = valueTypes;
|
||||
}
|
||||
|
||||
private String getInFileTitle() {
|
||||
return "- " + name + " -";
|
||||
}
|
||||
|
||||
public static ParticleAttributeType getByInFileTitle(String title) throws Exception {
|
||||
for (ParticleAttributeType setting : values()) {
|
||||
if (setting != NONE && setting.getInFileTitle().equals(title))
|
||||
return setting;
|
||||
}
|
||||
throw new Exception("Could not find ParticleAttributeType by title: " + title);
|
||||
}
|
||||
|
||||
public Attribute createInstance() throws Exception {
|
||||
if (this == NONE)
|
||||
throw new Exception("Cannot create Instance from Attribute NONE");
|
||||
return new Attribute(this, valueTypes);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class ImagePath extends ParticleAttributeValue {
|
||||
|
||||
private String imagePath;
|
||||
|
||||
public ImagePath() {
|
||||
super(ParticleAttributeValueType.IMAGE_PATH);
|
||||
}
|
||||
|
||||
public String getImagePath() {
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
public void setImagePath(String imagePath) {
|
||||
this.imagePath = imagePath;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class Options extends ParticleAttributeValue {
|
||||
|
||||
private boolean attached;
|
||||
private boolean continuous;
|
||||
private boolean aligned;
|
||||
private boolean additive;
|
||||
private boolean behind;
|
||||
private boolean premultipliedAlpha;
|
||||
|
||||
public Options() {
|
||||
super(ParticleAttributeValueType.OPTIONS);
|
||||
}
|
||||
|
||||
public boolean isAttached() {
|
||||
return attached;
|
||||
}
|
||||
|
||||
public void setAttached(boolean attached) {
|
||||
this.attached = attached;
|
||||
}
|
||||
|
||||
public boolean isContinuous() {
|
||||
return continuous;
|
||||
}
|
||||
|
||||
public void setContinuous(boolean continuous) {
|
||||
this.continuous = continuous;
|
||||
}
|
||||
|
||||
public boolean isAligned() {
|
||||
return aligned;
|
||||
}
|
||||
|
||||
public void setAligned(boolean aligned) {
|
||||
this.aligned = aligned;
|
||||
}
|
||||
|
||||
public boolean isAdditive() {
|
||||
return additive;
|
||||
}
|
||||
|
||||
public void setAdditive(boolean additive) {
|
||||
this.additive = additive;
|
||||
}
|
||||
|
||||
public boolean isBehind() {
|
||||
return behind;
|
||||
}
|
||||
|
||||
public void setBehind(boolean behind) {
|
||||
this.behind = behind;
|
||||
}
|
||||
|
||||
public boolean isPremultipliedAlpha() {
|
||||
return premultipliedAlpha;
|
||||
}
|
||||
|
||||
public void setPremultipliedAlpha(boolean premultipliedAlpha) {
|
||||
this.premultipliedAlpha = premultipliedAlpha;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public abstract class ParticleAttributeValue {
|
||||
|
||||
private ParticleAttributeValueType type;
|
||||
|
||||
public ParticleAttributeValue(ParticleAttributeValueType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ParticleAttributeValueType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public enum ParticleAttributeValueType {
|
||||
|
||||
RANGE, TIMELINE, TINT_TIMELINE, SPAWN_SHAPE, OPTIONS, IMAGE_PATH;
|
||||
|
||||
public ParticleAttributeValue createInstance() {
|
||||
switch (this) {
|
||||
case RANGE:
|
||||
return new Range();
|
||||
case TIMELINE:
|
||||
return new Timeline();
|
||||
case TINT_TIMELINE:
|
||||
return new TintTimeline();
|
||||
case SPAWN_SHAPE:
|
||||
return new SpawnShape();
|
||||
case OPTIONS:
|
||||
return new Options();
|
||||
case IMAGE_PATH:
|
||||
return new ImagePath();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class Range extends ParticleAttributeValue {
|
||||
|
||||
private float lowMin;
|
||||
private float lowMax;
|
||||
private float highMin;
|
||||
private float highMax;
|
||||
|
||||
public Range() {
|
||||
super(ParticleAttributeValueType.RANGE);
|
||||
}
|
||||
|
||||
public Range createNormalizedInstance(Random random) {
|
||||
Range range = new Range();
|
||||
float high = createHighValue(random);
|
||||
range.setHighMax(high);
|
||||
range.setHighMin(high);
|
||||
float low = createLowValue(random);
|
||||
range.setLowMax(low);
|
||||
range.setLowMin(low);
|
||||
return range;
|
||||
}
|
||||
|
||||
public float createValue(Random random, float mix) {
|
||||
if (mix == 1)
|
||||
return createHighValue(random);
|
||||
else if (mix == 0)
|
||||
return createLowValue(random);
|
||||
else {
|
||||
float highValue = createHighValue(random);
|
||||
float lowValue = createLowValue(random);
|
||||
return mix * (highValue - lowValue) + lowValue;
|
||||
}
|
||||
}
|
||||
|
||||
private float createHighValue(Random random) {
|
||||
float min = highMin;
|
||||
float max = highMax;
|
||||
if (min == max)
|
||||
return min;
|
||||
return random.nextFloat() * (max - min) + min;
|
||||
}
|
||||
|
||||
private float createLowValue(Random random) {
|
||||
float min = lowMin;
|
||||
float max = lowMax;
|
||||
if (min == max)
|
||||
return min;
|
||||
return random.nextFloat() * (max - min) + min;
|
||||
}
|
||||
|
||||
public void setLowMin(float lowMin) {
|
||||
this.lowMin = lowMin;
|
||||
}
|
||||
|
||||
public void setLowMax(float lowMax) {
|
||||
this.lowMax = lowMax;
|
||||
}
|
||||
|
||||
public void setHighMin(float highMin) {
|
||||
this.highMin = highMin;
|
||||
}
|
||||
|
||||
public void setHighMax(float highMax) {
|
||||
this.highMax = highMax;
|
||||
}
|
||||
|
||||
private boolean isLowDifference() {
|
||||
return lowMin - lowMax != 0;
|
||||
}
|
||||
|
||||
private boolean isHighDifference() {
|
||||
return highMin - highMax != 0;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class SpawnShape extends ParticleAttributeValue {
|
||||
|
||||
public enum Shape {
|
||||
POINT("point"), SQUARE("square"), LINE("line");
|
||||
|
||||
private String name;
|
||||
|
||||
Shape(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static Shape byName(String text) throws Exception {
|
||||
for (Shape shape : values())
|
||||
if (shape.name.equals(text))
|
||||
return shape;
|
||||
throw new Exception("spawnShape with name \"" + text + "\" does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
private Shape shape;
|
||||
|
||||
public SpawnShape() {
|
||||
super(ParticleAttributeValueType.SPAWN_SHAPE);
|
||||
}
|
||||
|
||||
public Shape getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
public void setShape(Shape shape) {
|
||||
this.shape = shape;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class Timeline extends ParticleAttributeValue {
|
||||
|
||||
private List<TimelinePoint> points = new ArrayList<>();
|
||||
|
||||
public Timeline() {
|
||||
super(ParticleAttributeValueType.TIMELINE);
|
||||
}
|
||||
|
||||
public void setValueOfPoint(int index, float value) {
|
||||
if (points.size() <= index) {
|
||||
points.add(new TimelinePoint());
|
||||
}
|
||||
points.get(index).setValue(value);
|
||||
}
|
||||
|
||||
public void setTimeOfPoint(int index, float time) {
|
||||
if (points.size() <= index) {
|
||||
points.add(new TimelinePoint());
|
||||
}
|
||||
points.get(index).setTime(time);
|
||||
}
|
||||
|
||||
public float getValueAtTime(float time) {
|
||||
TimelinePoint left = null, right = null;
|
||||
for (TimelinePoint point : points) {
|
||||
if (point.getTime() <= time) {
|
||||
if (left == null || left.getTime() < point.getTime())
|
||||
left = point;
|
||||
} else if (right == null || right.getTime() > point.getTime())
|
||||
right = point;
|
||||
}
|
||||
if (left != null) {
|
||||
if (right != null) {
|
||||
float leftDist = Math.abs(left.getTime() - time);
|
||||
float rightDist = Math.abs(right.getTime() - time);
|
||||
float totalDist = leftDist + rightDist;
|
||||
float leftMultiplier = 1 - (leftDist / totalDist);
|
||||
float rightMultiplier = 1 - (rightDist / totalDist);
|
||||
return left.getValue() * leftMultiplier + right.getValue() * rightMultiplier;
|
||||
}
|
||||
return left.getValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
public class TimelinePoint {
|
||||
|
||||
private float time, value;
|
||||
|
||||
public float getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(float time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class TimelineRange {
|
||||
|
||||
private Timeline timeline;
|
||||
private Range range;
|
||||
|
||||
public TimelineRange(Timeline timeline, Range range) {
|
||||
this.timeline = timeline;
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public Timeline getTimeline() {
|
||||
return timeline;
|
||||
}
|
||||
|
||||
public void setTimeline(Timeline timeline) {
|
||||
this.timeline = timeline;
|
||||
}
|
||||
|
||||
public Range getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public void setRange(Range range) {
|
||||
this.range = range;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
import de.frajul.endlessroll.data.Color;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class TintTimeline extends ParticleAttributeValue {
|
||||
|
||||
private List<TintTimelinePoint> points = new ArrayList<>();
|
||||
|
||||
public TintTimeline() {
|
||||
super(ParticleAttributeValueType.TINT_TIMELINE);
|
||||
}
|
||||
|
||||
public void setValueOfPoint(int index, int colorIndex, float value) {
|
||||
if (points.size() <= index) {
|
||||
points.add(new TintTimelinePoint());
|
||||
}
|
||||
points.get(index).setValue(colorIndex, value);
|
||||
}
|
||||
|
||||
public void setTimeOfPoint(int index, float time) {
|
||||
if (points.size() <= index) {
|
||||
points.add(new TintTimelinePoint());
|
||||
}
|
||||
points.get(index).setTime(time);
|
||||
}
|
||||
|
||||
public Color getValueAtTime(float time) {
|
||||
TintTimelinePoint left = null, right = null;
|
||||
for (TintTimelinePoint point : points) {
|
||||
if (point.getTime() <= time) {
|
||||
if (left == null || left.getTime() < point.getTime())
|
||||
left = point;
|
||||
} else if (right == null || right.getTime() > point.getTime())
|
||||
right = point;
|
||||
}
|
||||
if (left != null) {
|
||||
if (right != null) {
|
||||
float leftDist = Math.abs(left.getTime() - time);
|
||||
float rightDist = Math.abs(right.getTime() - time);
|
||||
float totalDist = leftDist + rightDist;
|
||||
float leftMultiplier = leftDist / totalDist;
|
||||
float rightMultiplier = rightDist / totalDist;
|
||||
|
||||
return left.getColor().interpolate(leftMultiplier,rightMultiplier, right.getColor());
|
||||
}
|
||||
return left.getColor();
|
||||
}
|
||||
return new Color();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package de.frajul.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
import de.frajul.endlessroll.data.Color;
|
||||
|
||||
public class TintTimelinePoint {
|
||||
|
||||
private float time;
|
||||
private Color color;
|
||||
|
||||
public float getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(float time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setValue(int colorIndex, float value) {
|
||||
if (color == null)
|
||||
color = new Color();
|
||||
if (colorIndex == 0)
|
||||
color.setR(value);
|
||||
else if (colorIndex == 1)
|
||||
color.setG(value);
|
||||
else if (colorIndex == 2)
|
||||
color.setB(value);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package de.frajul.endlessroll.entities.textures;
|
||||
|
||||
/**
|
||||
* Created by Julian on 11.12.2015.
|
||||
*/
|
||||
public class Texture {
|
||||
|
||||
private int id;
|
||||
private int atlasWidth;
|
||||
private int atlasHeight;
|
||||
|
||||
public Texture(int id, int atlasWidth, int atlasHeight) {
|
||||
this.id = id;
|
||||
this.atlasWidth = atlasWidth;
|
||||
this.atlasHeight = atlasHeight;
|
||||
}
|
||||
|
||||
public Texture(Texture other) {
|
||||
this.id = other.getId();
|
||||
this.atlasWidth = other.getAtlasWidth();
|
||||
this.atlasHeight = other.getAtlasHeight();
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getAtlasWidth() {
|
||||
return atlasWidth;
|
||||
}
|
||||
|
||||
public int getAtlasHeight() {
|
||||
return atlasHeight;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package de.frajul.endlessroll.entities.textures;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
|
||||
/**
|
||||
* Created by Julian on 26.11.2015.
|
||||
*/
|
||||
public class TextureLoader {
|
||||
|
||||
private Context context;
|
||||
|
||||
public TextureLoader(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public int loadTextureId(int texture, boolean isAtlas) {
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), texture);
|
||||
return loadTextureId(bitmap, isAtlas);
|
||||
}
|
||||
|
||||
public Texture loadTexture(String inAssetsLocation) throws Exception {
|
||||
InputStream is = context.getAssets().open(inAssetsLocation);
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inScaled = false;
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
|
||||
return new Texture(loadTextureId(bitmap, false), 1, 1);
|
||||
}
|
||||
|
||||
private int loadTextureId(Bitmap bitmap, boolean isAtlas) {
|
||||
int id = genTexture();
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
|
||||
GLES20.GL_NEAREST);
|
||||
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
|
||||
GLES20.GL_NEAREST);
|
||||
|
||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
|
||||
bitmap.recycle();
|
||||
GameLog.d("Texture " + id + " successfully loaded");
|
||||
return id;
|
||||
}
|
||||
|
||||
private int genTexture() {
|
||||
int[] idField = new int[1];
|
||||
GLES20.glGenTextures(1, idField, 0);
|
||||
return idField[0];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package de.frajul.endlessroll.entities.textures;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.DrawableRes;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.tools.ToolType;
|
||||
import de.frajul.endlessroll.levels.worlds.World;
|
||||
|
||||
/**
|
||||
* Created by Julian on 05.12.2015.
|
||||
*/
|
||||
public class TexturePack {
|
||||
|
||||
private TextureLoader loader;
|
||||
|
||||
public final Texture goal;
|
||||
public final Texture playerArrow;
|
||||
public final Texture star;
|
||||
public final Texture energy;
|
||||
|
||||
public TexturePack(Context context) {
|
||||
loader = new TextureLoader(context);
|
||||
goal = loadTexture(R.drawable.guis_goal);
|
||||
playerArrow = loadTexture(R.drawable.guis_playerarrow);
|
||||
|
||||
star = loadTexture(R.drawable.currency_star);
|
||||
energy = loadAtlas(R.drawable.currency_energy_atlas, 2, 2);
|
||||
|
||||
PlayerShape.loadAllTextures(this);
|
||||
ToolType.loadAllToolTextures(this);
|
||||
World.loadAllSpecificTextures(this);
|
||||
}
|
||||
|
||||
public Texture loadTexture(@DrawableRes int id) {
|
||||
int texId = loader.loadTextureId(id, false);
|
||||
return new Texture(texId, 1, 1);
|
||||
}
|
||||
|
||||
public Texture loadAtlas(@DrawableRes int id, int atlasWidth, int atlasHeight) {
|
||||
int texId = loader.loadTextureId(id, true);
|
||||
return new Texture(texId, atlasWidth, atlasHeight);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package de.frajul.endlessroll.entities.tileLists;
|
||||
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class Ceiling extends TileList {
|
||||
|
||||
public Ceiling(Texture texture) {
|
||||
super(Type.CEILING, texture);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package de.frajul.endlessroll.entities.tileLists;
|
||||
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class Terrain extends TileList {
|
||||
|
||||
public Terrain(Texture texture) {
|
||||
super(TileList.Type.TERRAIN, texture);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package de.frajul.endlessroll.entities.tileLists;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.levels.TileData;
|
||||
|
||||
/**
|
||||
* Created by Julian on 18.12.2015.
|
||||
*/
|
||||
|
||||
public class Tile extends Entity {
|
||||
|
||||
public Tile(TileList.Type type, Texture texture, float edge, TileData data) {
|
||||
this(type, texture, edge, data.getX(), data.getWidth());
|
||||
}
|
||||
|
||||
public Tile(TileList.Type type, Texture texture, float edge, float x, float width) {
|
||||
super(texture, new Vector(), width, 0);
|
||||
super.height = type.calculateTileHeightFromEdge(edge);
|
||||
super.position.x = x;
|
||||
switch (type) {
|
||||
case TERRAIN:
|
||||
super.position.y = edge - super.height / 2;
|
||||
break;
|
||||
case CEILING:
|
||||
super.position.y = edge + super.height / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package de.frajul.endlessroll.entities.tileLists;
|
||||
|
||||
import de.frajul.endlessroll.data.SynchronizedArrayList;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.levels.TileData;
|
||||
import de.frajul.endlessroll.levels.worlds.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TileList extends SynchronizedArrayList<Tile> {
|
||||
|
||||
public enum Type {
|
||||
TERRAIN, CEILING;
|
||||
|
||||
public float calculateTileHeightFromEdge(float edge) {
|
||||
switch (this) {
|
||||
case TERRAIN:
|
||||
return 1 + edge;
|
||||
case CEILING:
|
||||
return 1 - edge;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Type type;
|
||||
private Texture texture;
|
||||
private float edge;
|
||||
private boolean endless;
|
||||
|
||||
public TileList(Type type, Texture texture) {
|
||||
this.type = type;
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public void loadData(World world, float edge, List<TileData> tileData) {
|
||||
this.texture = world.getTerrainTexture();
|
||||
if (type == Type.CEILING)
|
||||
this.texture = world.getCeilingTexture();
|
||||
this.endless = false;
|
||||
super.clear();
|
||||
for (TileData data : tileData)
|
||||
super.add(new Tile(type, texture, edge, data));
|
||||
this.edge = edge;
|
||||
if (edge >= 1 || edge <= -1)
|
||||
super.clear();
|
||||
}
|
||||
|
||||
public void createEndless(World world, float edge) {
|
||||
loadData(world, edge, new ArrayList<TileData>());
|
||||
super.add(createEndlessTile(0));
|
||||
this.endless = true;
|
||||
}
|
||||
|
||||
public void update(float cameraX) {
|
||||
if (!super.isEmpty()) {
|
||||
if (endless) {
|
||||
Tile last = super.get(super.size() - 1);
|
||||
if (last.getRightEdge() - cameraX < 3)
|
||||
super.add(createEndlessTile(last.getRightEdge() + 2.5f));
|
||||
}
|
||||
if (super.get(0).getRightEdge() - cameraX < -3) {
|
||||
super.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Tile createEndlessTile(float x) {
|
||||
return new Tile(type, texture, edge, x, 5);
|
||||
}
|
||||
|
||||
public float getEdge() {
|
||||
return edge;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.DestroyEffect;
|
||||
import de.frajul.endlessroll.entities.Obstacle;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Geometry;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Quad;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.02.2016.
|
||||
*/
|
||||
public class Bomb extends Tool {
|
||||
|
||||
public final float RANGE = 1;
|
||||
private float delta;
|
||||
private boolean exploding = false;
|
||||
|
||||
public Bomb(Vector position) {
|
||||
super(ToolType.BOMB, position, .29f, .29f, false, false);
|
||||
animation.setIndexSequence(new int[]{0, 1, 2});
|
||||
animation.setLooping(false);
|
||||
animation.setRequiredDelta(
|
||||
(int) (ToolType.BOMB.getCurrentUpgradeValue(ToolUpgradeType.DURATION) / 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Timer timer) {
|
||||
super.update(timer);
|
||||
delta += timer.getFrameTimeSeconds();
|
||||
if (delta >= ToolType.BOMB.getCurrentUpgradeValue(ToolUpgradeType.DURATION))
|
||||
exploding = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player, Timer timer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createWorldCollisionBounds() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createPlayerCollisionBounds() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isExploding() {
|
||||
return exploding;
|
||||
}
|
||||
|
||||
public void explode(List<Obstacle> obstacles, CollisionDetector detector) {
|
||||
float range = RANGE * ToolType.BOMB.getCurrentUpgradeValue(ToolUpgradeType.RANGE) / 100;
|
||||
Quad explosionRange = new Quad(new Vector(super.getPosition()), range, range);
|
||||
for (Obstacle obstacle : obstacles) {
|
||||
if (detector.isQuadQuadCollision(obstacle, explosionRange))
|
||||
obstacle.destroy(DestroyEffect.EXPLOSION);
|
||||
}
|
||||
super.destroy(DestroyEffect.EXPLOSION);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.DestroyEffect;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Circle;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Geometry;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSource;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 11.02.2016.
|
||||
*/
|
||||
public class Magnet extends Tool {
|
||||
|
||||
private ParticleSource particleSource;
|
||||
|
||||
public Magnet(Vector position, ParticleSystem particleSystem) {
|
||||
super(ToolType.MAGNET, position, .24f, .24f, false, false);
|
||||
animation.setRequiredDelta(300);
|
||||
animation.setIndexSequence(new int[]{1, 1, 0});
|
||||
animation.setLooping(true);
|
||||
super.setFloating(true);
|
||||
particleSource = new ParticleSource(new Vector(position), particleSystem.magnet);
|
||||
particleSource.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(DestroyEffect destroyEffect) {
|
||||
super.destroy(destroyEffect);
|
||||
particleSource.kill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player, Timer timer) {
|
||||
float fromPlayerDistance = player.getPosition().vectorTo(super.getPosition()).length();
|
||||
float fromPlayerDistanceGreaterFour = Math.max(fromPlayerDistance, 0.4f);
|
||||
float fromPlayerYDistance = super.getPosition().y - player.getPosition().y;
|
||||
float force = 0.0000012f / (fromPlayerDistanceGreaterFour * fromPlayerDistanceGreaterFour);
|
||||
force *= ToolType.MAGNET.getCurrentUpgradeValue(ToolUpgradeType.FORCE) / 100;
|
||||
force *= timer.getFrameTimeSeconds();
|
||||
|
||||
if (fromPlayerYDistance < 0) {
|
||||
force = -force;
|
||||
}
|
||||
player.addForce(force);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createWorldCollisionBounds() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createPlayerCollisionBounds() {
|
||||
return new Circle(super.getPosition(), 2);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Geometry;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Triangle;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 29.11.2015.
|
||||
*/
|
||||
public class Ramp extends Tool {
|
||||
|
||||
public Ramp(Vector position) {
|
||||
super(ToolType.RAMP, position, .4f, .35f, true, true);
|
||||
animation.setLooping(true);
|
||||
}
|
||||
|
||||
public float getGradient() {
|
||||
return super.getHeight() / super.getWidth();
|
||||
}
|
||||
|
||||
public float getHeightAt(float x, boolean clamp) {
|
||||
float ratio = (x - getLeftEdge()) / super.getWidth();
|
||||
if (clamp) {
|
||||
if (ratio < 0)
|
||||
return getBottomEdge();
|
||||
if (ratio > 1)
|
||||
return getTopEdge();
|
||||
}
|
||||
return getBottomEdge() + super.getHeight() * ratio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player, Timer timer) {
|
||||
float necessaryY = calcNecessaryPlayerY(player);
|
||||
player.getPosition().y = necessaryY;
|
||||
float acceleration = player.getMovement().x * getGradient();
|
||||
|
||||
player.setGravityForce(0);
|
||||
player.getMovement().setY(0);
|
||||
player.addForce(acceleration);
|
||||
}
|
||||
|
||||
private float calcNecessaryPlayerY(Player player) {
|
||||
float normalM = -1 / getGradient();
|
||||
Vector normalToCircleCenter = new Vector(-1, -normalM).normalize();
|
||||
normalToCircleCenter.mul(player.RADIUS);
|
||||
float normalX = player.getPosition().x - normalToCircleCenter.x;
|
||||
float normalY = getHeightAt(normalX, false);
|
||||
return normalY + normalToCircleCenter.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createWorldCollisionBounds() {
|
||||
return new Triangle(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createPlayerCollisionBounds() {
|
||||
return new Triangle(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Geometry;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Quad;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 04.01.2016.
|
||||
*/
|
||||
public class Spring extends Tool {
|
||||
|
||||
private boolean hasYetCollided = false;
|
||||
|
||||
public Spring(Vector position) {
|
||||
super(ToolType.SPRING, position, .3f, .35f, true, true);
|
||||
animation.setIndexSequence(new int[]{1, 0, 0, 3, 3, 3, 1});
|
||||
animation.setRequiredDelta(80);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Timer timer) {
|
||||
if (hasYetCollided)
|
||||
super.update(timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player, Timer timer) {
|
||||
if (!hasYetCollided) {
|
||||
hasYetCollided = true;
|
||||
|
||||
player.clearAllForces();
|
||||
player.getMovement().setY(0);
|
||||
player.addForce(.0022f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createWorldCollisionBounds() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createPlayerCollisionBounds() {
|
||||
return new Quad(super.getPosition(), .2f, .1f);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.AnimatedEntity;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Geometry;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 04.01.2016.
|
||||
*/
|
||||
public abstract class Tool extends AnimatedEntity {
|
||||
|
||||
private boolean placedByRightEdge;
|
||||
private boolean updateBounds;
|
||||
private Geometry worldCollisionBounds;
|
||||
private Geometry playerCollisionBounds;
|
||||
private boolean floating = false;
|
||||
|
||||
public Tool(ToolType type, Vector position, float width, float height, boolean updateBounds, boolean placedByRightEdge) {
|
||||
super(type.getToolTexture(), position, width, height);
|
||||
this.updateBounds = updateBounds;
|
||||
this.placedByRightEdge = placedByRightEdge;
|
||||
worldCollisionBounds = createWorldCollisionBounds();
|
||||
playerCollisionBounds = createPlayerCollisionBounds();
|
||||
}
|
||||
|
||||
public abstract void onPlayerCollision(Player player, Timer timer);
|
||||
|
||||
protected abstract Geometry createWorldCollisionBounds();
|
||||
|
||||
protected abstract Geometry createPlayerCollisionBounds();
|
||||
|
||||
public Geometry getWorldCollisionBounds() {
|
||||
if (updateBounds)
|
||||
return createWorldCollisionBounds();
|
||||
return worldCollisionBounds;
|
||||
}
|
||||
|
||||
public Geometry getPlayerCollisionBounds() {
|
||||
if (updateBounds)
|
||||
return createPlayerCollisionBounds();
|
||||
return playerCollisionBounds;
|
||||
}
|
||||
|
||||
public void setFloating(boolean floating) {
|
||||
this.floating = floating;
|
||||
}
|
||||
|
||||
public boolean isFloating() {
|
||||
return floating;
|
||||
}
|
||||
|
||||
public boolean isPlacedByRightEdge() {
|
||||
return placedByRightEdge;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
|
||||
/**
|
||||
* Created by Julian on 16.07.2016.
|
||||
*/
|
||||
public class ToolSlot {
|
||||
|
||||
private ToolType toolType;
|
||||
private boolean locked;
|
||||
|
||||
public ToolSlot(ToolType toolType, boolean locked) {
|
||||
this.toolType = toolType;
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public ToolType getToolType() {
|
||||
return toolType;
|
||||
}
|
||||
|
||||
public int getDrawable() {
|
||||
if (locked)
|
||||
return R.drawable.tools_button_locked;
|
||||
else if(toolType != null)
|
||||
return toolType.getButtonDrawable();
|
||||
else
|
||||
return R.drawable.tools_button_empty;
|
||||
}
|
||||
|
||||
public void setToolType(ToolType toolType) {
|
||||
this.toolType = toolType;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
package de.frajul.endlessroll.entities.tools;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
import de.frajul.endlessroll.sounds.SoundManager;
|
||||
|
||||
public enum ToolType {
|
||||
|
||||
//Check newInstance when new Tool is added!
|
||||
RAMP(R.string.tool_name_ramp, R.string.tool_description_ramp, R.drawable.tools_ramp,
|
||||
R.drawable.tools_ramp_button, R.raw.ramp, 0, 1, 5,
|
||||
new ToolUpgrade(ToolUpgradeType.COOLDOWN, 3000, 1000)),
|
||||
SPRING(R.string.tool_name_spring, R.string.tool_description_spring, R.drawable.tools_spring,
|
||||
R.drawable.tools_spring_button, R.raw.ramp, 5, 2, 5,
|
||||
new ToolUpgrade(ToolUpgradeType.COOLDOWN, 4000, 2000)),
|
||||
BOMB(R.string.tool_name_bomb, R.string.tool_description_bomb, R.drawable.tools_bomb,
|
||||
R.drawable.tools_bomb_button, R.raw.ramp, 12, 4, 5,
|
||||
new ToolUpgrade(ToolUpgradeType.COOLDOWN, 6000, 4000),
|
||||
new ToolUpgrade(ToolUpgradeType.DURATION, 1200, 400),
|
||||
new ToolUpgrade(ToolUpgradeType.RANGE, 100, 200)),
|
||||
MAGNET(R.string.tool_name_magnet, R.string.tool_description_magnet, R.drawable.tools_magnet,
|
||||
R.drawable.tools_magnet_button, R.raw.ramp, 10, 4, 5,
|
||||
new ToolUpgrade(ToolUpgradeType.COOLDOWN, 6000, 4000),
|
||||
new ToolUpgrade(ToolUpgradeType.FORCE, 100, 500)),
|
||||
POWER_MUSHROOM(R.string.tool_name_power_mushroom, R.string.tool_description_power_mushroom,
|
||||
R.drawable.tools_power_mushroom, R.drawable.tools_power_mushroom_button, R.raw.ramp, 5,
|
||||
5, 7, new ToolUpgrade(ToolUpgradeType.COOLDOWN, 15000, 11000),
|
||||
new ToolUpgrade(ToolUpgradeType.DURATION, 5000, 10000)),
|
||||
STASIS(R.string.tool_name_stasis, R.string.tool_description_stasis, R.drawable.tools_stasis,
|
||||
R.drawable.tools_stasis_button, R.raw.ramp, 15, 6, 6,
|
||||
new ToolUpgrade(ToolUpgradeType.COOLDOWN, 8000, 5000),
|
||||
new ToolUpgrade(ToolUpgradeType.FORCE, 1, 2),
|
||||
new ToolUpgrade(ToolUpgradeType.SIZE, 100, 200));
|
||||
|
||||
@StringRes
|
||||
private final int name;
|
||||
@StringRes
|
||||
private final int description;
|
||||
private final int toolTextureId;
|
||||
private final int buttonDrawable;
|
||||
private final int placingSoundId;
|
||||
private final int buyPrice;
|
||||
private final int upgradePrice;
|
||||
private final int maxUpgradeLevel;
|
||||
private final List<ToolUpgrade> upgrades;
|
||||
|
||||
private Texture toolTexture = null;
|
||||
private int placingSound = -1;
|
||||
private boolean bought;
|
||||
private int currentUpgradeLevel = 1;
|
||||
|
||||
ToolType(@StringRes int name, @StringRes int description, int toolTextureId, int buttonDrawable, int placingSoundId, int buyPrice, int upgradePrice, int maxUpgradeLevel, ToolUpgrade... upgrades) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.toolTextureId = toolTextureId;
|
||||
this.buttonDrawable = buttonDrawable;
|
||||
this.placingSoundId = placingSoundId;
|
||||
this.buyPrice = buyPrice;
|
||||
this.upgradePrice = upgradePrice;
|
||||
this.maxUpgradeLevel = maxUpgradeLevel;
|
||||
this.upgrades = Arrays.asList(upgrades);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Tool newInstance(Vector position, ParticleSystem particleSystem) {
|
||||
Tool tool = null;
|
||||
switch (this) {
|
||||
case RAMP:
|
||||
tool = new Ramp(position);
|
||||
break;
|
||||
case SPRING:
|
||||
tool = new Spring(position);
|
||||
break;
|
||||
case MAGNET:
|
||||
tool = new Magnet(position, particleSystem);
|
||||
break;
|
||||
case BOMB:
|
||||
tool = new Bomb(position);
|
||||
break;
|
||||
case POWER_MUSHROOM:
|
||||
tool = new PowerMushroom(position);
|
||||
break;
|
||||
case STASIS:
|
||||
tool = new Stasis(position,particleSystem);
|
||||
break;
|
||||
}
|
||||
if (tool != null && tool.isPlacedByRightEdge())
|
||||
tool.move(new Vector(-tool.getWidth() / 2, 0));
|
||||
return tool;
|
||||
}
|
||||
|
||||
public static void loadAllPlacingSounds(SoundManager soundManager) {
|
||||
for (ToolType type : values())
|
||||
type.loadPlacingSound(soundManager);
|
||||
}
|
||||
|
||||
public static void loadAllToolTextures(TexturePack texturePack) {
|
||||
for (ToolType type : values())
|
||||
type.loadToolTexture(texturePack);
|
||||
}
|
||||
|
||||
private void loadPlacingSound(SoundManager soundManager) {
|
||||
if (placingSoundId == -1)
|
||||
return;
|
||||
placingSound = soundManager.loadSound(placingSoundId);
|
||||
}
|
||||
|
||||
private void loadToolTexture(TexturePack texturePack) {
|
||||
if (toolTextureId == -1)
|
||||
return;
|
||||
if (this != POWER_MUSHROOM)
|
||||
toolTexture = texturePack.loadAtlas(toolTextureId, 2, 2);
|
||||
else
|
||||
toolTexture = texturePack.loadTexture(toolTextureId);
|
||||
}
|
||||
|
||||
public Texture getToolTexture() {
|
||||
return toolTexture;
|
||||
}
|
||||
|
||||
public int getButtonDrawable() {
|
||||
return buttonDrawable;
|
||||
}
|
||||
|
||||
public int getPlacingSound() {
|
||||
return placingSound;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
public int getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
public int getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setBought(boolean bought) {
|
||||
this.bought = bought;
|
||||
}
|
||||
|
||||
public boolean isBought() {
|
||||
if (this == RAMP)
|
||||
bought = true;
|
||||
return bought;
|
||||
}
|
||||
|
||||
public void upgrade() {
|
||||
currentUpgradeLevel++;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
setBought(false);
|
||||
currentUpgradeLevel = 1;
|
||||
}
|
||||
|
||||
public int getBuyPrice() {
|
||||
return buyPrice;
|
||||
}
|
||||
|
||||
public int getUpgradePrice() {
|
||||
return upgradePrice + currentUpgradeLevel - 1;
|
||||
}
|
||||
|
||||
public int getCurrentUpgradeLevel() {
|
||||
return currentUpgradeLevel;
|
||||
}
|
||||
|
||||
public void setCurrentUpgradeLevel(int currentUpgradeLevel) {
|
||||
this.currentUpgradeLevel = currentUpgradeLevel;
|
||||
}
|
||||
|
||||
public float getCurrentUpgradeValue(ToolUpgradeType type) {
|
||||
for (ToolUpgrade upgrade : upgrades)
|
||||
if (upgrade.getType().equals(type))
|
||||
return upgrade.getValueAtLevel(currentUpgradeLevel, maxUpgradeLevel);
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean isAtMaxUpgradeLevel() {
|
||||
return currentUpgradeLevel == maxUpgradeLevel;
|
||||
}
|
||||
|
||||
}
|
22
app/src/main/java/de/frajul/endlessroll/levels/Gap.java
Normal file
22
app/src/main/java/de/frajul/endlessroll/levels/Gap.java
Normal file
@ -0,0 +1,22 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.11.2015.
|
||||
*/
|
||||
public class Gap {
|
||||
|
||||
@Attribute
|
||||
private float leftEdge;
|
||||
@Attribute
|
||||
private float rightEdge;
|
||||
|
||||
public float getLeftEdge() {
|
||||
return leftEdge;
|
||||
}
|
||||
|
||||
public float getRightEdge() {
|
||||
return rightEdge;
|
||||
}
|
||||
}
|
147
app/src/main/java/de/frajul/endlessroll/levels/Level.java
Normal file
147
app/src/main/java/de/frajul/endlessroll/levels/Level.java
Normal file
@ -0,0 +1,147 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.ElementList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.12.2015.
|
||||
*/
|
||||
public class Level {
|
||||
|
||||
@Attribute
|
||||
private int packId;
|
||||
@Attribute
|
||||
private int id;
|
||||
@Attribute
|
||||
private float goalX;
|
||||
@Attribute
|
||||
private float startSpeed;
|
||||
@Attribute
|
||||
private float endSpeed;
|
||||
@Attribute
|
||||
private float terrainEdge;
|
||||
@Attribute
|
||||
private float ceilingEdge;
|
||||
@ElementList
|
||||
private List<TileData> terrainTiles;
|
||||
@ElementList
|
||||
private List<TileData> ceilingTiles;
|
||||
@ElementList
|
||||
private List<ObstacleData> obstacles;
|
||||
@ElementList
|
||||
private List<PositionData> stars;
|
||||
@Element(required = false)
|
||||
private PositionData energy;
|
||||
|
||||
private boolean finished = false;
|
||||
private boolean locked = true;
|
||||
private boolean[] collectedStars = {false, false, false};
|
||||
private boolean energyCollected = false;
|
||||
|
||||
public int getPackId() {
|
||||
return packId;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public float getGoalX() {
|
||||
return goalX;
|
||||
}
|
||||
|
||||
public float getStartSpeed() {
|
||||
return startSpeed;
|
||||
}
|
||||
|
||||
public float getEndSpeed() {
|
||||
return endSpeed;
|
||||
}
|
||||
|
||||
public float getTerrainEdge() {
|
||||
return terrainEdge;
|
||||
}
|
||||
|
||||
public float getCeilingEdge() {
|
||||
return ceilingEdge;
|
||||
}
|
||||
|
||||
public List<TileData> getTerrainTiles() {
|
||||
return terrainTiles;
|
||||
}
|
||||
|
||||
public List<TileData> getCeilingTiles() {
|
||||
return ceilingTiles;
|
||||
}
|
||||
|
||||
public List<ObstacleData> getObstacles() {
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
public List<PositionData> getStars() {
|
||||
return stars;
|
||||
}
|
||||
|
||||
public PositionData getEnergyData() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
public void setFinished(boolean finished) {
|
||||
this.finished = finished;
|
||||
}
|
||||
|
||||
public boolean isStarCollected(int index) {
|
||||
return collectedStars[index];
|
||||
}
|
||||
|
||||
public void setStarCollected(int index, boolean collected) {
|
||||
collectedStars[index] = collected;
|
||||
}
|
||||
|
||||
public String getCollectedStarCodeForSQL() {
|
||||
String code = "";
|
||||
for (int i = 0; i < 3; i++)
|
||||
code += collectedStars[i] ? (i + 1) + "" : "";
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCollectedStarsFromSQL(String code) {
|
||||
for (int i = 0; i < 3; i++)
|
||||
collectedStars[i] = code.contains((i + 1) + "");
|
||||
}
|
||||
|
||||
public boolean[] getCollectedStars() {
|
||||
return collectedStars;
|
||||
}
|
||||
|
||||
public boolean isEnergyCollected() {
|
||||
return energyCollected;
|
||||
}
|
||||
|
||||
public void setEnergyCollected(boolean collected) {
|
||||
this.energyCollected = collected;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
finished = false;
|
||||
locked = true;
|
||||
collectedStars = new boolean[]{false, false, false};
|
||||
energyCollected = false;
|
||||
}
|
||||
|
||||
}
|
117
app/src/main/java/de/frajul/endlessroll/levels/LevelManager.java
Normal file
117
app/src/main/java/de/frajul/endlessroll/levels/LevelManager.java
Normal file
@ -0,0 +1,117 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.simpleframework.xml.Serializer;
|
||||
import org.simpleframework.xml.core.Persister;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.main.DataStorageHandler;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
import de.frajul.endlessroll.sqlDatabase.MyDatabase;
|
||||
|
||||
public class LevelManager extends ArrayList<LevelPack> {
|
||||
|
||||
public LevelManager(Context context, DataStorageHandler dataStorageHandler) throws Exception {
|
||||
String[] worldNames = context.getResources().getStringArray(R.array.world_names);
|
||||
String[] assets = context.getAssets().list("levelpacks");
|
||||
for (String asset : assets) {
|
||||
try {
|
||||
LevelPack pack = loadLevelPack(context, "levelpacks/" + asset);
|
||||
pack.setName(worldNames[pack.getId()]);
|
||||
|
||||
MyDatabase database = dataStorageHandler.getDatabase();
|
||||
database.open();
|
||||
for (Level level : pack.getLevels())
|
||||
database.readLevelProgress(level);
|
||||
database.readLevelPackLocked(pack);
|
||||
database.close();
|
||||
pack.tryToUnlockFirstLevel();
|
||||
if (pack.getId() == 1)
|
||||
pack.setLocked(false);
|
||||
super.add(pack);
|
||||
} catch (Exception e) {
|
||||
GameLog.e(e);
|
||||
}
|
||||
}
|
||||
sortPacks();
|
||||
}
|
||||
|
||||
private void sortPacks() {
|
||||
Collections.sort(this, packComparator);
|
||||
}
|
||||
|
||||
private LevelPack loadLevelPack(Context context, String name) throws Exception {
|
||||
try {
|
||||
InputStream source = context.getAssets().open(name);
|
||||
Serializer serializer = new Persister();
|
||||
return serializer.read(LevelPack.class, source);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("Could not load levelPack \"" + name + "\"", e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalCollectedStarCount(){
|
||||
int count = 0;
|
||||
for(LevelPack levelPack : this)
|
||||
count += levelPack.getCollectedStarCount();
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getTotalCollectedEnergyCount(){
|
||||
int count = 0;
|
||||
for(LevelPack levelPack : this)
|
||||
count += levelPack.getCollectedEnergyCount();
|
||||
return count;
|
||||
}
|
||||
|
||||
public LevelPack getNextLevelPack(LevelPack currentPack) {
|
||||
int searchedId = currentPack.getId() + 1;
|
||||
for (LevelPack pack : this) {
|
||||
if (pack.getId() == searchedId)
|
||||
return pack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public LevelPack getPackWithId(int id) {
|
||||
for (LevelPack pack : this)
|
||||
if (pack.getId() == id)
|
||||
return pack;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (LevelPack pack : this) {
|
||||
pack.reset();
|
||||
if (pack.getId() == 1)
|
||||
pack.setLocked(false);
|
||||
}
|
||||
}
|
||||
|
||||
private Comparator<LevelPack> packComparator = new Comparator<LevelPack>() {
|
||||
@Override
|
||||
public int compare(LevelPack lhs, LevelPack rhs) {
|
||||
return lhs.getId() - rhs.getId();
|
||||
}
|
||||
};
|
||||
|
||||
//CHEAT
|
||||
public void unlockAllPacks() {
|
||||
for (LevelPack levelPack : this)
|
||||
levelPack.setLocked(false);
|
||||
}
|
||||
|
||||
public void unlockAllLevels() {
|
||||
for (LevelPack levelPack : this) {
|
||||
for (Level level : levelPack.getLevels())
|
||||
level.setLocked(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
120
app/src/main/java/de/frajul/endlessroll/levels/LevelPack.java
Normal file
120
app/src/main/java/de/frajul/endlessroll/levels/LevelPack.java
Normal file
@ -0,0 +1,120 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
import org.simpleframework.xml.Element;
|
||||
import org.simpleframework.xml.ElementList;
|
||||
import org.simpleframework.xml.Root;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.levels.worlds.World;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.12.2015.
|
||||
*/
|
||||
@Root
|
||||
public class LevelPack {
|
||||
|
||||
@Attribute
|
||||
private int id;
|
||||
@Element
|
||||
private World world;
|
||||
@ElementList
|
||||
private List<Level> levels;
|
||||
|
||||
private String name;
|
||||
private boolean locked = true;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<Level> getLevels() {
|
||||
return levels;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getFinishedLevelCount() {
|
||||
int count = 0;
|
||||
for (Level level : levels)
|
||||
if (level.isFinished())
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getCollectedStarCount() {
|
||||
int count = 0;
|
||||
for (Level level : levels)
|
||||
count += level.getCollectedStarCodeForSQL().length();
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getAvailableStars() {
|
||||
return levels.size() * 3;
|
||||
}
|
||||
|
||||
public int getCollectedEnergyCount() {
|
||||
int count = 0;
|
||||
for (Level level : levels)
|
||||
count += level.isEnergyCollected() ? 1 : 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getAvailableEnergy() {
|
||||
return levels.size();
|
||||
}
|
||||
|
||||
public void tryToUnlockFirstLevel() {
|
||||
Level firstLevel = getLevel(1);
|
||||
if (firstLevel != null)
|
||||
firstLevel.setLocked(false);
|
||||
}
|
||||
|
||||
public Level getLevel(int id) {
|
||||
for (Level level : levels)
|
||||
if (level.getId() == id)
|
||||
return level;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Level getNextLevel(Level currentLevel) {
|
||||
return getLevel(currentLevel.getId() + 1);
|
||||
}
|
||||
|
||||
public boolean isAllLevelsFinished() {
|
||||
for (Level level : levels)
|
||||
if (!level.isFinished())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isLastLevel(Level level) {
|
||||
return getNextLevel(level) == null;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (Level level : levels)
|
||||
level.reset();
|
||||
setLocked(true);
|
||||
tryToUnlockFirstLevel();
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.Vertex;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
|
||||
public class MoveComponent {
|
||||
|
||||
@Attribute
|
||||
private float width;
|
||||
@Attribute
|
||||
private float height;
|
||||
@Attribute
|
||||
private float x;
|
||||
@Attribute
|
||||
private float y;
|
||||
@Attribute
|
||||
private float speed;
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public Vector getPositionOfVertex(Vertex vertex) {
|
||||
float x = this.x + (width / 2f) * vertex.getX();
|
||||
float y = this.y + (height / 2f) * vertex.getY();
|
||||
return new Vector(x, y);
|
||||
}
|
||||
|
||||
public void shrink(Vector value) {
|
||||
this.width -= value.getX();
|
||||
this.height -= value.getY();
|
||||
if (width < 0)
|
||||
width = 0;
|
||||
if (height < 0)
|
||||
height = 0;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
import org.simpleframework.xml.Element;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.12.2015.
|
||||
*/
|
||||
public class ObstacleData {
|
||||
|
||||
@Attribute
|
||||
private boolean floating;
|
||||
@Attribute
|
||||
private boolean moving;
|
||||
@Attribute
|
||||
private boolean deadly;
|
||||
@Attribute
|
||||
private float leftEdge;
|
||||
@Attribute
|
||||
private float rightEdge;
|
||||
@Attribute
|
||||
private float height;
|
||||
@Attribute
|
||||
private float y;
|
||||
@Element(required = false)
|
||||
private MoveComponent moveComponent;
|
||||
|
||||
public boolean isFloating() {
|
||||
return floating;
|
||||
}
|
||||
|
||||
public boolean isMoving() {
|
||||
return moving;
|
||||
}
|
||||
|
||||
public boolean isDeadly() {
|
||||
return deadly;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return leftEdge + getWidth() / 2;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return rightEdge - leftEdge;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public MoveComponent getMoveComponent() {
|
||||
return moveComponent;
|
||||
}
|
||||
|
||||
|
||||
//Only for glTestScreen
|
||||
public void setFloating(boolean floating) {
|
||||
this.floating = floating;
|
||||
}
|
||||
|
||||
public void setMoving(boolean moving) {
|
||||
this.moving = moving;
|
||||
}
|
||||
|
||||
public void setDeadly(boolean deadly) {
|
||||
this.deadly = deadly;
|
||||
}
|
||||
|
||||
public void setLeftEdge(float leftEdge) {
|
||||
this.leftEdge = leftEdge;
|
||||
}
|
||||
|
||||
public void setRightEdge(float rightEdge) {
|
||||
this.rightEdge = rightEdge;
|
||||
}
|
||||
|
||||
public void setHeight(float height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setMoveComponent(MoveComponent moveComponent) {
|
||||
this.moveComponent = moveComponent;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.01.2017.
|
||||
*/
|
||||
|
||||
public class PositionData {
|
||||
|
||||
@Attribute
|
||||
private float x;
|
||||
@Attribute
|
||||
private float y;
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
19
app/src/main/java/de/frajul/endlessroll/levels/TileData.java
Normal file
19
app/src/main/java/de/frajul/endlessroll/levels/TileData.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.frajul.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
|
||||
public class TileData {
|
||||
|
||||
@Attribute
|
||||
private float x;
|
||||
@Attribute
|
||||
private float width;
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package de.frajul.endlessroll.levels.worlds;
|
||||
|
||||
import android.support.annotation.DrawableRes;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.entities.textures.Texture;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
|
||||
/**
|
||||
* Created by Julian on 14.11.2016.
|
||||
*/
|
||||
|
||||
public enum World {
|
||||
|
||||
GRASSLANDS("Grasslands", R.drawable.world_previews_grass, R.drawable.backgrounds_game_grass, R.drawable.terrain_t_grass, R.drawable.terrain_c_grass, R.drawable.obstacles_grass),
|
||||
TESTCAVE("Testcave", R.drawable.world_previews_grass, R.drawable.backgrounds_game_cave, R.drawable.terrain_t_grass, R.drawable.terrain_c_grass, R.drawable.obstacles_grass),
|
||||
ICY_MOUNTAINS("Icy Mountains", R.drawable.world_previews_grass, R.drawable.backgrounds_game_mountains, R.drawable.terrain_t_grass, R.drawable.terrain_c_grass, R.drawable.obstacles_grass);
|
||||
|
||||
private String name;
|
||||
@DrawableRes
|
||||
private int previewId;
|
||||
@DrawableRes
|
||||
private int backgroundId;
|
||||
@DrawableRes
|
||||
private int terrainId;
|
||||
@DrawableRes
|
||||
private int ceilingId;
|
||||
@DrawableRes
|
||||
private int obstacleId;
|
||||
|
||||
private Texture background;
|
||||
private Texture terrain;
|
||||
private Texture ceiling;
|
||||
private Texture obstacle;
|
||||
|
||||
World(String name, @DrawableRes int previewId, @DrawableRes int backgroundId, @DrawableRes int terrainId, @DrawableRes int ceilingId, @DrawableRes int obstacleId) {
|
||||
this.name = name;
|
||||
this.previewId = previewId;
|
||||
this.backgroundId = backgroundId;
|
||||
this.terrainId = terrainId;
|
||||
this.ceilingId = ceilingId;
|
||||
this.obstacleId = obstacleId;
|
||||
}
|
||||
|
||||
public static void loadAllSpecificTextures(TexturePack texturePack) {
|
||||
for (World world : values())
|
||||
world.loadSpecificTextures(texturePack);
|
||||
}
|
||||
|
||||
private void loadSpecificTextures(TexturePack texturePack) {
|
||||
background = texturePack.loadTexture(backgroundId);
|
||||
terrain = texturePack.loadTexture(terrainId);
|
||||
ceiling = texturePack.loadTexture(ceilingId);
|
||||
obstacle = texturePack.loadAtlas(obstacleId, 8, 8);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getPreviewId() {
|
||||
return previewId;
|
||||
}
|
||||
|
||||
public Texture getBackgroundTexture() {
|
||||
return background;
|
||||
}
|
||||
|
||||
public Texture getTerrainTexture() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public Texture getCeilingTexture() {
|
||||
return ceiling;
|
||||
}
|
||||
|
||||
public Texture getObstacleTexture() {
|
||||
return obstacle;
|
||||
}
|
||||
}
|
12
app/src/main/java/de/frajul/endlessroll/main/DataSafer.java
Normal file
12
app/src/main/java/de/frajul/endlessroll/main/DataSafer.java
Normal file
@ -0,0 +1,12 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
import de.frajul.endlessroll.user.User;
|
||||
|
||||
/**
|
||||
* Created by Julian on 15.07.2016.
|
||||
*/
|
||||
public class DataSafer {
|
||||
|
||||
private User user;
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.tools.ToolType;
|
||||
import de.frajul.endlessroll.sqlDatabase.MyDatabase;
|
||||
import de.frajul.endlessroll.user.ToolSlotSettings;
|
||||
import de.frajul.endlessroll.user.User;
|
||||
|
||||
/**
|
||||
* Created by Julian on 25.04.2016.
|
||||
*/
|
||||
public class DataStorageHandler {
|
||||
|
||||
private final String PREFERENCES_NAME = "GamePreferences";
|
||||
private final String SOUND_ON = "Sound";
|
||||
private final String USER_EP = "EP";
|
||||
private final String USER_LEVEL = "Level";
|
||||
private final String USER_STARS = "Stars";
|
||||
private final String USER_ENERGY = "Energy";
|
||||
private final String USER_TOOL_1 = "Tool1";
|
||||
private final String USER_TOOL_2 = "Tool2";
|
||||
private final String USER_TOOL_3 = "Tool3";
|
||||
private final String USER_TOOL_4 = "Tool4";
|
||||
private final String USER_TOOLS_LOCKED = "ToolsLocked";
|
||||
private final String USER_PLAYER_SHAPE = "PlayerShape";
|
||||
private final String TOOL_SHOP_TUTORIAL_PART_1_FINISHED = "ToolShopTutorialPart1Finished";
|
||||
|
||||
private SharedPreferences preferences;
|
||||
private MyDatabase database;
|
||||
|
||||
public DataStorageHandler(Activity activity) {
|
||||
preferences = activity.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
|
||||
database = new MyDatabase(activity);
|
||||
}
|
||||
|
||||
public boolean readIsSoundOn() {
|
||||
return preferences.getBoolean(SOUND_ON, false);
|
||||
}
|
||||
|
||||
public void writeSoundOn(boolean soundOn) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putBoolean(SOUND_ON, soundOn);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public User readUserData(User.LvUpListener lvUpListener) throws Exception {
|
||||
int ep = preferences.getInt(USER_EP, 0);
|
||||
int level = preferences.getInt(USER_LEVEL, 1);
|
||||
int stars = preferences.getInt(USER_STARS, 0);
|
||||
int energy = preferences.getInt(USER_ENERGY, 0);
|
||||
int toolsLocked = preferences.getInt(USER_TOOLS_LOCKED, 3);
|
||||
String tool1 = preferences.getString(USER_TOOL_1, ToolType.RAMP.name());
|
||||
String tool2 = preferences.getString(USER_TOOL_2, "null");
|
||||
String tool3 = preferences.getString(USER_TOOL_3, "null");
|
||||
String tool4 = preferences.getString(USER_TOOL_4, "null");
|
||||
ToolSlotSettings toolSlotSettings = new ToolSlotSettings(tool1, tool2, tool3, tool4,
|
||||
toolsLocked);
|
||||
String playerShapeName = preferences.getString(USER_PLAYER_SHAPE, PlayerShape.BALL.name());
|
||||
PlayerShape playerShape;
|
||||
try{
|
||||
playerShape = PlayerShape.valueOf(playerShapeName);
|
||||
}catch (Exception e){
|
||||
playerShape = PlayerShape.BALL;
|
||||
}
|
||||
return new User(lvUpListener, ep, level, stars, energy, toolSlotSettings, playerShape);
|
||||
}
|
||||
|
||||
public void writeUserData(User user) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putInt(USER_EP, user.getEp());
|
||||
editor.putInt(USER_LEVEL, user.getLevel());
|
||||
editor.putInt(USER_STARS, user.getStarCount());
|
||||
editor.putInt(USER_ENERGY, user.getEnergyCount());
|
||||
editor.putString(USER_TOOL_1, toolSlotToString(user.getToolSlotSettings(), 0));
|
||||
editor.putString(USER_TOOL_2, toolSlotToString(user.getToolSlotSettings(), 1));
|
||||
editor.putString(USER_TOOL_3, toolSlotToString(user.getToolSlotSettings(), 2));
|
||||
editor.putString(USER_TOOL_4, toolSlotToString(user.getToolSlotSettings(), 3));
|
||||
editor.putInt(USER_TOOLS_LOCKED, user.getToolSlotSettings().getLockedSlotCount());
|
||||
editor.putString(USER_PLAYER_SHAPE, user.getCurrentPlayerShape().name());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private String toolSlotToString(ToolSlotSettings toolSlotSettings, int index) {
|
||||
ToolType toolType = toolSlotSettings.get(index).getToolType();
|
||||
return toolType == null ? "null" : toolType.toString();
|
||||
}
|
||||
|
||||
public void writeToolShopTutorialPart1Finished(boolean finished) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putBoolean(TOOL_SHOP_TUTORIAL_PART_1_FINISHED, finished);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public boolean readToolShopTutorialPart1Finished() {
|
||||
return preferences.getBoolean(TOOL_SHOP_TUTORIAL_PART_1_FINISHED, false);
|
||||
}
|
||||
|
||||
public MyDatabase getDatabase() {
|
||||
return database;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
/**
|
||||
* Created by Julian on 06.02.2016.
|
||||
*/
|
||||
public interface ExceptionHandler {
|
||||
|
||||
void onException(Exception e);
|
||||
|
||||
}
|
292
app/src/main/java/de/frajul/endlessroll/main/GameActivity.java
Normal file
292
app/src/main/java/de/frajul/endlessroll/main/GameActivity.java
Normal file
@ -0,0 +1,292 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ConfigurationInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.tools.ToolType;
|
||||
import de.frajul.endlessroll.levels.Level;
|
||||
import de.frajul.endlessroll.levels.LevelManager;
|
||||
import de.frajul.endlessroll.levels.LevelPack;
|
||||
import de.frajul.endlessroll.main.screens.GLTestScreen;
|
||||
import de.frajul.endlessroll.main.screens.GameScreen;
|
||||
import de.frajul.endlessroll.main.screens.LevelsScreen;
|
||||
import de.frajul.endlessroll.main.screens.PlayerShapeShopScreen;
|
||||
import de.frajul.endlessroll.main.screens.PreStartScreen;
|
||||
import de.frajul.endlessroll.main.screens.Screen;
|
||||
import de.frajul.endlessroll.main.screens.ScreenFlipper;
|
||||
import de.frajul.endlessroll.main.screens.SettingsScreen;
|
||||
import de.frajul.endlessroll.main.screens.StartScreen;
|
||||
import de.frajul.endlessroll.main.screens.ToolShopScreen;
|
||||
import de.frajul.endlessroll.main.screens.WorldsScreen;
|
||||
import de.frajul.endlessroll.main.tutorial.BreakPoint;
|
||||
import de.frajul.endlessroll.main.tutorial.TutorialManager;
|
||||
import de.frajul.endlessroll.main.tutorial.TutorialView;
|
||||
import de.frajul.endlessroll.rendering.renderer.GameRenderer;
|
||||
import de.frajul.endlessroll.sounds.SoundManager;
|
||||
import de.frajul.endlessroll.sqlDatabase.MyDatabase;
|
||||
import de.frajul.endlessroll.user.User;
|
||||
import de.frajul.endlessroll.views.GoalMessage;
|
||||
import de.frajul.endlessroll.views.LevelupMessage;
|
||||
import de.frajul.endlessroll.views.TaskCompletedMessage;
|
||||
|
||||
/**
|
||||
* Created by Julian on 06.02.2016.
|
||||
*/
|
||||
public class GameActivity extends Activity implements ExceptionHandler, User.LvUpListener {
|
||||
|
||||
private DataStorageHandler dataStorageHandler;
|
||||
private LevelManager levelManager;
|
||||
private SoundManager soundManager;
|
||||
private User user;
|
||||
private Typeface typeface;
|
||||
private TutorialManager tutorialManager;
|
||||
|
||||
private MyGlSurfaceView glSurfaceView;
|
||||
private ScreenFlipper flipper;
|
||||
private PreStartScreen preStartScreen;
|
||||
private StartScreen startScreen;
|
||||
private GLTestScreen glTestScreen;
|
||||
private WorldsScreen worldsScreen;
|
||||
private LevelsScreen levelsScreen;
|
||||
private ToolShopScreen toolShopScreen;
|
||||
private PlayerShapeShopScreen shapeShopScreen;
|
||||
private GameScreen gameScreen;
|
||||
private SettingsScreen settingsScreen;
|
||||
|
||||
private LevelupMessage levelupMessage;
|
||||
private TaskCompletedMessage taskCompletedMessage;
|
||||
private TutorialView tutorialView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
try {
|
||||
GameLog.d("OnCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
super.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
if (!hasGLES20())
|
||||
throw new Exception("OpenGL ES 2.0 not supported");
|
||||
|
||||
dataStorageHandler = new DataStorageHandler(this);
|
||||
dataStorageHandler.getDatabase().open();
|
||||
dataStorageHandler.getDatabase().readToolData();
|
||||
dataStorageHandler.getDatabase().close();
|
||||
|
||||
user = dataStorageHandler.readUserData(this);
|
||||
|
||||
soundManager = new SoundManager(this);
|
||||
soundManager.setSoundOn(dataStorageHandler.readIsSoundOn());
|
||||
soundManager.backgroundMusic.getPlayer().setLooping(true);
|
||||
soundManager.backgroundMusic.start();
|
||||
|
||||
levelManager = new LevelManager(this, dataStorageHandler);
|
||||
tutorialManager = new TutorialManager();
|
||||
|
||||
this.glSurfaceView = new MyGlSurfaceView(this, new GameRenderer(this));
|
||||
typeface = Typeface.createFromAsset(getAssets(), "fontBaron.ttf");
|
||||
|
||||
preStartScreen = new PreStartScreen(this);
|
||||
startScreen = new StartScreen(this, glSurfaceView);
|
||||
glTestScreen = new GLTestScreen(this, glSurfaceView);
|
||||
worldsScreen = new WorldsScreen(this);
|
||||
levelsScreen = new LevelsScreen(this);
|
||||
toolShopScreen = new ToolShopScreen(this);
|
||||
shapeShopScreen = new PlayerShapeShopScreen(this);
|
||||
gameScreen = new GameScreen(this, glSurfaceView);
|
||||
settingsScreen = new SettingsScreen(this);
|
||||
|
||||
levelupMessage = new LevelupMessage(this);
|
||||
taskCompletedMessage = new TaskCompletedMessage(this);
|
||||
tutorialView = new TutorialView(this);
|
||||
|
||||
flipper = new ScreenFlipper(this, preStartScreen, startScreen, worldsScreen,
|
||||
levelsScreen, gameScreen, toolShopScreen, glTestScreen, settingsScreen,
|
||||
shapeShopScreen);
|
||||
RelativeLayout relativeLayout = new RelativeLayout(this);
|
||||
relativeLayout.addView(glSurfaceView);
|
||||
relativeLayout.addView(flipper);
|
||||
relativeLayout.addView(levelupMessage.getLayout());
|
||||
relativeLayout.addView(taskCompletedMessage.getLayout());
|
||||
relativeLayout.addView(tutorialView.getLayout());
|
||||
setContentView(relativeLayout);
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void exitGame() {
|
||||
super.finish();
|
||||
}
|
||||
|
||||
public void flipToScreen(final Screen.ScreenType screen) {
|
||||
if (screen != Screen.ScreenType.NONE) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
flipper.showScreen(screen, flipper.getCurrentScreen().getType());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onSurfaceChanged() {
|
||||
if (flipper.getCurrentScreen().getType() == Screen.ScreenType.PRE_START)
|
||||
flipToScreen(Screen.ScreenType.START);
|
||||
}
|
||||
|
||||
public void onWorldSelected(LevelPack levelPack) {
|
||||
levelsScreen.onLevelPackSelected(levelPack);
|
||||
}
|
||||
|
||||
public void startGame(final LevelPack levelPack, final Level level) {
|
||||
flipToScreen(Screen.ScreenType.GAME);
|
||||
gameScreen.startGame(levelPack, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLvUp(final int level) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
levelupMessage.show(level);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onTasksCompleted(final List<PlayerShape> shapes) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
taskCompletedMessage.show(shapes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showTutorialScreen(final List<BreakPoint> breakPoints) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tutorialView.show(breakPoints);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onTutorialViewHidden() {
|
||||
if (!gameScreen.isLevelFinished())
|
||||
gameScreen.onResume();
|
||||
}
|
||||
|
||||
public void resetData() {
|
||||
user.clearData();
|
||||
dataStorageHandler.writeUserData(user);
|
||||
dataStorageHandler.writeToolShopTutorialPart1Finished(false);
|
||||
levelManager.reset();
|
||||
tutorialManager.getToolShopTutorial().reset();
|
||||
MyDatabase database = dataStorageHandler.getDatabase();
|
||||
database.open();
|
||||
database.clearLevelProgess();
|
||||
database.clearLevelPackLocked();
|
||||
for (ToolType type : ToolType.values())
|
||||
type.reset();
|
||||
database.writeToolData();
|
||||
database.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
try {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (tutorialView.isShowingTutorial())
|
||||
tutorialView.onClick(null);
|
||||
else
|
||||
flipper.getCurrentScreen().onBackKeyDown();
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(Exception e) {
|
||||
GameLog.e(e);
|
||||
super.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
GameLog.d("OnPause");
|
||||
glSurfaceView.onPause();
|
||||
if (flipper.getCurrentScreen() == gameScreen)
|
||||
gameScreen.onPause();
|
||||
soundManager.pause();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
GameLog.d("OnResume");
|
||||
glSurfaceView.onResume();
|
||||
soundManager.resume();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
GameLog.d("OnDestroy");
|
||||
soundManager.destroy();
|
||||
|
||||
dataStorageHandler.writeSoundOn(soundManager.isSoundOn());
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
private boolean hasGLES20() {
|
||||
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||
return info.reqGlEsVersion >= 0x20000;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public DataStorageHandler getDataStorageHandler() {
|
||||
return dataStorageHandler;
|
||||
}
|
||||
|
||||
public SoundManager getSoundManager() {
|
||||
return soundManager;
|
||||
}
|
||||
|
||||
public Typeface getTypeface() {
|
||||
return typeface;
|
||||
}
|
||||
|
||||
public LevelManager getLevelManager() {
|
||||
return levelManager;
|
||||
}
|
||||
|
||||
public TutorialManager getTutorialManager() {
|
||||
return tutorialManager;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import de.frajul.endlessroll.main.screens.Screen;
|
||||
import de.frajul.endlessroll.main.tutorial.BreakPoint;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 08.12.2015.
|
||||
*/
|
||||
public interface GameHandler extends ExceptionHandler {
|
||||
|
||||
void startInUiThread(Runnable runnable);
|
||||
|
||||
void toScreen(Screen.ScreenType screen);
|
||||
|
||||
RelativeLayout getRootLayout();
|
||||
|
||||
void showTutorialScreen(List<BreakPoint> breakPoints);
|
||||
|
||||
}
|
44
app/src/main/java/de/frajul/endlessroll/main/GameLog.java
Normal file
44
app/src/main/java/de/frajul/endlessroll/main/GameLog.java
Normal file
@ -0,0 +1,44 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Created by Julian on 23.11.2015.
|
||||
*/
|
||||
public class GameLog {
|
||||
|
||||
private final static String TAG = "GameLog";
|
||||
public static boolean debugging = true;
|
||||
|
||||
public static void i(String message) {
|
||||
Log.i(TAG + getCallerInfo(), message);
|
||||
}
|
||||
|
||||
public static void d(String message) {
|
||||
if (debugging)
|
||||
Log.d(TAG + getCallerInfo(), message);
|
||||
}
|
||||
|
||||
public static void e(String message) {
|
||||
Log.e(TAG + getCallerInfo(), message);
|
||||
}
|
||||
|
||||
public static void e(Throwable error) {
|
||||
Log.e(TAG + getCallerInfo(), error.getMessage(), error);
|
||||
}
|
||||
|
||||
//Possible to get Method which called i, d, e
|
||||
//Method found at stack[4]
|
||||
public static void stack() {
|
||||
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
|
||||
Log.i(TAG + "Stack", "StackSize: " + stack.length);
|
||||
for (int i = 0; i < stack.length; i++) {
|
||||
Log.i(TAG + "Stack", i + ": " + stack[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCallerInfo() {
|
||||
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
|
||||
return "(" + stack[4].getFileName() + ", " + stack[4].getMethodName() + ", " + stack[4].getLineNumber() + ")";
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package de.frajul.endlessroll.main;
|
||||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import de.frajul.endlessroll.rendering.Rendering;
|
||||
import de.frajul.endlessroll.rendering.renderer.GameRenderer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 30.07.2016.
|
||||
*/
|
||||
public class MyGlSurfaceView extends GLSurfaceView {
|
||||
|
||||
private GameRenderer renderer;
|
||||
|
||||
public MyGlSurfaceView(Context context, GameRenderer gameRenderer) throws Exception {
|
||||
super(context);
|
||||
this.renderer = gameRenderer;
|
||||
super.setEGLContextClientVersion(2);
|
||||
super.setRenderer(renderer);
|
||||
}
|
||||
|
||||
public void addRendering(Rendering rendering) {
|
||||
renderer.addRendering(rendering);
|
||||
}
|
||||
|
||||
public void setCurrentRendering(Rendering currentRendering) {
|
||||
super.setOnTouchListener(currentRendering);
|
||||
renderer.setCurrentRendering(currentRendering);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
GameLog.i("GLSurfaceView: onResume");
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
GameLog.i("GLSurfaceView: onPause");
|
||||
super.onPause();
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
/**
|
||||
* Created by Julian on 22.05.2017.
|
||||
*/
|
||||
|
||||
public class Camera {
|
||||
|
||||
private final float MOVE_SPEED_UP = 0.7f;
|
||||
private final float MOVE_SPEED_DOWN = 0.7f;
|
||||
private final float MAX_Y = 0.5f;
|
||||
private final float MIN_Y = 0;
|
||||
private float x, y;
|
||||
|
||||
public void update(float playerY, Timer timer){
|
||||
float frameTime = timer.getFrameTimeSeconds() / 1000f;
|
||||
float maxY = Math.min(playerY - 1 + 0.6f, MAX_Y);
|
||||
if(playerY >= 0.5f){
|
||||
y += MOVE_SPEED_UP * frameTime;
|
||||
if(y > maxY)
|
||||
y = maxY;
|
||||
} else if(y > MIN_Y){
|
||||
y -= MOVE_SPEED_DOWN * frameTime;
|
||||
if(y < MIN_Y)
|
||||
y = MIN_Y;
|
||||
}
|
||||
}
|
||||
|
||||
public void moveX(float move){
|
||||
x += move;
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
337
app/src/main/java/de/frajul/endlessroll/main/game/Game.java
Normal file
337
app/src/main/java/de/frajul/endlessroll/main/game/Game.java
Normal file
@ -0,0 +1,337 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.DestroyEffect;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collectables.Energy;
|
||||
import de.frajul.endlessroll.entities.collectables.Star;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionManager;
|
||||
import de.frajul.endlessroll.entities.particles.Firework;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.shapes.Task;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
import de.frajul.endlessroll.entities.tools.ToolType;
|
||||
import de.frajul.endlessroll.levels.Level;
|
||||
import de.frajul.endlessroll.levels.LevelPack;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.main.GameHandler;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
import de.frajul.endlessroll.main.physics.Physics;
|
||||
import de.frajul.endlessroll.main.screens.Screen;
|
||||
import de.frajul.endlessroll.main.tutorial.Tutorial;
|
||||
import de.frajul.endlessroll.rendering.Rendering;
|
||||
import de.frajul.endlessroll.sqlDatabase.MyDatabase;
|
||||
import de.frajul.endlessroll.views.ToolButton;
|
||||
import de.frajul.endlessroll.views.ToolButtonBar;
|
||||
import de.frajul.endlessroll.views.ViewManager;
|
||||
|
||||
/**
|
||||
* Created by Julian on 26.11.2015.
|
||||
*/
|
||||
public class Game extends Rendering<GameScene> {
|
||||
|
||||
private GameActivity gameActivity;
|
||||
private GameHandler handler;
|
||||
private ViewManager viewManager;
|
||||
private LevelPack levelPack;
|
||||
private ParticleSystem particleSystem;
|
||||
private Firework firework;
|
||||
|
||||
private ToolType currentTool;
|
||||
private Player player;
|
||||
private Physics physics;
|
||||
private CollisionManager collisionManager;
|
||||
private Timer timer;
|
||||
private GameState gameState = GameState.COUNTDOWN;
|
||||
|
||||
private Level level;
|
||||
private List<Integer> collectedStars = new ArrayList<>();
|
||||
private boolean energyCollected;
|
||||
|
||||
private Tutorial currentTutorial;
|
||||
|
||||
public Game(GameHandler handler, GameActivity gameActivity) throws Exception {
|
||||
super(gameActivity);
|
||||
this.handler = handler;
|
||||
this.gameActivity = gameActivity;
|
||||
physics = new Physics();
|
||||
collisionManager = new CollisionManager(this);
|
||||
particleSystem = new ParticleSystem(getContext());
|
||||
viewManager = new ViewManager(this, handler, gameActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameScene init(TexturePack texturePack, Timer timer, boolean isFirstTime) {
|
||||
GameLog.d("init Game");
|
||||
this.timer = timer;
|
||||
try {
|
||||
if (isFirstTime) {
|
||||
scene = new GameScene(texturePack, particleSystem);
|
||||
firework = new Firework(particleSystem.firework, scene.getCamera());
|
||||
if (level != null)
|
||||
startGame(levelPack, level);
|
||||
} else {
|
||||
scene.setTexturePack(texturePack);
|
||||
}
|
||||
particleSystem.loadTextures();
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
}
|
||||
return scene;
|
||||
}
|
||||
|
||||
public void startGame(LevelPack levelPack, Level level) {
|
||||
GameLog.d("Start game");
|
||||
try {
|
||||
this.level = level;
|
||||
this.levelPack = levelPack;
|
||||
if (scene != null) {
|
||||
gameState = GameState.COUNTDOWN;
|
||||
gameActivity.getTutorialManager().resetGameTutorials();
|
||||
currentTutorial = gameActivity.getTutorialManager().getGameTutorial(level);
|
||||
if (level.isFinished())
|
||||
currentTutorial = null;
|
||||
collectedStars.clear();
|
||||
energyCollected = false;
|
||||
particleSystem.deleteAllSources();
|
||||
scene.loadLevel(level, levelPack.getWorld(),
|
||||
gameActivity.getUser().getCurrentPlayerShape());
|
||||
player = scene.getPlayer();
|
||||
viewManager.resetViews(gameActivity.getUser());
|
||||
currentTool = viewManager.toolButtonBar.getActiveButton().getToolType();
|
||||
viewManager.startCountdown();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void countdownFinished() {
|
||||
gameState = GameState.RUNNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScreenSize(int width, int height) {
|
||||
Vector screenSize = new Vector(width, height);
|
||||
scene.setScreenSize(screenSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
try {
|
||||
particleSystem.update(timer);
|
||||
if (scene == null || player == null)
|
||||
return;
|
||||
|
||||
float playerProgress = player.getProgress();
|
||||
float playerSpeed = player.getMovement().getX();
|
||||
viewManager.update(gameState == GameState.RUNNING, timer, playerProgress, playerSpeed);
|
||||
switch (gameState) {
|
||||
case RUNNING:
|
||||
if (player.getPosition().y < -2f) {
|
||||
onGameOver(false);
|
||||
return;
|
||||
}
|
||||
if (player.getPosition().x >= scene.getGoalX()) {
|
||||
onGoalReached();
|
||||
return;
|
||||
}
|
||||
scene.getCamera().update(player.getPosition().y, timer);
|
||||
|
||||
if (currentTutorial != null) {
|
||||
currentTutorial.update(playerProgress);
|
||||
if (currentTutorial.isOverNewBreakPoints()) {
|
||||
gameState = GameState.PAUSED;
|
||||
handler.showTutorialScreen(currentTutorial.getCurrentBreakPoints());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
physics.applyGravity(scene, timer);
|
||||
scene.update(timer);
|
||||
collisionManager.update(physics, scene, timer);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (gameState == GameState.RUNNING) {
|
||||
ToolButtonBar bar = viewManager.toolButtonBar;
|
||||
ToolButton button = bar.getByToolType(currentTool);
|
||||
if (button != null && button.finishedLoading()) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
button.setProgress(0);
|
||||
addTool(event.getX(), event.getY());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void resetViews() {
|
||||
viewManager.resetViews(gameActivity.getUser());
|
||||
}
|
||||
|
||||
public void continueGame() {
|
||||
viewManager.hideShortMenu();
|
||||
gameState = GameState.COUNTDOWN;
|
||||
viewManager.startCountdown();
|
||||
}
|
||||
|
||||
public void startNextLevel() {
|
||||
level = levelPack.getNextLevel(level);
|
||||
startGame(levelPack, level);
|
||||
}
|
||||
|
||||
public void restartLevel() {
|
||||
startGame(levelPack, level);
|
||||
}
|
||||
|
||||
public void toLevelsScreen() {
|
||||
handler.toScreen(Screen.ScreenType.LEVELS);
|
||||
}
|
||||
|
||||
public void toToolShop() {
|
||||
handler.toScreen(Screen.ScreenType.TOOL_SHOP);
|
||||
}
|
||||
|
||||
public void setCurrentTool(ToolType toolType) {
|
||||
currentTool = toolType;
|
||||
}
|
||||
|
||||
public void tryToPause() {
|
||||
if (gameState == GameState.GAME_OVER || gameState == GameState.LEVEL_FINISHED || gameState == GameState.PAUSED)
|
||||
return;
|
||||
viewManager.showShortMenu();
|
||||
if (gameState == GameState.COUNTDOWN)
|
||||
viewManager.stopCountdown();
|
||||
gameState = GameState.PAUSED;
|
||||
}
|
||||
|
||||
public void onGoalMessageKeyBack(){
|
||||
viewManager.onGoalMessageKeyBack();
|
||||
}
|
||||
|
||||
public void setRunning() {
|
||||
gameState = GameState.RUNNING;
|
||||
}
|
||||
|
||||
private void addTool(float x, float y) {
|
||||
try {
|
||||
gameActivity.getSoundManager().playSound(currentTool.getPlacingSound());
|
||||
scene.addTool(currentTool, x, y, physics);
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onGameOver(boolean playerExplode) {
|
||||
if (playerExplode) {
|
||||
scene.getUncategorizedEntities().remove(player);
|
||||
DestroyEffect.EXPLOSION.createEffect(particleSystem, player.getPosition(),
|
||||
new Vector(player.getWidth(), player.getHeight())).start();
|
||||
}
|
||||
gameState = GameState.GAME_OVER;
|
||||
viewManager.showGameOverMessage();
|
||||
}
|
||||
|
||||
private void onGoalReached() {
|
||||
List<PlayerShape> alreadyUnlockedShapes = new ArrayList<>();
|
||||
for (PlayerShape shape : PlayerShape.values()) {
|
||||
Task task = shape.getUnlockTask();
|
||||
task.update(gameActivity.getLevelManager());
|
||||
if (task.isConditionFulfilled())
|
||||
alreadyUnlockedShapes.add(shape);
|
||||
}
|
||||
|
||||
|
||||
gameState = GameState.LEVEL_FINISHED;
|
||||
if (!level.isFinished())
|
||||
gameActivity.getUser().gainLvFinishedEp();
|
||||
level.setFinished(true);
|
||||
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
if (collectedStars.contains(i)) {
|
||||
level.setStarCollected(i, true);
|
||||
gameActivity.getUser().onStarCollected();
|
||||
}
|
||||
}
|
||||
|
||||
if (energyCollected) {
|
||||
level.setEnergyCollected(true);
|
||||
gameActivity.getUser().onEnergyCollected();
|
||||
}
|
||||
|
||||
firework.start();
|
||||
|
||||
//viewManager.showGameOverMessage(levelPack.isLastLevel(level), MessageType.WIN);
|
||||
//TODO: fadeInWithDelay something
|
||||
viewManager.showGoalMessage(levelPack, level);
|
||||
|
||||
MyDatabase database = gameActivity.getDataStorageHandler().getDatabase();
|
||||
database.open();
|
||||
database.writeLevelProgress(level);
|
||||
|
||||
List<PlayerShape> newUnlockedShapes = new ArrayList<>();
|
||||
for (PlayerShape shape : PlayerShape.values()) {
|
||||
Task task = shape.getUnlockTask();
|
||||
task.update(gameActivity.getLevelManager());
|
||||
if (task.isConditionFulfilled() && !alreadyUnlockedShapes.contains(shape))
|
||||
newUnlockedShapes.add(shape);
|
||||
}
|
||||
if (!newUnlockedShapes.isEmpty())
|
||||
gameActivity.onTasksCompleted(newUnlockedShapes);
|
||||
|
||||
Level nextLevel = levelPack.getNextLevel(level);
|
||||
if (nextLevel != null) {
|
||||
nextLevel.setLocked(false);
|
||||
database.writeLevelProgress(nextLevel);
|
||||
} else {
|
||||
LevelPack nextLevelPack = gameActivity.getLevelManager().getNextLevelPack(levelPack);
|
||||
if (nextLevelPack != null) {
|
||||
nextLevelPack.setLocked(false);
|
||||
database.writeLevelPackLocked(nextLevelPack);
|
||||
}
|
||||
}
|
||||
database.close();
|
||||
gameActivity.getDataStorageHandler().writeUserData(gameActivity.getUser());
|
||||
|
||||
if (currentTutorial != null) {
|
||||
currentTutorial.onLevelFinished();
|
||||
if (currentTutorial.isOverNewBreakPoints())
|
||||
handler.showTutorialScreen(currentTutorial.getCurrentBreakPoints());
|
||||
}
|
||||
}
|
||||
|
||||
public void onStarCollision(Star star) {
|
||||
scene.onStarCollision(star);
|
||||
collectedStars.add(star.getIndex());
|
||||
}
|
||||
|
||||
public void onEnergyCollision(Energy energy) {
|
||||
scene.onEnergyCollision(energy);
|
||||
energyCollected = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(Exception e) {
|
||||
handler.onException(e);
|
||||
}
|
||||
|
||||
public GameState getGameState() {
|
||||
return gameState;
|
||||
}
|
||||
|
||||
}
|
112
app/src/main/java/de/frajul/endlessroll/main/game/GameScene.java
Normal file
112
app/src/main/java/de/frajul/endlessroll/main/game/GameScene.java
Normal file
@ -0,0 +1,112 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.DestroyEffect;
|
||||
import de.frajul.endlessroll.entities.Goal;
|
||||
import de.frajul.endlessroll.entities.Obstacle;
|
||||
import de.frajul.endlessroll.entities.collectables.Energy;
|
||||
import de.frajul.endlessroll.entities.collectables.Star;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
import de.frajul.endlessroll.entities.tools.Bomb;
|
||||
import de.frajul.endlessroll.entities.tools.Tool;
|
||||
import de.frajul.endlessroll.entities.tools.ToolType;
|
||||
import de.frajul.endlessroll.levels.Level;
|
||||
import de.frajul.endlessroll.levels.ObstacleData;
|
||||
import de.frajul.endlessroll.levels.worlds.World;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
import de.frajul.endlessroll.main.physics.Physics;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.11.2015.
|
||||
*/
|
||||
public class GameScene extends Scene {
|
||||
|
||||
private World currentWorld;
|
||||
private CollisionDetector collisionDetector;
|
||||
private Goal goal;
|
||||
private float goalX;
|
||||
|
||||
public GameScene(TexturePack texturePack, ParticleSystem particleSystem) throws Exception {
|
||||
super(texturePack, particleSystem);
|
||||
collisionDetector = new CollisionDetector();
|
||||
|
||||
goal = new Goal(textures.goal);
|
||||
}
|
||||
|
||||
public void loadLevel(Level level, World world, PlayerShape playerPlayerShape) throws Exception {
|
||||
this.currentWorld = world;
|
||||
super.reset();
|
||||
background.changeTexture(world.getBackgroundTexture());
|
||||
terrain.loadData(world, level.getTerrainEdge(), level.getTerrainTiles());
|
||||
ceiling.loadData(world, level.getCeilingEdge(), level.getCeilingTiles());
|
||||
uncategorizedEntities.add(goal);
|
||||
player.init(playerPlayerShape, terrain.getEdge(), level.getStartSpeed(), level.getEndSpeed(), particleSystem);
|
||||
uncategorizedEntities.add(player);
|
||||
collectables.init(level, textures);
|
||||
for (ObstacleData data : level.getObstacles())
|
||||
addObstacle(data);
|
||||
|
||||
goalX = level.getGoalX();
|
||||
goal.setGoalX(goalX);
|
||||
GameLog.d("Level " + level.getId() + " successfully loaded");
|
||||
}
|
||||
|
||||
public void onStarCollision(Star collisionStar) {
|
||||
collisionStar.destroy(DestroyEffect.STAR_EXPLOSION);
|
||||
}
|
||||
|
||||
public void onEnergyCollision(Energy energy) {
|
||||
energy.destroy(DestroyEffect.ENERGY_COLLECT);
|
||||
}
|
||||
|
||||
public void addObstacle(ObstacleData data) {
|
||||
Obstacle obstacle = new Obstacle(currentWorld, data, terrain.getEdge());
|
||||
obstacles.add(obstacle);
|
||||
}
|
||||
|
||||
public void addTool(ToolType type, float screenX, float screenY, Physics physics) throws Exception {
|
||||
Vector position = calcWorldFromScreenCoords(screenX, screenY);
|
||||
Tool tool = type.newInstance(position, particleSystem);
|
||||
physics.checkSingleToolCollision(tool, this);
|
||||
|
||||
if (tool == null)
|
||||
throw new Exception(
|
||||
"Current ToolType(" + type + ") returns null at method newInstance()");
|
||||
tools.add(tool);
|
||||
}
|
||||
|
||||
|
||||
public void update(Timer timer) {
|
||||
player.setSpeedByProgress(player.getProgress() / goalX);
|
||||
player.preMoveUpdate(timer);
|
||||
|
||||
if (player.hasSuperPower() && player.getBottomEdge() < terrain.getEdge()) {
|
||||
player.setToTerrain(terrain.getEdge());
|
||||
if (player.getMovement().y < 0)
|
||||
player.getMovement().setY(0);
|
||||
}
|
||||
|
||||
super.update(timer);
|
||||
|
||||
player.postMoveUpdate();
|
||||
|
||||
synchronized (tools) {
|
||||
for (Tool tool : tools) {
|
||||
if (tool instanceof Bomb) {
|
||||
Bomb bomb = (Bomb) tool;
|
||||
if (bomb.isExploding())
|
||||
bomb.explode(obstacles, collisionDetector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public float getGoalX() {
|
||||
return goalX;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.02.2016.
|
||||
*/
|
||||
public enum GameState {
|
||||
|
||||
RUNNING, PAUSED, GAME_OVER, LEVEL_FINISHED, COUNTDOWN
|
||||
|
||||
}
|
191
app/src/main/java/de/frajul/endlessroll/main/game/Scene.java
Normal file
191
app/src/main/java/de/frajul/endlessroll/main/game/Scene.java
Normal file
@ -0,0 +1,191 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.data.Vector;
|
||||
import de.frajul.endlessroll.entities.AnimatedEntity;
|
||||
import de.frajul.endlessroll.entities.Background;
|
||||
import de.frajul.endlessroll.entities.collectables.Collectables;
|
||||
import de.frajul.endlessroll.entities.collectables.Energy;
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.Obstacle;
|
||||
import de.frajul.endlessroll.entities.Player;
|
||||
import de.frajul.endlessroll.entities.collectables.Star;
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
import de.frajul.endlessroll.entities.tileLists.Ceiling;
|
||||
import de.frajul.endlessroll.entities.tileLists.Terrain;
|
||||
import de.frajul.endlessroll.entities.tools.Tool;
|
||||
import de.frajul.endlessroll.levels.worlds.World;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.07.2016.
|
||||
*/
|
||||
public abstract class Scene {
|
||||
|
||||
//Not sure if needed, this why set on very high value
|
||||
private final float MAX_Y_MOVEMENT = -1f;
|
||||
|
||||
protected Camera camera;
|
||||
private Vector screenSize;
|
||||
private Entity playerArrow;
|
||||
|
||||
protected ParticleSystem particleSystem;
|
||||
protected TexturePack textures;
|
||||
protected Background background;
|
||||
protected Terrain terrain;
|
||||
protected Ceiling ceiling;
|
||||
protected Player player;
|
||||
|
||||
protected List<Entity> uncategorizedEntities = Collections.synchronizedList(new ArrayList<Entity>());
|
||||
protected List<Obstacle> obstacles = Collections.synchronizedList(new ArrayList<Obstacle>());
|
||||
protected List<Tool> tools = Collections.synchronizedList(new ArrayList<Tool>());
|
||||
protected Collectables collectables = new Collectables();
|
||||
|
||||
public Scene(TexturePack texturePack, ParticleSystem particleSystem) {
|
||||
this.particleSystem = particleSystem;
|
||||
setTexturePack(texturePack);
|
||||
camera = new Camera();
|
||||
playerArrow = new Entity(textures.playerArrow, new Vector(0, 0.9f), .2f, .2f);
|
||||
background = new Background(World.GRASSLANDS.getBackgroundTexture());
|
||||
terrain = new Terrain(World.GRASSLANDS.getTerrainTexture());
|
||||
ceiling = new Ceiling(World.GRASSLANDS.getTerrainTexture());
|
||||
player = new Player();
|
||||
}
|
||||
|
||||
public void setTexturePack(TexturePack texturePack) {
|
||||
this.textures = texturePack;
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
uncategorizedEntities.clear();
|
||||
obstacles.clear();
|
||||
tools.clear();
|
||||
collectables.reset();
|
||||
camera.reset();
|
||||
background.resetPosition();
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
updateEntityList(uncategorizedEntities, timer);
|
||||
updateEntityList(obstacles, timer);
|
||||
updateEntityList(tools, timer);
|
||||
updateEntityList(collectables, timer);
|
||||
|
||||
if (player.getPosition().y >= player.RADIUS + 1 + camera.getY()) {
|
||||
playerArrow.getPosition().x = player.getPosition().x;
|
||||
playerArrow.getPosition().y = camera.getY() + 0.9f;
|
||||
if (!uncategorizedEntities.contains(playerArrow)) {
|
||||
uncategorizedEntities.add(playerArrow);
|
||||
}
|
||||
} else
|
||||
uncategorizedEntities.remove(playerArrow);
|
||||
}
|
||||
|
||||
private void updateEntityList(List<? extends Entity> list, Timer timer){
|
||||
synchronized (list){
|
||||
Iterator<? extends Entity> iterator = list.iterator();
|
||||
while(iterator.hasNext()) {
|
||||
Entity entity = iterator.next();
|
||||
if(entity instanceof Obstacle){
|
||||
Obstacle obstacle = (Obstacle) entity;
|
||||
if (obstacle.isMoving())
|
||||
obstacle.moveWithMoveComponent(timer.getFrameTimeSeconds());
|
||||
}
|
||||
boolean remove = updateEntity(entity, timer);
|
||||
if (remove)
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateEntity(Entity entity, Timer timer){
|
||||
if (entity instanceof AnimatedEntity)
|
||||
((AnimatedEntity) entity).update(timer);
|
||||
Vector movement = entity.getMovement();
|
||||
Vector finalMovement = new Vector(movement).mul(timer.getFrameTimeSeconds());
|
||||
if(finalMovement.y < MAX_Y_MOVEMENT)
|
||||
finalMovement.y = MAX_Y_MOVEMENT;
|
||||
entity.move(finalMovement);
|
||||
if (entity.equals(player))
|
||||
moveEnviroment(finalMovement.x);
|
||||
|
||||
if (entity.isDestroyed() && entity.getDestroyEffect() != null)
|
||||
entity.getDestroyEffect()
|
||||
.createEffect(particleSystem, new Vector(entity.getPosition()),
|
||||
new Vector(entity.getWidth(), entity.getHeight())).start();
|
||||
if (entity.getRightEdge() - camera.getX() < -3f || entity.isDestroyed()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void moveEnviroment(float x) {
|
||||
camera.moveX(x);
|
||||
background.move(x * 0.95f, camera.getX());
|
||||
terrain.update(camera.getX());
|
||||
ceiling.update(camera.getX());
|
||||
}
|
||||
|
||||
protected Vector calcWorldFromScreenCoords(float screenX, float screenY) throws Exception {
|
||||
if (screenSize == null)
|
||||
throw new Exception("ScreenSize not set");
|
||||
float glCoordWidth = (2f * screenSize.x / screenSize.y);
|
||||
float x = ((screenX / screenSize.x) * 2f - 1f) * glCoordWidth / 2;
|
||||
x += camera.getX();
|
||||
float y = -((screenY / screenSize.y) * 2f - 1f);
|
||||
y += camera.getY();
|
||||
return new Vector(x, y);
|
||||
}
|
||||
|
||||
public void setScreenSize(Vector screenSize) {
|
||||
this.screenSize = screenSize;
|
||||
}
|
||||
|
||||
public synchronized Background getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
public synchronized Terrain getTerrain() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public synchronized Ceiling getCeiling() {
|
||||
return ceiling;
|
||||
}
|
||||
|
||||
public synchronized List<Entity> getUncategorizedEntities() {
|
||||
return uncategorizedEntities;
|
||||
}
|
||||
|
||||
public synchronized List<Obstacle> getObstacles() {
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
public synchronized List<Tool> getTools() {
|
||||
return tools;
|
||||
}
|
||||
|
||||
public synchronized Collectables getCollectables() {
|
||||
return collectables;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public TexturePack getTextures() {
|
||||
return textures;
|
||||
}
|
||||
|
||||
public ParticleSystem getParticleSystem() {
|
||||
return particleSystem;
|
||||
}
|
||||
|
||||
public Camera getCamera() {
|
||||
return camera;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.shapes.PlayerShape;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
import de.frajul.endlessroll.levels.worlds.World;
|
||||
|
||||
public class StartScene extends Scene {
|
||||
|
||||
public StartScene(TexturePack texturePack, ParticleSystem particleSystem) {
|
||||
super(texturePack, particleSystem);
|
||||
terrain.createEndless(World.ICY_MOUNTAINS, -.8f);
|
||||
player.init(PlayerShape.BALL, terrain.getEdge(), 0.5f, 0.5f, null);
|
||||
uncategorizedEntities.add(player);
|
||||
}
|
||||
|
||||
}
|
46
app/src/main/java/de/frajul/endlessroll/main/game/Timer.java
Normal file
46
app/src/main/java/de/frajul/endlessroll/main/game/Timer.java
Normal file
@ -0,0 +1,46 @@
|
||||
package de.frajul.endlessroll.main.game;
|
||||
|
||||
/**
|
||||
* Created by Julian on 22.11.2015.
|
||||
*/
|
||||
public class Timer {
|
||||
|
||||
private long lastFpsTime;
|
||||
private int fpsCounter;
|
||||
private int fps;
|
||||
|
||||
private long lastTime;
|
||||
private long delta;
|
||||
|
||||
|
||||
public Timer() {
|
||||
lastTime = System.currentTimeMillis();
|
||||
lastFpsTime = lastTime;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
delta = currentTime - lastTime;
|
||||
lastTime = currentTime;
|
||||
|
||||
fpsCounter++;
|
||||
if (currentTime - lastFpsTime > 1000) {
|
||||
fps = fpsCounter;
|
||||
lastFpsTime += 1000;
|
||||
fpsCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public float getFrameTimeSeconds() {
|
||||
return delta;
|
||||
}
|
||||
|
||||
public int getFps() {
|
||||
return fps;
|
||||
}
|
||||
|
||||
public long getCurrentTime() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,199 @@
|
||||
package de.frajul.endlessroll.main.physics;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.entities.Entity;
|
||||
import de.frajul.endlessroll.entities.Obstacle;
|
||||
import de.frajul.endlessroll.entities.collectables.Collectables;
|
||||
import de.frajul.endlessroll.entities.collectables.Energy;
|
||||
import de.frajul.endlessroll.entities.collectables.Star;
|
||||
import de.frajul.endlessroll.entities.collision.CollisionDetector;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.EntityCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.ObstacleCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.PlayerCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.collisionData.ToolCollisionData;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Circle;
|
||||
import de.frajul.endlessroll.entities.tileLists.Ceiling;
|
||||
import de.frajul.endlessroll.entities.tileLists.Terrain;
|
||||
import de.frajul.endlessroll.entities.tileLists.Tile;
|
||||
import de.frajul.endlessroll.entities.tools.Bomb;
|
||||
import de.frajul.endlessroll.entities.tools.Tool;
|
||||
import de.frajul.endlessroll.main.game.GameScene;
|
||||
import de.frajul.endlessroll.main.game.Scene;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.11.2015.
|
||||
*/
|
||||
public class Physics {
|
||||
|
||||
public final float GRAVITY_FORCE = .0000025f;
|
||||
private final float TOOL_ON_OBSTACLE_LEFT_EDGE_TOLERANCE = 0.05f;
|
||||
private CollisionDetector detector;
|
||||
|
||||
public Physics() {
|
||||
detector = new CollisionDetector();
|
||||
}
|
||||
|
||||
public void applyGravity(GameScene scene, Timer timer) {
|
||||
float gravity = GRAVITY_FORCE * timer.getFrameTimeSeconds();
|
||||
|
||||
scene.getPlayer().setGravityForce(-gravity);
|
||||
|
||||
synchronized (scene.getTools()) {
|
||||
for (Tool tool : scene.getTools()) {
|
||||
if (tool.isFloating())
|
||||
continue;
|
||||
tool.getMovement().y -= gravity * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void checkToolCollision(Scene scene) {
|
||||
synchronized (scene.getTools()) {
|
||||
for (Tool tool : scene.getTools()) {
|
||||
checkSingleToolCollision(tool, scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void checkSingleToolCollision(Tool tool, Scene scene) {
|
||||
if(tool.isFloating())
|
||||
return;
|
||||
float terrainEdge = getTerrainEdge(tool, scene.getTerrain());
|
||||
Obstacle toolIsCollidingWith = getHighestObstacleToolIsCollidingWith(tool, scene);
|
||||
|
||||
if (toolIsCollidingWith != null) {
|
||||
float distObstTool = tool.getRightEdge() - toolIsCollidingWith.getLeftEdge();
|
||||
if (distObstTool < TOOL_ON_OBSTACLE_LEFT_EDGE_TOLERANCE) {
|
||||
tool.getPosition().x -= TOOL_ON_OBSTACLE_LEFT_EDGE_TOLERANCE;
|
||||
terrainEdge = getTerrainEdge(tool, scene.getTerrain());
|
||||
toolIsCollidingWith = getHighestObstacleToolIsCollidingWith(tool, scene);
|
||||
}
|
||||
}
|
||||
|
||||
float orientingHeight = terrainEdge;
|
||||
if (toolIsCollidingWith != null)
|
||||
orientingHeight = Math.max(toolIsCollidingWith.getTopEdge(), terrainEdge);
|
||||
|
||||
if (tool.getBottomEdge() <= orientingHeight) {
|
||||
tool.getMovement().y = 0;
|
||||
if (tool instanceof Bomb)
|
||||
tool.setFloating(true);
|
||||
else
|
||||
tool.setToTerrain(orientingHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Obstacle getHighestObstacleToolIsCollidingWith(Tool tool, Scene scene) {
|
||||
List<Obstacle> collisionObstacles = new ArrayList<>();
|
||||
synchronized (scene.getObstacles()) {
|
||||
for (Obstacle obstacle : scene.getObstacles()) {
|
||||
if (tool.getWorldCollisionBounds().isCollisionWithQuad(obstacle, detector)) {
|
||||
collisionObstacles.add(obstacle);
|
||||
}
|
||||
}
|
||||
}
|
||||
Obstacle highest = null;
|
||||
for (Obstacle obstacle : collisionObstacles)
|
||||
if (highest == null || highest.getTopEdge() < obstacle.getTopEdge())
|
||||
highest = obstacle;
|
||||
return highest;
|
||||
}
|
||||
|
||||
private float getTerrainEdge(Entity tool, Terrain terrain) {
|
||||
for (Tile instance : terrain) {
|
||||
if ((tool.getLeftEdge() >= instance.getLeftEdge() && tool.getLeftEdge() <= instance
|
||||
.getRightEdge()) || (tool.getRightEdge() <= instance.getRightEdge() && tool
|
||||
.getRightEdge() >= instance.getLeftEdge()) || (instance.getLeftEdge() >= tool
|
||||
.getLeftEdge() && instance.getLeftEdge() <= tool.getRightEdge()) || (instance
|
||||
.getRightEdge() <= tool.getRightEdge() && instance.getRightEdge() >= tool
|
||||
.getLeftEdge()))
|
||||
return terrain.getEdge();
|
||||
}
|
||||
return -10;
|
||||
}
|
||||
|
||||
public PlayerCollisionData getPlayerCollisionData(GameScene scene) {
|
||||
EntityCollisionData terrainData = playerCollidesWithTerrain(scene);
|
||||
EntityCollisionData ceilingData = playerCollidesWithCeiling(scene);
|
||||
ObstacleCollisionData obstacleData = playerCollidesWithObstacle(scene);
|
||||
ToolCollisionData toolData = playerCollidesWithTool(scene);
|
||||
EntityCollisionData starData = playerCollidesWithStar(scene);
|
||||
EntityCollisionData energyData = playerCollidesWithEnergy(scene);
|
||||
return new PlayerCollisionData(terrainData, ceilingData, obstacleData, toolData, starData,
|
||||
energyData);
|
||||
}
|
||||
|
||||
private EntityCollisionData playerCollidesWithTerrain(GameScene scene) {
|
||||
Terrain terrain = scene.getTerrain();
|
||||
for (Tile terrainTile : terrain) {
|
||||
EntityCollisionData data = detector
|
||||
.playerEntityCollision(scene.getPlayer(), terrainTile);
|
||||
if (data.isCollision())
|
||||
return data;
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
private EntityCollisionData playerCollidesWithCeiling(GameScene scene) {
|
||||
Ceiling ceiling = scene.getCeiling();
|
||||
for (Tile ceilingTile : ceiling) {
|
||||
EntityCollisionData data = detector
|
||||
.playerEntityCollision(scene.getPlayer(), ceilingTile);
|
||||
if (data.isCollision())
|
||||
return data;
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
private ObstacleCollisionData playerCollidesWithObstacle(GameScene scene) {
|
||||
List<EntityCollisionData> collisions = new ArrayList<>();
|
||||
synchronized (scene.getObstacles()) {
|
||||
for (Obstacle obstacle : scene.getObstacles()) {
|
||||
EntityCollisionData data = detector
|
||||
.playerEntityCollision(scene.getPlayer(), obstacle);
|
||||
if (data.isCollision())
|
||||
collisions.add(data);
|
||||
}
|
||||
}
|
||||
return new ObstacleCollisionData(collisions);
|
||||
}
|
||||
|
||||
private ToolCollisionData playerCollidesWithTool(GameScene scene) {
|
||||
List<Tool> tools = new ArrayList<>();
|
||||
Circle circle = new Circle(scene.getPlayer());
|
||||
synchronized (scene.getTools()) {
|
||||
for (Tool tool : scene.getTools()) {
|
||||
if (tool.getPlayerCollisionBounds().isCollisionWithCircle(circle, detector))
|
||||
tools.add(tool);
|
||||
}
|
||||
}
|
||||
return new ToolCollisionData(tools);
|
||||
}
|
||||
|
||||
private EntityCollisionData playerCollidesWithStar(GameScene scene) {
|
||||
Collectables collectables = scene.getCollectables();
|
||||
synchronized (collectables.getStars()) {
|
||||
for (Star star : collectables.getStars()) {
|
||||
EntityCollisionData data = detector.playerEntityCollision(scene.getPlayer(), star);
|
||||
if (data.isCollision())
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
private EntityCollisionData playerCollidesWithEnergy(GameScene scene) {
|
||||
Energy energy = scene.getCollectables().getEnergy();
|
||||
if (energy != null) {
|
||||
EntityCollisionData data = detector.playerEntityCollision(scene.getPlayer(), energy);
|
||||
return data;
|
||||
} else
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.main.MyGlSurfaceView;
|
||||
|
||||
/**
|
||||
* Created by Julian on 30.07.2016.
|
||||
*/
|
||||
public abstract class GLScreen<V extends ViewGroup> extends Screen<V> {
|
||||
|
||||
protected MyGlSurfaceView glView;
|
||||
|
||||
public GLScreen(ScreenType type, GameActivity gameActivity, @LayoutRes int layoutId, MyGlSurfaceView glView) {
|
||||
super(type, gameActivity, layoutId);
|
||||
this.glView = glView;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.levels.Level;
|
||||
import de.frajul.endlessroll.levels.LevelPack;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.main.GameHandler;
|
||||
import de.frajul.endlessroll.main.MyGlSurfaceView;
|
||||
import de.frajul.endlessroll.main.game.Game;
|
||||
import de.frajul.endlessroll.main.game.GameState;
|
||||
import de.frajul.endlessroll.main.tutorial.BreakPoint;
|
||||
|
||||
/**
|
||||
* Created by Julian on 08.02.2016.
|
||||
*/
|
||||
public class GameScreen extends GLScreen<RelativeLayout> {
|
||||
|
||||
private Game game;
|
||||
|
||||
public GameScreen(GameActivity gameActivity, MyGlSurfaceView glSurfaceView) throws Exception {
|
||||
super(ScreenType.GAME, gameActivity, R.layout.game, glSurfaceView);
|
||||
game = new Game(gameViewHandler, gameActivity);
|
||||
glView.addRendering(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareToBeShown() {
|
||||
glView.setCurrentRendering(game);
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
game.tryToPause();
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
game.setRunning();
|
||||
}
|
||||
|
||||
public boolean isLevelFinished() {
|
||||
return game.getGameState() == GameState.LEVEL_FINISHED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackKeyDown() {
|
||||
game.tryToPause();
|
||||
if(isLevelFinished())
|
||||
game.onGoalMessageKeyBack();
|
||||
}
|
||||
|
||||
public void startGame(LevelPack levelPack, Level level) {
|
||||
game.resetViews();
|
||||
game.startGame(levelPack, level);
|
||||
}
|
||||
|
||||
private GameHandler gameViewHandler = new GameHandler() {
|
||||
|
||||
@Override
|
||||
public void startInUiThread(Runnable runnable) {
|
||||
gameActivity.runOnUiThread(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toScreen(ScreenType screen) {
|
||||
glView.setCurrentRendering(null);
|
||||
gameActivity.flipToScreen(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelativeLayout getRootLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showTutorialScreen(List<BreakPoint> breakPoints) {
|
||||
gameActivity.showTutorialScreen(breakPoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(Exception e) {
|
||||
gameActivity.onException(e);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.levels.Level;
|
||||
import de.frajul.endlessroll.levels.LevelPack;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.views.LevelButton;
|
||||
import de.frajul.endlessroll.views.LevelButtonOnClickListener;
|
||||
import de.frajul.endlessroll.views.TopBar;
|
||||
|
||||
/**
|
||||
* Created by Julian on 23.04.2016.
|
||||
*/
|
||||
public class LevelsScreen extends Screen<LinearLayout> implements LevelButtonOnClickListener {
|
||||
|
||||
private LevelPack levelPack;
|
||||
|
||||
private TopBar topBar;
|
||||
private LinearLayout topRow;
|
||||
private LinearLayout bottomRow;
|
||||
|
||||
public LevelsScreen(GameActivity gameActivity) {
|
||||
super(ScreenType.LEVELS, gameActivity, R.layout.levels);
|
||||
topBar = super.createTopBar(R.id.levels_topbar);
|
||||
topRow = (LinearLayout) layout.findViewById(R.id.levels_top_row);
|
||||
bottomRow = (LinearLayout) layout.findViewById(R.id.levels_bottom_row);
|
||||
}
|
||||
|
||||
public void onLevelPackSelected(LevelPack levelPack) {
|
||||
this.levelPack = levelPack;
|
||||
}
|
||||
|
||||
private void build() {
|
||||
topRow.removeAllViews();
|
||||
bottomRow.removeAllViews();
|
||||
int levelCount = levelPack.getLevels().size();
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.setMargins(15, 15, 15, 15);
|
||||
|
||||
for (Level level : levelPack.getLevels())
|
||||
createButton(level, levelCount, params);
|
||||
}
|
||||
|
||||
private void createButton(Level level, int levelCount, LinearLayout.LayoutParams params) {
|
||||
LevelButton button = new LevelButton(gameActivity, this, R.layout.levelbutton);
|
||||
button.init(level);
|
||||
|
||||
int halfLevelCount = levelCount / 2;
|
||||
if (levelCount % 2 == 1)
|
||||
halfLevelCount++;
|
||||
|
||||
if (level.getId() <= halfLevelCount)
|
||||
topRow.addView(button.getView(), params);
|
||||
else
|
||||
bottomRow.addView(button.getView(), params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareToBeShown() {
|
||||
topBar.update();
|
||||
build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackKeyDown() {
|
||||
flipTo(ScreenType.WORLDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(LevelButton levelButton) {
|
||||
Level level = levelButton.getLevel();
|
||||
if (!level.isLocked())
|
||||
gameActivity.startGame(levelPack, level);
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.views.TopBar;
|
||||
|
||||
/**
|
||||
* Created by Julian on 13.02.2016.
|
||||
*/
|
||||
public abstract class Screen<V extends ViewGroup> {
|
||||
|
||||
public enum ScreenType {
|
||||
NONE(-1),
|
||||
PRE_START(0),
|
||||
START(1),
|
||||
WORLDS(2),
|
||||
LEVELS(3),
|
||||
GAME(4),
|
||||
TOOL_SHOP(5),
|
||||
GL_TEST(6),
|
||||
SETTINGS(7),
|
||||
SHAPE_SHOP(8);
|
||||
|
||||
private int inFlipperPosition;
|
||||
|
||||
ScreenType(int inFlipperPosition) {
|
||||
this.inFlipperPosition = inFlipperPosition;
|
||||
}
|
||||
|
||||
public int getInFlipperPosition() {
|
||||
return inFlipperPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private ScreenType type;
|
||||
protected ScreenType caller;
|
||||
protected V layout;
|
||||
protected GameActivity gameActivity;
|
||||
|
||||
public Screen(ScreenType type, GameActivity gameActivity, @LayoutRes int layoutId) {
|
||||
this.type = type;
|
||||
this.gameActivity = gameActivity;
|
||||
layout = inflateLayout(gameActivity, layoutId);
|
||||
}
|
||||
|
||||
private V inflateLayout(Context context, @LayoutRes int layoutId) {
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
return (V) inflater.inflate(layoutId, null);
|
||||
}
|
||||
|
||||
protected TopBar createTopBar(@IdRes int id) {
|
||||
return new TopBar(gameActivity, type, layout.findViewById(id));
|
||||
}
|
||||
|
||||
public void setCaller(ScreenType caller) {
|
||||
this.caller = caller;
|
||||
}
|
||||
|
||||
public abstract void prepareToBeShown();
|
||||
|
||||
public abstract void onBackKeyDown();
|
||||
|
||||
protected void flipToCaller() {
|
||||
if (caller != null)
|
||||
gameActivity.flipToScreen(caller);
|
||||
}
|
||||
|
||||
protected void flipTo(ScreenType type) {
|
||||
gameActivity.flipToScreen(type);
|
||||
}
|
||||
|
||||
public ScreenType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public V get() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.ViewFlipper;
|
||||
|
||||
/**
|
||||
* Created by Julian on 13.02.2016.
|
||||
*/
|
||||
public class ScreenFlipper extends ViewFlipper {
|
||||
|
||||
private Screen[] screens;
|
||||
private Screen currentScreen;
|
||||
|
||||
public ScreenFlipper(Context context, Screen... screens) {
|
||||
super(context);
|
||||
this.screens = screens;
|
||||
for (Screen screen : screens)
|
||||
addView(screen);
|
||||
currentScreen = screens[0];
|
||||
showScreen(currentScreen.getType(), Screen.ScreenType.NONE);
|
||||
}
|
||||
|
||||
private void addView(Screen screen) {
|
||||
super.addView(screen.get(), screen.getType().getInFlipperPosition());
|
||||
}
|
||||
|
||||
public Screen getCurrentScreen() {
|
||||
return currentScreen;
|
||||
}
|
||||
|
||||
public void showScreen(Screen.ScreenType type, Screen.ScreenType caller) {
|
||||
Screen screen = findScreen(type);
|
||||
screen.setCaller(caller);
|
||||
screen.prepareToBeShown();
|
||||
|
||||
int positionDifference = type.getInFlipperPosition() - currentScreen.getType().getInFlipperPosition();
|
||||
if (positionDifference < 0)
|
||||
for (; positionDifference != 0; positionDifference++)
|
||||
super.showPrevious();
|
||||
else if (positionDifference > 0)
|
||||
for (; positionDifference != 0; positionDifference--)
|
||||
super.showNext();
|
||||
currentScreen = screen;
|
||||
}
|
||||
|
||||
private Screen findScreen(Screen.ScreenType type) {
|
||||
for (Screen screen : screens)
|
||||
if (screen.getType().equals(type)) {
|
||||
return screen;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.main.MyGlSurfaceView;
|
||||
import de.frajul.endlessroll.rendering.Rendering;
|
||||
import de.frajul.endlessroll.views.ExitConfirmDialog;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.07.2016.
|
||||
*/
|
||||
public class StartScreen extends GLScreen<RelativeLayout> implements View.OnClickListener {
|
||||
|
||||
private Rendering rendering;
|
||||
|
||||
private Button play;
|
||||
private Button unlockLevels;
|
||||
private Button gain90EP;
|
||||
private Button toGlTestScreen;
|
||||
private Button settings;
|
||||
|
||||
private ExitConfirmDialog exitConfirmDialog;
|
||||
|
||||
public StartScreen(GameActivity gameActivity, MyGlSurfaceView glSurfaceView) throws Exception {
|
||||
super(ScreenType.START, gameActivity, R.layout.start_screen, glSurfaceView);
|
||||
|
||||
Typeface typeface = gameActivity.getTypeface();
|
||||
play = createButton(R.id.startscreen_play, typeface);
|
||||
play.startAnimation(AnimationUtils.loadAnimation(gameActivity, R.anim.rotate));
|
||||
unlockLevels = createButton(R.id.startscreen_unlock_levels, typeface);
|
||||
gain90EP = createButton(R.id.startscreen_gain_90_ep, typeface);
|
||||
toGlTestScreen = createButton(R.id.startscreen_to_gl_test_screen, typeface);
|
||||
settings = (Button) layout.findViewById(R.id.startscreen_settings);
|
||||
settings.setOnClickListener(this);
|
||||
|
||||
exitConfirmDialog = new ExitConfirmDialog(gameActivity);
|
||||
|
||||
rendering = new StartScreenRendering(gameActivity);
|
||||
glView.addRendering(rendering);
|
||||
}
|
||||
|
||||
private Button createButton(@IdRes int id, Typeface typeface) {
|
||||
Button button = (Button) layout.findViewById(id);
|
||||
button.setTypeface(typeface);
|
||||
button.setOnClickListener(this);
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareToBeShown() {
|
||||
glView.setCurrentRendering(rendering);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackKeyDown() {
|
||||
exitConfirmDialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.equals(play)) {
|
||||
gameActivity.flipToScreen(ScreenType.WORLDS);
|
||||
glView.setCurrentRendering(null);
|
||||
} else if (v.equals(settings)) {
|
||||
gameActivity.flipToScreen(ScreenType.SETTINGS);
|
||||
glView.setCurrentRendering(null);
|
||||
} else if (v.equals(gain90EP)) {
|
||||
gameActivity.getUser().gainEp(90);
|
||||
} else if (v.equals(unlockLevels)) {
|
||||
gameActivity.getLevelManager().unlockAllLevels();
|
||||
gameActivity.getLevelManager().unlockAllPacks();
|
||||
} else if (v.equals(toGlTestScreen))
|
||||
gameActivity.flipToScreen(ScreenType.GL_TEST);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import de.frajul.endlessroll.entities.particles.ParticleSystem;
|
||||
import de.frajul.endlessroll.entities.textures.TexturePack;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
import de.frajul.endlessroll.main.game.StartScene;
|
||||
import de.frajul.endlessroll.main.game.Timer;
|
||||
import de.frajul.endlessroll.rendering.Rendering;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.07.2016.
|
||||
*/
|
||||
public class StartScreenRendering extends Rendering<StartScene> {
|
||||
|
||||
private Timer timer;
|
||||
private ParticleSystem particleSystem;
|
||||
|
||||
public StartScreenRendering(GameActivity gameActivity) throws Exception {
|
||||
super(gameActivity);
|
||||
this.particleSystem = new ParticleSystem(gameActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartScene init(TexturePack texturePack, Timer timer, boolean isFirstTime) {
|
||||
GameLog.d("init Start Screen Rendering");
|
||||
this.timer = timer;
|
||||
if (isFirstTime)
|
||||
scene = new StartScene(texturePack, particleSystem);
|
||||
else
|
||||
scene.setTexturePack(texturePack);
|
||||
try {
|
||||
particleSystem.loadTextures();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return scene;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
particleSystem.update(timer);
|
||||
scene.update(timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.entities.tools.ToolSlot;
|
||||
import de.frajul.endlessroll.entities.tools.ToolType;
|
||||
import de.frajul.endlessroll.main.DataStorageHandler;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.main.tutorial.ToolShopTutorial;
|
||||
import de.frajul.endlessroll.user.LevelUpBounties;
|
||||
import de.frajul.endlessroll.user.ToolSlotSettings;
|
||||
import de.frajul.endlessroll.views.ToolInspector;
|
||||
import de.frajul.endlessroll.views.ToolOfferSlot;
|
||||
import de.frajul.endlessroll.views.TopBar;
|
||||
|
||||
/**
|
||||
* Created by Julian on 08.07.2016.
|
||||
*/
|
||||
public class ToolShopScreen extends Screen<RelativeLayout> implements View.OnClickListener {
|
||||
|
||||
private LevelUpBounties levelUpBounties;
|
||||
private ToolSlotSettings slotSettings;
|
||||
private ToolOfferSlot selectedToolOfferSlot;
|
||||
|
||||
private TopBar topBar;
|
||||
private LinearLayout toolOfferTopRow;
|
||||
private LinearLayout toolOfferBottomRow;
|
||||
private List<ImageView> toolSlotViews = new ArrayList<>();
|
||||
private List<ToolOfferSlot> toolOfferSlots = new ArrayList<>();
|
||||
|
||||
private ToolInspector toolInspector;
|
||||
private ToolShopTutorial tutorial;
|
||||
|
||||
public ToolShopScreen(GameActivity gameActivity) {
|
||||
super(ScreenType.TOOL_SHOP, gameActivity, R.layout.toolshop);
|
||||
this.levelUpBounties = new LevelUpBounties(0);
|
||||
this.slotSettings = gameActivity.getUser().getToolSlotSettings();
|
||||
this.tutorial = gameActivity.getTutorialManager().getToolShopTutorial();
|
||||
tutorial.setFirstPartShown(
|
||||
gameActivity.getDataStorageHandler().readToolShopTutorialPart1Finished());
|
||||
|
||||
topBar = super.createTopBar(R.id.toolshop_topbar);
|
||||
toolSlotViews.add(getToolSlotView(R.id.toolshop_slot1));
|
||||
toolSlotViews.add(getToolSlotView(R.id.toolshop_slot2));
|
||||
toolSlotViews.add(getToolSlotView(R.id.toolshop_slot3));
|
||||
toolSlotViews.add(getToolSlotView(R.id.toolshop_slot4));
|
||||
toolOfferTopRow = (LinearLayout) layout.findViewById(R.id.toolshop_tool_offer_top_row);
|
||||
toolOfferBottomRow = (LinearLayout) layout
|
||||
.findViewById(R.id.toolshop_tool_offer_bottom_row);
|
||||
|
||||
toolInspector = new ToolInspector(this, gameActivity,
|
||||
layout.findViewById(R.id.toolshop_toolinspector));
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.setMargins(10, 0, 10, 0);
|
||||
|
||||
int i = 0;
|
||||
for (ToolType type : ToolType.values()) {
|
||||
i++;
|
||||
ToolOfferSlot slot = new ToolOfferSlot(this, gameActivity, gameActivity.getTypeface(),
|
||||
type);
|
||||
toolOfferSlots.add(slot);
|
||||
if (i > 5)
|
||||
toolOfferBottomRow.addView(slot.getLayout(), params);
|
||||
else
|
||||
toolOfferTopRow.addView(slot.getLayout(), params);
|
||||
}
|
||||
}
|
||||
|
||||
private ImageView getToolSlotView(int id) {
|
||||
FrameLayout slotLayout = (FrameLayout) layout.findViewById(id);
|
||||
ImageView imageView = (ImageView) slotLayout.findViewById(R.id.toolslot_image);
|
||||
imageView.setOnClickListener(this);
|
||||
return imageView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareToBeShown() {
|
||||
topBar.update();
|
||||
levelUpBounties.loadAllForLevel(gameActivity.getUser().getLevel());
|
||||
slotSettings.unlockSlotsIfLevelReached(levelUpBounties);
|
||||
onToolOfferSlotSelected(toolOfferSlots.get(0));
|
||||
|
||||
for (int i = 0; i < toolSlotViews.size(); i++) {
|
||||
ToolSlot toolSlot = slotSettings.get(i);
|
||||
ImageView toolSlotView = toolSlotViews.get(i);
|
||||
toolSlotView.setImageResource(toolSlot.getDrawable());
|
||||
}
|
||||
for (ToolOfferSlot toolOfferSlot : toolOfferSlots) {
|
||||
boolean locked = levelUpBounties.isToolLocked(toolOfferSlot.getToolType());
|
||||
toolOfferSlot.setLocked(locked);
|
||||
toolOfferSlot.updateBackgroundColor();
|
||||
}
|
||||
tutorial.onToolShopPrepare(!levelUpBounties.isToolLocked(ToolType.SPRING));
|
||||
if (tutorial.isOverNewBreakPoints()) {
|
||||
gameActivity.showTutorialScreen(tutorial.getCurrentBreakPoints());
|
||||
gameActivity.getDataStorageHandler()
|
||||
.writeToolShopTutorialPart1Finished(tutorial.isFirstPartShown());
|
||||
}
|
||||
}
|
||||
|
||||
public void onToolBought(int price, ToolType toolType) {
|
||||
topBar.showStarcountDecrease(-price);
|
||||
gameActivity.getUser().increaseStarCount(-price, false);
|
||||
topBar.update();
|
||||
DataStorageHandler dataStorageHandler = gameActivity.getDataStorageHandler();
|
||||
dataStorageHandler.getDatabase().open();
|
||||
dataStorageHandler.getDatabase().writeToolData();
|
||||
dataStorageHandler.getDatabase().close();
|
||||
for (ToolOfferSlot toolOfferSlot : toolOfferSlots) {
|
||||
toolOfferSlot.updateBackgroundColor();
|
||||
}
|
||||
tutorial.onToolBought(toolType);
|
||||
if (tutorial.isOverNewBreakPoints())
|
||||
gameActivity.showTutorialScreen(tutorial.getCurrentBreakPoints());
|
||||
}
|
||||
|
||||
public void onToolUpgraded(int price) {
|
||||
topBar.showEnergycountDecrease(-price);
|
||||
gameActivity.getUser().increaseEnergyCount(-price, false);
|
||||
topBar.update();
|
||||
DataStorageHandler dataStorageHandler = gameActivity.getDataStorageHandler();
|
||||
dataStorageHandler.getDatabase().open();
|
||||
dataStorageHandler.getDatabase().writeToolData();
|
||||
dataStorageHandler.getDatabase().close();
|
||||
}
|
||||
|
||||
|
||||
public void onToolOfferSlotSelected(ToolOfferSlot slot) {
|
||||
selectedToolOfferSlot = slot;
|
||||
for (ToolOfferSlot toolOfferSlot : toolOfferSlots)
|
||||
toolOfferSlot.setSelected(toolOfferSlot.equals(slot));
|
||||
toolInspector.update(slot.getToolType(), slot.isLocked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackKeyDown() {
|
||||
gameActivity.getDataStorageHandler().writeUserData(gameActivity.getUser());
|
||||
flipToCaller();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ImageView toolSlotView = (ImageView) v;
|
||||
int index = toolSlotViews.indexOf(toolSlotView);
|
||||
if (canSelectedToolBePutInSlot(index)) {
|
||||
slotSettings.changeToolSlotType(index, selectedToolOfferSlot.getToolType());
|
||||
for (int i = 0; i < toolSlotViews.size(); i++) {
|
||||
ToolSlot toolSlot = slotSettings.get(i);
|
||||
ImageView view = toolSlotViews.get(i);
|
||||
view.setImageResource(toolSlot.getDrawable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canSelectedToolBePutInSlot(int slotIndex) {
|
||||
return slotIndex != -1 && !slotSettings.get(slotIndex)
|
||||
.isLocked() && selectedToolOfferSlot != null && selectedToolOfferSlot.getToolType()
|
||||
.isBought();
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package de.frajul.endlessroll.main.screens;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.levels.LevelPack;
|
||||
import de.frajul.endlessroll.main.GameActivity;
|
||||
import de.frajul.endlessroll.views.TopBar;
|
||||
import de.frajul.endlessroll.views.WorldButton;
|
||||
import de.frajul.endlessroll.views.WorldButtonOnClickListener;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.07.2016.
|
||||
*/
|
||||
public class WorldsScreen extends Screen<RelativeLayout> implements WorldButtonOnClickListener {
|
||||
|
||||
private List<WorldButton> worldButtons = new ArrayList<>();
|
||||
private TopBar topBar;
|
||||
private LinearLayout buttonLayout;
|
||||
|
||||
public WorldsScreen(GameActivity gameActivity) {
|
||||
super(ScreenType.WORLDS, gameActivity, R.layout.worlds);
|
||||
topBar = super.createTopBar(R.id.worlds_topbar);
|
||||
buttonLayout = (LinearLayout) layout.findViewById(R.id.worlds_layout);
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.setMargins(25, 0, 25, 0);
|
||||
|
||||
for (LevelPack levelPack : gameActivity.getLevelManager()) {
|
||||
WorldButton button = new WorldButton(gameActivity, levelPack, this);
|
||||
buttonLayout.addView(button.getView(), params);
|
||||
worldButtons.add(button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareToBeShown() {
|
||||
topBar.update();
|
||||
for (WorldButton button : worldButtons)
|
||||
button.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackKeyDown() {
|
||||
flipTo(ScreenType.START);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(WorldButton worldButton) {
|
||||
LevelPack levelPack = worldButton.getLevelPack();
|
||||
if (!levelPack.isLocked()) {
|
||||
gameActivity.onWorldSelected(levelPack);
|
||||
gameActivity.flipToScreen(ScreenType.LEVELS);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package de.frajul.endlessroll.main.tutorial;
|
||||
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
/**
|
||||
* Created by Julian on 14.03.2017.
|
||||
*/
|
||||
|
||||
public class BreakPoint {
|
||||
|
||||
public final static float LEVEL_FINISHED_X = -1;
|
||||
|
||||
private float x;
|
||||
private boolean alreadyShown = false;
|
||||
@StringRes
|
||||
private int textId;
|
||||
@DrawableRes
|
||||
private int imageId;
|
||||
|
||||
public BreakPoint(float x, @StringRes int textId, @DrawableRes int imageId) {
|
||||
this.x = x;
|
||||
this.textId = textId;
|
||||
this.imageId = imageId;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getTextId() {
|
||||
return textId;
|
||||
}
|
||||
|
||||
public int getImageId() {
|
||||
return imageId;
|
||||
}
|
||||
|
||||
public void setAlreadyShown(boolean alreadyShown) {
|
||||
this.alreadyShown = alreadyShown;
|
||||
}
|
||||
|
||||
public boolean isAlreadyShown() {
|
||||
return alreadyShown;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package de.frajul.endlessroll.main.tutorial;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 14.03.2017.
|
||||
*/
|
||||
|
||||
public class Tutorial {
|
||||
|
||||
private int levelId, levelPackId;
|
||||
private List<BreakPoint> breakPoints;
|
||||
protected List<BreakPoint> currentBreakPoints = new ArrayList<>();
|
||||
|
||||
public Tutorial(int levelId, int levelPackId, BreakPoint... breakPoints) {
|
||||
this.levelId = levelId;
|
||||
this.levelPackId = levelPackId;
|
||||
this.breakPoints = Arrays.asList(breakPoints);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
for (BreakPoint breakPoint : breakPoints)
|
||||
breakPoint.setAlreadyShown(false);
|
||||
currentBreakPoints.clear();
|
||||
}
|
||||
|
||||
public void onLevelFinished() {
|
||||
currentBreakPoints.clear();
|
||||
|
||||
for (BreakPoint breakPoint : breakPoints) {
|
||||
if (breakPoint.getX() == BreakPoint.LEVEL_FINISHED_X) {
|
||||
breakPoint.setAlreadyShown(true);
|
||||
currentBreakPoints.add(breakPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void update(float playerProgress) {
|
||||
playerProgress *= 2f;
|
||||
currentBreakPoints.clear();
|
||||
|
||||
for (BreakPoint breakPoint : breakPoints) {
|
||||
if (!breakPoint.isAlreadyShown() && playerProgress >= breakPoint.getX() && breakPoint
|
||||
.getX() != BreakPoint.LEVEL_FINISHED_X) {
|
||||
breakPoint.setAlreadyShown(true);
|
||||
currentBreakPoints.add(breakPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOverNewBreakPoints() {
|
||||
return !currentBreakPoints.isEmpty();
|
||||
}
|
||||
|
||||
public List<BreakPoint> getCurrentBreakPoints() {
|
||||
return currentBreakPoints;
|
||||
}
|
||||
|
||||
public List<BreakPoint> getBreakPoints() {
|
||||
return breakPoints;
|
||||
}
|
||||
|
||||
public int getLevelId() {
|
||||
return levelId;
|
||||
}
|
||||
|
||||
public int getLevelPackId() {
|
||||
return levelPackId;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package de.frajul.endlessroll.main.tutorial;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import de.frajul.endlessroll.R;
|
||||
import de.frajul.endlessroll.levels.Level;
|
||||
|
||||
/**
|
||||
* Created by Julian on 17.03.2017.
|
||||
*/
|
||||
|
||||
public class TutorialManager {
|
||||
|
||||
private List<Tutorial> gameTutorials;
|
||||
private ToolShopTutorial toolShopTutorial;
|
||||
|
||||
public TutorialManager() {
|
||||
Tutorial t11 = new Tutorial(1, 1, new BreakPoint(0, R.string.tutorial_welcome, -1),
|
||||
new BreakPoint(0, R.string.tutorial_place_tools, R.drawable.tutorial_place_tools),
|
||||
new BreakPoint(7, R.string.tutorial_place_ramp_gap,
|
||||
R.drawable.tutorial_place_ramp_gap),
|
||||
new BreakPoint(21, R.string.tutorial_place_ramp_obstacle,
|
||||
R.drawable.tutorial_place_ramp_obstacle));
|
||||
Tutorial t21 = new Tutorial(2, 1, new BreakPoint(11, R.string.tutorial_place_ramp_air,
|
||||
R.drawable.tutorial_place_ramp_air_1),
|
||||
new BreakPoint(33, R.string.tutorial_place_ramp_air_2,
|
||||
R.drawable.tutorial_place_ramp_air_2));
|
||||
Tutorial t51 = new Tutorial(5, 1,
|
||||
new BreakPoint(BreakPoint.LEVEL_FINISHED_X, R.string.tutorial_leveled_up, -1),
|
||||
new BreakPoint(BreakPoint.LEVEL_FINISHED_X, R.string.tutorial_to_toolshop,
|
||||
R.drawable.tutorial_to_toolshop));
|
||||
|
||||
gameTutorials = Arrays.asList(t11, t21, t51);
|
||||
|
||||
toolShopTutorial = new ToolShopTutorial();
|
||||
}
|
||||
|
||||
public void resetGameTutorials() {
|
||||
for (Tutorial tutorial : gameTutorials)
|
||||
tutorial.reset();
|
||||
}
|
||||
|
||||
public Tutorial getGameTutorial(Level level) {
|
||||
for (Tutorial tutorial : gameTutorials) {
|
||||
if (tutorial.getLevelPackId() == level.getPackId() && tutorial.getLevelId() == level
|
||||
.getId())
|
||||
return tutorial;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ToolShopTutorial getToolShopTutorial() {
|
||||
return toolShopTutorial;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user