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];
}