CreateJs - Controlling timeline playhead with click & drag - javascript

First time posting here, hope I'm doing this right :) I am trying to create a 360 spin in Adobe Animate with createJS, using a sequence of images embedded in a MovieClip. I have managed to get control of the timeline playhead using the code below:-
var start_x;
var startFrame;
var changeDistance;
var travelDistance;
this.threeSixty.addEventListener("mousedown", onMouseDown.bind(this));
this.threeSixty.addEventListener("pressup", onMouseUp.bind(this));
function onMouseDown(e) {
start_x = e.stageX;
startFrame = this.threeSixty.timeline.position;
this.threeSixty.addEventListener("pressmove", onMouseMove.bind(this));
}
function onMouseUp(e) {
this.threeSixty.removeEventListener("pressmove", onMouseMove.bind(this));
}
function onMouseMove(e) {
var changeDistance = e.stageX-start_x;
var travelDistance = startFrame+changeDistance;
if (travelDistance > this.threeSixty.timeline.duration){
this.threeSixty.gotoAndStop(travelDistance % this.threeSixty.timeline.duration);
}else if (travelDistance < 0){
this.threeSixty.gotoAndStop (this.threeSixty.timeline.duration + (travelDistance % threeSixty.timeline.duration));
} else {
this.threeSixty.gotoAndStop(travelDistance);
}
}
The problem is, when you click and drag the image along the X axis, the image sequence only moves forward/backwards by a single frame, as opposed to continuing the image sequence until the either mouse has stopped moving, or the mouse click is released. Any ideas where I might be going wrong here?
Thanks

Related

3d motion/hitboxing with threejs

I am attempting to do some simple motion with threejs. My goal is to have a box you can move around that cannot walk through walls. As of right now my motion code looks like this
function handleMotion(mesh) {
var xClone = mesh.clone();
xClone.position.x += mesh.velocity.x;
if (checkColl(xClone, collisionMeshList, [mesh.uuid])) {
mesh.velocity.x = 0;
}
var yClone = mesh.clone();
yClone.position.y += mesh.velocity.y;
if (checkColl(yClone, collisionMeshList, [mesh.uuid])) {
mesh.velocity.y = 0;
}
var zClone = mesh.clone();
zClone.position.z += mesh.velocity.z;
if (checkColl(zClone, collisionMeshList, [mesh.uuid])) {
mesh.velocity.z = 0;
}
mesh.position.add(mesh.velocity);
}
It checks each axis of motion to ensure that it is not going to move into a wall on the next frame. The problem is it does not prevent the cube from moving into the wall, however, once it moves into the wall it prevents the cube move moving out.
I also tried adding a "sim step" just to check if it could be increased by increasing the number of calculations it did however led to no change. The code is basically acting like the clones are at the same position as the mesh however I have confirmed they are indeed offset.

javascript collision for game

The issue I'm having is when an npc and player are within 5 pixels a collision is triggered and then the npc's inventory is displayed in the console. The problem is that the npc inventory will only display this once.
I would like to make it so that every time the player is within 5 pixels of the npc their inventory is displayed. But also I don't want the collision to trigger constantly while the player is within 5 pixels of the npc, just once when they first get close.
Here's my code...
// collision for npc and player
function npc2Collision(){
for(var i = 0; i < 1; i++){
game.addEventListener('enterframe', function() {
//detects whether player sprite is within 5
//pixels of the npc sprite
if(player.within(npc2,5) && !npc2.isHit){
console.table(npcInvObject);
npc2.isHit = true;
}
});
}
}
npc2Collision();
To prevent the collision from firing again, you can use a simple flag set by the check (and its inverse):
function npc2Collision(){
for(var i = 0; i < 1; i++){
game.addEventListener('enterframe', function() {
//detects whether player sprite is within 5
//pixels of the npc sprite
if(player.within(npc2,5) && !npc2.isHit){
// split the checks so distance works well
if (!player.collided) {
console.table(npcInvObject);
npc2.isHit = true;
player.collided = true;
}
} else {
player.collided = false;
});
}
}
This will run once, set the collided flag on the player, and will not fire again until the player has left the collision radius.

rotate a globe with the mouse

I can determine where on a globe the user has clicked.
When the user first clicks the mouse button down, I can store where they have clicked; lets call it the pin.
Then, as they drag the mouse around, I want to put the pin under the mouse cursor.
Here is some code that seems to roughly keep the pin under the mouse pointer, but doesn't correctly maintain the globe; it flickers and spins randomly. Sometimes it flips the axis entirely so the globe is momentarily back-to-front.
function evtPos(evt) {
if(!scene.ortho) return null;
var x = lerp(scene.ortho[0],scene.ortho[1],evt.clientX/canvas.width),
y = lerp(scene.ortho[3],scene.ortho[2],evt.clientY/canvas.height), // flipped
sqrd = x*x+y*y;
return (sqrd > 1)?
null:
mat4_vec3_multiply(mat4_inverse(scene.mvMatrix),[x,y,Math.sqrt(1-sqrd)]);
}
function onMouseDown(evt) {
pin = evtPos(evt);
}
function onMouseMove(evt,keys,isMouseDown) {
if(!isMouseDown) return;
var pt = evtPos(evt);
if(pin == null) pin = pt;
if(pt == null) return;
var d = vec3_sub(pt,pin),
rotx = Math.atan2(d[1],d[2]),
roty = (d[2] >= 0)?
-Math.atan2(d[0] * Math.cos(rotx),d[2]):
Math.atan2(d[0] * Math.cos(rotx),-d[2]),
rotz = Math.atan2(Math.cos(rotx),Math.sin(rotx)*Math.sin(roty));
scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotx,[1,0,0]));
scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(roty,[0,1,0]));
scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotz,[0,0,1]));
}
function onMouseUp(evt) {
pin = null;
}
Also, over time, an error seems to build up and the pin drifts further and further from the mouse pointer. I presume I should somehow compute the mvMatrix completely rather than by lots of samll increments each event?
I want the user to be able to drag the globe around to navigate naturally. All code to spin globes that I've found uses fixed speeds e.g. arrow keys, rather than 'pinning' the globe under a mouse pointer. Unity has a function Quaternion.FromToRotation(fromPos,toPos) which seems very promising but the source is not available.
One of the approaches for doing this is the arcBall algorithm. There are even JavaScript implementations available so you don't need to roll your own.

