Class : Gravity
L'idée est de simuler la chute d'un objet.
La chute ne doit pas être linéaire mais accélérée.
Physique
Équation
A chaque itération, il suffit d'appliquer les équations suivantes :
y += gravitySpeed;
Avec les valeurs de simulation suivantes, on voit clairement que durant :
- les dix premières itérations l'objet passe de la position 1 à 6
- les dix itérations suivantes l'objet passe de la position 6 à 22
- de l'itération 60 à 70 l'objet passe de la position de 183 à 249
Frame 1 : y = 1 (valeur tronquée)
(index):186 Frame 2 : y = 1
(index):186 Frame 3 : y = 1
(index):186 Frame 4 : y = 1
(index):186 Frame 5 : y = 2
(index):186 Frame 6 : y = 3
(index):186 Frame 7 : y = 3
(index):186 Frame 8 : y = 4
(index):186 Frame 9 : y = 5
(index):186 Frame 10 : y = 6
(index):186 Frame 11 : y = 7
(index):186 Frame 12 : y = 8
(index):186 Frame 13 : y = 10
(index):186 Frame 14 : y = 11
(index):186 Frame 15 : y = 12
(index):186 Frame 16 : y = 14
(index):186 Frame 17 : y = 16
(index):186 Frame 18 : y = 18
(index):186 Frame 19 : y = 20
(index):186 Frame 20 : y = 22
...
(index): 186Frame 60 : y = 183
(index):186 Frame 61 : y = 190
(index):186 Frame 62 : y = 196
(index):186 Frame 63 : y = 202
(index):186 Frame 64 : y = 208
(index):186 Frame 65 : y = 215
(index):186 Frame 66 : y = 222
(index):186 Frame 67 : y = 228
(index):186 Frame 68 : y = 235
(index):186 Frame 69 : y = 242
(index):186 Frame 70 : y = 249
L'objet chute :
- durant les dix premières itérations l'objet chute de ( 6 - 1) 5px,
- de l'itération 60, la chute sera de (249 - 183 ) 66px
- et à partir de l'itération 1000, l'objet chute à une très grande vitesse (or, nous savons qu'il existe une vitesse limite de chute qui est du au freinage des frottement)
Code
class GravityBloc extends AnimatedBloc {
constructor(elt, {
speed
}) {
super(elt, {
speed
});
this.gravity = 0.1;
this.gravitySpeed = 0;
}
static construct(elt, {
speed = 0
} = {}) {
return new GravityBloc( elt, speed );
}
update() {
super.update();
this.gravitySpeed +=this.gravity;
this.y += this.gravitySpeed;
}
}
Animation : class
Pour obtenir un temps écoulé :
let startTime = new Date().getTime();
function main() {
//pour avoir un temps de simu depuis le départ
let currTime = new Date().getTime(),
dt = ((currTime - startTime)/1000);
update(dt);
render();
requestId = window.requestAnimationFrame(main);
}
temps quasi constant
function main() {
let now = Date.now(),
dt = (now - lastTime) / 1000.0;
update(dt);
render();
lastTime = now;
requestId = window.requestAnimationFrame(main);
}
on pourra écrire la classe suivante :
class Oxilo extends AnimatedBloc {
constructor(elt, { speed }) {
super(elt, {
speed
});
}
static construct(elt, { speed = 1 } = {}) {
return new Oxilo(elt, { speed });
}
update(dt) {
this.x = Math.cos(2*Math.PI*(dt))*50;
this.y = Math.sin(Math.PI*(dt))*50;
}
}
on pourra écrire la classe suivante :
class Oxilo extends AnimatedBloc {
constructor(elt, { speed }) {
super(elt, {
speed
});
}
static construct(elt, { speed = 1 } = {}) {
return new Oxilo(elt, { speed });
}
update(dt) {
this.x = Math.cos(2*Math.PI*(dt))*50;
this.y = Math.sin(Math.PI*(dt))*50;
}
}
animation : class
Élément de base
class AnimatedBloc {
constructor(elt, {speed = 1} = {} ) {
this.elt = elt;
// initial CSS
this.initPosition( speed );
}
initPosition( speed ) {
if (this.elt) {
const {
left,
top
} = this.elt.getBoundingClientRect();
// CSS
this.cssX = left;
this.cssY = top;
this.x = 0;
this.y = 0;
this.speed = speed;
}
}
render() {
this.elt.style.cssText = `left:${this.x+this.cssX}px`;
//ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
}
update() {
this.x = this.x + this.speed;
}
}
Héritage
class BouncingBloc extends AnimatedBloc {
constructor(elt, {speed = 3, at = 300 } = {} ) {
super(elt, {speed});
this.boundary = at;
}
update() {
super.update();
if (this.x >= this.boundary || this.x == 0) {
this.speed *= -1;
this.elt.classList.toggle("bouncing");
}
}
}
Passage par défault
class Player {
constructor({
keysMap = new Map([
["up", "ArrowUp"],
["right", "ArrowRight"],
["down", "ArrowDown"],
["left", "ArrowLeft"],
]),
x = 20,
y = 20,
speed = 0.5,
} = {}) {
Object.assign(this, { touches, x, y, speed });
...
this.moveX = 0;
this.moveY = 0;
}
...
}
https://es6console.com/jpcwjhve/
constructor({
keysMap = new Map([
["up", "ArrowUp"],
["right", "ArrowRight"],
["down", "ArrowDown"],
["left", "ArrowLeft"],
]),
x = 20,
y = 20,
speed = 0.5,
} = {}) {
Object.assign(this, { touches, x, y, speed });
...
this.moveX = 0;
this.moveY = 0;
}
...
}
https://es6console.com/jpcwjhve/
------------ Amélioration du code
Méthode static !
class Player {
constructor( {keysMap, x, y, speed} ) {
Object.assign(this, {
keysMap,
x,
y,
speed
});
this.moveX = 0;
this.moveY = 0;
...
}
static create({
keysMap = new Map([
["ArrowUp", "up"],
["ArrowRight", "right"],
["ArrowDown", "down"],
["ArrowLeft", "left"],
]),
x = 100,
y = 100,
speed = 0.5,
} = {}) {
return new Player({keysMap, x, y, speed})
}
...
}
appel
Player.create();
Player.create({
keysMap: new Map([
["z", "up"],
["d", "right"],
["x", "down"],
["q", "left"],
]),
speed: 2
});
https://es6console.com/jpdtv6zx/
itérator
Ne marche pas si appellé deux fois
const dateRange = {
from: new Date(2018, 0, 23),
to: new Date(2018, 3, 28),
[Symbol.iterator]() {
this.current = this.from
return this
},
next() {
if (this.current <= this.to) {
this.current.setDate(this.current.getDate() + 1)
return {
done: false,
value: new Date(this.current)
}
}
return {
done: true
}
}
}
const dateList = Array.from(dateRange);
dateList.forEach(date => {
console.log(date.toString())
})
const dateRange = {
from: new Date(2018, 0, 23),
to: new Date(2018, 3, 28),
[Symbol.iterator]() {
this.current = this.from
return this
},
next() {
if (this.current <= this.to) {
this.current.setDate(this.current.getDate() + 1)
return {
done: false,
value: new Date(this.current)
}
}
return {
done: true
}
}
}
const dateList = Array.from(dateRange);
dateList.forEach(date => {
console.log(date.toString())
})
Getter et Setter d'une classe
La syntaxe
Exemple :
class CodeSecret {
constructor(num) {
// invokes the setter
this.code = num;
}
set code(num) {
if ( !/^ISBN/.test(num)) {
console.log("votre code doit commencer par ISBN");
return;
}
this._code = num;
}
get code() {
return this._code;
}
}
let t = new CodeSecret("dD1");
https://es6console.com/jpbn7x38/
set
permet de lier une propriété d'un objet à une fonction qui sera appelée à chaque tentative de modification de cette propriété.Exemple :
class CodeSecret {
constructor(num) {
// invokes the setter
this.code = num;
}
set code(num) {
if ( !/^ISBN/.test(num)) {
console.log("votre code doit commencer par ISBN");
return;
}
this._code = num;
}
get code() {
return this._code;
}
}
let t = new CodeSecret("dD1");
https://es6console.com/jpbn7x38/
Inscription à :
Articles (Atom)