How can I quickly calculate particle attributes? - particle-system

Firstly can I say I have only a very basic knowledge of maths / three.js / webgl, so sorry if some of these questions sound daft!
Anyway, I want to make a particle system - something like this: https://www.youtube.com/watch?v=jwCAsyiYimY
As I make it I realise that I have lots of questions!
I have created a particle(s), that has velocity and direction etc..
These get pushed to a THREE.PointCloud
With each render loop, I loop through each particle in the point cloud and alter the velocity / direction,
//move the particles
for( var i = 0; i < _this.pool.length; i++ ){
//direction is the mouse pos
var dir = mousePos;
//var dir = new THREE.Vector3(500, 500, 0);
dir.sub( _this.pool[i].position).normalize().multiplyScalar(0.10);
//acceleration
_this.pool[i].force = dir;
//velocity
_this.pool[i].velocity.add( _this.pool[i].force );
//position
_this.pool[i].position.add( _this.pool[i].velocity );
}
I guess this is all ok , untill I start to add lots of particles, 10000's or particles looped through each render loop, starts to slow things down.
I guess Im doing something wrong as i can hear the fans on my mac starting to blow.
At the moment I'm not using any shaders.
Is there a way to get the calculations, positioning, velocity etc onto the GPU as I would imaging that would be quicker, than using JS to calcuate this?

Related

Randomly placing objects on a circular path outside of the stage. [AS3]

I'm creating a game for a project and have stumbled across a problem. I have managed to figure out how to create tweens using Action Script 3 and make them go to a specific point on the stage, however my problem comes when resetting the object to a random point outside of the stage.
The game is a simple click to kill game, where enemies are approaching your base from all angles on the stage, and you need to click them multiple times to destroy them.
I am able to code the rest of the game, however I have no idea how to make object spawn at random point outside of the stage, and travel towards the center of the stage.
I have included a photo depicting what I am trying to accomplish.
Thanks in advance for any help!
http://postimg.org/image/ch8iakok7/
I'd do something like this :
// increase or decrease radius to your liking
var radius:Number = 500;
// get a random angle (in radians)
var angle:Number = 2 * Math.PI * Math.random();
var spawnX:Number = radius * Math.cos(angle);
var spawnY:Number = radius * Math.sin(angle);

Making a blocking obstacle

I'm new at ActionScript 3.0 so if you guys can help me a little.
I want to make an obstacle which block a path to player. I made this like that that I'm saving all movments to array and than if they collide it moves player to previous position. Is there another way because I think this is not the proper way to do it. And sometimes when it collides player is unable to move. Can you give me an example :)
Thanks
This is the only way you can ever detect a collision, but in a bit more refined way.
You actually collide the bodies (but do not apply the change to the actual object, yet).
Check for all colliding bodies on stage.
Take necessary step (roll back, destroy.. anything)
Apply the change & Render the bodies, on screen.
Considering the above as an example for flash :
var hero:Sprite = new Sprite();
addChild(hero);
while(1) {
var newX = hero.x + 1;
if(newX < 100)
hero.x = newX;
}
Every game should have a loop. The loop must branch out to various situations. So that's your start.
The hero object probably moves with the user interaction & the checks keep increasing, compelling you to re think the solution as your project grows more & more dense...

Split screen in Actionscript 3

I'm trying to make a pure AS3 game, and need a way to split the screen so that two players can have individual "cameras" that follow the around the game world. The problem is that a sprite can't have multiple parents. I'm trying to hack my way around this problem by having classes that duplicate sprites and manage all of their updates, but I'm not getting very far and my code is getting very, very ugly.
Does anyone know a good workaround or method for doing this? I can't seem to find much on-line on the subject.
I think you should use BitmapData copyPixels method
.copyPixels(point_0, rectangle_0)---> FirstPlayerScreen
World.Bitmap -
.copyPixels(point_0, rectangle_0)---> SecondPlayerScreen
Thanks for everyone's suggestions. What I've ended up with is a World class that I can add regular Sprite objects to as children. The World object manages and updates copies of those sprites, and world.getCamera() can be called as many times as necessary to display custom copies of the game world.
The key part is making copies of the sprites, this is the function I wrote to do that:
public function bitmapCopy(original:DisplayObject):Sprite
{
var returnSprite:Sprite = new Sprite();
if (original.width == 0 || original.height == 0) return returnSprite
var x = original.x; var y = original.y
var rotation = original.rotation
original.x = 0; original.y = 0; original.rotation = 0
var bounds:Rectangle = original.getBounds(original.parent)
var m:Matrix = new Matrix()
m.tx = -bounds.x
m.ty = -bounds.y
var bitmapData:BitmapData = new BitmapData( bounds.width, bounds.height, true,
0xFF0000 );
bitmapData.draw(original, m);
var bitmap:Bitmap = new Bitmap( bitmapData );
bitmap.x = bounds.x
bitmap.y = bounds.y
returnSprite.addChild(bitmap);
returnSprite.x = original.x = position.x
returnSprite.y = original.y = position.y
returnSprite.rotation = original.rotation = rotation
return returnSprite;
}
The returned Sprite can be added to the stage and will act in exactly the same way as the original (except for being static, of course). Hopefully this should help anyone else who comes across this problem.
Your theory is on the right track - you're probably just stumbling over your implementation. Organization and keeping things object-oriented will be your best friend in this scenario.
It's hard to give you a good example based off of a limited description of your game, but in general, I'd have a Screen class that can be instantiated multiple times, and I'd keep track of each instantiation (that gives us our multiple "players"). Each Screen has a stage, and you're building your game world on that stage.
The key here is data organization and good communication. Remember, there's only one "world", and you're just showing multiple instances of it. So you'll want a central Model to store data about every object in your singular game world. That Model will drive the rendering of that world to your multiple screens. If a player changes an object on their screen (let's say they move it), then you'll update the Model with that object's new location. Then, you'll broadcast those new coordinates to each Screen instance, so that all of your screens will update.
How you "broadcast" this can vary (and depends largely on the real-time nature of your game). If your game is very real-time and you're running a game loop, then you may just want to pass the objects' data along in every loop, and they'd update that way. If your game isn't as dependent of being real-time, then you can set up event listeners or a custom notification system that'll alert all of the instances of an object to update itself.
I know this is very high-level, but it's hard to give an in-depth answer without more info about your game. Hopefully this helps point you in the right direction - what you're attempting is definitely not simple, so don't get discouraged!
If you develop your game using MVC architecture principles then it should be trivial to draw your game twice, each player having an instance of the game's "view" but positioned according to a different character. If you give a layer mask to each instance then you could put the two instances side by side and so create a split screen effect.
Happy coding!
I'm working on a split screen myself just now:
masking to draw 1 world in 2 branches of your DisplayObject tree (separated cleanly), copying pixels for a split screen is a bad idea
data object to describe the world (not Sprite or DisplayObject)
Works very well so far. I've got 1 level, 2 players who move independently from each other and 2 screens that follow one player at a time. I see the other player in one player's screen and the one player in the other player's screen.
Here is how I did the data object part:
Define a central data object which describes the world and all it's world objects.
Write: make some sprites being able to manipulate 1 object of the world.
Read: update sprites by checking the properties of the world objects. 2 Screens -> 2 sprites for every world object. Check them every frame or try events.

