From 8e431dc9e4d1b8d10263858767a03817b98ab857 Mon Sep 17 00:00:00 2001 From: Naveen Radhakrishnan Date: Sat, 6 Jun 2020 14:03:19 +0000 Subject: [PATCH] Initial checkin --- src/Data.hx | 1 + src/Game.hx | 489 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 490 insertions(+) create mode 100644 src/Data.hx create mode 100644 src/Game.hx diff --git a/src/Data.hx b/src/Data.hx new file mode 100644 index 0000000..80b732e --- /dev/null +++ b/src/Data.hx @@ -0,0 +1 @@ +private typedef Init = haxe.macro.MacroType < [cdb.Module.build("data.cdb")] > ; diff --git a/src/Game.hx b/src/Game.hx new file mode 100644 index 0000000..1d175ac --- /dev/null +++ b/src/Game.hx @@ -0,0 +1,489 @@ +import hxd.res.DynamicText.Key; +import h3d.pass.Default; +import ent.Entity; +import ent.Object; +import hxd.Key in K; + +class EnvPart extends h2d.SpriteBatch.BatchElement { + + public var speed : Float; + public var rspeed : Float; + + public function new(t) { + super(t); + x = Math.random() * Game.LW * 32; + y = Math.random() * Game.LH * 32; + speed = 6 + Math.random() * 3; + rspeed = 0.02 * (1 + Math.random()); + } + +} + +@:publicFields +class Game extends hxd.App { + + static var LW = 13; + static var LH = 13; + + static var LAYER_SOIL = 0; + static var LAYER_ENT_UNDER = 1; + static var LAYER_COL = 2; + static var LAYER_ENT = 3; + static var LAYER_CARRY = 4; + static var LAYER_HERO = 5; + static var LAYER_PARTS = 6; + static var LAYER_ENVP = 7; + static var LAYER_END = 8; + + + var currentLevel : Int; + + var tiles : h2d.Tile; + var level : Data.Level; + var soils : Array; + var entities : Array = []; + var world : h2d.Layers; + var dbgCol : h2d.TileGroup; + var soilLayer : h2d.TileGroup; + var pad : hxd.Pad; + var allActive : Bool; + + var bg : h2d.Object; + var clouds = []; + + var parts : h2d.SpriteBatch; + var way : Float = 1.; + var bmpTrans : h2d.Bitmap; + + var hueShaderHalf = new h3d.shader.ColorMatrix(); + var hueValue = 0; + + var title : h2d.Bitmap; + var end : h2d.Bitmap; + + var errorSound: hxd.res.Sound; + + function loadGame() { + haxe.Timer.delay(function() { + for( e in entities.copy() ) + if( e.hasFlag(NeedActive) ) + e.remove(); + bg.visible = false; + parts.visible = false; + + var t = new h3d.mat.Texture(LW * 32, LH * 32, [Target]); + var old = world.filter; + world.filter = null; + world.drawTo(t); + world.filter = old; + bmpTrans = new h2d.Bitmap(h2d.Tile.fromTexture(t)); + + bg.visible = true; + parts.visible = true; + + initLevel(); + + world.add(bmpTrans, LAYER_ENT - 1); + + },0); + } + + function initLevel() + { + level = Data.level.all[currentLevel]; + if( level == null ) + return; + + soils = level.soils.decode(Data.soil.all); + while( soilLayer.numChildren > 0 ) + soilLayer.getChildAt(0).remove(); + + // Build game board + var empty = tiles.sub(0, 2 * 32, 32, 32); + var edgeTile = tiles.sub(2*32, 2 * 32, 32, 32); + soilLayer.clear(); + for( y in 0...LH ) { + for( x in 0...LW ) { + var index = x + y * LW; + var s = soils[x + y * LW]; + if(x > 1 && x < 11 && y > 1 && y < 11) + { + // check if it is the corner or center tile + if((x==y || (x + y) == 12)&& (x == 2 || x == 6 || x == 10) ) + { + soilLayer.add(x * 32, y * 32, edgeTile); + } + else + { + soilLayer.add(x * 32, y * 32, empty); + } + } + + // place object on the board + createObject(x, y); + } + } + + // Handle interactions + var prevKind = null; + var clickedObjKind = null; + var clickedObj = null; + var isFirstClick = true; + var sX = 0, sY = 0; + var eX = 0, eY = 0; + var interaction = new h2d.Interactive(1000, 1000, soilLayer); + var count = 0; + interaction.onClick = function(event : hxd.Event) { + var xPos = Std.int((event.relX)/32); + var yPos = Std.int((event.relY)/32); + + if (isFirstClick == true){ + sX = xPos; + sY = yPos; + //trace (isFirstClick); + clickedObj = Std.downcast(pick(sX, sY), Object); + if(clickedObj != null) + { + isFirstClick = false; + // Treat the purple circle and the purple gem as same kind + if (isKing(clickedObj.kind)) + clickedObjKind = Data.ObjectKind.Exit; + else + clickedObjKind = clickedObj.kind; + } + } + else{ + trace (prevKind); + eX = xPos; + eY = yPos; + isFirstClick = true; + //trace (isFirstClick); + var destinationObj = Std.downcast(pick(eX, eY), Object); + + var isAcceptableMove = true; + if (destinationObj == null && // destination tile is empty + clickedObj != null && // you have clicked an object to move + prevKind != clickedObjKind && // alternating turns + (eX == sX || eY == sY)) // moving horizontally or vertically + { + + // Check that there are no blockade between start and end + var isHorizontal = false; + var distanceToMove = 0; + var tempX = sX; + var tempY = sY; + if (eX == sX){ + distanceToMove = eY - sY; + if (distanceToMove < 0){ + tempY--; + } + else{ + tempY++; + } + } + else if (eY == sY){ + isHorizontal = true; + distanceToMove = eX - sX; + if (distanceToMove < 0){ + tempX--; + } + else{ + tempX++; + } + + } + trace ('sX, sY: ' + sX + ',' + sY); + trace ('eX, eY: ' + eX + ',' + eY); + + trace ('isHorizontal: ' + isHorizontal); + trace ('distanceToMove: ' + distanceToMove); + + + while (distanceToMove != 0){ + var oB = Std.downcast(pick(tempX, tempY), Object); + + trace ('tempX, tempY: ' + tempX + ',' + tempY); + if (oB == null && isHorizontal){ + if (distanceToMove < 0) + tempX--; + else + tempX++; + } + else if (oB == null && !isHorizontal){ + if (distanceToMove < 0) + tempY--; + else + tempY++; + } + else if (oB != null){ + trace ('oB is not null '); + isAcceptableMove = false; + break; + + } + if (distanceToMove > 0) + distanceToMove--; + else + distanceToMove++; + } + + // check if a non-player object is moving to the cornre + if((eX == 2 || eX == 10) && (eY == 2 || eY == 10)) + { + if (!isKing(clickedObj.kind)){ + isAcceptableMove = false; + } + } + + // Move the object + if (isAcceptableMove){ + // remove from the source position + clickedObj.remove(); + + // create the object in the destination position + var movedObj = new ent.Object(clickedObj.kind, eX, eY); + if ((eX == 2 || eX == 10) && (eY == 2 || eY == 10)){ + + // End game if reached the corner + if (isKing(movedObj.kind)){ + displayEnd(); + } + } + prevKind = clickedObjKind; + + //To Do: Add Logic for Capture + /*if (eX == sX){ + if (distanceToMove > 0){ + var obJ = Std.downcast(pick(eX, eY + 2), Object); + var Obj = Std.downcast(pick(eX, eY + 1), Object); + if (obJ != null && Obj != null){ + if (obJ.kind == movedObj.kind && Obj.kind != movedObj.kind){ + if (movedObj.kind == Square3) + movedObj.kind = Exit; + else if (obJ.kind == Square3){ + obJ.kind = Exit; + } + + } + } + } + }*/ + + + } + } + else + { + isAcceptableMove = false; + } + + if(!isAcceptableMove && errorSound != null) + { + errorSound.play(false, 0.5 + Math.random() * 0.5); + } + } + } + } + + function displayEnd() { + end = new h2d.Bitmap(hxd.Res.end_png.toTile()); + end.scale(1); + world.add(end, LAYER_END); + // Pause for 5 sec and then end the game + haxe.Timer.delay(function() { + Game.restartGame(); + }, 5000); + } + + function createObject(x, y) : ent.Entity { + var myX = x * 1; + var myY = y * 1; + if(x==6 && y == 6) + { + return new ent.Object(Square2, x, y); + } + else if ( ((x > 4 && x < 8) && ((y == 2) || (y == 10))) || + ((y > 4 && y < 8) && ((x == 2) || (x == 10))) || + (x == 6 && (y == 3 || y == 9)) || + (y == 6 && (x == 3 || x == 9)) + ) + { + return new ent.Object(Square1, x, y); + } + else if ( (x == 6 && (y > 3 && y < 6)) || + (x == 6 && (y > 6 && y < 9)) || + (y == 6 && (x > 3 && x < 6)) || + (y == 6 && (x > 6 && x < 9)) + ) + { + return new ent.Object(Exit, x, y); + } + + return null; + } + + function isKing(kind : Data.ObjectKind ){ + return (kind == Square2); + } + + function getSoil( x, y ) : Data.SoilKind { + if( x < 0 || y < 0 || x >= LW || y >= LH ) + return Block; + return soils[x + y * LH].id; + } + + function pick( x : Float, y : Float ) { + var ix = Std.int(x); + var iy = Std.int(y); + for( e in entities ) + { + if( Std.int(e.x) == ix && Std.int(e.y) == iy ) + { + return e; + } + } + return null; + } + + override function init() { + + errorSound = hxd.Res.load("sfx/error.wav").toSound(); + + // preload sounds + for( s in hxd.Res.load("sfx") ) + s.toSound().getData(); + + s2d.scaleMode = Stretch(LW * 32, LH * 32); + currentLevel = 1; + world = new h2d.Layers(s2d); + world.filter = new h2d.filter.Bloom(0.5,0.2,3); + tiles = hxd.Res.tiles.toTile(); + soilLayer = new h2d.TileGroup(tiles); + + bg = new h2d.Object(world); + bg.filter = new h2d.filter.Blur(3); + bg.filter.smooth = true; + var tbg = tiles.sub(32 * 3, 64, 32, 32); + tbg.scaleToSize(LW * 32, LH * 32); + new h2d.Bitmap(tbg, bg).addShader(hueShaderHalf); + + // Display background clouds + var rnd = new hxd.Rand(42); + var ctiles = [for( i in 0...3 ) tiles.sub(i * 32 * 3, 192, 32 * 3, 64, -32 * 3 >> 1, -32)]; + for( i in 0...100 ) { + var b = new h2d.Bitmap(ctiles[rnd.random(ctiles.length)], bg); + b.smooth = true; + b.addShader(hueShaderHalf); + clouds.push({ sc : 0.7 + rnd.rand(), x : rnd.rand() * (LW * 32 + 200) - 100, y : rnd.rand() * (LH * 32 + 200) - 100, speed : rnd.rand() + 1, spr : b, t : Math.random() * Math.PI * 2 }); + } + + // Display the flying snow + var ptiles = hxd.Res.envParts.toTile().split(); + parts = new h2d.SpriteBatch(ptiles[0]); + world.add(parts, LAYER_ENVP); + for( i in 0...100 ) + parts.add(new EnvPart(ptiles[Std.random(ptiles.length)])); + world.add(soilLayer, LAYER_SOIL); + + pad = hxd.Pad.createDummy(); + hxd.Pad.wait(function(p) pad = p); + + // Display title and instruction to start game + title = new h2d.Bitmap(hxd.Res.title.toTile(), world); + var tf = new h2d.Text(hxd.res.DefaultFont.get(), title); + tf.textColor = 0; + tf.text = "Press space to start"; + tf.x=180; + tf.y = 180; + } + + override function update( dt : Float ) { + dt *= 60; // old dt support + + if( bmpTrans != null ) { + bmpTrans.alpha -= 0.05 * dt; + if( bmpTrans.alpha < 0 ) { + bmpTrans.tile.getTexture().dispose(); + bmpTrans.remove(); + bmpTrans = null; + } + } + + for( e in entities.copy() ) + e.update(dt); + + var ang = -0.3; + for( c in clouds ) { + var ds = c.speed * dt * 0.3 * way; + + c.t += ds * 0.01; + c.spr.setScale(1 + Math.sin(c.t) * 0.2); + c.spr.scaleX *= c.sc; + + c.x += Math.cos(ang) * ds; + c.y += Math.sin(ang) * ds; + c.spr.x = c.x; + c.spr.y = c.y; + if( c.x > LW * 32 + 100 ) + c.x -= LW * 32 + 300; + if( c.y > LH * 32 + 100 ) + c.y -= LH * 32 + 300; + if( c.x < -100 ) + c.x += LW * 32 + 300; + if( c.y < -100 ) + c.y += LH * 32 + 300; + + } + + parts.hasRotationScale = true; + for( p in parts.getElements() ) { + var p = cast(p, EnvPart); + var ds = dt * p.speed * way; + p.x += Math.cos(ang) * ds; + p.y += Math.sin(ang) * ds; + p.rotation += ds * p.rspeed; + if( p.x > LW * 32 ) + p.x -= LW * 32; + if( p.y > LH * 32 ) + p.y -= LH * 32; + if( p.y < 0 ) + p.y += LH * 32; + if( p.x < 0 ) + p.x += LW * 32; + } + + if( title != null && title.alpha < 1 ) { + title.alpha -= 0.01 * dt; + if( title.alpha < 0 ) { + title.remove(); + title = null; + } + } + + + if( title != null && title.alpha == 1 ) { + if(K.isPressed(K.SPACE)) { + title.alpha = 0.99; + loadGame(); + } + } + } + + + public static var inst : Game; + + static function main() { + #if js + hxd.Res.initEmbed(); + #else + hxd.res.Resource.LIVE_UPDATE = true; + hxd.Res.initLocal(); + #end + Data.load(hxd.Res.data.entry.getText()); + inst = new Game(); + } + + static function restartGame() { + Game.main(); + } +} \ No newline at end of file