Easeljs sprite animation stuck on frame

I'm learning javascript by using the easeljs library to make a simple game, for school lessons.
I want to make a crosshair give some feedback to the player by showing a small animation while you are pointing at your target, using a hittest I made.
However, when the crosshair touches the target, the animation (should be two little triangles pointing to the middle of the crosshair) seems to be stuck on it's first frame.
Here is a bit of my code, I put both of these functions inside a ticker function. The functions do what they're supposed to do (I checked by sending a message to the console.log), but I think the animation is reset as soon as the variable "hitTestControle" is set to true, at every tick.
If you want to check out all of the code, here is a link to the "game":
http://athena.fhict.nl/users/i279907/achtergrond/achtergrond.html
function hitTest() {
if(distance(crossHair, block) < 60) {
hitTestControle = true;
} else {
hitTestControle = false;
console.log(hitTestControle);
}
}
function hitTestControl() {
if(hitTestControle == true) {
crossHair.gotoAndPlay("move");
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
}
}
PS: There also seems to be something wrong with this hittest I used.
function distance() {
var difx = blok.x - crossHair.x;
var dify = blok.y - crossHair.y;
return Math.sqrt( (difx * difx) + (dify * dify) );
}
It looks like you're starting the animation... setting it to the first frame and starting it... every time hitTestControle is true. Since hitTestControle will be true as long as you're hovering over the target, the animation will never reach the second frame.
What you need to do is start the animation when you transition from hitTestControle = false to hitTestControle = true, but once that happens you just let it play automatically.
Try changing your hitTestControl() function to something like this:
function hitTestControl() {
if(hitTestControle == true && alreadyOverHit == false) {
crossHair.gotoAndPlay("move");
alreadyOverHit = true;
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
alreadyOverHit = false;
}
}
In other words, only start the animation once, during the first frame you're detecting a hit, and then don't touch it unless you move off the target and back on.

Articulated animation

I am trying to figure out how to sequence the train animation so I can offset and rotate each wagon in turn around curves, for example, in Route_51 (click Test>Run[twice]) in this display. Needs Chrome or other HTML5 compliant browser.
Here is my so far 'non-complying' code (using KineticJs):
function animate(nr,path,incr,train,dirX,dirY){
var steps,offsetX,offsetY,count,a;
steps = Math.round(path[nr][2] / incr);
offsetX = path[nr][2]/steps;
offsetY = path[nr][3]/steps;
count = 0;
stage.onFrame(function(frame){
layer = train[0].getLayer();
if(count < steps){
for(a=0; a<train.length; a+=1){
incrX = train[a].getX() + offsetX * -dirX;
incrY = train[a].getY() - offsetY * -dirY;
train[a].setX(incrX);
train[a].setY(incrY);
}
layer.draw();
count += 1;
}
else{
stage.stop();
nr += 1;
if(path[nr]){
animate(nr,path,incr,train,dirX,dirY);
}
}
});
stage.start();
}
I don't seem to be able to grasp the logic (getting old).
All help appreciated. Thanks.
It seems a certain amount of time has to pass before some kind of logic emerges.
In this case it was that each loco/wagon needed its own fully incremented path for the starts and optionally finishes to be staggered. Here is a screenshot of the train in motion with the "normal" scale view inset. Room for improvement of course especially with curve coordinates.
For the animation visit http://glasier.hk and follow the KJS link.

Categories

Resources