How can you get different objects working at different framerates working in html5 canvas?

Say I want a ball bouncing at 5 frames per second and only want to have a square bouncing at 2 frames per second, how is this possible?
return setInterval(draw,10) is used in the current simulation to move 1000 particles around, but I also want to draw a radial gradient on a second canvas which gets data from the particle simulation. I cant figure out how to draw the gradient a frame per second and the particles at another framerate
What i do is create a Timer constructor, and everytime I make something animate, i make a var animateThing = new Timer().
It may not be necessary to do this, but it can be a useful peice of code as you get deeper into canvas with more moving parts.
Update
So something sorta like this.
function Timer(fps, callback) {
return setTimout(callback, 1000 / fps);
}
var timer1 = new Timer(33, callback1);
var timer2 = new Timer(55, callback2);
Now that's probably not gonna work, but it's the idea.

How to make multiple videoclips play simultaneous from Actionscript 3.0

I am trying to do a little multimedia player where I have at least 9 small videoclips that I would like to place and play - all controlled by AS 3.0.
It might even be more than 9 clips, but they will show randomly in 9 places. A movie can switch viewport too.
I will preload them all into buffers and I would like to play them randomly at the same time.
This means that there could be 9 equally sized areas showing small movieclips including sound and random times.
Like this:
[1][2][3]
[4][5][6]
[7][8][9]
So its 1 Flash canvas/player showing them all at the same time.
Is this possible or will it crash Flash to play 9 movies including their sound? The movies might be of different length and will have to be reset and played many times, but I cant prerender the result as its randomly generated from user input.
Any sharp AS 3.0 guru in here who can point me in the right direction for this idea?
EDIT
like in... an example code of where to start? I've been thinking that I could put all the parts into one "sprite movie" and the play from frame XYZ for each "window" - but not sure how or if it will work... nor whats best approach.
I think it's more than possible. You create 9 video objects and you need 9 NetStreams for them. You set a timer to start each video respectively.
So the easiest is to have 9 flv names in an array, and 9 times in an array. Then you create a loop, where you create the 9 video objects, arrange them in a matrix, then use a timeout to start each at the specific time.
The easiest and shortest code I can think of is as follows:
//we use the same flv now
var flvs:Array = ["filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv"];
//setting the times in milliseconds
var times:Array = [0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000];
//creating a NetConnection
var nc:NetConnection = new NetConnection();
//connect null, the flv is in the same folder and a simple file loading
nc.connect(null);
//the loop
for(var i:int = 0; i < times.length; i++)
{
var ns:NetStream = new NetStream(nc);
var video:Video = new Video(100, 100);
addChild(video);
//i%3 and int(i/3) arranges them in a 3x3 matrix
video.x = (i%3) * video.width;
video.y = int(i/3) * video.height;
video.attachNetStream(ns);
//the tricky timeout to call the funcion playFlv, in times[i] time, for the specific nc NetStream to play the given flvs[i] flv
flash.utils.setTimeout(playFlv, times[i], ns, flvs[i]);
}
function playFlv(ns:NetStream, flv:String):void
{
ns.play(flv);
}
Yes this is definitely possible. You will want to optimize you videos as much as possible of course. There is precedent for this in the Pine Point website, (you'll have to navigate to the "shelf life" section, and hit "next" a few times to see it) It is playing 12 videos at once, all different lengths. In terms of building it, its no different than playing one video, just repeat the steps X number of times.
I hope that helps,