what done?
This commit is contained in:
28
app/src/main/AndroidManifest.xml
Normal file
28
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.julian.endlessroll">
|
||||
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true">
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity
|
||||
android:name=".main.GameActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:screenOrientation="landscape">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
BIN
app/src/main/assets/fontBaron.ttf
Normal file
BIN
app/src/main/assets/fontBaron.ttf
Normal file
Binary file not shown.
44
app/src/main/assets/levelpack_01.xml
Normal file
44
app/src/main/assets/levelpack_01.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<levelPack name="Levelpack 1">
|
||||
<levels>
|
||||
<level goalX="24" number="1">
|
||||
<terrain endX="27" height="-0.6">
|
||||
<gaps>
|
||||
<gap leftEdge="4" rightEdge="5"/>
|
||||
<gap leftEdge="12" rightEdge="13"/>
|
||||
<gap leftEdge="16" rightEdge="16.5"/>
|
||||
<gap leftEdge="16.8" rightEdge="17.3"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles>
|
||||
<obstacle height="0.3" leftEdge="9" rightEdge="10" type="default"/>
|
||||
<obstacle height="0.2" leftEdge="13" rightEdge="14" type="default"/>
|
||||
<obstacle height="0.3" leftEdge="18" rightEdge="20" type="default"/>
|
||||
<obstacle height="0.5" leftEdge="20" rightEdge="21" type="default"/>
|
||||
<obstacle height="0.1" leftEdge="21" rightEdge="22" type="default"/>
|
||||
</obstacles>
|
||||
</level>
|
||||
<level goalX="21.25" number="2">
|
||||
<terrain endX="21" height="-0.6">
|
||||
<gaps>
|
||||
<gap leftEdge="1" rightEdge="1.7" />
|
||||
<gap leftEdge="8.9" rightEdge="9.6" />
|
||||
<gap leftEdge="9.7" rightEdge="10.4" />
|
||||
<gap leftEdge="15" rightEdge="16.1" />
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles>
|
||||
<obstacle height="0.3" leftEdge="1.73" rightEdge="2.3" type="default" />
|
||||
<obstacle height="0.5" leftEdge="2.9" rightEdge="3.6" type="default" />
|
||||
<obstacle height="0.3" leftEdge="5" rightEdge="7" type="default" />
|
||||
<obstacle height="0.52" leftEdge="7.1" rightEdge="8.5" type="default" />
|
||||
<obstacle height="0.5" leftEdge="11.4" rightEdge="12.8" type="default" />
|
||||
<obstacle height="0.5" leftEdge="13.9" rightEdge="14.2" type="default" />
|
||||
<obstacle height="0.24" leftEdge="16.8" rightEdge="18.3" type="default" />
|
||||
<obstacle height="0.35" leftEdge="18.30001" rightEdge="18.8" type="default" />
|
||||
<obstacle height="0.54" leftEdge="18.80001" rightEdge="19.4" type="default" />
|
||||
<obstacle height="0.41" leftEdge="19.40001" rightEdge="20.5" type="default" />
|
||||
</obstacles>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
196
app/src/main/assets/levelpacks/Grasslands.xml
Normal file
196
app/src/main/assets/levelpacks/Grasslands.xml
Normal file
@ -0,0 +1,196 @@
|
||||
<levelPack name="Grasslands" id="1">
|
||||
<levels class="java.util.ArrayList">
|
||||
<level number="1" goalX="22.606565">
|
||||
<terrain height="-0.6" endX="25.106565">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="5.3500023" rightEdge="5.950004"/>
|
||||
<gap leftEdge="15.353701" rightEdge="15.7197"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="10.873024" rightEdge="11.427025" height="0.304" y="-0.448" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="14.860029" rightEdge="15.360029" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.096622" rightEdge="22.096622" height="0.25" y="-0.47500002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="22.166656" rightEdge="22.666656" height="0.639" y="-0.28050002" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="11.159975" y="-0.15999995" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="15.106676" y="-0.14000002" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="22.043303" y="-0.20666662" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="2" goalX="22.366613">
|
||||
<terrain height="-0.6" endX="25.36662">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="4.863002" rightEdge="5.6970024"/>
|
||||
<gap leftEdge="10.581718" rightEdge="11.33174"/>
|
||||
<gap leftEdge="15.4032545" rightEdge="16.05025"/>
|
||||
<gap leftEdge="19.54848" rightEdge="20.111479"/>
|
||||
<gap leftEdge="20.609486" rightEdge="21.050488"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="3.3708305" rightEdge="4.8758307" height="0.2" y="-0.5" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.334382" rightEdge="11.912381" height="0.319" y="-0.44050002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.4509985" rightEdge="3.3089983" height="0.275" y="-0.46250004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.6111658" rightEdge="2.3221657" height="0.338" y="-0.43100002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="16.037212" rightEdge="16.856213" height="0.435" y="-0.38250002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="16.873312" rightEdge="17.873312" height="0.367" y="-0.41650003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="17.884027" rightEdge="18.896029" height="0.327" y="-0.4365" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.046677" rightEdge="19.546677" height="0.884" y="-0.15800002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.113306" rightEdge="20.613306" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="10.94335" y="-0.61999965" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="15.7367" y="0.3199999" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="18.893328" y="-0.12666662" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="3" goalX="19.200012">
|
||||
<terrain height="-0.6" endX="18.900013">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="2.3799982" rightEdge="2.9799984"/>
|
||||
<gap leftEdge="4.825835" rightEdge="5.200835"/>
|
||||
<gap leftEdge="7.5069995" rightEdge="8.013"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="8.00651" rightEdge="8.67351" height="0.319" y="-0.44050002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.703371" rightEdge="12.7233715" height="0.299" y="-0.4505" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="15.164396" rightEdge="15.762396" height="0.466" y="-0.36700004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="15.891703" rightEdge="16.901701" height="0.402" y="-0.39900002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="16.998373" rightEdge="18.248373" height="0.353" y="-0.42350003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="18.396694" rightEdge="18.896694" height="0.789" y="-0.20550004" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="2.6399994" y="0.10666669" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="8.793346" y="-0.4733331" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="12.253348" y="-0.13333318" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="4" goalX="23.639889">
|
||||
<terrain height="-0.6" endX="23.639889">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="15.903543" rightEdge="17.656546"/>
|
||||
<gap leftEdge="20.776228" rightEdge="22.557226"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="1.948999" rightEdge="2.5509992" height="0.354" y="-0.42300004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="5.592169" rightEdge="8.321169" height="0.408" y="-0.39600003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="8.408872" rightEdge="11.137872" height="0.803" y="-0.19850004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.196732" rightEdge="14.196732" height="0.5" y="0.3966666" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="14.865067" rightEdge="17.775066" height="0.299" y="0.48666632" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="17.871216" rightEdge="18.522217" height="1.415" y="0.10749996" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="18.612877" rightEdge="20.853878" height="0.231" y="0.55999976" attachedToGround="false"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="11.560022" y="-0.26000002" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="16.310017" y="0.80666655" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="21.629972" y="-0.12" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="5" goalX="16.249996">
|
||||
<terrain height="-0.6" endX="18.249996">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="6.810508" rightEdge="8.329505"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="2.3669987" rightEdge="2.7929988" height="1.074" y="-0.06300002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="12.000204" rightEdge="13.373203" height="0.946" y="-0.12700003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="13.539708" rightEdge="15.093709" height="0.725" y="-0.23750001" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="15.29672" rightEdge="15.79672" height="1.539" y="0.1695" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="2.5799987" y="0.62" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="7.5566673" y="0.26000008" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="11.85002" y="-0.4533334" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="6" goalX="27.539873">
|
||||
<terrain height="-0.6" endX="26.939873">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="4.026832" rightEdge="5.179832"/>
|
||||
<gap leftEdge="9.292203" rightEdge="10.061208"/>
|
||||
<gap leftEdge="10.566699" rightEdge="11.166699"/>
|
||||
<gap leftEdge="16.414387" rightEdge="16.75238"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="1.1131666" rightEdge="1.5001667" height="0.941" y="-0.12950003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.6498328" rightEdge="1.7768329" height="0.902" y="-0.14900002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.9103338" rightEdge="2.1163337" height="0.838" y="-0.18100002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.224499" rightEdge="2.415499" height="0.735" y="-0.23250002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.500666" rightEdge="2.6726658" height="0.613" y="-0.29350004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.731666" rightEdge="3.961666" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="5.1713314" rightEdge="5.955332" height="0.186" y="-0.507" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="10.060041" rightEdge="10.560041" height="0.843" y="-0.17850003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.506636" rightEdge="20.806635" height="0.558" y="-0.321" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.5105" rightEdge="20.8095" height="0.286" y="0.9333331" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="14.943075" rightEdge="16.437075" height="0.231" y="-0.48450002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="25.285612" rightEdge="26.707613" height="0.599" y="-0.30050004" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="4.586666" y="-0.5866665" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="10.696706" y="-0.46666694" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="20.64665" y="0.39999995" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="7" goalX="25.473257">
|
||||
<terrain height="-0.6" endX="28.473238">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="7.3475013" rightEdge="9.372511"/>
|
||||
<gap leftEdge="9.8666935" rightEdge="10.466708"/>
|
||||
<gap leftEdge="15.304541" rightEdge="16.335531"/>
|
||||
<gap leftEdge="19.761318" rightEdge="20.305317"/>
|
||||
<gap leftEdge="24.703619" rightEdge="25.36962"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="2.9593315" rightEdge="3.9473314" height="0.313" y="-0.01333334" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="3.987667" rightEdge="5.565667" height="0.272" y="-0.046666723" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="8.7657" rightEdge="10.8077" height="0.095" y="-0.5525" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="5.595845" rightEdge="6.950845" height="0.19" y="-0.073333286" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="15.055702" rightEdge="16.537703" height="0.218" y="-0.49100003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="6.992841" rightEdge="7.353841" height="0.558" y="-0.321" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.35432" rightEdge="19.75232" height="0.762" y="-0.21900001" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.963318" rightEdge="20.463318" height="0.5" y="0.7533332" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="20.287636" rightEdge="21.245636" height="0.435" y="-0.38250002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.503141" rightEdge="21.190142" height="0.5" y="0.42999995" attachedToGround="false"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="6.6800065" y="-0.38666666" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="15.820039" y="-0.7866664" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="20.679989" y="0.85333335" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="8" goalX="20.523335">
|
||||
<terrain height="-0.6" endX="23.523335">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="-1.3473341" rightEdge="2.240666"/>
|
||||
<gap leftEdge="3.05333" rightEdge="7.05333"/>
|
||||
<gap leftEdge="11.257536" rightEdge="14.282536"/>
|
||||
<gap leftEdge="15.696874" rightEdge="16.10987"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="-0.9233334" rightEdge="2.0766666" height="0.136" y="-0.90666574" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="4.979664" rightEdge="5.9736643" height="0.286" y="-0.89333284" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="3.057998" rightEdge="3.9619977" height="0.299" y="-0.81333286" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="3.9729972" rightEdge="4.9669976" height="0.286" y="-0.8533326" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="5.997839" rightEdge="6.8288393" height="0.231" y="-0.9199996" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="11.854198" rightEdge="13.119198" height="1.02" y="0.023333304" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="13.141195" rightEdge="13.792196" height="0.639" y="0.18666656" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="14.541548" rightEdge="15.698547" height="0.422" y="-0.38900003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.074863" rightEdge="20.851864" height="1.02" y="-0.09000003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.280017" rightEdge="14.280017" height="0.218" y="-1.1066662" attachedToGround="false"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="2.6366663" y="0.44666678" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="14.12338" y="-0.79999965" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="20.230003" y="0.5599996" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
50
app/src/main/assets/levelpacks/Testcave.xml
Normal file
50
app/src/main/assets/levelpacks/Testcave.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<levelPack name="Testcave" id="0" terrainHeight="0.306" ceilingHeight="0.538">
|
||||
<levels class="java.util.ArrayList">
|
||||
<level number="1" goalX="32.129963" startSpeed="0.25" endSpeed="0.7">
|
||||
<terrainTiles class="entities.tileLists.Terrain">
|
||||
<tile x="-1.6499999" width="2.7000003"/>
|
||||
<tile x="0.6273333" width="0.6546662"/>
|
||||
<tile x="5.837672" width="5.558014"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="entities.tileLists.Ceiling">
|
||||
<tile x="-0.41333365" width="5.1733327"/>
|
||||
<tile x="7.895005" width="1.4433479"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="9.0" rightEdge="10.0" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="13.0" rightEdge="14.0" height="0.2" y="-0.5" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.52634" rightEdge="20.580341" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.580004" rightEdge="21.580004" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="21.580002" rightEdge="22.580002" height="0.1" y="-0.55" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.6033329" rightEdge="2.103333" height="0.5" y="-0.18399999" attachedToGround="true"/>
|
||||
<obstacleData type="default" leftEdge="-0.25" rightEdge="0.25" height="0.5" y="0.0" attachedToGround="false"/>
|
||||
<obstacleData type="default" leftEdge="-0.25" rightEdge="0.25" height="0.5" y="0.0" attachedToGround="false"/>
|
||||
<obstacleData type="default" leftEdge="-0.25" rightEdge="0.25" height="0.5" y="0.0" attachedToGround="true"/>
|
||||
<obstacleData type="default" leftEdge="-0.25" rightEdge="0.25" height="0.5" y="0.0" attachedToGround="false"/>
|
||||
<obstacleData type="default" leftEdge="-0.25" rightEdge="0.25" height="0.5" y="0.0" attachedToGround="false"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="10.163283" y="-0.05999978" width="0.25" height="0.25"/>
|
||||
<starData index="2" x="19.366709" y="-0.046666652" width="0.25" height="0.25"/>
|
||||
<starData index="3" x="21.73662" y="0.05333341" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="3" goalX="8.616679" startSpeed="0.19" endSpeed="0.44">
|
||||
<terrainTiles class="entities.tileLists.Terrain">
|
||||
<tile x="-1.0226668" width="3.9546664"/>
|
||||
<tile x="5.837672" width="5.5580134"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="entities.tileLists.Ceiling">
|
||||
<tile x="-0.43666697" width="5.126666"/>
|
||||
<tile x="7.8716717" width="1.4900146"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="1.3278332" rightEdge="3.098833" height="0.5" y="-0.2733331" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="4.0364995" rightEdge="6.2235" height="0.109" y="0.61333334" attachedToGround="false"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData index="1" x="6.0466657" y="0.83333325" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
106
app/src/main/assets/levelpacks/levelpack_First Pack.xml
Normal file
106
app/src/main/assets/levelpacks/levelpack_First Pack.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<levelPack name="First Pack">
|
||||
<levels class="java.util.ArrayList">
|
||||
<level number="1" goalX="22.259893">
|
||||
<terrain height="-0.6" endX="23.259893">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="5.3500023" rightEdge="5.950004"/>
|
||||
<gap leftEdge="15.353701" rightEdge="15.7197"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="10.873024" rightEdge="11.427025" height="0.304" y="-0.448" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="14.860029" rightEdge="15.360029" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.383318" rightEdge="21.383318" height="0.25" y="-0.47500002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="21.586645" rightEdge="22.086645" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData x="11.150023" y="-0.1200001" width="0.25" height="0.25"/>
|
||||
<starData x="15.120053" y="-0.12666668" width="0.25" height="0.25"/>
|
||||
<starData x="21.42998" y="-0.20666662" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="2" goalX="16.220043">
|
||||
<terrain height="-0.6" endX="19.220049">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="4.8896685" rightEdge="5.723669"/>
|
||||
<gap leftEdge="10.581718" rightEdge="11.33174"/>
|
||||
<gap leftEdge="15.4032545" rightEdge="16.05025"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="3.3708305" rightEdge="4.8758307" height="0.2" y="-0.5" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.334382" rightEdge="11.912381" height="0.319" y="-0.44050002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.4509985" rightEdge="3.3089983" height="0.275" y="-0.46250004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.6111658" rightEdge="2.3221657" height="0.338" y="-0.43100002" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData x="5.310005" y="-0.61333305" width="0.25" height="0.25"/>
|
||||
<starData x="10.976699" y="-0.6333332" width="0.25" height="0.25"/>
|
||||
<starData x="15.743367" y="0.31333324" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="3" goalX="19.146683">
|
||||
<terrain height="-0.6" endX="18.846684">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="2.3799982" rightEdge="2.9799984"/>
|
||||
<gap leftEdge="4.825835" rightEdge="5.200835"/>
|
||||
<gap leftEdge="7.5069995" rightEdge="8.013"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="8.00651" rightEdge="8.67351" height="0.319" y="-0.44050002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.703371" rightEdge="12.7233715" height="0.299" y="-0.4505" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="15.164396" rightEdge="15.762396" height="0.466" y="-0.36700004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="15.818368" rightEdge="16.828367" height="0.402" y="-0.39900002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="16.858376" rightEdge="18.108376" height="0.353" y="-0.42350003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="18.216705" rightEdge="18.716705" height="0.789" y="-0.20550004" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData x="2.6933327" y="0.1266667" width="0.25" height="0.25"/>
|
||||
<starData x="8.853351" y="-0.4533331" width="0.25" height="0.25"/>
|
||||
<starData x="12.253348" y="-0.13333318" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="4" goalX="17.23667">
|
||||
<terrain height="-0.6" endX="19.23667">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="6.810508" rightEdge="8.329505"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="2.3669987" rightEdge="2.7929988" height="1.074" y="-0.06300002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.929536" rightEdge="13.150537" height="0.946" y="-0.12700003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="13.377707" rightEdge="14.495707" height="0.725" y="-0.23750001" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="14.676702" rightEdge="15.176702" height="1.539" y="0.1695" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData x="2.573332" y="0.62" width="0.25" height="0.25"/>
|
||||
<starData x="7.5566673" y="0.26000008" width="0.25" height="0.25"/>
|
||||
<starData x="11.710016" y="-0.42666656" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="5" goalX="10.1833515">
|
||||
<terrain height="-0.6" endX="9.483352">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="4.026832" rightEdge="5.179832"/>
|
||||
<gap leftEdge="8.085517" rightEdge="8.854522"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="1.1131666" rightEdge="1.5001667" height="0.941" y="-0.12950003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.6498328" rightEdge="1.7768329" height="0.902" y="-0.14900002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="1.9103338" rightEdge="2.1163337" height="0.838" y="-0.18100002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.224499" rightEdge="2.415499" height="0.735" y="-0.23250002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.500666" rightEdge="2.6726658" height="0.613" y="-0.29350004" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.731666" rightEdge="3.961666" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="5.1713314" rightEdge="5.955332" height="0.186" y="-0.507" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="8.860007" rightEdge="9.360007" height="0.843" y="-0.17850003" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData x="4.5599995" y="-0.54666656" width="0.25" height="0.25"/>
|
||||
<starData x="6.203336" y="0.36666653" width="0.25" height="0.25"/>
|
||||
<starData x="9.543362" y="-0.43333334" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
84
app/src/main/assets/levelpacks/levelpack_Test Pack.xml
Normal file
84
app/src/main/assets/levelpacks/levelpack_Test Pack.xml
Normal file
@ -0,0 +1,84 @@
|
||||
<levelPack name="Test Pack">
|
||||
<levels class="java.util.ArrayList">
|
||||
<level number="1" goalX="24.0">
|
||||
<terrain height="-0.6" endX="27.0">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="4.0" rightEdge="5.0"/>
|
||||
<gap leftEdge="12.0" rightEdge="13.0"/>
|
||||
<gap leftEdge="16.0" rightEdge="16.5"/>
|
||||
<gap leftEdge="16.8" rightEdge="17.3"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="9.0" rightEdge="10.0" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="13.0" rightEdge="14.0" height="0.2" y="-0.5" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.52634" rightEdge="20.580341" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="20.580004" rightEdge="21.580004" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="21.580002" rightEdge="22.580002" height="0.1" y="-0.55" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
<level number="2" goalX="21.25">
|
||||
<terrain height="-0.6" endX="21.0">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="1.0" rightEdge="1.7"/>
|
||||
<gap leftEdge="8.9" rightEdge="9.6"/>
|
||||
<gap leftEdge="9.7" rightEdge="10.4"/>
|
||||
<gap leftEdge="15.0" rightEdge="16.1"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="0.42333412" rightEdge="0.99333405" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="2.9" rightEdge="3.6" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="5.0" rightEdge="7.0" height="0.3" y="-0.45000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="7.1000004" rightEdge="8.5" height="0.52" y="-0.34000003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="11.4" rightEdge="12.800001" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="13.9" rightEdge="14.199999" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="16.8" rightEdge="18.3" height="0.24" y="-0.48000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="18.30001" rightEdge="18.8" height="0.35" y="-0.425" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="18.80001" rightEdge="19.400002" height="0.54" y="-0.33" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="19.40001" rightEdge="20.5" height="0.41" y="-0.39500004" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList">
|
||||
<starData x="0.19333333" y="-0.02" width="0.25" height="0.25"/>
|
||||
</stars>
|
||||
</level>
|
||||
<level number="3" goalX="10.013344">
|
||||
<terrain height="-0.6" endX="13.013344">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="0.99333334" rightEdge="1.5933334"/>
|
||||
<gap leftEdge="2.3266642" rightEdge="5.326664"/>
|
||||
<gap leftEdge="5.376665" rightEdge="8.376666"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="1.0611664" rightEdge="1.5121664" height="0.431" y="-0.12666668" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="2.615834" rightEdge="3.590834" height="0.181" y="-0.37333322" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="3.5901666" rightEdge="4.2031665" height="0.27" y="-0.21999994" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="4.1894994" rightEdge="4.910499" height="0.294" y="0.0" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="5.1586647" rightEdge="6.5946646" height="0.279" y="-0.24049996" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="5.76284" rightEdge="5.9838395" height="0.76" y="0.5999998" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="6.808838" rightEdge="8.097838" height="0.211" y="-0.33999994" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="8.2516775" rightEdge="8.761678" height="0.877" y="-0.16150004" attachedToGround="true"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
<level number="4" goalX="14.916662">
|
||||
<terrain height="-0.6" endX="17.916662">
|
||||
<gaps class="java.util.ArrayList">
|
||||
<gap leftEdge="12.363373" rightEdge="12.963373"/>
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData type="" leftEdge="2.5548315" rightEdge="3.9518313" height="0.201" y="-0.09283342" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="0.84966636" rightEdge="1.1636665" height="0.27" y="-0.46500003" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="4.0266647" rightEdge="4.5266647" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="5.05683" rightEdge="6.16983" height="0.25" y="-0.09333334" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="6.2320023" rightEdge="6.948002" height="0.5" y="-0.35000002" attachedToGround="true"/>
|
||||
<obstacleData type="" leftEdge="7.572172" rightEdge="8.621172" height="0.284" y="-0.08666665" attachedToGround="false"/>
|
||||
<obstacleData type="" leftEdge="8.682344" rightEdge="9.084345" height="1.142" y="0.40666664" attachedToGround="false"/>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
12
app/src/main/assets/levelpacks/test.xml
Normal file
12
app/src/main/assets/levelpacks/test.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<levelPack name="test" id="1" terrainHeight="0.0" ceilingHeight="0.0">
|
||||
<levels class="java.util.ArrayList">
|
||||
<level number="2" goalX="3.0">
|
||||
<terrainTiles class="java.util.ArrayList">
|
||||
<tile x="0.0" width="6.0"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="java.util.ArrayList"/>
|
||||
<obstacles class="java.util.ArrayList"/>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
157
app/src/main/assets/particleEffects/collectStar.pe
Normal file
157
app/src/main/assets/particleEffects/collectStar.pe
Normal file
@ -0,0 +1,157 @@
|
||||
Untitled
|
||||
- Delay -
|
||||
active: false
|
||||
- Duration -
|
||||
lowMin: 300.0
|
||||
lowMax: 300.0
|
||||
- Count -
|
||||
min: 0
|
||||
max: 500
|
||||
- Emission -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 60.0
|
||||
highMax: 60.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Life -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 600.0
|
||||
highMax: 600.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
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: 15.0
|
||||
lowMax: 15.0
|
||||
highMin: 110.0
|
||||
highMax: 110.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 0.0
|
||||
scaling1: 0.19607843
|
||||
scaling2: 0.60784316
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.80136985
|
||||
timeline2: 1.0
|
||||
- Velocity -
|
||||
active: true
|
||||
lowMin: 1000.0
|
||||
lowMax: 1000.0
|
||||
highMin: -2000.0
|
||||
highMax: -2000.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 0.0
|
||||
scaling1: 0.0
|
||||
scaling2: 1.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.30170777
|
||||
timeline2: 1.0
|
||||
- Angle -
|
||||
active: true
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 0.0
|
||||
highMax: 360.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.7191781
|
||||
timeline2: 1.0
|
||||
- Rotation -
|
||||
active: false
|
||||
- Wind -
|
||||
active: false
|
||||
- Gravity -
|
||||
active: false
|
||||
- Tint -
|
||||
colorsCount: 9
|
||||
colors0: 1.0
|
||||
colors1: 0.92941177
|
||||
colors2: 0.047058824
|
||||
colors3: 1.0
|
||||
colors4: 0.92941177
|
||||
colors5: 0.047058824
|
||||
colors6: 1.0
|
||||
colors7: 0.78039217
|
||||
colors8: 0.047058824
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.7521515
|
||||
timeline2: 1.0
|
||||
- Transparency -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 1.0
|
||||
highMax: 1.0
|
||||
relative: false
|
||||
scalingCount: 7
|
||||
scaling0: 0.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
scaling3: 1.0
|
||||
scaling4: 1.0
|
||||
scaling5: 1.0
|
||||
scaling6: 0.0
|
||||
timelineCount: 7
|
||||
timeline0: 0.0
|
||||
timeline1: 0.12068965
|
||||
timeline2: 0.28767124
|
||||
timeline3: 0.5
|
||||
timeline4: 0.7873563
|
||||
timeline5: 0.967433
|
||||
timeline6: 1.0
|
||||
- Options -
|
||||
attached: false
|
||||
continuous: false
|
||||
aligned: false
|
||||
additive: true
|
||||
behind: false
|
||||
premultipliedAlpha: false
|
||||
- Image Path -
|
||||
star.png
|
184
app/src/main/assets/particleEffects/explosion.pe
Normal file
184
app/src/main/assets/particleEffects/explosion.pe
Normal file
@ -0,0 +1,184 @@
|
||||
Untitled
|
||||
- Delay -
|
||||
active: false
|
||||
- Duration -
|
||||
lowMin: 500.0
|
||||
lowMax: 500.0
|
||||
- Count -
|
||||
min: 0
|
||||
max: 1000
|
||||
- Emission -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 300.0
|
||||
highMax: 300.0
|
||||
relative: false
|
||||
scalingCount: 4
|
||||
scaling0: 1.0
|
||||
scaling1: 0.74509805
|
||||
scaling2: 0.3137255
|
||||
scaling3: 0.0
|
||||
timelineCount: 4
|
||||
timeline0: 0.0
|
||||
timeline1: 0.5205479
|
||||
timeline2: 0.8630137
|
||||
timeline3: 1.0
|
||||
- Life -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 500.0
|
||||
highMax: 800.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: square
|
||||
- Spawn Width -
|
||||
lowMin: 200.0
|
||||
lowMax: 200.0
|
||||
highMin: 20.0
|
||||
highMax: 20.0
|
||||
relative: false
|
||||
scalingCount: 2
|
||||
scaling0: 0.0
|
||||
scaling1: 0.0
|
||||
timelineCount: 2
|
||||
timeline0: 0.0
|
||||
timeline1: 1.0
|
||||
- Spawn Height -
|
||||
lowMin: 200.0
|
||||
lowMax: 200.0
|
||||
highMin: 20.0
|
||||
highMax: 20.0
|
||||
relative: false
|
||||
scalingCount: 2
|
||||
scaling0: 0.0
|
||||
scaling1: 0.0
|
||||
timelineCount: 2
|
||||
timeline0: 0.0
|
||||
timeline1: 1.0
|
||||
- Scale -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 27.0
|
||||
highMax: 37.0
|
||||
relative: false
|
||||
scalingCount: 2
|
||||
scaling0: 1.0
|
||||
scaling1: 0.54901963
|
||||
timelineCount: 2
|
||||
timeline0: 0.0
|
||||
timeline1: 1.0
|
||||
- Velocity -
|
||||
active: true
|
||||
lowMin: 100.0
|
||||
lowMax: 300.0
|
||||
highMin: 500.0
|
||||
highMax: 900.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 0.7647059
|
||||
scaling2: 0.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.69863015
|
||||
timeline2: 1.0
|
||||
- Angle -
|
||||
active: true
|
||||
lowMin: 90.0
|
||||
lowMax: 90.0
|
||||
highMin: 0.0
|
||||
highMax: 360.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.51369864
|
||||
timeline2: 1.0
|
||||
- Rotation -
|
||||
active: false
|
||||
- Wind -
|
||||
active: true
|
||||
lowMin: -50.0
|
||||
lowMax: 50.0
|
||||
highMin: -100.0
|
||||
highMax: 100.0
|
||||
relative: false
|
||||
scalingCount: 2
|
||||
scaling0: 0.0
|
||||
scaling1: 1.0
|
||||
timelineCount: 2
|
||||
timeline0: 0.0
|
||||
timeline1: 1.0
|
||||
- Gravity -
|
||||
active: false
|
||||
- Tint -
|
||||
colorsCount: 18
|
||||
colors0: 0.07058824
|
||||
colors1: 0.67058825
|
||||
colors2: 1.0
|
||||
colors3: 1.0
|
||||
colors4: 0.7176471
|
||||
colors5: 0.07058824
|
||||
colors6: 1.0
|
||||
colors7: 0.7411765
|
||||
colors8: 0.07058824
|
||||
colors9: 1.0
|
||||
colors10: 0.12156863
|
||||
colors11: 0.07058824
|
||||
colors12: 0.9647059
|
||||
colors13: 0.0
|
||||
colors14: 0.0
|
||||
colors15: 0.39607844
|
||||
colors16: 0.047058824
|
||||
colors17: 0.02745098
|
||||
timelineCount: 6
|
||||
timeline0: 0.0
|
||||
timeline1: 0.024096385
|
||||
timeline2: 0.09638554
|
||||
timeline3: 0.59380376
|
||||
timeline4: 0.9328744
|
||||
timeline5: 1.0
|
||||
- Transparency -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 1.0
|
||||
highMax: 1.0
|
||||
relative: false
|
||||
scalingCount: 5
|
||||
scaling0: 0.10526316
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
scaling3: 0.14035088
|
||||
scaling4: 0.0
|
||||
timelineCount: 5
|
||||
timeline0: 0.0
|
||||
timeline1: 0.2
|
||||
timeline2: 0.5273973
|
||||
timeline3: 0.74657536
|
||||
timeline4: 1.0
|
||||
- Options -
|
||||
attached: false
|
||||
continuous: false
|
||||
aligned: false
|
||||
additive: true
|
||||
behind: false
|
||||
premultipliedAlpha: false
|
||||
- Image Path -
|
||||
particle.png
|
149
app/src/main/assets/particleEffects/magnet.pe
Normal file
149
app/src/main/assets/particleEffects/magnet.pe
Normal file
@ -0,0 +1,149 @@
|
||||
Untitled
|
||||
- Delay -
|
||||
active: false
|
||||
- Duration -
|
||||
lowMin: 1000.0
|
||||
lowMax: 1000.0
|
||||
- Count -
|
||||
min: 0
|
||||
max: 500
|
||||
- Emission -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 10.0
|
||||
highMax: 10.0
|
||||
relative: false
|
||||
scalingCount: 1
|
||||
scaling0: 1.0
|
||||
timelineCount: 1
|
||||
timeline0: 0.0
|
||||
- Life -
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 1300.0
|
||||
highMax: 1600.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
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: 15.0
|
||||
lowMax: 15.0
|
||||
highMin: 30.0
|
||||
highMax: 35.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 0.0
|
||||
scaling1: 0.0
|
||||
scaling2: 1.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.37671232
|
||||
timeline2: 1.0
|
||||
- Velocity -
|
||||
active: true
|
||||
lowMin: 100.0
|
||||
lowMax: 150.0
|
||||
highMin: 370.0
|
||||
highMax: 400.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 0.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.08628652
|
||||
timeline2: 0.087286524
|
||||
- Angle -
|
||||
active: true
|
||||
lowMin: 0.0
|
||||
lowMax: 0.0
|
||||
highMin: 0.0
|
||||
highMax: 360.0
|
||||
relative: false
|
||||
scalingCount: 3
|
||||
scaling0: 1.0
|
||||
scaling1: 1.0
|
||||
scaling2: 1.0
|
||||
timelineCount: 3
|
||||
timeline0: 0.0
|
||||
timeline1: 0.7191781
|
||||
timeline2: 1.0
|
||||
- Rotation -
|
||||
active: false
|
||||
- Wind -
|
||||
active: false
|
||||
- Gravity -
|
||||
active: false
|
||||
- Tint -
|
||||
colorsCount: 6
|
||||
colors0: 1.0
|
||||
colors1: 1.0
|
||||
colors2: 0.047058824
|
||||
colors3: 1.0
|
||||
colors4: 0.89411765
|
||||
colors5: 0.047058824
|
||||
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: 0.0
|
||||
scaling2: 1.0
|
||||
scaling3: 1.0
|
||||
scaling4: 0.0
|
||||
timelineCount: 5
|
||||
timeline0: 0.0
|
||||
timeline1: 0.10344828
|
||||
timeline2: 0.3659004
|
||||
timeline3: 0.8082192
|
||||
timeline4: 1.0
|
||||
- Options -
|
||||
attached: false
|
||||
continuous: true
|
||||
aligned: false
|
||||
additive: true
|
||||
behind: false
|
||||
premultipliedAlpha: false
|
||||
- Image Path -
|
||||
particle.png
|
BIN
app/src/main/assets/particleEffects/particle.png
Normal file
BIN
app/src/main/assets/particleEffects/particle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/assets/particleEffects/star.png
Normal file
BIN
app/src/main/assets/particleEffects/star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
29
app/src/main/assets/shader/entityFragmentShader.glsl
Normal file
29
app/src/main/assets/shader/entityFragmentShader.glsl
Normal file
@ -0,0 +1,29 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform float alpha;
|
||||
uniform vec2 texAtlasSize;
|
||||
uniform float texAtlasIndex;
|
||||
|
||||
varying vec2 pass_TexCoords;
|
||||
|
||||
vec2 getTexCoordsInAtlas(in float atlasIndex);
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texAtlasCoords = getTexCoordsInAtlas(texAtlasIndex);
|
||||
gl_FragColor = texture2D(texture, texAtlasCoords);
|
||||
gl_FragColor.a = min(gl_FragColor.a, alpha);
|
||||
|
||||
}
|
||||
|
||||
vec2 getTexCoordsInAtlas(in float atlasIndex){
|
||||
|
||||
vec2 texAtlasCoords = vec2(0.0, 0.0);
|
||||
texAtlasCoords.x = mod(pass_TexCoords.x, 1.0) / texAtlasSize.x;
|
||||
texAtlasCoords.x += mod(atlasIndex, texAtlasSize.x) / texAtlasSize.x;
|
||||
texAtlasCoords.y = mod(pass_TexCoords.y, 1.0) / texAtlasSize.y;
|
||||
texAtlasCoords.y += floor(atlasIndex / texAtlasSize.y) / texAtlasSize.y;
|
||||
return texAtlasCoords;
|
||||
|
||||
}
|
15
app/src/main/assets/shader/entityVertexShader.glsl
Normal file
15
app/src/main/assets/shader/entityVertexShader.glsl
Normal file
@ -0,0 +1,15 @@
|
||||
uniform mat4 mvpMatrix;
|
||||
uniform mat4 transformationMatrix;
|
||||
|
||||
attribute vec4 position;
|
||||
attribute vec2 texCoords;
|
||||
|
||||
varying vec2 pass_TexCoords;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 transformatedPosition = transformationMatrix * position;
|
||||
gl_Position = mvpMatrix * transformatedPosition;
|
||||
pass_TexCoords = texCoords;
|
||||
|
||||
}
|
13
app/src/main/assets/shader/particleFragmentShader.glsl
Normal file
13
app/src/main/assets/shader/particleFragmentShader.glsl
Normal file
@ -0,0 +1,13 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform vec3 color;
|
||||
|
||||
varying vec2 pass_TexCoords;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragColor.a = texture2D(texture, pass_TexCoords).a;
|
||||
gl_FragColor.rgb = color;
|
||||
|
||||
}
|
11
app/src/main/assets/shader/simpleFragmentShader.glsl
Normal file
11
app/src/main/assets/shader/simpleFragmentShader.glsl
Normal file
@ -0,0 +1,11 @@
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
varying vec2 pass_TexCoords;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragColor = texture2D(texture, pass_TexCoords);
|
||||
|
||||
}
|
12
app/src/main/assets/shader/simpleVertexShader.glsl
Normal file
12
app/src/main/assets/shader/simpleVertexShader.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
attribute vec4 position;
|
||||
attribute vec2 texCoords;
|
||||
|
||||
varying vec2 pass_TexCoords;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_Position = position;
|
||||
pass_TexCoords.x = texCoords.x;
|
||||
pass_TexCoords.y = -texCoords.y;
|
||||
|
||||
}
|
18
app/src/main/assets/shader/terrainVertexShader.glsl
Normal file
18
app/src/main/assets/shader/terrainVertexShader.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
uniform mat4 mvpMatrix;
|
||||
uniform mat4 transformationMatrix;
|
||||
|
||||
attribute vec4 position;
|
||||
attribute vec2 texCoords;
|
||||
|
||||
varying vec2 pass_TexCoords;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 transformatedPosition = transformationMatrix * position;
|
||||
gl_Position = mvpMatrix * transformatedPosition;
|
||||
|
||||
pass_TexCoords = (transformationMatrix * vec4(texCoords, 0.0, 0.0)).xy;
|
||||
pass_TexCoords *= vec2(3.0, 3.0);
|
||||
pass_TexCoords.y = clamp(pass_TexCoords.y, 0.0, 1.0) + 0.01;
|
||||
|
||||
}
|
33
app/src/main/assets/testlevelpack.xml
Normal file
33
app/src/main/assets/testlevelpack.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<levelPack name="Testpack">
|
||||
<levels>
|
||||
<level goalX="110" number="1">
|
||||
<terrain endX="100" height="1.0">
|
||||
<gaps></gaps>
|
||||
</terrain>
|
||||
<obstacles></obstacles>
|
||||
</level>
|
||||
<level goalX="110" number="2">
|
||||
<terrain endX="100" height="-0.6">
|
||||
<gaps></gaps>
|
||||
</terrain>
|
||||
<obstacles></obstacles>
|
||||
</level>
|
||||
<level goalX="110" number="3">
|
||||
<terrain endX="100" height="-0.6">
|
||||
<gaps>
|
||||
<gap leftEdge="10" rightEdge="11" />
|
||||
<gap leftEdge="20" rightEdge="21" />
|
||||
<gap leftEdge="30" rightEdge="31" />
|
||||
<gap leftEdge="40" rightEdge="41" />
|
||||
<gap leftEdge="50" rightEdge="51" />
|
||||
<gap leftEdge="60" rightEdge="61" />
|
||||
<gap leftEdge="70" rightEdge="71" />
|
||||
<gap leftEdge="80" rightEdge="81" />
|
||||
<gap leftEdge="90" rightEdge="91" />
|
||||
</gaps>
|
||||
</terrain>
|
||||
<obstacles></obstacles>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
BIN
app/src/main/ic_launcher-web.png
Normal file
BIN
app/src/main/ic_launcher-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
@ -0,0 +1,69 @@
|
||||
package com.example.julian.endlessroll.data;
|
||||
|
||||
/**
|
||||
* 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 mix(float leftValue, float rightValue, Color color2) {
|
||||
Color mySelf = new Color(this);
|
||||
Color second = new Color(color2);
|
||||
mySelf.mul(leftValue);
|
||||
second.mul(rightValue);
|
||||
mySelf.add(second);
|
||||
return mySelf;
|
||||
}
|
||||
|
||||
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,101 @@
|
||||
package com.example.julian.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,51 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.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 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,45 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.07.2016.
|
||||
*/
|
||||
public class Background extends ArrayList<Entity> {
|
||||
|
||||
private final float PART_WIDTH = 5;
|
||||
private final float HALF_PART_WIDTH = PART_WIDTH / 2;
|
||||
private Texture texture;
|
||||
|
||||
public Background(Texture texture) {
|
||||
this.texture = texture;
|
||||
super.add(createPart(-HALF_PART_WIDTH));
|
||||
}
|
||||
|
||||
private Entity createPart(float xLeftEdge) {
|
||||
return new Entity(texture, new Vector(xLeftEdge + HALF_PART_WIDTH, 0), PART_WIDTH, 2);
|
||||
}
|
||||
|
||||
public void move(float x, float cameraX) {
|
||||
Vector movement = new Vector(x, 0);
|
||||
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,37 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleEffect;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSource;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
|
||||
/**
|
||||
* Created by Julian on 11.03.2016.
|
||||
*/
|
||||
public enum DestroyEffect {
|
||||
|
||||
EXPLOSION, STAR_EXPLOSION, 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;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Quad;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.11.2015.
|
||||
*/
|
||||
public class Entity extends Quad {
|
||||
|
||||
private Texture texture;
|
||||
private Vector movement;
|
||||
private float rotation;
|
||||
private float alpha = 1.0f;
|
||||
private boolean destroyed;
|
||||
private DestroyEffect destroyEffect;
|
||||
|
||||
public Entity(Texture texture, Vector position, float width, float height) {
|
||||
super(position, width, height);
|
||||
this.texture = texture;
|
||||
this.movement = new Vector();
|
||||
}
|
||||
|
||||
public void move(Vector movement) {
|
||||
position.translate(movement);
|
||||
}
|
||||
|
||||
public void rotate(float factor) {
|
||||
rotation += factor;
|
||||
}
|
||||
|
||||
public void setToTerrain(float terrainHeight) {
|
||||
position.y = terrainHeight + 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
|
||||
public class Goal extends Entity {
|
||||
|
||||
public Goal(Texture texture) {
|
||||
super(texture, new Vector(), 0.1f, 2);
|
||||
}
|
||||
|
||||
public void setGoalX(float goalX) {
|
||||
super.setPosition(new Vector(goalX - 0.05f, 0));
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
import com.example.julian.endlessroll.levels.ObstacleData;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.11.2015.
|
||||
*/
|
||||
public class Obstacle extends Entity {
|
||||
|
||||
public Obstacle(Texture texture, ObstacleData data, float terrainHeight) {
|
||||
super(texture, new Vector(data.getX(), data.getY()), data.getWidth(), data.getHeight());
|
||||
if (data.isAttachedToGround())
|
||||
super.setToTerrain(terrainHeight);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
|
||||
/**
|
||||
* 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 float speed = 0.001f;
|
||||
|
||||
public Player(Texture texture) {
|
||||
super(texture, new Vector(), 0, 0);
|
||||
super.setWidth(RADIUS * 2);
|
||||
super.setHeight(RADIUS * 2);
|
||||
}
|
||||
|
||||
public void init(float terrainHeight) {
|
||||
super.setToTerrain(terrainHeight);
|
||||
super.getPosition().x = START_X;
|
||||
super.setMovement(new Vector(speed, 0));
|
||||
}
|
||||
|
||||
public void setSpeed(float speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
return getPosition().x - START_X;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(Vector movement) {
|
||||
super.move(movement);
|
||||
rotate(movement.x * ROTATION_SPEED);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
import com.example.julian.endlessroll.levels.StarData;
|
||||
|
||||
public class Star extends Entity {
|
||||
|
||||
private int index;
|
||||
|
||||
public Star(Texture texture, StarData starData) {
|
||||
super(texture, new Vector(starData.getX(), starData.getY()), starData.getWidth(), starData.getHeight());
|
||||
this.index = starData.getIndex();
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
import com.example.julian.endlessroll.levels.Gap;
|
||||
import com.example.julian.endlessroll.levels.TerrainData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 08.12.2015.
|
||||
*/
|
||||
public class Terrain extends ArrayList<TerrainTile> {
|
||||
|
||||
private Texture texture;
|
||||
private float height;
|
||||
private boolean endless;
|
||||
|
||||
public Terrain(Texture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
private void create(float endX, float height, List<Gap> gaps) {
|
||||
this.height = height;
|
||||
float y = calculateYPositionFromHeight();
|
||||
float h = 1 + height;
|
||||
float lastGapRightEdge = -3;
|
||||
for (int i = 0; i < gaps.size() + 1; i++) {
|
||||
float nextGapLeftEdge;
|
||||
if (i == gaps.size())
|
||||
nextGapLeftEdge = endX;
|
||||
else
|
||||
nextGapLeftEdge = gaps.get(i).getLeftEdge();
|
||||
float width = nextGapLeftEdge - lastGapRightEdge;
|
||||
float x = lastGapRightEdge + width / 2;
|
||||
TerrainTile entity = new TerrainTile(texture, new Vector(x, y), width, h);
|
||||
super.add(entity);
|
||||
if (i != gaps.size())
|
||||
lastGapRightEdge = gaps.get(i).getRightEdge();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadData(TerrainData data) {
|
||||
super.clear();
|
||||
this.endless = false;
|
||||
create(data.getEndX(), data.getHeight(), data.getGaps());
|
||||
}
|
||||
|
||||
public void createEndless(float height) {
|
||||
super.clear();
|
||||
this.endless = true;
|
||||
this.height = height;
|
||||
super.add(new TerrainTile(texture, new Vector(0, calculateYPositionFromHeight()), 5, 1 + height));
|
||||
}
|
||||
|
||||
public void update(float cameraX) {
|
||||
if (!super.isEmpty()) {
|
||||
if (super.get(0).getRightEdge() - cameraX < -3) {
|
||||
super.remove(0);
|
||||
}
|
||||
if (endless) {
|
||||
Entity last = super.get(super.size() - 1);
|
||||
if (last.getRightEdge() - cameraX < 3)
|
||||
super.add(new TerrainTile(texture, new Vector(last.getRightEdge() + 2.5f, calculateYPositionFromHeight()), 5, 1 + height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float calculateYPositionFromHeight() {
|
||||
return height - (1 + height) / 2;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.example.julian.endlessroll.entities;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
|
||||
/**
|
||||
* Created by Julian on 18.12.2015.
|
||||
*/
|
||||
|
||||
public class TerrainTile extends Entity {
|
||||
|
||||
public TerrainTile(Texture texture, Vector position, float width, float height) {
|
||||
super(texture, position, width, height);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.example.julian.endlessroll.entities.collision;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Circle;
|
||||
import com.example.julian.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,126 @@
|
||||
package com.example.julian.endlessroll.entities.collision;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.EntityCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Circle;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Geometry;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Quad;
|
||||
import com.example.julian.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 quadQuadCollision(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 EntityCollisionData playerEntityCollision(Player player, Entity entity) {
|
||||
Circle circle = new Circle(player);
|
||||
Quad quad = entity;
|
||||
if (circleQuadCollision(circle, quad)) {
|
||||
Edge edge = circleQuadCollisionEdge(circle, player.getMovement(), quad, entity.getMovement());
|
||||
return new EntityCollisionData(entity, edge);
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
public boolean circleToolCollision(Circle circle, Geometry bounds) {
|
||||
if (bounds instanceof Circle)
|
||||
return circleCircleCollision(circle, (Circle) bounds);
|
||||
else if (bounds instanceof Quad)
|
||||
return circleQuadCollision(circle, (Quad) bounds);
|
||||
else if (bounds instanceof Triangle)
|
||||
return triangleDetector.circleTriangleCollision(circle, (Triangle) bounds);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean circleCircleCollision(Circle c1, Circle c2) {
|
||||
float distance = Math.abs(c1.getCenter().vectorTo(c2.getCenter()).length());
|
||||
float radiusSum = c1.getRadius() + c2.getRadius();
|
||||
return distance < radiusSum;
|
||||
}
|
||||
|
||||
private boolean circleQuadCollision(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();
|
||||
}
|
||||
|
||||
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,76 @@
|
||||
package com.example.julian.endlessroll.entities.collision;
|
||||
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.Star;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.EntityCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.ObstacleCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.PlayerCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.ToolCollisionData;
|
||||
import com.example.julian.endlessroll.entities.tools.Tool;
|
||||
import com.example.julian.endlessroll.main.game.Game;
|
||||
import com.example.julian.endlessroll.main.game.GameScene;
|
||||
import com.example.julian.endlessroll.main.game.Physics;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.01.2016.
|
||||
*/
|
||||
public class CollisionManager {
|
||||
|
||||
private Game game;
|
||||
private Player player;
|
||||
|
||||
public CollisionManager(Game game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
//Check Obstacle always before tool
|
||||
public void update(Physics physics, GameScene scene) {
|
||||
this.player = scene.getPlayer();
|
||||
PlayerCollisionData data = physics.getPlayerCollisionData(scene);
|
||||
if (data.isTerrainCollision())
|
||||
checkTerrainCollision(data.getTerrainCollisionData());
|
||||
if (data.isObstacleCollision())
|
||||
checkObstacleCollision(data.getObstacleCollisionData());
|
||||
if (data.isToolCollision())
|
||||
checkToolCollision(data.getToolCollisionData());
|
||||
if (data.isStarCollision())
|
||||
game.onStarCollision((Star) data.getStarCollisionData().getEntity());
|
||||
}
|
||||
|
||||
private void checkTerrainCollision(EntityCollisionData data) {
|
||||
checkEntityCollision(data, -0.01f);
|
||||
if (data.getEdge() != Edge.TOP)
|
||||
game.onGameOver(true);
|
||||
}
|
||||
|
||||
private void checkToolCollision(ToolCollisionData data) {
|
||||
for (Tool tool : data.getTools())
|
||||
tool.onPlayerCollision(player);
|
||||
}
|
||||
|
||||
private void checkObstacleCollision(ObstacleCollisionData data) {
|
||||
for (EntityCollisionData entityData : data.getCollisions()) {
|
||||
checkEntityCollision(entityData, 0);
|
||||
if (entityData.getEdge() != Edge.TOP)
|
||||
game.onGameOver(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEntityCollision(EntityCollisionData data, float xBounceFactor) {
|
||||
switch (data.getEdge()) {
|
||||
case TOP:
|
||||
player.getMovement().y = 0;
|
||||
player.setToTerrain(data.getEntity().getTopEdge());
|
||||
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 com.example.julian.endlessroll.entities.collision;
|
||||
|
||||
public enum Edge {
|
||||
LEFT, RIGHT, TOP, BOTTOM, NONE;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.example.julian.endlessroll.entities.collision.collisionData;
|
||||
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.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 com.example.julian.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,51 @@
|
||||
package com.example.julian.endlessroll.entities.collision.collisionData;
|
||||
|
||||
/**
|
||||
* Created by Julian on 05.12.2015.
|
||||
*/
|
||||
public class PlayerCollisionData {
|
||||
|
||||
private EntityCollisionData terrainCollision;
|
||||
private ObstacleCollisionData obstacleCollision;
|
||||
private ToolCollisionData toolCollision;
|
||||
private EntityCollisionData starCollision;
|
||||
|
||||
public PlayerCollisionData(EntityCollisionData terrainCollision, ObstacleCollisionData obstacleCollision, ToolCollisionData toolCollision, EntityCollisionData starCollision) {
|
||||
this.terrainCollision = terrainCollision;
|
||||
this.obstacleCollision = obstacleCollision;
|
||||
this.toolCollision = toolCollision;
|
||||
this.starCollision = starCollision;
|
||||
}
|
||||
|
||||
public boolean isTerrainCollision() {
|
||||
return terrainCollision.isCollision();
|
||||
}
|
||||
|
||||
public EntityCollisionData getTerrainCollisionData() {
|
||||
return terrainCollision;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.example.julian.endlessroll.entities.collision.collisionData;
|
||||
|
||||
import com.example.julian.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,38 @@
|
||||
package com.example.julian.endlessroll.entities.collision.geometry;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
|
||||
/**
|
||||
* 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 void setCenter(Vector center) {
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
public float getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public void setRadius(float radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.example.julian.endlessroll.entities.collision.geometry;
|
||||
|
||||
/**
|
||||
* Created by Julian on 28.02.2016.
|
||||
*/
|
||||
public interface Geometry {
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.example.julian.endlessroll.entities.collision.geometry;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.collision.Edge;
|
||||
|
||||
/**
|
||||
* 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 float getEdge(Edge edge) {
|
||||
switch (edge) {
|
||||
case LEFT:
|
||||
return getLeftEdge();
|
||||
case RIGHT:
|
||||
return getRightEdge();
|
||||
case TOP:
|
||||
return getTopEdge();
|
||||
case BOTTOM:
|
||||
return getBottomEdge();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.example.julian.endlessroll.entities.collision.geometry;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.tools.Ramp;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
*/
|
||||
public class Triangle implements Geometry {
|
||||
|
||||
private Vector vertex1, vertex2, 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());
|
||||
setVertex1(vertex1);
|
||||
setVertex2(vertex2);
|
||||
setVertex3(vertex3);
|
||||
}
|
||||
|
||||
public Triangle(Vector vertex1, Vector vertex2, Vector vertex3) {
|
||||
this.vertex1 = vertex1;
|
||||
this.vertex2 = vertex2;
|
||||
this.vertex3 = vertex3;
|
||||
}
|
||||
|
||||
public Vector getVertex1() {
|
||||
return vertex1;
|
||||
}
|
||||
|
||||
public void setVertex1(Vector vertex1) {
|
||||
this.vertex1 = vertex1;
|
||||
}
|
||||
|
||||
public Vector getVertex2() {
|
||||
return vertex2;
|
||||
}
|
||||
|
||||
public void setVertex2(Vector vertex2) {
|
||||
this.vertex2 = vertex2;
|
||||
}
|
||||
|
||||
public Vector getVertex3() {
|
||||
return vertex3;
|
||||
}
|
||||
|
||||
public void setVertex3(Vector vertex3) {
|
||||
this.vertex3 = vertex3;
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package com.example.julian.endlessroll.entities.particles;
|
||||
|
||||
import com.example.julian.endlessroll.data.Color;
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
import com.example.julian.endlessroll.main.game.Timer;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public void update(Timer timer, float windStrength, float gravityStrength) {
|
||||
if (active) {
|
||||
passedLifetime += timer.getFrameTime();
|
||||
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)), windStrength, gravityStrength);
|
||||
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,58 @@
|
||||
package com.example.julian.endlessroll.entities.particles;
|
||||
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
|
||||
import com.example.julian.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;
|
||||
|
||||
public ParticleData(Range life, TimelineRange scaleTR, TimelineRange velocityTR, TimelineRange angleTR, TimelineRange rotationTR, Timeline transparencyT, TintTimeline tint) {
|
||||
this.life = life;
|
||||
this.scaleTR = scaleTR;
|
||||
this.velocityTR = velocityTR;
|
||||
this.angleTR = angleTR;
|
||||
this.rotationTR = rotationTR;
|
||||
this.transparencyT = transparencyT;
|
||||
this.tint = tint;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,224 @@
|
||||
package com.example.julian.endlessroll.entities.particles;
|
||||
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Options;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
import com.example.julian.endlessroll.main.game.Timer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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;
|
||||
|
||||
//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 TimelineRange wind;
|
||||
private TimelineRange gravity;
|
||||
|
||||
private Options options;
|
||||
private Texture texture;
|
||||
private String textureName;
|
||||
|
||||
private Random random;
|
||||
private List<ParticleSource> sources = new ArrayList<>();
|
||||
|
||||
public ParticleEffect() {
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
for (ParticleSource source : sources)
|
||||
source.update(timer);
|
||||
}
|
||||
|
||||
public ParticleData createParticleData() {
|
||||
return new ParticleData(life.getRange(), scale, velocity, angle, rotation, transparency, tint);
|
||||
}
|
||||
|
||||
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 List<ParticleSource> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
public TimelineRange getLife() {
|
||||
return life;
|
||||
}
|
||||
|
||||
public SpawnShape.Shape getSpawnShape() {
|
||||
return spawnShape;
|
||||
}
|
||||
|
||||
public TimelineRange getSpawnHeight() {
|
||||
return spawnHeight;
|
||||
}
|
||||
|
||||
public void deleteSources() {
|
||||
for(ParticleSource source : sources)
|
||||
source.kill();
|
||||
sources.clear();
|
||||
}
|
||||
|
||||
public TimelineRange getSpawnWidth() {
|
||||
return spawnWidth;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,163 @@
|
||||
package com.example.julian.endlessroll.entities.particles;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.Attribute;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.AttributeValueReader;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.ParticleAttributeType;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.ImagePath;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Options;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
|
||||
import com.example.julian.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,163 @@
|
||||
package com.example.julian.endlessroll.entities.particles;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import com.example.julian.endlessroll.main.game.Timer;
|
||||
import com.example.julian.endlessroll.rendering.Lock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class ParticleSource {
|
||||
|
||||
private Vector position;
|
||||
private ParticleEffect effect;
|
||||
private Random random;
|
||||
|
||||
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 float windStrength;
|
||||
private float gravityStrength;
|
||||
|
||||
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;
|
||||
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.getFrameTime();
|
||||
lifePercent = passedTime / maxTime;
|
||||
|
||||
if (passedTime >= currentDelay) {
|
||||
passedEmittPause += timer.getFrameTime();
|
||||
calcWindAndGravity();
|
||||
while (passedEmittPause >= emittPause) {
|
||||
passedEmittPause -= emittPause;
|
||||
emitt();
|
||||
}
|
||||
|
||||
passedSecond += timer.getFrameTime();
|
||||
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, windStrength, gravityStrength);
|
||||
if (!particle.isActive()) {
|
||||
inactiveParticles.add(particle);
|
||||
iter.remove();
|
||||
} else {
|
||||
particle.move(new Vector(particle.getMovement()).mul(timer.getFrameTime() / 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) {
|
||||
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 void calcWindAndGravity() {
|
||||
windStrength = effect.getWind().getRange().createValue(random, effect.getWind().getTimeline().getValueAtTime(lifePercent));
|
||||
gravityStrength = effect.getGravity().getRange().createValue(random, effect.getGravity().getTimeline().getValueAtTime(lifePercent));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.example.julian.endlessroll.entities.particles;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.entities.textures.TextureLoader;
|
||||
import com.example.julian.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 explosion;
|
||||
public final ParticleEffect magnet;
|
||||
public final ParticleEffect starCollect;
|
||||
private ParticleEffect[] effects;
|
||||
|
||||
private TextureLoader textureLoader;
|
||||
|
||||
public ParticleSystem(Context context) throws Exception {
|
||||
this.textureLoader = new TextureLoader(context);
|
||||
ParticleReader reader = new ParticleReader(context);
|
||||
explosion = reader.read("particleEffects/explosion.pe");
|
||||
magnet = reader.read("particleEffects/magnet.pe");
|
||||
starCollect = reader.read("particleEffects/collectStar.pe");
|
||||
|
||||
effects = new ParticleEffect[]{explosion, magnet, starCollect};
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
for (ParticleEffect effect : effects)
|
||||
effect.update(timer);
|
||||
}
|
||||
|
||||
public void loadTextures() throws Exception {
|
||||
for (ParticleEffect effect : effects)
|
||||
effect.setTexture(textureLoader.loadTexture("particleEffects/"+effect.getTextureName()));
|
||||
}
|
||||
|
||||
public void deleteAllSources(){
|
||||
for(ParticleEffect effect : effects){
|
||||
effect.deleteSources();
|
||||
}
|
||||
}
|
||||
|
||||
public ParticleEffect[] getEffects() {
|
||||
return effects;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.example.julian.endlessroll.entities.particles.attributes;
|
||||
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValue;
|
||||
import com.example.julian.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 com.example.julian.endlessroll.entities.particles.attributes;
|
||||
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.ImagePath;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Options;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Range;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
|
||||
import com.example.julian.endlessroll.entities.particles.attributes.attributeValues.Timeline;
|
||||
import com.example.julian.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 com.example.julian.endlessroll.entities.particles.attributes;
|
||||
|
||||
import com.example.julian.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 com.example.julian.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 com.example.julian.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 com.example.julian.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 com.example.julian.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 com.example.julian.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 com.example.julian.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.08.2016.
|
||||
*/
|
||||
public class SpawnShape extends ParticleAttributeValue {
|
||||
|
||||
public enum Shape {
|
||||
POINT("point"), SQUARE("square");
|
||||
|
||||
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("Shape 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,52 @@
|
||||
package com.example.julian.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 = 1 - Math.abs(left.getTime() - time);
|
||||
float rightDist = 1 - Math.abs(right.getTime() - time);
|
||||
float totalDist = leftDist + rightDist;
|
||||
return left.getValue() * (leftDist / totalDist) + right.getValue() * (rightDist / totalDist);
|
||||
}
|
||||
return left.getValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.example.julian.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 com.example.julian.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,57 @@
|
||||
package com.example.julian.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
import com.example.julian.endlessroll.data.Color;
|
||||
import com.example.julian.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) {
|
||||
GameLog.i("Set value: index="+index+"; colorIndex="+colorIndex+"; value="+value);
|
||||
if (points.size() <= index) {
|
||||
points.add(new TintTimelinePoint());
|
||||
}
|
||||
points.get(index).setValue(colorIndex, value);
|
||||
}
|
||||
|
||||
public void setTimeOfPoint(int index, float time) {
|
||||
GameLog.i("Set time: index="+index+"; time="+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 = 1 - Math.abs(left.getTime() - time);
|
||||
float rightDist = 1 - Math.abs(right.getTime() - time);
|
||||
float totalDist = leftDist + rightDist;
|
||||
return left.getColor().mix((leftDist / totalDist), (rightDist / totalDist), right.getColor());
|
||||
}
|
||||
return left.getColor();
|
||||
}
|
||||
return new Color();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.example.julian.endlessroll.entities.particles.attributes.attributeValues;
|
||||
|
||||
import com.example.julian.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,44 @@
|
||||
package com.example.julian.endlessroll.entities.textures;
|
||||
|
||||
/**
|
||||
* Created by Julian on 11.12.2015.
|
||||
*/
|
||||
public class Texture {
|
||||
|
||||
private int id;
|
||||
private int atlasWidth;
|
||||
private int atlasHeight;
|
||||
private int atlasIndex;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public int getAtlasIndex() {
|
||||
return atlasIndex;
|
||||
}
|
||||
|
||||
public void setAtlasIndex(int atlasIndex) {
|
||||
this.atlasIndex = atlasIndex;
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.example.julian.endlessroll.entities.textures;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
|
||||
import com.example.julian.endlessroll.main.GameLog;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (!isAtlas) {
|
||||
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_LINEAR);
|
||||
} else {
|
||||
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_LINEAR);
|
||||
}
|
||||
|
||||
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,53 @@
|
||||
package com.example.julian.endlessroll.entities.textures;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.R;
|
||||
import com.example.julian.endlessroll.entities.tools.ToolType;
|
||||
|
||||
/**
|
||||
* Created by Julian on 05.12.2015.
|
||||
*/
|
||||
public class TexturePack {
|
||||
|
||||
private TextureLoader loader;
|
||||
|
||||
public final Texture background;
|
||||
public final Texture goal;
|
||||
public final Texture terrain;
|
||||
public final Texture playerArrow;
|
||||
public final Texture player;
|
||||
public final Texture obstacle;
|
||||
public final Texture star;
|
||||
public final Texture blueParticle;
|
||||
public final Texture yellowParticle;
|
||||
public final Texture redParticle;
|
||||
|
||||
public TexturePack(Context context) {
|
||||
loader = new TextureLoader(context);
|
||||
background = loadTexture(R.drawable.background);
|
||||
goal = loadTexture(R.drawable.goal);
|
||||
terrain = loadAtlas(R.drawable.terrain, 1, 1);
|
||||
player = loadTexture(R.drawable.ball);
|
||||
playerArrow = loadTexture(R.drawable.playerarrow);
|
||||
|
||||
obstacle = loadTexture(R.drawable.obstacle);
|
||||
star = loadTexture(R.drawable.star);
|
||||
|
||||
blueParticle = loadTexture(R.drawable.blueparticle);
|
||||
yellowParticle = loadTexture(R.drawable.yellowparticle);
|
||||
redParticle = loadTexture(R.drawable.redparticle);
|
||||
|
||||
ToolType.loadAllToolTextures(this);
|
||||
}
|
||||
|
||||
private Texture loadTexture(int id) {
|
||||
int texId = loader.loadTextureId(id, false);
|
||||
return new Texture(texId, 1, 1);
|
||||
}
|
||||
|
||||
public Texture loadAtlas(int id, int atlasWidth, int atlasHeight) {
|
||||
int texId = loader.loadTextureId(id, true);
|
||||
return new Texture(texId, atlasWidth, atlasHeight);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.DestroyEffect;
|
||||
import com.example.julian.endlessroll.entities.Obstacle;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.collision.CollisionDetector;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Geometry;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Quad;
|
||||
import com.example.julian.endlessroll.main.game.Timer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 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(300);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Timer timer) {
|
||||
super.update(timer);
|
||||
delta += timer.getFrameTime();
|
||||
if (delta >= 1000)
|
||||
exploding = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createCollisionBounds() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isExploding() {
|
||||
return exploding;
|
||||
}
|
||||
|
||||
public void explode(List<Obstacle> obstacles, CollisionDetector detector) {
|
||||
Quad explotionRange = new Quad(new Vector(super.getPosition()), RANGE, RANGE);
|
||||
for (Obstacle obstacle : obstacles) {
|
||||
if (detector.quadQuadCollision(obstacle, explotionRange))
|
||||
obstacle.destroy(DestroyEffect.EXPLOSION);
|
||||
}
|
||||
super.destroy(DestroyEffect.EXPLOSION);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.DestroyEffect;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Circle;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Geometry;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSource;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
import com.example.julian.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 update(Timer timer) {
|
||||
super.update(timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(DestroyEffect destroyEffect) {
|
||||
super.destroy(destroyEffect);
|
||||
particleSource.kill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player) {
|
||||
float fromPlayerDistance = player.getPosition().vectorTo(super.getPosition()).length();
|
||||
float fromPlayerYDistance = super.getPosition().y - player.getPosition().y;
|
||||
float t = Math.min(2f, 1 / fromPlayerDistance);
|
||||
float influenz = .00004f * t * t;
|
||||
if (fromPlayerYDistance < 0) {
|
||||
player.getMovement().y -= influenz;
|
||||
} else if (fromPlayerYDistance > 0) {
|
||||
player.getMovement().y += influenz;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createCollisionBounds() {
|
||||
return new Circle(super.getPosition(), 2);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Geometry;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Triangle;
|
||||
import com.example.julian.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, .4f, 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 update(Timer timer) {
|
||||
super.update(timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCollision(Player player) {
|
||||
float necessaryY = calcNecessaryPlayerY(player);
|
||||
if (necessaryY - player.RADIUS >= super.getBottomEdge() && necessaryY + player.RADIUS <= super.getTopEdge())
|
||||
player.getPosition().y = necessaryY;
|
||||
float acceleration = player.getMovement().x * getGradient();
|
||||
player.getMovement().y = 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 createCollisionBounds() {
|
||||
return new Triangle(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Geometry;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Quad;
|
||||
import com.example.julian.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) {
|
||||
if (!hasYetCollided) {
|
||||
hasYetCollided = true;
|
||||
player.getMovement().y = .0024f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Geometry createCollisionBounds() {
|
||||
return new Quad(super.getPosition(), .2f, .2f);
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Animation;
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Geometry;
|
||||
import com.example.julian.endlessroll.main.game.Timer;
|
||||
|
||||
/**
|
||||
* Created by Julian on 04.01.2016.
|
||||
*/
|
||||
public abstract class Tool extends Entity {
|
||||
|
||||
private boolean placedByRightEdge;
|
||||
private boolean updateBounds;
|
||||
private Geometry collisionBounds;
|
||||
protected Animation animation;
|
||||
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;
|
||||
animation = new Animation();
|
||||
collisionBounds = createCollisionBounds();
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
animation.update(timer);
|
||||
super.getTexture().setAtlasIndex(animation.getCurrentTexIndex());
|
||||
}
|
||||
|
||||
public abstract void onPlayerCollision(Player player);
|
||||
|
||||
protected abstract Geometry createCollisionBounds();
|
||||
|
||||
public Geometry getCollisionBounds() {
|
||||
if (updateBounds)
|
||||
return createCollisionBounds();
|
||||
return collisionBounds;
|
||||
}
|
||||
|
||||
public void setFloating(boolean floating) {
|
||||
this.floating = floating;
|
||||
}
|
||||
|
||||
public boolean isFloating() {
|
||||
return floating;
|
||||
}
|
||||
|
||||
public boolean isPlacedByRightEdge() {
|
||||
return placedByRightEdge;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.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.lockedbutton;
|
||||
else
|
||||
return toolType.getButtonDrawable();
|
||||
}
|
||||
|
||||
public void setToolType(ToolType toolType) {
|
||||
this.toolType = toolType;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import com.example.julian.endlessroll.levels.levelup.LevelUpBounties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 15.07.2016.
|
||||
*/
|
||||
public class ToolSlotSettings extends ArrayList<ToolSlot> {
|
||||
|
||||
public ToolSlotSettings() {
|
||||
this(new ToolSlot(ToolType.RAMP, false), new ToolSlot(ToolType.NONE, true), new ToolSlot(ToolType.NONE, true), new ToolSlot(ToolType.NONE, true));
|
||||
}
|
||||
|
||||
public ToolSlotSettings(ToolSlot slot1, ToolSlot slot2, ToolSlot slot3, ToolSlot slot4) {
|
||||
super(4);
|
||||
super.add(slot1);
|
||||
super.add(slot2);
|
||||
super.add(slot3);
|
||||
super.add(slot4);
|
||||
}
|
||||
|
||||
public ToolSlotSettings(List<ToolSlot> list) {
|
||||
super(list);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.set(0, new ToolSlot(ToolType.RAMP, false));
|
||||
super.set(1, new ToolSlot(ToolType.NONE, true));
|
||||
super.set(2, new ToolSlot(ToolType.NONE, true));
|
||||
super.set(3, new ToolSlot(ToolType.NONE, true));
|
||||
}
|
||||
|
||||
public void changeToolSlotType(int slot, ToolType newType) {
|
||||
for (ToolSlot toolSlot : this) {
|
||||
if (super.indexOf(toolSlot) == slot)
|
||||
toolSlot.setToolType(newType);
|
||||
else if (toolSlot.getToolType() == newType)
|
||||
toolSlot.setToolType(ToolType.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void unlockSlotsIfLevelReached(int level, LevelUpBounties levelUpBounties) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
super.get(i).setLocked(!levelUpBounties.isToolSlotUnlockedAtLevel(i, level));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
package com.example.julian.endlessroll.entities.tools;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.example.julian.endlessroll.R;
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
import com.example.julian.endlessroll.entities.textures.Texture;
|
||||
import com.example.julian.endlessroll.entities.textures.TexturePack;
|
||||
import com.example.julian.endlessroll.sounds.SoundManager;
|
||||
|
||||
public enum ToolType {
|
||||
|
||||
//Check newInstance when new Tool is added!
|
||||
RAMP("Ramp", R.drawable.ramp, R.drawable.rampbutton, R.raw.ramp, 3f, 0),
|
||||
SPRING("Spring", R.drawable.spring, R.drawable.springbutton, R.raw.ramp, 4f, 5),
|
||||
MAGNET("Magnet", R.drawable.magnet, R.drawable.magnetbutton, R.raw.ramp, 6f, 10),
|
||||
BOMB("Bomb", R.drawable.bomb, R.drawable.bombbutton, R.raw.ramp, 6f, 12),
|
||||
NONE("None", -1, R.drawable.emptybutton, -1, 0, 0);
|
||||
|
||||
private String name;
|
||||
private int toolTextureId;
|
||||
private Texture toolTexture = null;
|
||||
private int buttonDrawable;
|
||||
private int placingSoundId;
|
||||
private int placingSound = -1;
|
||||
private float regenerationTime;
|
||||
private int costs;
|
||||
private boolean bought = false;
|
||||
|
||||
ToolType(String name, int toolTextureId, int buttonDrawable, int placingSoundId, float regenerationTime, int costs) {
|
||||
this.name = name;
|
||||
this.toolTextureId = toolTextureId;
|
||||
this.buttonDrawable = buttonDrawable;
|
||||
this.placingSoundId = placingSoundId;
|
||||
this.regenerationTime = regenerationTime;
|
||||
this.costs = costs;
|
||||
}
|
||||
|
||||
@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 NONE:
|
||||
break;
|
||||
}
|
||||
if (tool != null && tool.isPlacedByRightEdge())
|
||||
tool.move(new Vector(-tool.getWidth() / 2, 0));
|
||||
return tool;
|
||||
}
|
||||
|
||||
public 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;
|
||||
toolTexture = texturePack.loadAtlas(toolTextureId, 2, 2);
|
||||
}
|
||||
|
||||
public Texture getToolTexture() {
|
||||
return toolTexture;
|
||||
}
|
||||
|
||||
public int getButtonDrawable() {
|
||||
return buttonDrawable;
|
||||
}
|
||||
|
||||
public int getPlacingSound() {
|
||||
return placingSound;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setBought(boolean bought) {
|
||||
this.bought = bought;
|
||||
}
|
||||
|
||||
public boolean isBought() {
|
||||
return bought;
|
||||
}
|
||||
|
||||
public int getCosts() {
|
||||
return costs;
|
||||
}
|
||||
|
||||
public float getRegenerationTime() {
|
||||
return regenerationTime;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.example.julian.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;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.example.julian.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 number;
|
||||
@Attribute
|
||||
private float goalX;
|
||||
@Element
|
||||
private TerrainData terrain;
|
||||
@ElementList
|
||||
private List<ObstacleData> obstacles;
|
||||
@ElementList
|
||||
private List<StarData> stars;
|
||||
|
||||
private boolean completed;
|
||||
private boolean unlocked;
|
||||
private boolean firstStarCollected;
|
||||
private boolean secondStarCollected;
|
||||
private boolean thirdStarCollected;
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public float getGoalX() {
|
||||
return goalX;
|
||||
}
|
||||
|
||||
public TerrainData getTerrain() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public List<ObstacleData> getObstacles() {
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
public List<StarData> getStars() {
|
||||
return stars;
|
||||
}
|
||||
|
||||
public boolean isUnlocked() {
|
||||
return unlocked;
|
||||
}
|
||||
|
||||
public void setUnlocked(boolean unlocked) {
|
||||
this.unlocked = unlocked;
|
||||
}
|
||||
|
||||
public boolean isCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setCompleted(boolean completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
|
||||
public boolean isFirstStarCollected() {
|
||||
return firstStarCollected;
|
||||
}
|
||||
|
||||
public boolean isSecondStarCollected() {
|
||||
return secondStarCollected;
|
||||
}
|
||||
|
||||
public boolean isThirdStarCollected() {
|
||||
return thirdStarCollected;
|
||||
}
|
||||
|
||||
public void setStarCollected(int index, boolean collected){
|
||||
if(index == 1)
|
||||
firstStarCollected = collected;
|
||||
else if(index == 2)
|
||||
secondStarCollected = collected;
|
||||
else if(index == 3)
|
||||
thirdStarCollected = collected;
|
||||
}
|
||||
|
||||
public String getCollectedStars(){
|
||||
String code = "";
|
||||
code+= firstStarCollected?"1":"";
|
||||
code+= secondStarCollected?"2":"";
|
||||
code+= thirdStarCollected?"3":"";
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCollectedStars(String code){
|
||||
firstStarCollected = code.contains("1");
|
||||
secondStarCollected = code.contains("2");
|
||||
thirdStarCollected = code.contains("3");
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
completed = false;
|
||||
unlocked = false;
|
||||
firstStarCollected = false;
|
||||
secondStarCollected = false;
|
||||
thirdStarCollected = false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.example.julian.endlessroll.levels;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.main.DataStorageHandler;
|
||||
import com.example.julian.endlessroll.main.GameLog;
|
||||
|
||||
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;
|
||||
|
||||
public class LevelManager extends ArrayList<LevelPack> {
|
||||
|
||||
public LevelManager(Context context, DataStorageHandler dataStorageHandler) throws Exception {
|
||||
String[] assets = context.getAssets().list("levelpacks");
|
||||
for (String asset : assets) {
|
||||
try {
|
||||
LevelPack pack = loadLevelPack(context, "levelpacks/" + asset);
|
||||
dataStorageHandler.readLevelProgress(pack);
|
||||
dataStorageHandler.readLevelPackLocked(pack);
|
||||
pack.tryToUnlockFirstLevel();
|
||||
if (pack.getId() == 0)
|
||||
pack.setLocked(false);
|
||||
super.add(pack);
|
||||
} catch (Exception e) {
|
||||
GameLog.e(e);
|
||||
}
|
||||
sort();
|
||||
}
|
||||
}
|
||||
|
||||
private void sort() {
|
||||
Collections.sort(this, new Comparator<LevelPack>() {
|
||||
@Override
|
||||
public int compare(LevelPack lhs, LevelPack rhs) {
|
||||
return lhs.getId() - rhs.getId();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 void reset() {
|
||||
for (LevelPack pack : this) {
|
||||
pack.reset();
|
||||
if (pack.getId() != 0)
|
||||
pack.setLocked(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void unlockAllPacks() {
|
||||
for (LevelPack levelPack : this)
|
||||
levelPack.setLocked(false);
|
||||
}
|
||||
|
||||
public void unlockAllLevels() {
|
||||
for (LevelPack levelPack : this) {
|
||||
for (Level level : levelPack.getLevels())
|
||||
level.setUnlocked(true);
|
||||
}
|
||||
}
|
||||
|
||||
public LevelPack nextLevelPack(LevelPack old) {
|
||||
int oldId = old.getId();
|
||||
for (LevelPack pack : this) {
|
||||
if (pack.getId() == oldId + 1)
|
||||
return pack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package com.example.julian.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
import org.simpleframework.xml.ElementList;
|
||||
import org.simpleframework.xml.Root;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.12.2015.
|
||||
*/
|
||||
@Root
|
||||
public class LevelPack {
|
||||
|
||||
@Attribute
|
||||
private String name;
|
||||
@Attribute
|
||||
private int id;
|
||||
@ElementList
|
||||
private List<Level> levels;
|
||||
private boolean locked;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<Level> getLevels() {
|
||||
return levels;
|
||||
}
|
||||
|
||||
public int getUnlockedLevels(){
|
||||
int count = 0;
|
||||
for(Level level : levels)
|
||||
if(level.isUnlocked())
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getCollectedStars(){
|
||||
int count = 0;
|
||||
for(Level level : levels)
|
||||
count += level.getCollectedStars().length();
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getAvailableStars(){
|
||||
return levels.size() * 3;
|
||||
}
|
||||
|
||||
public void tryToUnlockFirstLevel() {
|
||||
try {
|
||||
levels.get(0).setUnlocked(true);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public Level getLevel(int number) {
|
||||
for (Level level : levels)
|
||||
if (level.getNumber() == number)
|
||||
return level;
|
||||
return null;
|
||||
}
|
||||
|
||||
public Level getNextLevel(Level currentLevel) {
|
||||
if (isLastLevel(currentLevel)) {
|
||||
return null;
|
||||
}
|
||||
int index = levels.indexOf(currentLevel);
|
||||
return levels.get(index + 1);
|
||||
}
|
||||
|
||||
public boolean isLastLevel(Level level) {
|
||||
int index = levels.indexOf(level);
|
||||
return levels.size() == index + 1;
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
for(Level level : levels){
|
||||
level.reset();
|
||||
}
|
||||
tryToUnlockFirstLevel();
|
||||
}
|
||||
|
||||
public void setLocked(boolean locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public boolean isLocked() {
|
||||
return locked;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.example.julian.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
|
||||
/**
|
||||
* Created by Julian on 07.12.2015.
|
||||
*/
|
||||
public class ObstacleData {
|
||||
|
||||
@Attribute
|
||||
private String type;
|
||||
@Attribute
|
||||
private float leftEdge;
|
||||
@Attribute
|
||||
private float rightEdge;
|
||||
@Attribute
|
||||
private float height;
|
||||
@Attribute
|
||||
private float y;
|
||||
@Attribute
|
||||
public boolean attachedToGround;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return leftEdge + getWidth() / 2;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return rightEdge - leftEdge;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public boolean isAttachedToGround() {
|
||||
return attachedToGround;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.example.julian.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
|
||||
public class StarData {
|
||||
|
||||
@Attribute
|
||||
private int index;
|
||||
@Attribute
|
||||
private float x;
|
||||
@Attribute
|
||||
private float y;
|
||||
@Attribute
|
||||
private float width;
|
||||
@Attribute
|
||||
private float height;
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.example.julian.endlessroll.levels;
|
||||
|
||||
import org.simpleframework.xml.Attribute;
|
||||
import org.simpleframework.xml.ElementList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.11.2015.
|
||||
*/
|
||||
public class TerrainData {
|
||||
|
||||
@Attribute
|
||||
private float height;
|
||||
@Attribute
|
||||
private float endX;
|
||||
@ElementList
|
||||
private List<Gap> gaps;
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public float getEndX() {
|
||||
return endX;
|
||||
}
|
||||
|
||||
public List<Gap> getGaps() {
|
||||
return gaps;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.example.julian.endlessroll.levels.levelup;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.entities.tools.ToolType;
|
||||
import com.example.julian.endlessroll.views.BountyMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Julian on 17.07.2016.
|
||||
*/
|
||||
public class LevelUpBounties extends HashMap<Integer, List<LevelUpBounties.Bounty>> {
|
||||
|
||||
public interface Bounty {
|
||||
BountyMessage createMessage(Context context);
|
||||
}
|
||||
|
||||
private Map<ToolBounty, Integer> allToolBounties = new HashMap<>();
|
||||
private List<Integer> allToolSlotLevels = new ArrayList<>();
|
||||
|
||||
public LevelUpBounties() {
|
||||
addBounties(1, new ToolBounty(ToolType.RAMP), new ToolSlotBounty());
|
||||
addBounties(2, new StarBounty(5), new ToolBounty(ToolType.SPRING));
|
||||
addBounties(3, new StarBounty(6), new ToolBounty(ToolType.MAGNET), new ToolSlotBounty());
|
||||
addBounties(4, new StarBounty(7), new ToolBounty(ToolType.BOMB), new ToolSlotBounty());
|
||||
addBounties(5, new StarBounty(8), new ToolSlotBounty());
|
||||
}
|
||||
|
||||
private void addBounties(int unlockLevel, Bounty... bounties) {
|
||||
List<Bounty> list = new ArrayList<>();
|
||||
for (Bounty bounty : bounties) {
|
||||
list.add(bounty);
|
||||
if (bounty instanceof ToolBounty)
|
||||
allToolBounties.put((ToolBounty) bounty, unlockLevel);
|
||||
else if (bounty instanceof ToolSlotBounty)
|
||||
allToolSlotLevels.add(unlockLevel);
|
||||
}
|
||||
super.put(unlockLevel, list);
|
||||
}
|
||||
|
||||
public boolean isToolAlreadyUnlockedAtLevel(int level, ToolType toolType) {
|
||||
for (ToolBounty bounty : allToolBounties.keySet())
|
||||
if (bounty.getToolType() == toolType && allToolBounties.get(bounty) <= level)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isToolSlotUnlockedAtLevel(int toolSlotIndex, int level) {
|
||||
return allToolSlotLevels.get(toolSlotIndex) <= level;
|
||||
}
|
||||
|
||||
public int getBountyStarsAtLevel(int level) {
|
||||
for (Bounty bounty : this.get(level)) {
|
||||
if (bounty instanceof StarBounty)
|
||||
return ((StarBounty) bounty).getStarCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bounty> get(Object key) {
|
||||
List<Bounty> list = super.get(key);
|
||||
if (list == null)
|
||||
return new ArrayList<>();
|
||||
return list;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.example.julian.endlessroll.levels.levelup;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.views.BountyMessage;
|
||||
|
||||
/**
|
||||
* Created by Julian on 17.07.2016.
|
||||
*/
|
||||
public class StarBounty implements LevelUpBounties.Bounty {
|
||||
|
||||
private int starCount;
|
||||
|
||||
public StarBounty(int starCount) {
|
||||
this.starCount = starCount;
|
||||
}
|
||||
|
||||
public int getStarCount() {
|
||||
return starCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BountyMessage createMessage(Context context) {
|
||||
return new BountyMessage(context, starCount);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.example.julian.endlessroll.levels.levelup;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.entities.tools.ToolType;
|
||||
import com.example.julian.endlessroll.views.BountyMessage;
|
||||
|
||||
/**
|
||||
* Created by Julian on 17.07.2016.
|
||||
*/
|
||||
public class ToolBounty implements LevelUpBounties.Bounty {
|
||||
|
||||
private ToolType toolType;
|
||||
|
||||
public ToolBounty(ToolType toolType) {
|
||||
this.toolType = toolType;
|
||||
}
|
||||
|
||||
public ToolType getToolType() {
|
||||
return toolType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BountyMessage createMessage(Context context) {
|
||||
return new BountyMessage(context, toolType);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.example.julian.endlessroll.levels.levelup;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.example.julian.endlessroll.views.BountyMessage;
|
||||
|
||||
/**
|
||||
* Created by Julian on 17.07.2016.
|
||||
*/
|
||||
public class ToolSlotBounty implements LevelUpBounties.Bounty {
|
||||
|
||||
@Override
|
||||
public BountyMessage createMessage(Context context) {
|
||||
return new BountyMessage(context);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.example.julian.endlessroll.main;
|
||||
|
||||
import com.example.julian.endlessroll.main.game.User;
|
||||
|
||||
/**
|
||||
* Created by Julian on 15.07.2016.
|
||||
*/
|
||||
public class DataSafer {
|
||||
|
||||
private User user;
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.example.julian.endlessroll.main;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.example.julian.endlessroll.entities.tools.ToolSlot;
|
||||
import com.example.julian.endlessroll.entities.tools.ToolSlotSettings;
|
||||
import com.example.julian.endlessroll.levels.Level;
|
||||
import com.example.julian.endlessroll.levels.LevelPack;
|
||||
import com.example.julian.endlessroll.main.game.User;
|
||||
import com.example.julian.endlessroll.sqlDatabase.MyDatabase;
|
||||
|
||||
/**
|
||||
* 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_STARS = "Stars";
|
||||
private final String USER_LEVEL = "Level";
|
||||
private final String USER_LEVEL_PROGRESS = "LevelProgress";
|
||||
|
||||
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, true);
|
||||
}
|
||||
|
||||
public void writeSoundOn(boolean soundOn) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putBoolean(SOUND_ON, soundOn);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public User readUserData() {
|
||||
int stars = preferences.getInt(USER_STARS, 0);
|
||||
int level = preferences.getInt(USER_LEVEL, 1);
|
||||
int levelProgress = preferences.getInt(USER_LEVEL_PROGRESS, 0);
|
||||
//TODO: Default Tooltypes to NONE
|
||||
database.open();
|
||||
ToolSlotSettings toolSlotSettings = database.readToolSlotSettings();
|
||||
database.close();
|
||||
return new User(stars, level, levelProgress, toolSlotSettings);
|
||||
}
|
||||
|
||||
public void writeUserData(User user) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putInt(USER_STARS, user.getStarCount());
|
||||
editor.putInt(USER_LEVEL, user.getLevel());
|
||||
editor.putInt(USER_LEVEL_PROGRESS, user.getLevelProgress());
|
||||
editor.apply();
|
||||
database.open();
|
||||
for (ToolSlot toolSlot : user.getToolSlotSettings())
|
||||
database.writeToolSlot(user.getToolSlotSettings().indexOf(toolSlot), toolSlot);
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void writeLevelProgress(int levelpackNumber, Level level) {
|
||||
database.open();
|
||||
database.writeLevelProgress(levelpackNumber, level);
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void writeLevelPackLocked(LevelPack levelPack) {
|
||||
database.open();
|
||||
database.writeLevelPackLocked(levelPack);
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void readLevelPackLocked(LevelPack levelPack){
|
||||
database.open();
|
||||
database.readLevelPackLocked(levelPack);
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void readLevelProgress(LevelPack levelPack) {
|
||||
database.open();
|
||||
for (Level level : levelPack.getLevels()) {
|
||||
database.readLevelProgress(levelPack.getId(), level);
|
||||
}
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void clearLevelProgess() {
|
||||
database.open();
|
||||
database.clearLevelProgess();
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void readBoughtTools() {
|
||||
database.open();
|
||||
database.readBoughtTools();
|
||||
database.close();
|
||||
}
|
||||
|
||||
public void writeBoughtTools() {
|
||||
database.open();
|
||||
database.writeBoughtTools();
|
||||
database.close();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.example.julian.endlessroll.main;
|
||||
|
||||
/**
|
||||
* Created by Julian on 06.02.2016.
|
||||
*/
|
||||
public interface ExceptionHandler {
|
||||
|
||||
void onException(Exception e);
|
||||
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
package com.example.julian.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 com.example.julian.endlessroll.levels.Level;
|
||||
import com.example.julian.endlessroll.levels.LevelManager;
|
||||
import com.example.julian.endlessroll.levels.LevelPack;
|
||||
import com.example.julian.endlessroll.main.game.User;
|
||||
import com.example.julian.endlessroll.main.screens.GameScreen;
|
||||
import com.example.julian.endlessroll.main.screens.LevelsScreen;
|
||||
import com.example.julian.endlessroll.main.screens.Screen;
|
||||
import com.example.julian.endlessroll.main.screens.ScreenFlipper;
|
||||
import com.example.julian.endlessroll.main.screens.StartScreen;
|
||||
import com.example.julian.endlessroll.main.screens.ToolShopScreen;
|
||||
import com.example.julian.endlessroll.main.screens.WorldsScreen;
|
||||
import com.example.julian.endlessroll.rendering.renderer.GameRenderer;
|
||||
import com.example.julian.endlessroll.sounds.SoundManager;
|
||||
import com.example.julian.endlessroll.views.TopBarData;
|
||||
|
||||
/**
|
||||
* Created by Julian on 06.02.2016.
|
||||
*/
|
||||
public class GameActivity extends Activity implements ExceptionHandler {
|
||||
|
||||
private DataStorageHandler dataStorageHandler;
|
||||
private LevelManager levelManager;
|
||||
private SoundManager soundManager;
|
||||
private User user;
|
||||
|
||||
private MyGlSurfaceView glSurfaceView;
|
||||
private ScreenFlipper flipper;
|
||||
private StartScreen startScreen;
|
||||
private WorldsScreen worldsScreen;
|
||||
private LevelsScreen levelsScreen;
|
||||
private ToolShopScreen toolShopScreen;
|
||||
private GameScreen gameScreen;
|
||||
|
||||
@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.readBoughtTools();
|
||||
user = dataStorageHandler.readUserData();
|
||||
soundManager = new SoundManager(this);
|
||||
soundManager.setSoundOn(dataStorageHandler.readIsSoundOn());
|
||||
soundManager.backgroundMusic.getPlayer().setLooping(true);
|
||||
soundManager.backgroundMusic.start();
|
||||
levelManager = new LevelManager(this, dataStorageHandler);
|
||||
|
||||
this.glSurfaceView = new MyGlSurfaceView(this, new GameRenderer(this));
|
||||
Typeface typeface = Typeface.createFromAsset(getAssets(), "fontBaron.ttf");
|
||||
TopBarData topBarData = new TopBarData(this, dataStorageHandler, soundManager, levelManager, user, typeface);
|
||||
startScreen = new StartScreen(this, glSurfaceView, soundManager, levelManager, user, typeface);
|
||||
worldsScreen = new WorldsScreen(topBarData);
|
||||
levelsScreen = new LevelsScreen(topBarData);
|
||||
toolShopScreen = new ToolShopScreen(topBarData);
|
||||
gameScreen = new GameScreen(topBarData, glSurfaceView);
|
||||
|
||||
flipper = new ScreenFlipper(this, startScreen, worldsScreen, levelsScreen, gameScreen, toolShopScreen);
|
||||
RelativeLayout relativeLayout = new RelativeLayout(this);
|
||||
relativeLayout.addView(glSurfaceView);
|
||||
relativeLayout.addView(flipper);
|
||||
setContentView(relativeLayout);
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void flipToScreen(final Screen.ScreenType screen) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
flipper.showScreen(screen);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setToolshopCaller(Screen.ScreenType caller) {
|
||||
toolShopScreen.setCaller(caller);
|
||||
}
|
||||
|
||||
public void selectWorld(LevelPack levelPack) {
|
||||
levelsScreen.createList(levelPack);
|
||||
}
|
||||
|
||||
public void startGame(final LevelPack levelPack, final Level level) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
flipper.showScreen(Screen.ScreenType.GAME);
|
||||
gameScreen.startGame(levelPack, level);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
try {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.example.julian.endlessroll.main;
|
||||
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
/**
|
||||
* Created by Julian on 08.12.2015.
|
||||
*/
|
||||
public interface GameHandler extends ExceptionHandler {
|
||||
|
||||
void startInUiThread(Runnable runnable);
|
||||
|
||||
void toLevelsScreen();
|
||||
|
||||
RelativeLayout getRootLayout();
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.example.julian.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,47 @@
|
||||
package com.example.julian.endlessroll.main;
|
||||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
|
||||
import com.example.julian.endlessroll.rendering.renderer.GameRenderer;
|
||||
import com.example.julian.endlessroll.rendering.Rendering;
|
||||
|
||||
/**
|
||||
* Created by Julian on 30.07.2016.
|
||||
*/
|
||||
public class MyGlSurfaceView extends GLSurfaceView {
|
||||
|
||||
private GameRenderer renderer;
|
||||
private boolean rendererSet;
|
||||
|
||||
public MyGlSurfaceView(Context context, GameRenderer gameRenderer) throws Exception {
|
||||
super(context);
|
||||
this.renderer = gameRenderer;
|
||||
super.setEGLContextClientVersion(2);
|
||||
super.setRenderer(renderer);
|
||||
rendererSet = true;
|
||||
}
|
||||
|
||||
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("SurfaceView: onResume");
|
||||
if (rendererSet)
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
GameLog.i("SurfaceView: onPause");
|
||||
if (rendererSet)
|
||||
super.onPause();
|
||||
}
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
package com.example.julian.endlessroll.main.game;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.DestroyEffect;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.Star;
|
||||
import com.example.julian.endlessroll.entities.collision.CollisionManager;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
import com.example.julian.endlessroll.entities.textures.TexturePack;
|
||||
import com.example.julian.endlessroll.entities.tools.ToolType;
|
||||
import com.example.julian.endlessroll.levels.Level;
|
||||
import com.example.julian.endlessroll.levels.LevelManager;
|
||||
import com.example.julian.endlessroll.levels.LevelPack;
|
||||
import com.example.julian.endlessroll.levels.levelup.LevelUpBounties;
|
||||
import com.example.julian.endlessroll.main.DataStorageHandler;
|
||||
import com.example.julian.endlessroll.main.GameHandler;
|
||||
import com.example.julian.endlessroll.main.GameLog;
|
||||
import com.example.julian.endlessroll.rendering.Rendering;
|
||||
import com.example.julian.endlessroll.sounds.SoundManager;
|
||||
import com.example.julian.endlessroll.views.MessageType;
|
||||
import com.example.julian.endlessroll.views.ToolButton;
|
||||
import com.example.julian.endlessroll.views.ToolButtonBar;
|
||||
import com.example.julian.endlessroll.views.TopBarData;
|
||||
import com.example.julian.endlessroll.views.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 26.11.2015.
|
||||
*/
|
||||
public class Game extends Rendering<GameScene> {
|
||||
|
||||
private User user;
|
||||
private DataStorageHandler dataStorageHandler;
|
||||
private LevelManager levelManager;
|
||||
private GameHandler handler;
|
||||
private ViewManager viewManager;
|
||||
private SoundManager sounds;
|
||||
private LevelPack levelPack;
|
||||
private ParticleSystem particleSystem;
|
||||
private LevelUpBounties levelUpBounties;
|
||||
|
||||
private ToolType currentTool;
|
||||
private Player player;
|
||||
private Physics physics;
|
||||
private CollisionManager collisionManager;
|
||||
private Timer timer;
|
||||
private GameState gameState = GameState.PAUSED;
|
||||
|
||||
private Level level;
|
||||
private List<Integer> collectedStars = new ArrayList<>();
|
||||
|
||||
public Game(GameHandler handler, TopBarData topBarData) throws Exception{
|
||||
super(topBarData.getGameActivity());
|
||||
this.handler = handler;
|
||||
this.user = topBarData.getUser();
|
||||
this.levelManager = topBarData.getLevelManager();
|
||||
this.sounds = topBarData.getSoundManager();
|
||||
levelUpBounties = new LevelUpBounties();
|
||||
physics = new Physics();
|
||||
collisionManager = new CollisionManager(this);
|
||||
particleSystem = new ParticleSystem(getContext());
|
||||
this.dataStorageHandler = topBarData.getDataStorageHandler();
|
||||
viewManager = new ViewManager(this, handler, topBarData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameScene init(TexturePack texturePack, Timer timer, boolean isFirstTime) {
|
||||
GameLog.d("initGame");
|
||||
this.timer = timer;
|
||||
try {
|
||||
if (isFirstTime) {
|
||||
scene = new GameScene(texturePack, particleSystem);
|
||||
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) {
|
||||
collectedStars.clear();
|
||||
particleSystem.deleteAllSources();
|
||||
scene.loadLevel(level);
|
||||
player = scene.getPlayer();
|
||||
if (viewManager.isScreenSizeSet())
|
||||
viewManager.resetToolButtonBar();
|
||||
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);
|
||||
viewManager.setScreenSize(screenSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// GameLog.d("update GAME");
|
||||
particleSystem.update(timer);
|
||||
float playerProgress = 0;
|
||||
if (player != null)
|
||||
playerProgress = player.getProgress();
|
||||
viewManager.update(gameState == GameState.RUNNING, timer, playerProgress);
|
||||
switch (gameState) {
|
||||
case RUNNING:
|
||||
if (player.getPosition().y < -2f) {
|
||||
onGameOver(false);
|
||||
return;
|
||||
}
|
||||
if (player.getPosition().x >= scene.getGoalX()) {
|
||||
onGoalReached();
|
||||
return;
|
||||
}
|
||||
physics.applyGravity(scene);
|
||||
scene.update(timer);
|
||||
collisionManager.update(physics, scene);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@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.resetToolButtonBar();
|
||||
}
|
||||
|
||||
public void continueGame() {
|
||||
viewManager.hideShortMenu();
|
||||
viewManager.startCountdown();
|
||||
}
|
||||
|
||||
public void startNextLevel() {
|
||||
level = levelPack.getNextLevel(level);
|
||||
startGame(levelPack, level);
|
||||
}
|
||||
|
||||
public void restartLevel() {
|
||||
startGame(levelPack, level);
|
||||
}
|
||||
|
||||
public void toLevelsScreen() {
|
||||
handler.toLevelsScreen();
|
||||
}
|
||||
|
||||
public void setCurrentTool(ToolType toolType) {
|
||||
currentTool = toolType;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
viewManager.showShortMenu();
|
||||
if (gameState == GameState.RUNNING) {
|
||||
gameState = GameState.PAUSED;
|
||||
} else {
|
||||
viewManager.stopCountdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void addTool(float x, float y) {
|
||||
try {
|
||||
sounds.playSound(currentTool.getPlacingSound());
|
||||
scene.addTool(currentTool, x, y);
|
||||
} catch (Exception e) {
|
||||
onException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onGameOver(boolean playerExplode) {
|
||||
if (playerExplode) {
|
||||
scene.remove(player);
|
||||
DestroyEffect.EXPLOSION.createEffect(particleSystem, player.getPosition(), new Vector(player.getWidth(), player.getHeight())).start();
|
||||
}
|
||||
gameState = GameState.GAME_OVER;
|
||||
viewManager.showMessage(false, MessageType.GAME_OVER);
|
||||
}
|
||||
|
||||
private void onGoalReached() {
|
||||
gameState = GameState.LEVEL_FINISHED;
|
||||
if (!level.isCompleted())
|
||||
user.gainLvUpExp();
|
||||
level.setCompleted(true);
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
if (collectedStars.contains(i)) {
|
||||
level.setStarCollected(i, true);
|
||||
user.increaseStarCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (user.isShowLevelUp()) {
|
||||
user.levelUpShown();
|
||||
viewManager.showLevelUp(user.getLevel());
|
||||
user.getToolSlotSettings().unlockSlotsIfLevelReached(user.getLevel(), levelUpBounties);
|
||||
user.increaseStarCount(levelUpBounties.getBountyStarsAtLevel(user.getLevel()));
|
||||
viewManager.resetToolButtonBar();
|
||||
}
|
||||
viewManager.showMessage(levelPack.isLastLevel(level), MessageType.WIN);
|
||||
|
||||
dataStorageHandler.writeLevelProgress(levelPack.getId(), level);
|
||||
Level nextLevel = levelPack.getNextLevel(level);
|
||||
if (nextLevel != null) {
|
||||
nextLevel.setUnlocked(true);
|
||||
dataStorageHandler.writeLevelProgress(levelPack.getId(), nextLevel);
|
||||
}else{
|
||||
LevelPack nextLevelPack = levelManager.nextLevelPack(levelPack);
|
||||
if(nextLevelPack != null){
|
||||
nextLevelPack.setLocked(false);
|
||||
dataStorageHandler.writeLevelPackLocked(nextLevelPack);
|
||||
}
|
||||
}
|
||||
dataStorageHandler.writeUserData(user);
|
||||
}
|
||||
|
||||
public void onStarCollision(Star star) {
|
||||
scene.onStarCollision(star);
|
||||
collectedStars.add(star.getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(Exception e) {
|
||||
handler.onException(e);
|
||||
}
|
||||
|
||||
public GameState getGameState() {
|
||||
return gameState;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
package com.example.julian.endlessroll.main.game;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.DestroyEffect;
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.Goal;
|
||||
import com.example.julian.endlessroll.entities.Obstacle;
|
||||
import com.example.julian.endlessroll.entities.Star;
|
||||
import com.example.julian.endlessroll.entities.Terrain;
|
||||
import com.example.julian.endlessroll.entities.TerrainTile;
|
||||
import com.example.julian.endlessroll.entities.collision.CollisionDetector;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
import com.example.julian.endlessroll.entities.textures.TexturePack;
|
||||
import com.example.julian.endlessroll.entities.tools.Bomb;
|
||||
import com.example.julian.endlessroll.entities.tools.Tool;
|
||||
import com.example.julian.endlessroll.entities.tools.ToolType;
|
||||
import com.example.julian.endlessroll.levels.Level;
|
||||
import com.example.julian.endlessroll.levels.ObstacleData;
|
||||
import com.example.julian.endlessroll.levels.StarData;
|
||||
import com.example.julian.endlessroll.main.GameLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.11.2015.
|
||||
*/
|
||||
public class GameScene extends Scene {
|
||||
|
||||
private CollisionDetector collisionDetector;
|
||||
private Goal goal;
|
||||
|
||||
private float goalX;
|
||||
private List<Obstacle> obstacles = new ArrayList<>();
|
||||
private List<Star> stars = new ArrayList<>();
|
||||
private List<Tool> tools = new ArrayList<>();
|
||||
|
||||
public GameScene(TexturePack texturePack, ParticleSystem particleSystem) throws Exception {
|
||||
super(texturePack, particleSystem);
|
||||
collisionDetector = new CollisionDetector();
|
||||
|
||||
goal = new Goal(textures.goal);
|
||||
}
|
||||
|
||||
public void loadLevel(Level level) throws Exception {
|
||||
reset();
|
||||
lock.lock();
|
||||
terrain.loadData(level.getTerrain());
|
||||
super.add(goal);
|
||||
player.init(terrain.getHeight());
|
||||
super.add(player);
|
||||
lock.unlock();
|
||||
for (ObstacleData data : level.getObstacles())
|
||||
addObstacle(data);
|
||||
for (StarData data : level.getStars()) {
|
||||
if (data.getIndex() == 1 && level.isFirstStarCollected())
|
||||
continue;
|
||||
if (data.getIndex() == 2 && level.isSecondStarCollected())
|
||||
continue;
|
||||
if (data.getIndex() == 3 && level.isThirdStarCollected())
|
||||
continue;
|
||||
addStar(data);
|
||||
}
|
||||
goalX = level.getGoalX();
|
||||
goal.setGoalX(goalX);
|
||||
GameLog.d("Level " + level.getNumber() + " successfully loaded");
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
lock.lock();
|
||||
super.clear();
|
||||
lock.unlock();
|
||||
obstacles.clear();
|
||||
tools.clear();
|
||||
cameraX = 0;
|
||||
background.resetPosition();
|
||||
}
|
||||
|
||||
public void onStarCollision(Star collisionStar) {
|
||||
Iterator<Star> iter = stars.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Star star = iter.next();
|
||||
if (star.equals(collisionStar)) {
|
||||
star.destroy(DestroyEffect.STAR_EXPLOSION);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addObstacle(ObstacleData data) {
|
||||
Obstacle obstacle = new Obstacle(textures.obstacle, data, terrain.getHeight());
|
||||
lock.lock();
|
||||
super.add(obstacle);
|
||||
obstacles.add(obstacle);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void addStar(StarData data) {
|
||||
Star star = new Star(textures.star, data);
|
||||
lock.lock();
|
||||
super.add(star);
|
||||
stars.add(star);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public void addTool(ToolType type, float screenX, float screenY) throws Exception {
|
||||
Vector position = calcWorldFromScreenCoords(screenX, screenY);
|
||||
Tool tool = type.newInstance(position, particleSystem);
|
||||
if (tool == null)
|
||||
throw new Exception("Current ToolType(" + type + ") returns null at method newInstance()");
|
||||
lock.lock();
|
||||
super.add(tool);
|
||||
tools.add(tool);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(Timer timer) {
|
||||
super.update(timer);
|
||||
for (Tool tool : tools) {
|
||||
tool.update(timer);
|
||||
if (tool instanceof Bomb) {
|
||||
Bomb bomb = (Bomb) tool;
|
||||
if (bomb.isExploding())
|
||||
bomb.explode(obstacles, collisionDetector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeEntityFromAllLists(Entity entity) {
|
||||
GameLog.i("REMOVE FROM ALL LISTS");
|
||||
if (!entity.isDestroyed())
|
||||
entity.destroy(null);
|
||||
if (entity instanceof Tool)
|
||||
tools.remove(entity);
|
||||
if (entity instanceof Obstacle)
|
||||
obstacles.remove(entity);
|
||||
}
|
||||
|
||||
public Terrain getTerrain() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public List<Tool> getTools() {
|
||||
return tools;
|
||||
}
|
||||
|
||||
public List<Obstacle> getObstacles() {
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
public List<Star> getStars() {
|
||||
return stars;
|
||||
}
|
||||
|
||||
public float getGoalX() {
|
||||
return goalX;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.example.julian.endlessroll.main.game;
|
||||
|
||||
/**
|
||||
* Created by Julian on 02.02.2016.
|
||||
*/
|
||||
public enum GameState {
|
||||
|
||||
RUNNING, PAUSED, GAME_OVER, LEVEL_FINISHED
|
||||
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package com.example.julian.endlessroll.main.game;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.Obstacle;
|
||||
import com.example.julian.endlessroll.entities.Star;
|
||||
import com.example.julian.endlessroll.entities.Terrain;
|
||||
import com.example.julian.endlessroll.entities.TerrainTile;
|
||||
import com.example.julian.endlessroll.entities.collision.CollisionDetector;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.EntityCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.ObstacleCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.PlayerCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.collisionData.ToolCollisionData;
|
||||
import com.example.julian.endlessroll.entities.collision.geometry.Circle;
|
||||
import com.example.julian.endlessroll.entities.tools.Bomb;
|
||||
import com.example.julian.endlessroll.entities.tools.Tool;
|
||||
import com.example.julian.endlessroll.main.GameLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Julian on 27.11.2015.
|
||||
*/
|
||||
public class Physics {
|
||||
|
||||
public final float GRAVITY_FORCE = .00004f;
|
||||
private CollisionDetector detector;
|
||||
|
||||
public Physics() {
|
||||
detector = new CollisionDetector();
|
||||
}
|
||||
|
||||
public void applyGravity(GameScene scene) {
|
||||
scene.getPlayer().getMovement().y -= GRAVITY_FORCE;
|
||||
for (Tool tool : scene.getTools()) {
|
||||
if (tool.isFloating())
|
||||
continue;
|
||||
if (tool instanceof Bomb) {
|
||||
for (Obstacle obstacle : scene.getObstacles()) {
|
||||
if (detector.quadQuadCollision(obstacle, tool)) {
|
||||
GameLog.i("collision");
|
||||
tool.setFloating(true);
|
||||
tool.getMovement().y = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tool.isFloating())
|
||||
continue;
|
||||
}
|
||||
float terrainHeight = getTerrainHeight(tool, scene.getTerrain());
|
||||
Obstacle toolIsOver = getObstacleToolIsOver(tool, scene.getObstacles());
|
||||
|
||||
float orientingHeight = terrainHeight;
|
||||
if (toolIsOver != null) {
|
||||
if (toolIsOver.getBottomEdge() < tool.getTopEdge())
|
||||
orientingHeight = Math.max(toolIsOver.getTopEdge(), terrainHeight);
|
||||
else{
|
||||
orientingHeight = terrainHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (tool.getBottomEdge() > orientingHeight) {
|
||||
tool.getMovement().y -= GRAVITY_FORCE * 2;
|
||||
} else {
|
||||
tool.getMovement().y = 0;
|
||||
tool.setToTerrain(orientingHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Obstacle getObstacleToolIsOver(Entity tool, List<Obstacle> obstacles) {
|
||||
Map<Float, Obstacle> isOver = new HashMap<>();
|
||||
for (Obstacle obstacle : obstacles) {
|
||||
if ((tool.getLeftEdge() >= obstacle.getLeftEdge() && tool.getLeftEdge() <= obstacle.getRightEdge()) || (tool.getRightEdge() <= obstacle.getRightEdge() && tool.getRightEdge() >= obstacle.getLeftEdge()))
|
||||
isOver.put(obstacle.getTopEdge(), obstacle);
|
||||
}
|
||||
float max = -100;
|
||||
for (float height : isOver.keySet()) {
|
||||
if(isOver.get(height).getBottomEdge() < tool.getTopEdge()) {
|
||||
max = Math.max(max, height);
|
||||
}
|
||||
}
|
||||
if (max != -100)
|
||||
return isOver.get(max);
|
||||
return null;
|
||||
}
|
||||
|
||||
private float getTerrainHeight(Entity tool, Terrain terrain) {
|
||||
for (TerrainTile 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.getHeight();
|
||||
}
|
||||
return -10;
|
||||
}
|
||||
|
||||
public PlayerCollisionData getPlayerCollisionData(GameScene scene) {
|
||||
EntityCollisionData terrainData = playerCollidesWithTerrain(scene);
|
||||
ObstacleCollisionData obstacleData = playerCollidesWithObstacle(scene);
|
||||
ToolCollisionData toolData = playerCollidesWithTool(scene);
|
||||
EntityCollisionData starData = playerCollidesWithStar(scene);
|
||||
return new PlayerCollisionData(terrainData, obstacleData, toolData, starData);
|
||||
}
|
||||
|
||||
private EntityCollisionData playerCollidesWithTerrain(GameScene scene) {
|
||||
Terrain terrain = scene.getTerrain();
|
||||
for (TerrainTile terrainTile : terrain) {
|
||||
EntityCollisionData data = detector.playerEntityCollision(scene.getPlayer(), terrainTile);
|
||||
if (data.isCollision())
|
||||
return data;
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
private ObstacleCollisionData playerCollidesWithObstacle(GameScene scene) {
|
||||
List<EntityCollisionData> collisions = new ArrayList<>();
|
||||
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());
|
||||
for (Tool tool : scene.getTools()) {
|
||||
if (detector.circleToolCollision(circle, tool.getCollisionBounds()))
|
||||
tools.add(tool);
|
||||
}
|
||||
return new ToolCollisionData(tools);
|
||||
}
|
||||
|
||||
private EntityCollisionData playerCollidesWithStar(GameScene scene) {
|
||||
for (Star star : scene.getStars()) {
|
||||
EntityCollisionData data = detector.playerEntityCollision(scene.getPlayer(), star);
|
||||
if (data.isCollision())
|
||||
return data;
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
package com.example.julian.endlessroll.main.game;
|
||||
|
||||
import com.example.julian.endlessroll.data.Vector;
|
||||
import com.example.julian.endlessroll.entities.Background;
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.Player;
|
||||
import com.example.julian.endlessroll.entities.Terrain;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
import com.example.julian.endlessroll.entities.textures.TexturePack;
|
||||
import com.example.julian.endlessroll.rendering.Lock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Created by Julian on 20.07.2016.
|
||||
*/
|
||||
public abstract class Scene extends ArrayList<Entity> {
|
||||
|
||||
public float cameraX;
|
||||
public final Lock lock;
|
||||
|
||||
private Vector screenSize;
|
||||
private Entity playerArrow;
|
||||
|
||||
protected ParticleSystem particleSystem;
|
||||
protected TexturePack textures;
|
||||
protected Background background;
|
||||
protected Terrain terrain;
|
||||
protected Player player;
|
||||
|
||||
public Scene(TexturePack texturePack, ParticleSystem particleSystem) {
|
||||
this.particleSystem = particleSystem;
|
||||
setTexturePack(texturePack);
|
||||
playerArrow = new Entity(textures.playerArrow, new Vector(0, 0.9f), .2f, .2f);
|
||||
background = new Background(textures.background);
|
||||
terrain = new Terrain(textures.terrain);
|
||||
player = new Player(textures.player);
|
||||
lock = new Lock();
|
||||
}
|
||||
|
||||
public void setTexturePack(TexturePack texturePack) {
|
||||
this.textures = texturePack;
|
||||
}
|
||||
|
||||
public void update(Timer timer) {
|
||||
lock.lock();
|
||||
Iterator<Entity> iterator = super.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = iterator.next();
|
||||
Vector movement = entity.getMovement();
|
||||
Vector finalMovement = new Vector(movement).mul(timer.getFrameTime());
|
||||
entity.move(finalMovement);
|
||||
if (entity.isDestroyed() && entity.getDestroyEffect() != null)
|
||||
entity.getDestroyEffect().createEffect(particleSystem, new Vector(entity.getPosition()), new Vector(entity.getWidth(), entity.getHeight())).start();
|
||||
if (entity.equals(player))
|
||||
moveEnviroment(finalMovement.x);
|
||||
else if (entity.getRightEdge() - cameraX < -3f || entity.isDestroyed()) {
|
||||
iterator.remove();
|
||||
removeEntityFromAllLists(entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getPosition().y >= player.RADIUS + 1) {
|
||||
playerArrow.getPosition().x = player.getPosition().x;
|
||||
if (!super.contains(playerArrow)) {
|
||||
super.add(playerArrow);
|
||||
}
|
||||
} else super.remove(playerArrow);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object object) {
|
||||
removeEntityFromAllLists((Entity) object);
|
||||
return super.remove(object);
|
||||
}
|
||||
|
||||
protected abstract void removeEntityFromAllLists(Entity entity);
|
||||
|
||||
private void moveEnviroment(float x) {
|
||||
cameraX += x;
|
||||
background.move(x * 0.95f, cameraX);
|
||||
terrain.update(cameraX);
|
||||
}
|
||||
|
||||
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 += cameraX;
|
||||
float y = -((screenY / screenSize.y) * 2f - 1f);
|
||||
return new Vector(x, y);
|
||||
}
|
||||
|
||||
public void setScreenSize(Vector screenSize) {
|
||||
this.screenSize = screenSize;
|
||||
}
|
||||
|
||||
public Background getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
public Terrain getTerrain() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public TexturePack getTextures() {
|
||||
return textures;
|
||||
}
|
||||
|
||||
public ParticleSystem getParticleSystem() {
|
||||
return particleSystem;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.example.julian.endlessroll.main.game;
|
||||
|
||||
import com.example.julian.endlessroll.entities.Entity;
|
||||
import com.example.julian.endlessroll.entities.particles.ParticleSystem;
|
||||
import com.example.julian.endlessroll.entities.textures.TexturePack;
|
||||
|
||||
public class StartScene extends Scene {
|
||||
|
||||
public StartScene(TexturePack texturePack, ParticleSystem particleSystem) {
|
||||
super(texturePack, particleSystem);
|
||||
terrain.createEndless(-.8f);
|
||||
player.init(terrain.getHeight());
|
||||
super.add(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeEntityFromAllLists(Entity entity) {
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user