Acceleration on Keypress - javascript

I'd like to add acceleration in javascript. For instance, if I press and hold a button, then the object moves accelerated in the chosen direction.
Could someone suggest please, how to start this one? Should I log the time of the keypress? If yes, how can I do this?
Thank you

You should do dome research on Kinematics.
You can do this with a simple loop that models the correspondence between position, velocity and acceleration.
I've made a simple example (using jQuery for accessing DOM/CSS):
var position = 0;
var velocity = 0;
var acceleration = 0.1;
var $thing = $("#thing");
var loop = function () {
$thing.css("left", position + "px");
position = position + velocity;
velocity = velocity + acceleration;
}
window.setInterval(loop, 100);
You can run it here: http://jsfiddle.net/QAn3Z/
Now you just need to add keypress detection.
This should get you started. Come back with more specific questions or problems, they will be less downvoted than "how should I begin" ;-)

Related

collect data from usb mouse macintosh os x

I would like to collect the data from my usb mouse with my OS X Sierra, with javascript / angular js.
Any idea where I can find the inputs ?
I would like to get the bits packets. Precisely, I would like then to calculate position, speed ect... of the cursor.
With some help from https://www.w3schools.com/js/js_events_examples.asp (seriously, this SHOULD have everything you need), you can create a function that calculates the current mouse position and speed.
The event you may have been looking for would be onmousemove. Try giving the window object that property. Your function should be called with an event object too which contains clientX and clientY data, use that to track the current position of the mouse.
Of course, to calculate the mouse speed, we just need to know the difference between the last position it was in, and the current position. So this should work:
var Mx = 0; // Mouse X position
var My = 0; // Mouse Y position
var lastSpeedx = 0; // Last movement by mouse on x axis
var lastSpeedy = 0; // Last movement by mouse on y axis
window.onmousemove = function (e) {
lastSpeedx = e.clientX - Mx; lastSpeedy = e.clientY - My;
Mx = e.clientX; My = e.clientY;
}
Although I hear you want to hear exactly what comes through that usb port, well I'm afraid it's not exactly that simple. Even if javascript has some kind of extension that might do that, it won't be fun to deal with the hundreds of different interfaces mice use to talk to your computer. Drivers are somewhat there to simplify this, then the OS simplifies it further, and by the time it gets to your javascript parser, it would have be quite basic.
I actually to accomplish low level usb input on C++ a couple years back (just for fun) but I just couldn't find what I needed.
I'll look into a direct solution for you, along with an angularjs solution (because I wrote this answer before I saw angularjs tagged), although I'm not sure if there's one as low level as you want it to be.

three.js editor will not execute position change script

Disclaimer: I am utilizing the three.js editor (https://threejs.org/editor/) as an ide to create an animated 3d scene with 6 objects and 6 directional lights. The scene itself will export and display without any animation/position changes.
When I attempted to add this script below to edit the xy positions of the objects the scene will not display when I press play.
var box = this.getObjectByName ('box');
var filledTube =this.getObjectByName('filledTube');
var ball =this.getObjectByName('ball');
var dice =this.getObjectByName('dice');
var tube =this.getObjectByName('tube');
var knot=this.getObjectByName('knot');
var blue1=this.getObjectByName('blue');
var blue2=this.getObjectByName('blue2');
var red1=this.getObjectByName('red');
var red2=this.getObjectByName('red2');
var green1=this.getObjectByName('green');
var green2=this.getObjectByName('green2');
function update( event ) {
var time = (event.time*.01);
box.position.x=-time;
box.position.y=-time;
filledTube.position.x=-time;
filledTube.position.y=-time;
ball.position.x=-time;
ball.position.y=-time;
dice.position.x=-time;
dice.position.y=-time;
tube.position.x=-time;
tube.position.y=-time;
knot.position.x=-time;
knot.position.y=-time;
blue1.position.x=+time;
blue1.position.y=+time;
blue2.position.x=+time;
blue2.position.y=+time;
red1.position.x=+time;
red1.position.y=+time;
red2.position.x=+time;
red2.position.y=+time;
green1.position.x=+time;
green1.position.y=+time;
green2.position.x=+time;
green2.position.y=+time;
}
I cannot find any information on google on the editor so here I am... any help or direction to documentation would be appreciated.
Try event.delta instead of event.time in the update function. My guess is that all objects are moving to fast.
So in update function:
var time = (event.delta*.01);
Good luck!
The script works and probably "kicks" everything far away, out of the view.
The reason is that the event.time values are very big, even if they are divided.
To see those objects, and move them in the scene try this:
var speed = 0.02;
box.position.x += speed; // adds 0.02 to the current box x position value
box.position.y -= speed; // subtracts 0.02 to the current box y position value
A nice tool, the browser console, can help you track values (for example: event.time) and solve problems.
For example: Add the following line inside the update function and see for yourself the huge time values.
console.log(event.time); // outputs time values
You can learn more for console here and here

Canvas Rendering Optical Illusion in JS Game (Briefly duplicated graphics) - Fix?

I'm creating a side-scrolling space-shooter in javascript. So far everything seems to be working well. However, there is an odd bug in the canvas rendering that I can't quite figure out (and is difficult to describe, so bear with me!)
I have a player that can shoot projectiles by clicking the left mouse button. When the projectile first leaves the player, there appears to be two of them for a brief second, until they eventually merge in to the one projectile. I'm not creating two, so this seems like an optical illusion (this is most evident if you fire a few projectiles in quick succession).
The really odd thing is, when I try and capture a screenshot of this happening, all looks fine. Can anyone figure out what's going on?
Player code including projectiles (full code in fiddle);
var Player = (function () {
// ------------------------------------------------------------------------------------------------
// PLAYER VARIABLES
// ------------------------------------------------------------------------------------------------
var w = 50;
var h = 50;
var x = 0;
var y = 0;
var projectiles = [];
// ------------------------------------------------------------------------------------------------
// BIND EVENTS TO THE GLOBAL CANVAS
// ------------------------------------------------------------------------------------------------
Canvas.bindEvent('mousemove', function (e) {
y = (e.pageY - Canvas.element.getBoundingClientRect().top) - (h / 2);
});
Canvas.bindEvent('click', function () {
createProjectile(50, (y + (h / 2)) - 10);
});
// ------------------------------------------------------------------------------------------------
// FUNCTIONS
// ------------------------------------------------------------------------------------------------
var createProjectile = function (x, y) {
projectiles.push({
x: x,
y: y
})
};
var update = function () {
for (var p = projectiles.length - 1; p >= 0; p--) {
projectiles[p].x += 10;
if (projectiles[p].x > Canvas.element.width)projectiles.splice(p, 1);
}
};
var render = function () {
Canvas.context.fillStyle = 'white';
Canvas.context.fillRect(x, y, w, h);
for (var p = 0; p < projectiles.length; p++) {
Canvas.context.fillStyle = 'red';
Canvas.context.fillRect(projectiles[p].x, projectiles[p].y, 5, 5);
}
};
// ------------------------------------------------------------------------------------------------
// Exposed Variables and Functions
// ------------------------------------------------------------------------------------------------
return {
update: update,
render: render
}
})();
Js Fiddle Demo HERE: https://jsfiddle.net/oqz204bj/
EDIT
Based on #Pimskie's answer, It does indeed seem like an optical illusion - so my question now becomes, how could I reduce this effect? I plan on implementing a feature in the future that allows the player to switch weapons (where some of them would **actually* fire multiple projectiles) but I don't want this effect to remain for fear of confusion.
yes it is an optical illusion. The reason it looks like there multiple squares when first fired is because your eyes are focused on the big static ship square. Once your eye starts to follow the movement path, then it looks more like a fluid square moving instead of a square being redrawn 60 or 30 times per second. hold a piece of paper or your hand up to your screen covering the left half of it. Focus on the piece of paper and fire a few shots. You'll notice that the shots seem to appear multiple, the same as when just fired. It's a matter of your mind seeing 3 different frames as the same one.
requestAnimationFrame depends on the frame rate of your browser and computer. In most cases that's 60fps. 60 to 70fps is the limit of most monitors, and so it doesn't make sense to try and go above that. HOWEVER you can create the illusion of a more fluid movement by having a trailing tracer effect on your projectiles. That would involve having 2 or 3 extra squares created behind each projectile that have less and less opacity.
My best guess it's an optical illusion indeed.
Check this updated fiddle: https://jsfiddle.net/oqz204bj/1/
I removed one requestAnimationFrame and replaced a other with a very slow setInterval, just for demonstration. You can see only one bullet is created.

How do js animations work?

Im trying to understand how to make a javascript animation run smoothly and I've been reading some answers around here and I found something I don't understand.
Here is the link to the question Smooth javascript animation
In the answer with most votes it says "which is why generally it's a good idea to base position/frame on the amount of time that has elapsed since the start of the animation (using new Date().getTime()) rather than moving/changing a fixed amount each frame."
Can anyone show me a very very simple example that uses the method from this answer, and explain how you then control the speed of the animation?
Overview
Generally with animations, you have three components
Update
Draw
Timer
These are run within a loop, called the animation loop. A typical animation loop might look like the following (I will explain all of the functions in detail below):
function animate() {
update(); // Executes all game logic and updates your world
draw(); // Draws all of the animated elements onto your drawing context
timer(); // Controls the timing of when animate will be called again
};
animate(); // Start animating
The animation loop is the main flow controller of what goes on inside your animation. Basically the code inside the animation loop is called over and over again. Each execution of the animate function constitutes a frame. During a frame, your world is updated and redrawn on the screen. The frequency with which the animate function runs is called the frame rate, and is controlled by the timer.
You will also need a reference to the drawing context, which will be used to hold the elements you wish to animate, also known as sprites:
// Create a variable with a reference to our drawing context
// Note this is not the same as using a canvas element
var canvas = document.getElementById("canvas");
Update
Update is responsible for updating the status of each item you wish to animate, once per frame. To take a simplistic example, say you have an array containing three cars, each with an x and y position and a velocity. On each frame, you want to update the position of the car to reflect the distance it should travel based on its velocity.
Our cars array, and the code used to generate a car might look like this:
// A method to create new cars
var Car = new Car(x, y, vx, vy) {
this.className = "car"; // The CSS class name we want to give the car
this.x = x || 0; // The x position of the car
this.y = y || 0; // The y position of the car
this.vx = vx || 0; // the x component of the car's velocity
this.vy = vy || 0 // the y component of the car's velocity
};
// A function that can be called to update the position of the car on each frame
Car.prototype.drive = function () {
this.x += this.vx;
this.y += this.vy;
// Return an html string that represents our car sprite, with correct x and y
// positions
return "<div class='"
+ this.className
+ "' style='left:"
+ this.x
+ "px; top:"
+ this.y
+ "px;'></div>";
};
// Create a variable to hold our cars
var cars = [
new Car(10, 10, 5, 3),
new Car(50, 22, 1, 0),
new Car(9, 33, 20, 10)
];
When we call update, we will want to call the drive method of each car in order to move the car sprites around the screen. This drive method will return an html string that represents the sprite, including it's current position. We will want to append this string to a variable that can be used to set the inner HTML of the canvas div:
// An empty string that will be used to contain the innerHTML for our canvas
var htmlStr = "";
// Update the position of each car
function update() {
// Clear the canvas content
htmlStr = "";
for (var i = 0, len = cars.length; i < len; i++) {
// Add the car sprite to the html string to be rendered
htmlStr += cars[i].drive();
}
};
Draw
When the update function is done outputting our sprites, we will need to actually draw the elements on the canvas. In order to do this, we use the innerHTML method of the canvas variable, passing it in htmlStr, which contains markup used to represent all of the sprites. This will ask the browser to parse the text and spit DOM elements out on the screen:
function draw() {
// Parse the text containing our sprites and render them on the DOM tree
canvas.innerHTML = htmlStr;
};
You could argue that there are better ways to do this, and there probably are. However, in the interest of keeping it simple, I kept it simple. This is also not the most performant method, as the DOM API is very slow. If you look at the system resource usage of this application, most of it will be hogged by innerHTML calls. If you want a faster context for drawing, you should use HTML 5 canvas.
Timer
Finally, you need some way of calling animate over and over again. You could do this a couple of ways. First, there is good old setTimeout:
setTimeout(animate, 0);
This instructs the browsers to call animate after a delay of 0ms. In practice, animate will never execute after a delay of 0ms. The minimum resolution of setTimeout in most browsers is around 15ms, but even that is not guaranteed, due to the way the UI thread works in javascript.
A better solution is to use requestAnimationFrame, which basically tells the browser you are doing animation. The browser will do a bunch of nice optimizations for you. However, this is not fully supported across browsers. You should use this solution for a cross-browser requestAnimationFrame polyfill:
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
Then you can use:
requestAnimFrame(animate);
In the end your finished program will look something like:
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback, /* DOMElement */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// Create a variable with a reference to our drawing context
// Note this is not the same as using a canvas element
var canvas = document.getElementById("canvas");
// A method to create new cars
var Car = new Car(x, y, vx, vy) {
this.className = "car"; // The CSS class name we want to give the car
this.x = x || 0; // The x position of the car
this.y = y || 0; // The y position of the car
this.vx = vx || 0; // the x component of the car's velocity
this.vy = vy || 0 // the y component of the car's velocity
};
// A function that can be called to update the position of the car on each frame
Car.prototype.drive = function () {
this.x += this.vx;
this.y += this.vy;
// Return an html string that represents our car sprite, with correct x and y positions
return "<div class='"
+ this.className
+ "' style='left:"
+ this.x
+ "px; top:"
+ this.y
+ "px;'></div>";
};
// Create a variable to hold our cars
var cars = [
new Car(10, 10, 5, 3),
new Car(50, 22, 1, 0),
new Car(9, 33, 20, 10)
];
// An empty string that will be used to contain the innerHTML for our canvas
var htmlStr = "";
// Update the position of each car
function update() {
// Clear the canvas content
htmlStr = "";
for (var i = 0, len = cars.length; i < len; i++) {
// Add the car sprite to the html string to be rendered
htmlStr += cars[i].drive();
}
};
function draw() {
// Parse the text containing our sprites and render them on the DOM tree
canvas.innerHTML = htmlStr;
};
function animate() {
update(); // Executes all game logic and updates your world
draw(); // Draws all of the animated elements onto your drawing context
requestAnimFrame(animate); // Controls the timing of when animate will be called again
};
animate(); // Start animating
Conclusion
There is a lot of room for optimization, tweaking, abstraction, and a whole lot of other goodness that I didn't go into here. There are a ton of ways to implement update and draw, and all have there pros and cons.
However, every animation you will ever write will use some sort of animation loop and they all have this basic architecture. Hopefully, this illustrates the basics of an animation in javascript.
The basic idea is the following:
You want to move a DIV from 0,0 to 100,0 in 1 second.
You'd like it to have 50 frames per second (using a setTimeout(fun, 20))
However, since the callback is not guaranteed to run in exactly 20ms, your callback needs to figure out when it was actually run. For example, let's say your animation started at time X but your first animation callback wasn't called until X+5ms. You need to calculate the position that the div should be at 25ms of the animation, your animation callback can't assume 50 even steps.
Here's a very simple code sample. I don't usually code with globals but this is the easiest way to show the technique.
http://jsfiddle.net/MWWm6/2/
var duration = 1000; // in ms
var startTime; // in ms
var startX = 0;
var endX = 500;
// 0 means try to get as many frames as possible
// > 1: Remember that this is not guaranteed to run as often as requested
var refreshInterval = 0;
var div = document.getElementById('anim');
function updatePosition() {
var now = (new Date()).getTime();
var msSinceStart = now - startTime;
var percentageOfProgress = msSinceStart / duration;
var newX = (endX - startX) * percentageOfProgress;
div.style.left = Math.min(newX, endX) + "px";
if (window.console) {
console.log('Animation Frame - percentageOfProgress: ' + percentageOfProgress + ' newX = ' + newX);
}
if (newX < endX) {
scheduleRepaint();
}
}
function scheduleRepaint() {
setTimeout(updatePosition, refreshInterval);
}
div.onclick = function() {
startTime = (new Date()).getTime();
scheduleRepaint();
}
This post describes the best way to do animations: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
That will run at 60fps, or as fast as possible.
Once you know that, then you can decide how long you want your animation to take and how far the object is moving, then work out how far it has to move each frame.
Of course, for smooth animations, you should use CSS Transitions where ever possible – take a look at http://css3.bradshawenterprises.com.
The quick answer is that setTimeout doesn't guarantee that the callback will be executed n number of milliseconds after you call it. It just guarantees that it will be executed no sooner than n milliseconds from that time. John Resig covers some of this in this piece.
For this reason, you need to check what time your animation callback has actually executed, not what time you've scheduled it with setTimeout.
I've written a blogpost which demonstrates the concept of "time based" animation using canvas and a sprite sheet.
The example animates a sprite and takes into account the elapsed time to make sure it remains consistent in different framerates. You could easily apply this into moving an element around a page by changing the code slightly. The concepts related to timing and animation itself remain pretty much the same.
http://codeutopia.net/blog/2009/08/21/using-canvas-to-do-bitmap-sprite-animation-in-javascript/
(I always feel so spammy leaving answers that basically just link to my blog, even if the link is actually entirely relevant :D )
Look at it this way: You've got some object you want to move. Let's say you're giving it 5 seconds to move from A to B, and you want it to be done at 30fps. That means you've got to update the object's position 150 times, and have at most 1/30 = 0.0333 seconds per update.
If you're using the "time since last adjustment", and your code takes 0.05 seconds to execute, then you're not going to make the 30fps. However, if you're basing the animation off when it started, then it doesn't matter how long your code takes - when your update code fires, it'll calculate and set the object's position should be at that stage of the animal, regardless of how many frames have actually been displayed.

Why does my my gravity work in this?

http://davzy.com/gameA/
I can't figure out a smart way to get gravity. Now with this it detects which block the character is over but it does't drop to that block!
Is there a better way to do gravity? I'd like to do this without a game library.
I don't know what you mean by "get gravity"; your question is unclear. I assume that if you can detect when the block is over, you can use the following formula:
s(t) = ut + 1/2at2
Where s is the distance at time t, u is the initial velocity (which in your case would be zero), and a is the acceleration (on Earth this is 9.8m/s2). Essentially you would be adjusting the top position of your object based on the value you get at time t (so original top position of object + s(t)). I would imagine you would use some sort of animation loop. Perhaps a setInterval. Maybe others with more experience in Javascript animation can chime in about the best way to implement this. However, this would be the formula that you would be using to figure out where the object is at time t, if it falls.
Basically gravity in a platformer goes like this:
var currentGrav = 0.0;
var gravAdd = 0.5; // add this every iteration of the game loop to currentGrav
var maxGrav = 4.0; // this caps currentGrav
var charPosY = getCharPosY(); // vertical position of the character, in this case the lower end
var colPosY = getColDow(); // some way to get the vertical position of the next "collision"
for(var i = 0; i < Math.abs(Math.ceil(currentGrav)); i++) { // make sure we have "full pixel" values
if (charPosY == colPosY) {
onGround = true;
break; // we hit the ground
}
onGround = false;
charPosY++;
}
Now to jump one could simply do this:
if (jumpKeyPressed && onGround) {
currentGrav = -5.0; //
}
You can, if you want(and understand C), check out my game for a basic platformer(with moving platforms) here:
http://github.com/BonsaiDen/Norum/blob/master/sources/character.c

Categories

Resources