v0.4.3: plants and traps are now on a terrain tilemap pt.1

Still needs some cleaning up, but everything works
This commit is contained in:
Evan Debenham 2016-10-07 04:10:01 -04:00
parent 7e0fc9f2f0
commit fef73210e9
14 changed files with 171 additions and 41 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -97,9 +97,8 @@ public class Assets {
public static final String ROT_HEART= "rot_heart.png";
public static final String GUARD = "guard.png";
public static final String ITEMS = "items.png";
public static final String PLANTS = "plants.png";
public static final String TRAPS = "traps.png";
public static final String ITEMS = "items.png";
public static final String TERRAIN_FEATURES = "terrain_features.png";
public static final String TILES_SEWERS = "tiles0.png";
public static final String TILES_PRISON = "tiles1.png";

View File

@ -734,19 +734,19 @@ public abstract class Level implements Bundlable {
map[pos] == Terrain.EMPTY_DECO) {
map[pos] = Terrain.GRASS;
flamable[pos] = true;
GameScene.updateMap( pos );
}
plant = seed.couch( pos );
plants.put( pos, plant );
GameScene.add( plant );
GameScene.updateMap( pos );
return plant;
}
public void uproot( int pos ) {
plants.remove(pos);
GameScene.updateMap( pos );
}
public Trap setTrap( Trap trap, int pos ){
@ -757,7 +757,7 @@ public abstract class Level implements Bundlable {
}
trap.set( pos );
traps.put( pos, trap );
GameScene.add(trap);
GameScene.updateMap( pos );
return trap;
}

View File

