![](/img/trans.png)
[英]Can I run multiple instances at once(simultaneously) with selenium-webdriver?
[英]run multiple instances of a class simultaneously javascript
您可能只需要查看障礙.js
我有一個 class 在 canvas 上繪制一個正方形並為其添加碰撞檢測。
當我創建一個實例時,它可以完美運行,
new Obstacle(100, 100, 100, 100).init()
但如果我創建 2 它只適用於我創建的第二個
new Obstacle(100, 100, 100, 100).init()
new Obstacle(400, 100, 100, 100).init()
有誰知道讓這段代碼在兩個實例上都工作的方法?
// utility.js //define variables let Keys = { W: false, A: false, S: false, D: false } let Allow = { W: true, A: true, S: true, D: true } let Character = { X: 0, Y: 0, H: parseInt(window.getComputedStyle(character).getPropertyValue("height")), W: parseInt(window.getComputedStyle(character).getPropertyValue("width")), } //function to update the position of `character` every milisecond setInterval(function() { document.getElementById("character").style.left = Character.X + "px" document.getElementById("character").style.top = Character.Y + "px" }, 1) //waits for event `keyDOWN` to happen, if it happens it sets `Keys.` + the key to TRUE so it START animating document.addEventListener("keydown", (event) => { if (event.key === "w") Keys.W = true if (event.key === "a") Keys.A = true if (event.key === "s") Keys.S = true if (event.key === "d") Keys.D = true }) //waits for event `keyUP` to happen, if it happens it sets `Keys.` + the key to FALSE so it STOPS animating document.addEventListener("keyup", (event) => { if (event.key === "w") Keys.W = false if (event.key === "a") Keys.A = false if (event.key === "s") Keys.S = false if (event.key === "d") Keys.D = false }) //function that makes `character` move by adding to its X and Y value setInterval(function() { if (Keys.W && Allow.W) { if (Character.Y > 0) { Character.Y -= 1 } } if (Keys.A && Allow.A) { if (Character.X > 0) { Character.X -= 1 } } if (Keys.S && Allow.S) { if (Character.Y < 500 - Character.H) { Character.Y += 1 } } if (Keys.D && Allow.D) { if (Character.X < 800 - Character.W) { Character.X += 1 } } }, 1) // obstacle.js //define variables let canvas = document.getElementById("ObstacleHolder") let ctx = canvas.getContext("2d") //resize the canvas canvas.width = 800 canvas.height = 500 class Obstacle { constructor(x, y, height, width, src = null) { this.H = height this.W = width this.X = x this.Y = y this.src = src } //function to draw the obstacle on the canvas & apply colision detection init() { //array for the coordinates let ObstaclePositions = [this.X - Character.W, this.Y - Character.H, (this.X + this.W), (this.Y + this.H)] //draw the obstacle on the canvas ctx.beginPath() ctx.rect(this.X, this.Y, this.W, this.H) ctx.fillStyle = "Red" ctx.fill() //colision detection setInterval(function() { //colision detection X if (Character.Y > ObstaclePositions[1] && Character.Y < ObstaclePositions[3] && Character.X > ObstaclePositions[0] - 1 && Character.X < ObstaclePositions[2] - 1) { Allow.D = false Allow.A = true Allow.S = true Allow.W = true } else { Allow.D = true } if (Character.Y > ObstaclePositions[1] && Character.Y < ObstaclePositions[3] && Character.X > ObstaclePositions[0] + 1 && Character.X < ObstaclePositions[2] + 1) { Allow.A = false Allow.D = true Allow.S = true Allow.W = true } else { Allow.A = true } //colision detection Y if (Character.Y > ObstaclePositions[1] - 1 && Character.Y < ObstaclePositions[3] - 1 && Character.X > ObstaclePositions[0] && Character.X < ObstaclePositions[2]) { Allow.S = false Allow.D = true Allow.A = true Allow.W = true } else { Allow.S = true } if (Character.Y > ObstaclePositions[1] + 1 && Character.Y < ObstaclePositions[3] + 1 && Character.X > ObstaclePositions[0] && Character.X < ObstaclePositions[2]) { Allow.W = false Allow.A = true Allow.D = true Allow.S = true } else { Allow.W = true } }, 1) } } new Obstacle(100, 100, 100, 100).init() new Obstacle(400, 100, 100, 100).init()
* { padding: 0; margin: 0; font-family: "Dosis", "Source Sans Pro", "Helvetica Neue", Arial, sans-serif; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #canvas { height: 500px; width: 800px; border: 1px solid black; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } #character { height: 50px; width: 50px; background-color: rgb(0, 204, 255); position: absolute; top: 0px; left: 0px; } #ObstacleHolder { background-color: rgba(100, 100, 158, 0.288); position: absolute; }
<,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>Prototype</title> </head> <body> <div id="canvas"> <canvas id="ObstacleHolder"></canvas> <div id="character"></div> </div> </body> </html> <.-- import css file --> <link rel="stylesheet" href="style.css"> <!-- import javascript files --> <script src="utility.js"></script> <script src="obstacle.js"></script>
創建你的TickManager
(這個,基於EventEmitter
):
class TickManager extends EventEmitter {
timer = false;
running = false;
constructor(...props) {
super(...props);
this.onStop = this.stop.bind(this);
this.on('stop', this.onStop);
}
destroy(...props) {
this.off('stop', this.onStop);
super.destroy(...props);
}
start() {
if(!this.running) {
this.running = true;
this.tick();
}
}
stop() {
cancelAnimationFrame(this.timer);
this.running = false;
}
tick() {
this.timer = false;
this.emit( 'beforetick' );
this.emit( 'tick' );
this.emit( 'aftertick' );
if(this.running) {
this.timer = requestAnimationFrame(this.tick.bind(this));
}
}
}
const tickManager = new TickManager();
在您的播放器中使用它:
tickManager.on('beforetick', function() {
Allow = {
W: true,
A: true,
S: true,
D: true
};
// Allow obstacles to disallow directions
tickManager.emit('afterplayertick');
});
// Update the position of `character` after all calculations have been done
tickManager.on('aftertick', function() {
document.getElementById("character").style.left = Character.X + "px"
document.getElementById("character").style.top = Character.Y + "px"
});
// Makes `character` move by adding to its X and Y value, if allowed by obstacles
tickManager.on('tick', function() {
if (Keys.W && Allow.W) {
if (Character.Y > 0) {
Character.Y -= 1
}
}
if (Keys.A && Allow.A) {
if (Character.X > 0) {
Character.X -= 1
}
}
if (Keys.S && Allow.S) {
if (Character.Y < 500 - Character.H) {
Character.Y += 1
}
}
if (Keys.D && Allow.D) {
if (Character.X < 800 - Character.W) {
Character.X += 1
}
}
});
在你的障礙中使用它:
class Obstacle {
// ...
init() {
// ...
// Colision detection
tickManager.on('afterplayertick', function() {
//colision detection X
if (Character.Y > ObstaclePositions[1] &&
Character.Y < ObstaclePositions[3] &&
Character.X > ObstaclePositions[0] - 1 &&
Character.X < ObstaclePositions[2] - 1) {
Allow.D = false
}
if (Character.Y > ObstaclePositions[1] &&
Character.Y < ObstaclePositions[3] &&
Character.X > ObstaclePositions[0] + 1 &&
Character.X < ObstaclePositions[2] + 1) {
Allow.A = false
}
if (Character.Y > ObstaclePositions[1] - 1 &&
Character.Y < ObstaclePositions[3] - 1 &&
Character.X > ObstaclePositions[0] &&
Character.X < ObstaclePositions[2]) {
Allow.S = false
}
if (Character.Y > ObstaclePositions[1] + 1 &&
Character.Y < ObstaclePositions[3] + 1 &&
Character.X > ObstaclePositions[0] &&
Character.X < ObstaclePositions[2]) {
Allow.W = false
}
});
}
}
最后,啟動分時管理器:
tickManager.start();
您可以使用來自EventEmitter
事件 package的 EventEmitter 或自己做(從本文復制):
class EventEmitter {
listeners = [];
emit(eventName, data) {
this.listeners
.filter(({ name }) => name === eventName)
.forEach(
({ callback }) => setTimeout(
callback.apply(this, [this, ...data]), 0
);
)
}
on(name, callback) {
if (
typeof callback === 'function'
&& typeof name === 'string'
) {
this.listeners.push({ name, callback });
}
}
off(eventName, callback) {
this.listeners = this.listeners.filter(
listener => !(listener.name === eventName &&
listener.callback === callback)
);
}
destroy() {
this.listeners.length = 0;
}
}
你可以對這段代碼做很多其他的改進:
Player
class(這樣您就可以擁有多個播放器。)。 向其中添加Keys
、 Allow
、 Character
和 DOM 元素。import
模塊來拆分和組織您的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.