我对javascript和easelJS / createJS很新,但我认为我理解它们足以完成简单的任务。我开始尝试画布,并且卡在一个地方。
这个小项目使用canvas和easelJS来渲染带有2个引擎的简单穿梭,以及简单的物理移动它。 (伪)物理工作正常:对于两个引擎,都会采取单独的操作,但渲染失败。每当我打开引擎(按键' q'或者' w')两个引擎的火灾都会出现。
我试图找到这个代码的最简单的子集来重现那个问题,但是我失败了,所以我提供了这个简单项目的完整代码。
<!DOCTYPE HTML>
<html>
<head>
<title></title>
<style>
/*#myCanvas{
width: 1200px;
height: 600px;
}*/
</style>
<script src="createjs-2013.12.12.min.js"></script>
<script>
/* Keyboard */
var Key = {
_pressed: {},
/*LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,*/
Q: 81, W: 87, E: 69, R:82, T:84, Y: 89,
isDown: function(keyCode) {
return this._pressed[keyCode];
},
onKeydown: function(event) {
this._pressed[event.keyCode] = true;
},
onKeyup: function(event) {
delete this._pressed[event.keyCode];
},
getThrottles: function () {
var resObj = {};
for(var code in this._pressed){
resObj[String.fromCharCode(code)] = 1;
}
return resObj;
}
};
/* Vector2 */
function Vector2 (x, y, dx, dy){
this.x = x ? x : 0;
this.y = y ? y : 0;
this.dx = dx ? dx : 0;
this.dy = dy ? dy : 0;
}
/* Physics */
var Physics = {
objects: [],
update: function(){
for(ind in this.objects){
var obj = this.objects[ind];
for(ind2 in obj.forces){
var f = obj.forces[ind2];
// velocities calculations
if(f.x == obj.x && f.y == obj.y){
obj.velocity.dx += f.dx/obj.mass;
obj.velocity.dy += f.dy/obj.mass;
}
else{
var len = Math.sqrt((f.x-obj.x)*(f.x-obj.x) + (f.y-obj.y)*(f.y-obj.y));
var fpar = new Vector2(0, 0, (obj.x-f.x)/len, (obj.y-f.y)/len);
var fper = new Vector2(0, 0, (obj.y-f.y)/len, -(obj.x-f.x)/len);
var factorpar = f.dx*fpar.dx + f.dy*fpar.dy;
var factorper = f.dx*fper.dx + f.dy*fper.dy;
obj.velocity.dx += f.dx/obj.mass;
obj.velocity.dy += f.dy/obj.mass;
// TODO: here radius should be considered in equation
obj.avelocity += factorper/obj.imoment;
}
}
obj.forces.length = 0;
// rotations and translations
obj.x += obj.velocity.dx;
obj.y += obj.velocity.dy;
obj.rotation += obj.avelocity;
// dumping
var dumping = 0.95;
var adumping = 0.95;
var minvel = 0.0001;
var minavel = 0.0001;
obj.velocity.dx = dumping * obj.velocity.dx;
obj.velocity.dy = dumping * obj.velocity.dy;
obj.avelocity = adumping * obj.avelocity;
}
}
};
var myStage;
createjs.DisplayObject.prototype.mass =0.5;
createjs.DisplayObject.prototype.imoment = 0.1;
createjs.DisplayObject.prototype.forces = [];
createjs.DisplayObject.prototype.velocity = new Vector2();
createjs.DisplayObject.prototype.avelocity = 0;
function Engine(width, height){
var that = this;
this.width = width;
this.height = height;
this.innerThrottle = 0;
this.throttle = function(value){
if(value!==null)
that.innerThrottle = value;
that.flame.graphics.clear();
that.flame.graphics.beginFill("#ff0000").drawRoundRect(
-that.width*that.innerThrottle/2,
that.height+that.margin,
that.width*that.innerThrottle,
that.width*that.innerThrottle,
that.margin);
return that.innerThrottle;
};
//drawing
this.margin = 0.1 * this.width;
this.body = new createjs.Shape();
this.body.graphics.beginFill("#999999").drawRect(-this.width/2, 0, this.width, this.height);
this.addChild(this.body);
this.flame = new createjs.Shape();
this.flame.graphics.beginFill("#ff0000").drawRoundRect(
-this.width*this.throttle()/2,
this.height+this.margin,
this.width*this.throttle(),
this.width*this.throttle(),
this.margin);
this.addChild(this.flame);
}
Engine.prototype = new createjs.Container();
function Shuttle(radius){
var that = this;
this.engineNames = ['Q','W','E','R','T','Y'];
this.engines = {};
this.addEngine = function (x,y,rotation){
var tmpEn = new Engine(radius/2, radius/1);
tmpEn.x = x;
tmpEn.y = y;
tmpEn.rotation = rotation;
that.addChild(tmpEn);
that.engines[that.engineNames[Object.keys(that.engines).length]] = tmpEn;
};
this.steering = null;
this.shuttleTick = function(){
var throttles = that.steering.getThrottles();
var engines = that.engines;
for(var key in engines)
engines[key].throttle(0);
for(var key2 in throttles){
if(engines[key2]){
engines[key2].throttle(throttles[key2]);
var end = engines[key2].localToGlobal(0,-0.1);
var start = engines[key2].localToGlobal(0,0);
that.forces.push(new Vector2(start.x, start.y, (end.x-start.x)*throttles[key2], (end.y-start.y)*throttles[key2]));
}
}
};
// drawing
var core = new createjs.Shape();
core.graphics.beginFill("#000000").drawCircle(0,0,radius);
this.addChild(core);
}
Shuttle.prototype = new createjs.Container();
var shuttle;
function init(){
// Key object initialization
window.addEventListener('keyup', function(event) { Key.onKeyup(event); }, false);
window.addEventListener('keydown', function(event) { Key.onKeydown(event); }, false);
myStage = new createjs.Stage("myCanvas");
//var engine = new Engine(200,300);
var r = 10;
shuttle = new Shuttle(r);
shuttle.steering = Key;
shuttle.addEngine(-r,0,0);
shuttle.addEngine(r,0,0);
shuttle.x = 500;
shuttle.y = 200;
//shuttle.velocity.dx = 1;
//shuttle.avelocity = 1;
myStage.addChild(shuttle);
Physics.objects = [shuttle];
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener('tick', tick);
}
function tick(){
shuttle.shuttleTick();
Physics.update();
myStage.update();
}
</script>
</head>
<body onload="init()">
<canvas id="myCanvas" width="1200" height="600">
</canvas>
</body>
</html>
答案 0 :(得分:0)
您的具体问题是您正在扩展Container
类,但在创建Engine
实例时不会对其进行初始化。如果您将其插入Engine(width, height)
函数的顶部,它应该可以工作:
this.initialize();
更一般地说,您应该研究Javascript的原型继承是如何工作的 - 您的代码很难阅读并且不必要地复杂化。
在JS中实现“经典”OOP继承模式有很多不同的方法,但是由于你正在使用CreateJS,在你的情况下最有用的方法可能是首先学习他们的方法,调整你的类遵循相同的模式,从那里开始工作 - 见例如this question