@ -216,9 +216,6 @@ public class PrisonBossLevel extends Level {
}
private void resetTraps(){
for (Trap trap : traps.values()){
trap.sprite.kill();
}
traps.clear();
for (int i = 0; i < length(); i++){
@ -273,7 +270,6 @@ public class PrisonBossLevel extends Level {
for (Plant plant : plants.values()){
if (safeArea == null || !safeArea.inside(cellToPoint(plant.pos))){
plants.remove(plant.pos);
plant.sprite.kill();
}
}
}

View File

@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.traps;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite;
import com.watabou.noosa.audio.Sample;
import com.watabou.noosa.tweeners.AlphaTweener;
@ -54,6 +55,7 @@ public abstract class Trap implements Bundlable {
sprite.alpha( 0 );
sprite.parent.add( new AlphaTweener( sprite, 1, 0.6f));
}
GameScene.updateMap(pos);
return this;
}
@ -61,6 +63,7 @@ public abstract class Trap implements Bundlable {
visible = false;
if (sprite != null)
sprite.visible = false;
GameScene.updateMap(pos);
return this;
}

View File

@ -38,7 +38,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.SandalsOfNature;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.PlantSprite;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
@ -52,8 +51,6 @@ public abstract class Plant implements Bundlable {
public int image;
public int pos;
public PlantSprite sprite;
public void trigger(){
@ -71,8 +68,7 @@ public abstract class Plant implements Bundlable {
public void wither() {
Dungeon.level.uproot( pos );
sprite.kill();
if (Dungeon.visible[pos]) {
CellEmitter.get( pos ).burst( LeafParticle.GENERAL, 6 );
}
@ -142,7 +138,7 @@ public abstract class Plant implements Bundlable {
@Override
protected void onThrow( int cell ) {
if (Dungeon.level.map[cell] == Terrain.ALCHEMY || Level.pit[cell]) {
if (Dungeon.level.map[cell] == Terrain.ALCHEMY || Level.pit[cell] || Dungeon.level.traps.get(cell) != null) {
super.onThrow( cell );
} else {
Dungeon.level.plant( this, cell );

View File

@ -71,6 +71,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.LootIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.ResumeIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toast;
import com.shatteredpixel.shatteredpixeldungeon.ui.Toolbar;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
@ -111,6 +112,7 @@ public class GameScene extends PixelScene {
private SkinnedBlock water;
private DungeonTilemap tiles;
private TerrainFeaturesTilemap terrainFeatures;
private FogOfWar fog;
private HeroSprite hero;
@ -193,30 +195,17 @@ public class GameScene extends PixelScene {
for( CustomTileVisual visual : Dungeon.level.customTiles){
addCustomTile(visual.create());
}
terrainFeatures = new TerrainFeaturesTilemap(Dungeon.level.plants, Dungeon.level.traps);
terrain.add(terrainFeatures);
levelVisuals = Dungeon.level.addVisuals();
add(levelVisuals);
traps = new Group();
add(traps);
int size = Dungeon.level.traps.size();
for (int i=0; i < size; i++) {
addTrapSprite( Dungeon.level.traps.valueAt( i ) );
}
plants = new Group();
add( plants );
size = Dungeon.level.plants.size();
for (int i=0; i < size; i++) {
addPlantSprite( Dungeon.level.plants.valueAt( i ) );
}
heaps = new Group();
add( heaps );
size = Dungeon.level.heaps.size();
int size = Dungeon.level.heaps.size();
for (int i=0; i < size; i++) {
addHeapSprite( Dungeon.level.heaps.valueAt( i ) );
}
@ -541,12 +530,11 @@ public class GameScene extends PixelScene {
}
private void addPlantSprite( Plant plant ) {
(plant.sprite = (PlantSprite)plants.recycle( PlantSprite.class )).reset( plant );
}
private void addTrapSprite( Trap trap ) {
(trap.sprite = (TrapSprite)traps.recycle( TrapSprite.class )).reset( trap );
trap.sprite.visible = trap.visible;
}
private void addBlobSprite( final Blob gas ) {
@ -689,12 +677,14 @@ public class GameScene extends PixelScene {
public static void updateMap() {
if (scene != null) {
scene.tiles.updateMap();
scene.terrainFeatures.updateMap();
}
}
public static void updateMap( int cell ) {
if (scene != null) {
scene.tiles.updateMapCell( cell );
scene.terrainFeatures.updateMapCell( cell );
}
}

View File

@ -44,7 +44,7 @@ public class PlantSprite extends Image {
private int pos = -1;
public PlantSprite() {
super( Assets.PLANTS );
super( Assets.TERRAIN_FEATURES );
if (frames == null) {
frames = new TextureFilm( texture, 16, 16 );

View File

@ -56,7 +56,7 @@ public class TrapSprite extends Image {
public TrapSprite() {
super( Assets.TRAPS );
super( Assets.TERRAIN_FEATURES );
if (frames == null) {
frames = new TextureFilm( texture, 16, 16 );

View File

@ -0,0 +1,140 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite;
import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.Tilemap;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
import com.watabou.utils.SparseArray;
public class TerrainFeaturesTilemap extends Tilemap {
public static final int SIZE = 16;
private static TerrainFeaturesTilemap instance;
private int[] map;
private float[] tileVariance;
private SparseArray<Plant> plants;
private SparseArray<Trap> traps;
public TerrainFeaturesTilemap(SparseArray<Plant> plants, SparseArray<Trap> traps) {
super(Assets.TERRAIN_FEATURES, new TextureFilm( Assets.TERRAIN_FEATURES, SIZE, SIZE ));
this.plants = plants;
this.traps = traps;
Random.seed( Dungeon.seedCurDepth());
tileVariance = new float[Dungeon.level.map.length];
for (int i = 0; i < tileVariance.length; i++)
tileVariance[i] = Random.Float();
Random.seed();
map( Dungeon.level.map, Dungeon.level.width() );
instance = this;
}
@Override
//we need to retain two arrays, map is the dungeon tilemap which we can reference.
// Data is our own internal image representation of the tiles, which may differ.
public void map(int[] data, int cols) {
map = data;
super.map(new int[data.length], cols);
}
@Override
public synchronized void updateMap() {
super.updateMap();
for (int i = 0; i < data.length; i++)
data[i] = getTileVisual(i ,map[i]);
}
@Override
public synchronized void updateMapCell(int cell) {
//update in a 3x3 grid to account for neighbours which might also be affected
if (Dungeon.level.insideMap(cell)) {
super.updateMapCell(cell - mapWidth - 1);
super.updateMapCell(cell + mapWidth + 1);
for (int i : PathFinder.NEIGHBOURS9)
data[cell + i] = getTileVisual(cell + i, map[cell + i]);
//unless we're at the level's edge, then just do the one tile.
} else {
super.updateMapCell(cell);
data[cell] = getTileVisual(cell, map[cell]);
}
}
private int getTileVisual(int pos, int tile){
if (traps.get(pos) != null){
Trap trap = traps.get(pos);
if (!trap.visible)
return -1;
else
return (trap.active ? trap.color : TrapSprite.BLACK) + (trap.shape * 16);
}
if (plants.get(pos) != null){
return plants.get(pos).image + 7*16;
}
if (tile == Terrain.HIGH_GRASS){
return 9 + 16*((Dungeon.depth-1)/5) + (tileVariance[pos] > 0.5f ? 1 : 0);
} else if (tile == Terrain.GRASS) {
return 11 + 16*((Dungeon.depth-1)/5) + (tileVariance[pos] > 0.5f ? 1 : 0);
} else if (tile == Terrain.EMBERS) {
return 13 + (tileVariance[pos] > 0.5f ? 1 : 0);
}
return -1;
}
public static Image tile(int pos, int tile ) {
Image img = new Image( instance.texture );
img.frame( instance.tileset.get( instance.getTileVisual( pos, tile ) ) );
return img;
}
@Override
public boolean overlapsPoint( float x, float y ) {
return true;
}
@Override
public boolean overlapsScreenPoint( int x, int y ) {
return true;
}
@Override
protected boolean needsRender(int pos) {
return data[pos] != -1;
}
}

View File

@ -20,14 +20,19 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.PlantSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap;
public class WndInfoPlant extends WndTitledMessage {
public WndInfoPlant( Plant plant ) {
super(new PlantSprite( plant.image ), plant.plantName, plant.desc());
super(TerrainFeaturesTilemap.tile( plant.pos, Dungeon.level.map[plant.pos]),
plant.plantName, plant.desc());
}
}

View File

@ -20,15 +20,16 @@
*/
package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.TrapSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.TerrainFeaturesTilemap;
public class WndInfoTrap extends WndTitledMessage {
public WndInfoTrap(Trap trap) {
super(new TrapSprite( trap.color + (trap.shape * 16) ),
super(TerrainFeaturesTilemap.tile( trap.pos, Dungeon.level.map[trap.pos]),
trap.name,
(!trap.active ? Messages.get(WndInfoTrap.class, "inactive") + "\n\n" : "") + trap.desc());