Created
April 23, 2012 06:27
-
-
Save Blecki/2469125 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import Box2D.Collision.Shapes.b2PolygonShape; | |
import Box2D.Common.Math.b2Vec2; | |
import Box2D.Dynamics.b2Body; | |
import Box2D.Dynamics.b2BodyDef; | |
import Box2D.Dynamics.b2FixtureDef; | |
import flash.display.BitmapData; | |
import flash.display.GraphicsBitmapFill; | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import net.flashpunk.Entity; | |
import net.flashpunk.graphics.Graphiclist; | |
import net.flashpunk.graphics.Image; | |
import net.flashpunk.graphics.Spritemap; | |
import net.flashpunk.masks.Hitbox; | |
import net.flashpunk.FP; | |
/** | |
* ... | |
* @author AJC | |
*/ | |
public class Chunk extends Entity | |
{ | |
public var traversed:Boolean = false; | |
public var physicsBody:b2Body = null; | |
public var biome:int = 0; | |
public var blockType:int = 0; | |
public var tilesWidth:Number = 0; | |
public var tilesHeight:Number = 0; | |
private static var rect:Rectangle = new Rectangle(); | |
public var connectedChunks:Array = []; | |
public static var connectionOverlay:Spritemap = new Spritemap(Assets.CONNECTION_OVERLAY, 20, 20); | |
public function Chunk(world:TinyWorld, btype:int, worldType:int) | |
{ | |
biome = FP.rand(5); | |
//if (btype == 0) | |
// blockType = FP.rand(4); | |
//else | |
blockType = btype; | |
var angle:Number = 0; | |
if (blockType == 6) | |
{ | |
angle = -Math.PI / 2; | |
blockType = 1; | |
} | |
else if (blockType == 7) | |
{ | |
angle = -Math.PI / 2; | |
blockType = 2; | |
} | |
switch (blockType) | |
{ | |
case 0: | |
tilesWidth = 1; | |
tilesHeight = 1; | |
rect.x = 0; | |
rect.y = 0; | |
break; | |
case 1: | |
tilesWidth = 2; | |
tilesHeight = 1; | |
rect.x = 1; | |
rect.y = 0; | |
break; | |
case 2: | |
tilesWidth = 3; | |
tilesHeight = 1; | |
rect.x = 0; | |
rect.y = 1; | |
break; | |
case 3: | |
tilesWidth = 2; | |
tilesHeight = 2; | |
rect.x = 3; | |
rect.y = 0; | |
break; | |
case 4: | |
tilesWidth = 2; | |
tilesHeight = 2; | |
rect.x = 0; | |
rect.y = 0; | |
break; | |
} | |
rect.x *= Assets.TILE_WIDTH; | |
rect.y *= Assets.TILE_HEIGHT; | |
rect.width = tilesWidth * Assets.TILE_WIDTH; | |
rect.height = tilesHeight * Assets.TILE_HEIGHT; | |
if (blockType != 4) | |
{ | |
switch (biome) | |
{ | |
case 0: | |
rect.x += ((worldType == 0 ? 2 : 0) * Assets.TILE_WIDTH); | |
break; | |
case 1: | |
rect.x += ((worldType == 0 ? 7 : 5) * Assets.TILE_WIDTH); | |
break; | |
case 2: | |
rect.x += ((worldType == 0 ? 12 : 10) * Assets.TILE_WIDTH); | |
break; | |
case 3: | |
rect.y += (2 * Assets.TILE_HEIGHT); | |
break; | |
case 4: | |
rect.y += (2 * Assets.TILE_HEIGHT); | |
rect.x += (5 * Assets.TILE_WIDTH); | |
} | |
} | |
rect.y += worldType * (Assets.TILE_HEIGHT * 4); | |
var image:Image = new Image(Assets.WORLDTILES, new Rectangle(rect.x, rect.y, rect.width, rect.height)); | |
var bodyDef:b2BodyDef = new b2BodyDef(); | |
physicsBody = world.physicsWorld.CreateBody(bodyDef); | |
physicsBody.SetUserData(this); | |
physicsBody.SetType(b2Body.b2_dynamicBody); | |
//var image:Image = new Image(new BitmapData(width * 16, height * 16, false, 0xFFFFFFFF)); | |
image.originX = (tilesWidth * Assets.TILE_WIDTH) / 2;// + (tilesWidth % 2 == 1 ? -(Assets.TILE_WIDTH / 2) : 0); | |
image.originY = (tilesHeight * Assets.TILE_HEIGHT) / 2;// + (tilesHeight % 2 == 1 ? -(Assets.TILE_HEIGHT / 2) : 0); | |
graphic = image; | |
var boxShape:b2PolygonShape = new b2PolygonShape(); | |
boxShape.SetAsBox(tilesWidth/2, tilesHeight/2); | |
//for each (var vertex:b2Vec2 in boxShape.GetVertices()) | |
//{ | |
// if (tilesWidth % 2 == 1) vertex.x += 0.5; | |
// if (tilesHeight % 2 == 1) vertex.y += 0.5; | |
//} | |
var fixtureDef:b2FixtureDef = new b2FixtureDef(); | |
fixtureDef.shape = boxShape; | |
fixtureDef.density = 0.2; | |
fixtureDef.restitution = 0.0; | |
physicsBody.CreateFixture(fixtureDef).SetUserData(this); | |
physicsBody.SetAngle(angle); | |
//physicsBody.SetFixedRotation(true); | |
//physicsBody.SetLinearDamping(0.9999); | |
/*var tetrimo:int = FP.rand(tetrimos.length); | |
for (var x:int = 0; x < 3; ++x) | |
for (var y:int = 0; y < 3; ++y) | |
if (tetrimos[tetrimo][ (y * 3) + x ] == 1) AddSquare(x - 2, y - 2, 1, 1); | |
*/ | |
} | |
public function CalculateTargetOffset(localVec:b2Vec2):Object | |
{ | |
var angle:Number = TinyWorld.AngleBetweenVectors(b2Vec2.Make(0, -1), localVec); | |
if (Math.abs(angle) < Math.PI * 0.25) | |
return { | |
offset: b2Vec2.Make(0, -tilesHeight / 2), | |
normal: b2Vec2.Make(0, -1), | |
frame: (tilesWidth == 1 ? 2 : 1) | |
} | |
else if (Math.abs(angle) > Math.PI * 0.75) | |
return { | |
offset: b2Vec2.Make(0, tilesHeight / 2), | |
normal: b2Vec2.Make(0, 1), | |
frame: (tilesWidth == 1 ? 2 : 1) | |
} | |
else if (angle < 0) | |
return { | |
offset: b2Vec2.Make(-tilesWidth / 2, 0), | |
normal: b2Vec2.Make( -1, 0), | |
frame: (tilesHeight == 1 ? 2 : 1) | |
} | |
else | |
return { | |
offset: b2Vec2.Make(tilesWidth / 2, 0), | |
normal: b2Vec2.Make(1, 0), | |
frame: (tilesHeight == 1 ? 2 : 1) | |
} | |
} | |
override public function update():void | |
{ | |
(graphic as Image).angle = -physicsBody.GetAngle() * (180.0 / Math.PI); | |
this.x = physicsBody.GetPosition().x * Assets.TILE_WIDTH; | |
this.y = physicsBody.GetPosition().y * Assets.TILE_HEIGHT; | |
super.update(); | |
} | |
private function hiliteEdge(type:int, ex:Number, ey:Number, angle:Number) | |
{ | |
angle *= 90; | |
connectionOverlay.frame = type; | |
connectionOverlay.angle = angle + (graphic as Image).angle; | |
connectionOverlay.centerOrigin(); | |
var pos:b2Vec2 = physicsBody.GetWorldPoint(b2Vec2.Make(ex + 0.5, ey + 0.5)); | |
connectionOverlay.render(FP.buffer, new Point(pos.x * 20, pos.y * 20), FP.camera); | |
} | |
override public function render():void | |
{ | |
super.render(); | |
for each (var conn:Object in connectedChunks) | |
DrawConnectedEdge(conn.chunk, 1); | |
} | |
public function GetClassifiedRelativeAngle(chunk:Chunk):int | |
{ | |
var classifyAngle:Number = (TinyWorld.normalizeAngle(chunk.physicsBody.GetAngle() - physicsBody.GetAngle()) + 2 * Math.PI) | |
/ (Math.PI / 2); | |
return ClassifyAngle(classifyAngle); | |
} | |
public function ClassifyAngle(classifyAngle:Number):int | |
{ | |
var cAngle:int = 0; | |
if (classifyAngle < 0.5) cAngle = 0; | |
else if (classifyAngle < 1.5) cAngle = 1; | |
else if (classifyAngle < 2.5) cAngle = 0; | |
else if (classifyAngle < 3.5) cAngle = 1; | |
else if (classifyAngle < 4.5) cAngle = 0; | |
else if (classifyAngle < 5.5) cAngle = 1; | |
else if (classifyAngle < 6.5) cAngle = 0; | |
else if (classifyAngle < 7.5) cAngle = 1; | |
else if (classifyAngle < 8.5) cAngle = 0; | |
else if (classifyAngle < 9.5) cAngle = 1; | |
else cAngle = 0; | |
return cAngle; | |
} | |
public function makeEdge(point:b2Vec2, dir:b2Vec2, min:Number, max:Number):Object | |
{ | |
point = physicsBody.GetWorldPoint(point); | |
dir = physicsBody.GetWorldVector(dir); | |
return { | |
start: TinyWorld.vAdd(point, TinyWorld.Multiply(dir, min)), | |
end: TinyWorld.vAdd(point, TinyWorld.Multiply(dir, max)), | |
point: point, | |
dir: dir, | |
min: min, | |
max: max | |
}; | |
} | |
public function FindConnectedEdgeLine(chunk:Chunk):Object | |
{ | |
var otherRelativePosition:b2Vec2 = physicsBody.GetLocalPoint(chunk.physicsBody.GetPosition()); | |
var cAngle:int = GetClassifiedRelativeAngle(chunk); | |
var otherEdgeLength:Number = 0; | |
if (otherRelativePosition.x < - (tilesWidth / 2) + 0.5) | |
{ | |
if (cAngle == 0) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.y - (otherEdgeLength / 2), -(tilesHeight / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.y + (otherEdgeLength / 2), (tilesHeight / 2)); | |
if (edgeMin + 0.5 < edgeMax) return makeEdge( | |
b2Vec2.Make(-(tilesWidth/2), 0), b2Vec2.Make(0, 1), edgeMin, edgeMax); | |
} | |
if (otherRelativePosition.x > (tilesWidth / 2) - 0.5) | |
{ | |
if (cAngle == 0) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.y - (otherEdgeLength / 2), -(tilesHeight / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.y + (otherEdgeLength / 2), (tilesHeight / 2)); | |
if (edgeMin + 0.5 < edgeMax) return makeEdge( | |
b2Vec2.Make((tilesWidth / 2), 0), b2Vec2.Make(0, 1), edgeMin, edgeMax); | |
} | |
if (otherRelativePosition.y < -(tilesHeight / 2) + 0.5) | |
{ | |
if (cAngle == 1) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.x - (otherEdgeLength / 2), -(tilesWidth / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.x + (otherEdgeLength / 2), (tilesWidth / 2)); | |
if (edgeMin + 0.5 < edgeMax) return makeEdge( | |
b2Vec2.Make(0, -(tilesHeight / 2)), b2Vec2.Make(1, 0), edgeMin, edgeMax); | |
} | |
if (otherRelativePosition.y > (tilesHeight / 2) - 0.5) | |
{ | |
if (cAngle == 1) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.x - (otherEdgeLength / 2), -(tilesWidth / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.x + (otherEdgeLength / 2), (tilesWidth / 2)); | |
if (edgeMin + 0.5 < edgeMax) return makeEdge( | |
b2Vec2.Make(0, (tilesHeight / 2)), b2Vec2.Make(1, 0), edgeMin, edgeMax); | |
} | |
return null; | |
} | |
public function DrawConnectedEdge(chunk:Chunk, type:int):void | |
{ | |
var otherRelativePosition:b2Vec2 = physicsBody.GetLocalPoint(chunk.physicsBody.GetPosition()); | |
var cAngle:int = GetClassifiedRelativeAngle(chunk); | |
var otherEdgeLength:Number = 0; | |
if (otherRelativePosition.x < - (tilesWidth / 2) + 0.5) | |
{ | |
if (cAngle == 0) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.y - (otherEdgeLength / 2), -(tilesHeight / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.y + (otherEdgeLength / 2), (tilesHeight / 2)); | |
while (edgeMin + 0.5 < edgeMax) | |
{ | |
hiliteEdge(type, -(tilesWidth / 2), edgeMin, 1); | |
edgeMin += 1; | |
} | |
} | |
if (otherRelativePosition.x > (tilesWidth / 2) - 0.5) | |
{ | |
if (cAngle == 0) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.y - (otherEdgeLength / 2), -(tilesHeight / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.y + (otherEdgeLength / 2), (tilesHeight / 2)); | |
while (edgeMin + 0.5 < edgeMax) | |
{ | |
hiliteEdge(type, (tilesWidth / 2) - 1, edgeMin, -1); | |
edgeMin += 1; | |
} | |
} | |
if (otherRelativePosition.y < -(tilesHeight / 2) + 0.5) | |
{ | |
if (cAngle == 1) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.x - (otherEdgeLength / 2), -(tilesWidth / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.x + (otherEdgeLength / 2), (tilesWidth / 2)); | |
while (edgeMin + 0.5 < edgeMax) | |
{ | |
hiliteEdge(type, edgeMin, -(tilesHeight / 2), 0); | |
edgeMin += 1; | |
} | |
} | |
if (otherRelativePosition.y > (tilesHeight / 2) - 0.5) | |
{ | |
if (cAngle == 1) otherEdgeLength = chunk.tilesHeight; | |
else otherEdgeLength = chunk.tilesWidth; | |
var edgeMin:Number = Math.max(otherRelativePosition.x - (otherEdgeLength / 2), -(tilesWidth / 2)); | |
var edgeMax:Number = Math.min(otherRelativePosition.x + (otherEdgeLength / 2), (tilesWidth / 2)); | |
while (edgeMin + 0.5 < edgeMax) | |
{ | |
hiliteEdge(type, edgeMin, (tilesHeight / 2) - 1, 2); | |
edgeMin += 1; | |
} | |
} | |
} | |
private function IsOdd(x:Number):Boolean { return x % 2 == 1; } | |
public function ClearSelected():void | |
{ | |
(graphic as Image).color = 0xFFFFFFFF; | |
} | |
public function SetActive():void | |
{ | |
(graphic as Image).color = 0xFFFF0000; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment