I will create web-based game - some sort of multiplayer survival game (something like die2nite).
I will use haxe for it.
Will try to make it using:
- ufront
- jive
So, that's it, in short words.
smoke = new ParticlesManager(1000, ParticleState.Update_particle, true); emitterPosition = new Point(stageWidth + 40, stageHeight / 3); addChild(smoke);
var speed_x:Float = -20 * (Math.random()) - 20; var speed_y:Float = 14 * (Math.random()) - 7; var state:ParticleState = new ParticleState(new Point(speed_x, speed_y), 1); smoke.Create_particle(Assets.getBitmapData("assets/round_20.png"), new Point(emitterPosition.x, emitterPosition.y), 0xff0000ff, 30, new Point(0.1, 0.1), state, 0, 0.2, 0.04); // look at ParticleManager code for params description
package; import flash.geom.Point; import particles.Particle; class ParticleState { public var velocity:Point; public var lengthMultiplier:Float = 0.0; public function new(velocity:Point, lengthMultiplier:Float) { this.velocity = velocity; this.lengthMultiplier = lengthMultiplier; } public static function Update_particle(particle:Particle):Void //here you have to define how particles move { var vel:Point = particle.state.velocity; particle.position.x += vel.x; particle.position.y += vel.y; particle.bitmap.scaleX += (1 - particle.bitmap.scaleX) * particle.sizeReduction; particle.bitmap.scaleY += (1 - particle.bitmap.scaleX) * particle.sizeReduction; particle.bitmap.alpha -= particle.fading; } }
package mmg.particles; package particles; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; /** * ... * @author gordev */ typedef Action = Particle -> Void; class CircularParticleArray{ private var _start:Int; private var _list:Array ; private var _targetClass:Class ; private var _args:Array ; public var start(get, set):Int; public function get_start():Int { return _start; } public function set_start(value:Int) { _start = value % _list.length; return 0; } public var capacity(get, never):Int; public function get_capacity():Int { return _list.length; } public var list(get, never):Array ; public function get_list():Array { return _list; } public var count:Int = 0; public function new(targetClass:Class , initialCapacity:Int, args:Array ) { _targetClass = targetClass; _list = []; _args = args; for (i in 0...initialCapacity) { _list.push(Type.createInstance(_targetClass, _args)); } } public function get(i:Int):T { return _list[(_start + i) % _list.length]; } public function set(i:Int, value:T):Void { _list[(_start + i) % _list.length] = value; } } class ParticlesManager extends Sprite { private var update_particle:Action; private var particle_list:CircularParticleArray ; public function new(capacity:Int, update_particle:Action, isDisplayList:Bool) { super(); this.update_particle = update_particle; particle_list = new CircularParticleArray (Particle, capacity, []); if(isDisplayList) { for(particle in particle_list.list) { addChild(particle.bitmap); } } } public function Create_particle(texture:BitmapData, position:Point, color:UInt, duration:Float, scale:Point, state:Dynamic, theta:Float = 0, sizeReduction:Float = 1, fading:Float = 1):Void { var particle:Particle; if (particle_list.count == particle_list.capacity) { // if the list is full, overwrite the oldest particle, and rotate the circular list particle = particle_list.get(0); particle_list.start++; }else{ particle = particle_list.get(particle_list.count); particle_list.count++; } // Create the particle particle.texture = texture; removeChild(particle.bitmap); particle.bitmap = new Bitmap(texture); addChild(particle.bitmap); particle.position = position; particle.color = color; particle.duration = duration; particle.percent_life = 1.0; particle.scale = scale; particle.bitmap.scaleX = scale.x; particle.bitmap.scaleY = scale.y; particle.orientation = theta; particle.state = state; particle.sizeReduction = sizeReduction; particle.fading = fading; } public function Update() { var removal_count:Int = 0; var index:Int = 0; for (i in 0...particle_list.count) { var particle:Particle = particle_list.get(i); update_particle(particle); particle.percent_life -= 1.0 / particle.duration; Swap(particle_list, index - removal_count, index); if (particle.percent_life < 0) removal_count++; index++; } particle_list.count -= removal_count; } public function Draw(canvas:Bitmap) { canvas.bitmapData.fillRect(canvas.bitmapData.rect, 0x00000000); for (i in 0...particle_list.count) { var particle:Particle = particle_list.get(i); var origin:Point = new Point(particle.texture.width / 2, particle.texture.height / 2); var mat:Matrix = new Matrix(); mat.translate(particle.position.x - origin.x, particle.position.y - origin.y); canvas.bitmapData.draw(particle.texture, mat); //and so on } } public function Move() { for (i in 0...particle_list.count) { var particle:Particle = particle_list.get(i); particle.bitmap.x = particle.position.x - particle.bitmap.width * 0.5; particle.bitmap.y = particle.position.y - particle.bitmap.height * 0.5; } } public function Swap(list:CircularParticleArray , index1:Int, index2:Int):Void { var temp:Particle = list.get(index1); list.set(index1, list.get(index2)); list.set(index2, temp); } public function RenderBitmap(canvas:Bitmap):Void { Update(); Draw(canvas); } public function RenderDisplayList():Void { Update(); Move(); } }
package particles; import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Point; /** * ... * @author gordev */ class Particle { public var texture:BitmapData; public var bitmap:Bitmap; public var position:Point; public var origin:Point; public var orientation:Float; public var scale:Point; public var color:UInt; public var duration:Float; public var percent_life:Float; public var state:Dynamic; public var fading:Float; public var sizeReduction:Float; public function new() { bitmap = new Bitmap(); scale = new Point(1, 1); percent_life = 1.0; } }
package com.nailedgames; import flash.geom.Point; typedef PathTile = { var x:Int; var y:Int; var step:Int; } class GBVF_pathfinding { private var _tile_width:Int; private var _tile_height:Int; private var _field_width:Int; private var _field_height:Int; private var _field_wtiles:Int; private var _field_htiles:Int; private var _distances:Array<Int>; private var _vectors:Array<Point>; public var vectors(get,null):Array<Point>; public function new() { } function get_vectors():Array<Point> { return _vectors; } public function Init(tile_width:Int, tile_height:Int, field_width:Int, field_height:Int) { _tile_width = tile_width; _tile_height = tile_height; _field_width = field_width; _field_height = field_height; _field_wtiles = Std.int(field_width/tile_width); _field_htiles = Std.int(field_height/tile_height); _distances = new Array(); for(i in 0..._field_htiles) for(j in 0..._field_wtiles) _distances.push(-1); } public function Calculate_field(walls_map:Array<Int>, x_block:Int, y_block:Int):Array<Point> { for(i in 0..._distances.length) if(walls_map[i] == 1) _distances[i] = -3; else _distances[i] = -1; Mark_tiles([{x:x_block, y:y_block, step:0}]); return _vectors; } private function Mark_tiles(points:Array<Pathtile>):Void { if(Lambda.empty(points)) return; var neighbours:Array<Pathtile> = new Array<Pathtile>(); for(point in points) { _distances[point.x + point.y*_field_wtiles] = point.step; if(point.x > 0) { if(_distances[(point.x-1) + point.y*_field_wtiles] == -1) { neighbours.push({x:point.x-1, y:point.y, step:point.step+1}); _distances[(point.x-1) + point.y*_field_wtiles] = -2; } } if(point.x < (_field_wtiles-1)) { if(_distances[(point.x+1) + point.y*_field_wtiles] == -1) { neighbours.push({x:point.x+1, y:point.y, step:point.step+1}); _distances[(point.x+1) + point.y*_field_wtiles] = -2; } } if(point.y > 0) { if(_distances[point.x + (point.y-1)*_field_wtiles] == -1) { neighbours.push({x:point.x, y:point.y-1, step:point.step+1}); _distances[point.x + (point.y-1)*_field_wtiles] = -2; } } if(point.y < (_field_htiles-1)) { if(_distances[point.x + (point.y+1)*_field_wtiles] == -1) { neighbours.push({x:point.x, y:point.y+1, step:point.step+1}); _distances[point.x + (point.y+1)*_field_wtiles] = -2; } } } Mark_tiles(neighbours); Assign_vectors(); } private function Assign_vectors():Void { _vectors = new Array<Point>(); for(y_tile in 0..._field_htiles) { for(x_tile in 0..._field_wtiles) { if(_distances[x_tile + y_tile*_field_wtiles] > 0) { var left_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; var right_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; var up_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; var down_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; if((x_tile > 0) && (_distances[(x_tile-1) + y_tile*_field_wtiles] >= 0)) left_dist = _distances[(x_tile-1) + y_tile*_field_wtiles]; if((x_tile < (_field_wtiles-1)) && (_distances[(x_tile+1) + y_tile*_field_wtiles] >= 0)) right_dist = _distances[(x_tile+1) + y_tile*_field_wtiles]; if((y_tile > 0) && (_distances[x_tile + (y_tile-1)*_field_wtiles] >= 0)) up_dist = _distances[x_tile + (y_tile-1)*_field_wtiles]; if((y_tile < (_field_htiles-1)) && (_distances[x_tile + (y_tile+1)*_field_wtiles] >= 0)) down_dist = _distances[x_tile + (y_tile+1)*_field_wtiles]; _vectors.push(new Point( left_dist - right_dist, up_dist - down_dist)); }else{ _vectors.push(new Point(0,0)); } } } } }Here is usage example:
var tile_width:Int = 40; var tile_height:Int = 40; var field_width:Int = 800; var field_height:Int = 600; gbvf = new GBVF_pathfinding(); walls_map = [ 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1, 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0, ]; gbvf.Init(tile_width, tile_height, field_width, field_height); var vectors:Array<Point> = gbvf.Calculate_field(walls_map, x_block, y_block);As a result you will have array of vectors coordinates relative to the center of tiles.
// let's define keys, which will move player (keyCode, state) private static var keys:Array<Array<Int>> = [[37,0],[39,0],[38,0],[40,0],[69,0],[65,0],[68,0],[87,0],[83,0]]; // define array, where angles will be stored private var angles:Array<Int>; // adjust angles to special indexes private function Init(e:Event):Void // Event.ADDED_TO_STAGE { angles = new Array<Int>(); angles[1] = 0; angles[3] = 45; angles[2] = 90; angles[6] = 135; angles[4] = 180; angles[11] = 225; angles[7] = 270; angles[8] = 315; } public function on_key_down(e:KeyboardEvent):Void // KeyboardEvent.KEY_DOWN { for(key in keys) if(e.keyCode == key[0] && key[1] == 0) key[1] = 1; } public function on_key_up(e:KeyboardEvent):Void // KeyboardEvent.KEY_UP { for(key in keys) if(e.keyCode == key[0]) key[1] = 0; } public function on_enter_frame(e:Event):Void // Event.ENTER_FRAME { var r_index:Int = 0; // up - down if(keys[2][1] == 1 || keys[7][1] == 1) { r_index += 1; }else if(keys[3][1] == 1 || keys[8][1] == 1){ r_index += 4; } // left - right if(keys[0][1] == 1 || keys[5][1] == 1) { r_index += 7; }else if(keys[1][1] == 1 || keys[6][1] == 1){ r_index +=2; } if(r_index != 0) this.rotation = angles[r_index]; }