Skip to content

Instantly share code, notes, and snippets.

@jquave
Created April 8, 2014 04:47
Show Gist options
  • Select an option

  • Save jquave/10091965 to your computer and use it in GitHub Desktop.

Select an option

Save jquave/10091965 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Reflection;
public class BlockColors {
Color wall = new Color(0,0,0);
Color enemySpawner = new Color(255,0,0);
Color floor = new Color(0, 255, 255);
Color spawnPoint = new Color(0, 255, 0);
Color goal = new Color(255, 255, 0);
Color background = new Color(0,0,0);
public bool IsSolid(Color c) {
return (c==wall || (c.r==0 && c.g>0.0f && c.b>0.0f));
}
public bool isGoal(Color c) {
return (c.r>0 && c.g>0 && c.b==0);
}
public bool IsSpawnPoint(Color c) {
return (c.r==0 && c.g>0 && c.b==0);
}
public bool IsEnemySpawner(Color c) {
return (c.r>0 && c.g==0 && c.b==0);
}
}
//[ExecuteInEditMode]
public class World : MonoBehaviour {
GameObject masterGameObject;
public GameObject spawnPointPrefab;
public GameObject goalPrefab;
public GameObject enemySpawnerPrefab;
public int tileSize;
public BlockColors blockColors = new BlockColors();
//public Texture2D levelMap;
Color []pixels;
LayerGroup activeLayer;
public LayerGroup baseLayer;
public LayerGroup foregroundLayer;
public LayerGroup backgroundLayer;
/*public*/ Sprite []tops;
/*public*/ Sprite []middles;
/*public*/ Sprite []trs;
/*public*/ Sprite []leftCaps;
/*public*/ Sprite []singleCorners;
/*public*/ Sprite []singleVerticals;
Sprite []innerCornerTLs;
Sprite top;
Sprite middle;
Sprite tr;
Sprite leftCap;
Sprite singleCorner;
Sprite singleVertical;
Sprite innerCornerTL;
/*public*/ Sprite bottom;
/*public*/ Sprite left;
/*public*/ Sprite right;
/*public*/ Sprite tl;
/*public*/ Sprite br;
/*public*/ Sprite bl;
/*public*/ Sprite rightCap;
/*public*/ Sprite topCap;
/*public*/ Sprite bottomCap;
/*public*/ Sprite singleHorizontal;
public Sprite none;
public Sprite errorSprite;
public Sprite defaultSprite;
int width;
int height;
//ArrayList blocks;
WorldBlock [,]bMap;
ArrayList objectsCreated;
void DestroyEverything() {
if(objectsCreated==null) {
objectsCreated = new ArrayList();
return;
}
foreach(GameObject g in objectsCreated) {
//GameObject.Destroy(g);
GameObject.DestroyImmediate(g);
}
objectsCreated = new ArrayList();
}
void NewObjectWasCreated(GameObject go) {
go.transform.parent = transform;
objectsCreated.Add(go);
}
Texture2D baseLevel;
Texture2D backgroundLevel;
Texture2D foregroundLevel;
public void SetLevels(Texture2D _baseLevel, Texture2D _backgroundLevel, Texture2D _foregroundLevel) {
baseLevel = _baseLevel;
backgroundLevel = _backgroundLevel;
foregroundLevel = _foregroundLevel;
}
void SetLayer(LayerGroup ll) {
activeLayer = ll;
tops = activeLayer.tops;
middles = activeLayer.middles;
trs = activeLayer.trs;
leftCaps = activeLayer.leftCaps;
singleCorners = activeLayer.singleCorners;
singleVerticals = activeLayer.singleVerticals;
innerCornerTLs = activeLayer.innerCornerTLs;
}
float zOrder = 0;
public void Create() {
DestroyEverything();
createColliders = true;
zOrder = -0.2f;
if(baseLevel!=null && baseLayer!=null) {
SetLayer(baseLayer);
CreateWithLevel(baseLevel);
}
if(backgroundLevel!=null && backgroundLayer!=null) {
createColliders = false;
zOrder = -0.1f;
SetLayer(backgroundLayer);
CreateWithLevel(backgroundLevel);
}
if(foregroundLevel!=null && foregroundLayer!=null) {
createColliders = false;
zOrder = -0.3f;
SetLayer(foregroundLayer);
CreateWithLevel(foregroundLevel);
}
}
bool createColliders = true;
public void CreateWithLevel (Texture2D levelData) {
ShuffleSprites();
//if(UnityEditor.EditorApplication.isPlaying) return;
Debug.Log("Start");
pixels = levelData.GetPixels();
width = levelData.width;
height = levelData.height;
int x = 0;
int y = 0;
int z = 0;
bMap = new WorldBlock[levelData.width,levelData.height];
foreach(Color c in pixels) {
WorldBlock block = new WorldBlock(c);
block.x = x;
block.y = y;
// Save this to our map for arrangement later
bMap[x,y] = block;
//Debug.Log("saved "+block.Name()+" as "+bMap[x,y].Name());
// blocks.Add(block);
x++;
if(x>=width) {
x=0;
y++;
}
}
InstantiateAllBlocks();
}
void InstantiateAllBlocks() {
foreach(WorldBlock b in bMap) {
InstantiateBlock(b);
}
DiscoverBlocks();
AdjustSprites();
}
void DiscoverBlocks() {
// Inform the block of it's surrounding blocks
int i = 0;
foreach(WorldBlock iBlock in bMap) {
//Debug.Log("thisblock: "+iBlock.Name()+" thisblock2: "+bMap[iBlock.x, iBlock.y].Name());
bool hasLeftBlock = true;
bool hasRightBlock = true;
bool hasUpBlock = true;
bool hasDownBlock = true;
bool hasUpLeftBlock = true;
bool hasUpRightBlock = true;
bool hasDownLeftBlock = true;
bool hasDownRightBlock = true;
if(iBlock.x==0) {
hasLeftBlock = false;
hasUpLeftBlock = false;
hasDownLeftBlock = false;
}
if(iBlock.x==(width-1)) {
hasRightBlock = false;
hasUpRightBlock = false;
hasDownRightBlock = false;
}
if(iBlock.y==0) {
hasUpBlock = false;
hasUpRightBlock = false;
hasUpLeftBlock = false;
}
if(iBlock.y==(height-1)) {
hasDownBlock = false;
hasDownLeftBlock = false;
hasDownRightBlock = false;
}
if(hasLeftBlock) {
iBlock.leftBlock = bMap[iBlock.x-1, iBlock.y];
iBlock.leftBlockColor = bMap[iBlock.x-1, iBlock.y].color;
// Debug.Log("set left block to "+iBlock.leftBlock.Name());
}
if(hasRightBlock) iBlock.rightBlock = bMap[iBlock.x+1,iBlock.y];
if(hasUpBlock) iBlock.upBlock = bMap[iBlock.x, iBlock.y-1];
if(hasDownBlock) iBlock.downBlock = bMap[iBlock.x, iBlock.y+1];
if(hasUpLeftBlock) iBlock.upLeftBlock = bMap[iBlock.x-1,iBlock.y-1];
if(hasUpRightBlock) iBlock.upRightBlock = bMap[iBlock.x+1,iBlock.y-1];
if(hasDownLeftBlock) iBlock.downLeftBlock = bMap[iBlock.x-1,iBlock.y+1];
if(hasDownRightBlock) iBlock.downRightBlock = bMap[iBlock.x+1,iBlock.y+1];
//if(hasDownLeftBlock) {
//Debug.Log("has downleft "+ iBlock);
//}
}
}
void InstantiateBlock(WorldBlock b) {
GameObject newTile = new GameObject();
newTile.name = "Block "+b.x+" "+b.y;
WorldBlockGameObject newWBO = newTile.AddComponent<WorldBlockGameObject>();
newWBO.worldBlock = b;
SpriteRenderer sr = newTile.AddComponent<SpriteRenderer>();
sr.sortingLayerID = 0;
float scale = tileSize / 100.0f ;//1.28f;
int z = 0;
newTile.transform.position = new Vector3(scale*b.x,scale*b.y,z);
newWBO.worldBlock.gameObject = newWBO.gameObject;
NewObjectWasCreated(newTile);
if(masterGameObject==null) {
masterGameObject = new GameObject();
masterGameObject.name = "Blocks";
masterGameObject.transform.parent = transform;
}
newTile.transform.parent = masterGameObject.transform;
}
int RotationForSprite(Sprite s) {
if(s==singleHorizontal) return 90;
return 0;
}
void ShuffleSprites() {
if(tops.Length>0)
top = tops[ Mathf.FloorToInt(Random.Range(0,tops.Length)) ];
else top = defaultSprite;
if(middles.Length>0) {
int index = Mathf.FloorToInt(Random.Range(0,middles.Length));
middle = middles[index];
/// Debug.Log("Suffled middle to "+index+" with a range of 0 to "+middles.Length);
}
else middle = defaultSprite;
if(trs.Length>0)
tr = trs[ Mathf.FloorToInt(Random.Range(0,trs.Length)) ];
else tr = defaultSprite;
if(leftCaps.Length>0)
leftCap = leftCaps[ Mathf.FloorToInt(Random.Range(0,leftCaps.Length)) ];
else leftCap = defaultSprite;
if(singleCorners.Length>0)
singleCorner = singleCorners[ Mathf.FloorToInt(Random.Range(0,singleCorners.Length)) ];
else singleCorner = defaultSprite;
if(singleVerticals.Length>0)
singleVertical = singleVerticals[ Mathf.FloorToInt(Random.Range(0,singleVerticals.Length)) ];
else singleVertical = defaultSprite;
if(innerCornerTLs.Length>0)
innerCornerTL = innerCornerTLs[ Mathf.FloorToInt(Random.Range(0,innerCornerTLs.Length)) ];
else innerCornerTL = defaultSprite;
}
void AdjustSprites() {
foreach(WorldBlock b in bMap) {
float rot = 0;
Sprite chosenSprite = none;
/*ArrayList possibleSprites = new ArrayList();
possibleSprites.Add(top);
possibleSprites.Add(bottom);
possibleSprites.Add(middle);
possibleSprites.Add(left);
possibleSprites.Add(right);
possibleSprites.Add(tr);
possibleSprites.Add(tl);
possibleSprites.Add(br);
possibleSprites.Add(bl);
possibleSprites.Add(singleHorizontal);
possibleSprites.Add(singleVertical);
possibleSprites.Add(innerCornerTL);*/
WorldBlockGameObject wbgo = b.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject;
// For debugging
if(b.leftBlock!=null) wbgo.leftBlock = (b.leftBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.rightBlock!=null) wbgo.rightBlock = (b.rightBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.downBlock!=null) wbgo.downBlock = (b.downBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.upBlock!=null) wbgo.upBlock = (b.upBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.upRightBlock!=null) wbgo.upRightBlock = (b.upRightBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.upLeftBlock!=null) wbgo.upLeftBlock = (b.upLeftBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.downLeftBlock!=null) wbgo.downLeftBlock = (b.downLeftBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(b.downRightBlock!=null) wbgo.downRightBlock = (b.downRightBlock.gameObject.GetComponent<WorldBlockGameObject>() as WorldBlockGameObject);
if(blockColors.IsSolid(b.color)) {
int blockCode = 0;
/*if(b.leftBlock!=null && blockColors.IsSolid(b.leftBlock.color) ) blockCode += 1;
if(b.rightBlock!=null && blockColors.IsSolid(b.rightBlock.color) ) blockCode += 10;
if(b.downBlock!=null && blockColors.IsSolid(b.downBlock.color) ) blockCode += 100;
if(b.upBlock!=null && blockColors.IsSolid(b.upBlock.color) ) blockCode += 1000;*/
//if(b.upRightBlock!=null && blockColors.IsSolid(b.upRightBlock.color))
WorldBlock []blocks = { b.leftBlock, b.rightBlock, b.downBlock, b.upBlock, b.upRightBlock, b.upLeftBlock, b.downLeftBlock, b.downRightBlock};
//int codeTensPlace = 1;
//int codeBits = 1;
int bitPlace = 0;
foreach(WorldBlock testBlock in blocks) {
/*//if(testBlock!=null && blockColors.IsSolid(testBlock.color) ) blockCode += codeTensPlace;
if(testBlock!=null && blockColors.IsSolid(testBlock.color) ) {
if(codeBits==1)
blockCode = 1;
else
blockCode = 1 << codeBits;
}
else if(codeBits==1)
blockCode = 0;
codeTensPlace *= 10;
codeBits++;*/
int thisBitValue = 1<<bitPlace;
if(testBlock!=null && blockColors.IsSolid(testBlock.color) ) blockCode |= thisBitValue;
bitPlace++;
}
if(createColliders) {
BoxCollider2D bc = wbgo.gameObject.AddComponent<BoxCollider2D>() as BoxCollider2D;
bc.size = new Vector2(tileSize/100.0f,tileSize/100.0f);
bc.gameObject.tag = "Ground";
}
Debug.Log("d");
wbgo.code = blockCode;
int bLeftBlock = (1<<0);
int bRightBlock = (1<<1);
int bDownBlock = (1<<2);
int bUpBlock = (1<<3);
int bUpRightBlock = (1<<4);
int bUpLeftBlock = (1<<5);
int bDownLeftBlock = (1<<6);
int bDownRightBlock = (1<<7);
// Some default cases
if( (blockCode&(1<<1))!=0) {
// Has right block
chosenSprite = left;
}
else if( (blockCode&(1<<0)) == 0 ){
chosenSprite = singleVertical;
}
if( (blockCode&(1<<0)) != 0 ) {
// Has left block.
chosenSprite = right;
if( (blockCode&(1<<1))!=0) {
// Has right block too
chosenSprite = middle;
if( (blockCode&(1<<3))==0) {
// Doesn't have a block above
chosenSprite = top;
if( (blockCode&(1<<2))==0) {
// Doesn't have a block below
chosenSprite = singleHorizontal;
}
}
}
}
if( ((blockCode^(1<<1))==0) ) {
// Only has left block
chosenSprite = leftCap;
}
if( ((blockCode^(1<<0))==0) ) {
// Only has right block
chosenSprite = rightCap;
}
// bool sbAbove = (blockCode&
/*if( (blockCode^( (1<<1)|(1<<2)|(1<<3) ))==0 ) {
// Surronded by pieces, but not above
chosenSprite = top;
}*/
// Edge cases
switch(blockCode) {
case 9:
case 73:
case 25:
case 89:
case 137:
// SingleTR
chosenSprite = singleCorner;
break;
case 5:
case 37:
case 133:
case 165:
case 55:
// SingleBR
chosenSprite = singleCorner;
rot = 270;
break;
case 6:
case 22:
case 70:
case 86:
// SingleBL
rot = 180;
chosenSprite = singleCorner;
break;
case 10:
case 138:
case 42:
case 170:
// SingleTL
rot = 90;
chosenSprite = singleCorner;
break;
case 12:
case 14:
case 44:
case 76:
case 92:
case 13:
case 28:
case 124:
case 140:
case 108:
case 141:
chosenSprite = singleVertical;
break;
case 11:
case 3:
case 99:
case 147:
case 131:
case 67:
case 83:
case 35:
case 7:
case 19:
case 51:
case 195:
case 75:
case 163:
case 243:
//chosenSprite = singleHorizontal;
chosenSprite = singleVertical;
rot = 90;
break;
case 1:
case 33:
case 65:
case 193:
case 145:
case 17:
case 97:
case 161:
case 129:
//chosenSprite = rightCap;
chosenSprite = leftCap;
rot = 180;
break;
case 2:
case 18:
case 130:
case 34:
case 82:
case 146:
chosenSprite = leftCap;
break;
case 56:
case 40:
case 24:
//chosenSprite = topCap;
chosenSprite = leftCap;
rot = 270;
break;
case 4:
case 132:
//chosenSprite = bottomCap;
chosenSprite = leftCap;
rot = 90;
break;
case 199:
case 231:
case 247:
case 215:
//chosenSprite = bottom;
chosenSprite = top;
rot = 180;
break;
case 59:
case 123:
case 187:
case 251:
chosenSprite = top;
break;
case 222:
case 158:
case 159:
case 191:
case 254:
case 190:
//chosenSprite = left;
chosenSprite = top;
rot = 90;
break;
case 109:
case 125:
case 111:
case 127:
case 237:
//chosenSprite = right;
chosenSprite = top;
rot = 270;
break;
case 41:
case 61:
case 105:
case 57:
case 121:
case 253:
case 47:
case 43:
case 107:
case 169:
case 45:
case 173:
case 171:
chosenSprite = tr;
break;
case 134:
case 142:
case 135:
case 150:
case 230:
case 214:
case 167:
case 166:
case 198:
case 206:
case 174:
//chosenSprite = bl;
chosenSprite = tr;
rot = 180;
break;
case 229:
case 69:
case 71:
case 101:
case 87:
case 197:
case 93:
case 77:
case 205:
//chosenSprite = br;
chosenSprite = tr;
rot = 270;
break;
case 31:
case 26:
case 58:
case 186:
case 154:
case 91:
case 27:
case 30:
case 62:
case 90:
case 155:
//chosenSprite = tl;
chosenSprite = tr;
rot = 90;
break;
case 255:
chosenSprite = middle;
break;
}
bool surrounded = blockColors.IsSolid(b.upBlock.color) && blockColors.IsSolid(b.leftBlock.color) && blockColors.IsSolid(b.downBlock.color) && blockColors.IsSolid(b.rightBlock.color);
if( surrounded && !blockColors.IsSolid(b.downRightBlock.color) && blockColors.IsSolid(b.downLeftBlock.color) && blockColors.IsSolid(b.upRightBlock.color) && blockColors.IsSolid(b.upLeftBlock.color) ) {
chosenSprite = innerCornerTL;
rot = -90;
}
else if( surrounded && !blockColors.IsSolid(b.downLeftBlock.color) && blockColors.IsSolid(b.downRightBlock.color) && blockColors.IsSolid(b.upRightBlock.color) && blockColors.IsSolid(b.upLeftBlock.color) ) {
chosenSprite = innerCornerTL;
rot = 0;
}
else if( surrounded && !blockColors.IsSolid(b.upRightBlock.color) && blockColors.IsSolid(b.downLeftBlock.color) && blockColors.IsSolid(b.downRightBlock.color) && blockColors.IsSolid(b.upLeftBlock.color) ) {
chosenSprite = innerCornerTL;
rot = 180;
}
else if( surrounded && !blockColors.IsSolid(b.upLeftBlock.color) && blockColors.IsSolid(b.downLeftBlock.color) && blockColors.IsSolid(b.upRightBlock.color) && blockColors.IsSolid(b.downRightBlock.color) ) {
chosenSprite = innerCornerTL;
rot = 90;
}
// chosenSprite = innerCornerTL;
if(chosenSprite==null) chosenSprite = errorSprite;
}
else {
// This is a non-solid block
chosenSprite = null;
if(blockColors.IsEnemySpawner(b.color)) {
NewObjectWasCreated(GameObject.Instantiate(enemySpawnerPrefab, wbgo.transform.position, Quaternion.identity) as GameObject);
}
else if(blockColors.isGoal(b.color)) {
NewObjectWasCreated(GameObject.Instantiate(goalPrefab, wbgo.transform.position, Quaternion.identity) as GameObject);
}
else if(blockColors.IsSpawnPoint(b.color)) {
NewObjectWasCreated(GameObject.Instantiate(spawnPointPrefab, wbgo.transform.position, Quaternion.identity) as GameObject);
}
}
ShuffleSprites();
SpriteRenderer sr = b.gameObject.GetComponent<SpriteRenderer>() as SpriteRenderer;
sr.sprite = chosenSprite;
sr.gameObject.transform.position = new Vector3(sr.gameObject.transform.position.x, sr.gameObject.transform.position.y, zOrder);
if(rot!=0) {
sr.transform.localRotation = Quaternion.Euler(0,0,rot);
}
else {
//sr.transform.localRotation = Quaternion.Euler(0,0,RotationForSprite(chosenSprite));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment