「gameLoop」というプロトタイプメソッドを持つ「Game」というオブジェクト(関数)があります。このループを一定の間隔で呼び出す必要があるので、これを実行しようとします。
setInterval(game.gameLoop,setIntervalAmount);
しかし、受け取る "TypeError: Cannot read property 'clearRect' of undefined(…)"
プロトタイプメソッドは次のとおりです。
Game.prototype.gameLoop = function()
{
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
}
私はまだJavascriptのオブジェクト指向プログラミングを理解するのに苦労しています。関数が単なる通常の関数であり、ゲームオブジェクトを渡した作業バージョンがありました。何か案は?
ちなみに、ここに役立つかもしれないいくつかの追加のコードがあります。
function Sprite(imgg,w,h)
{
this.img = imgg;
this.x = 350;//Math.random()*700;
this.y = 350;//Math.random()*700;
this.vx = 0;//Math.random()*8-4;
this.vy = 0;//Math.random()*8-4;
this.width = w;
this.height = h;
this.rotatespeed = 0.01;
this.rotate = 40;
}
Sprite.prototype.drawSprite = function(ctx)
{
ctx.save();
ctx.translate(this.x,this.y);
ctx.rotate(this.rotate);
ctx.drawImage(this.img,0,0,this.img.width,this.img.height,-this.width/2,-this.height/2,this.width,this.height);
ctx.restore();
}
Sprite.prototype.updateSprite = function()
{
this.x += this.vx;
this.y += this.vy;
this.rotate += this.rotatespeed;
if(this.x > 700)
this.vx = -this.vx;
if(this.x < 0)
this.vx = -this.vy;
if(this.y > 700)
this.vy = -this.vy;
if(this.y < 0)
this.vy = -this.vy;
}
Sprite.prototype.mouseEventListener = function(evt, type)
{
console.log("Hello");
}
//------------------------------------------
//GLOBAL VARIALBES
var setIntervalAmount = 30;
var scrollAmount = 0.5;
var game;
function Game()
{
this.camera = new Object();
this.camera.x = -350;
this.camera.y = -350;
this.camera.scale = 1;
this.camera.rotate = 0;
this.canvas = document.createElement("canvas");
document.body.appendChild(this.canvas);
this.canvas.id="mycanvas";
this.canvas.width = 700;
this.canvas.height = 700;
this.context = this.canvas.getContext("2d");
var ctx = this.context;
ctx.canvas.addEventListener('mousemove', function(event){
var mouseX = event.clientX - ctx.canvas.offsetLeft;
var mouseY = event.clientY - ctx.canvas.offsetTop;
var canvasX = mouseX * ctx.canvas.width / ctx.canvas.clientWidth;
var canvasY = mouseY * ctx.canvas.height / ctx.canvas.clientHeight;
//console.log(canvasX+" | "+canvasY);
});
this.objects = new Array();
}
Game.prototype.handleMouse = function(evt,type)
{
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].mouseEventListener(evt,type);
}
};
Game.prototype.gameLoop = function()
{
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
}
/*Game.prototype.drawGame = function()
{
var gameLoop = setInterval(function(){
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
},setIntervalAmount);
}*/
function mouseWheelListener()
{
var evt = window.event;
console.log(evt.wheelDelta);
if(evt.wheelDelta < 0)
game.camera.scale /= (1+scrollAmount);
else
game.camera.scale *= (1+scrollAmount);
}
function mouseDownListener()
{
var evt = window.event;
var type = "down"
game.handleMouse(evt,type);
}
function mouseUpListener()
{
var evt = window.event;
var type = "up"
game.handleMouse(evt,type);
}
function mouseMoveListener()
{
var evt = window.event;
var type = "move"
game.handleMouse(evt,type);
}
//------------------
window.addEventListener('load',function(event){startgame();});
var dog = new Image();
dog.src = "grid.gif";
function startgame()
{
game = new Game();
for(var i=0;i<1;i++)
game.objects.push(new Sprite(dog,250,250));
setInterval(game.gameLoop,setIntervalAmount);
document.getElementById("mycanvas").addEventListener("wheel", mouseWheelListener);
document.getElementById("mycanvas").addEventListener("mousedown", mouseDownListener);
document.getElementById("mycanvas").addEventListener("mouseup", mouseUpListener);
document.getElementById("mycanvas").addEventListener("mousemove", mouseMoveListener);
}
唯一の問題は、コードで、gameloopメソッドを実行しているコンテキストです。
通常、setInterval、setTimeout関数は、グローバル/ウィンドウコンテキストで実行されます。したがって、メソッド内でこれを指定すると、オブジェクトに対して実行している場合でも、技術的にはグローバルコンテキストを参照していることになります。
したがって、問題が発生しないようにするために、setIntervalの最初の引数として、メソッド参照の代わりに必要な関数を実行するメソッドを常に用意してください。
setInterval(function(){/*
game.gameLoop()
*/}, 1000);
このように、グローバルコンテキストでsetInterval関数を実行していますが、ゲームオブジェクトのメソッドを明示的に呼び出しています。
function Sprite(imgg, w, h) {
this.img = imgg;
this.x = 350; //Math.random()*700;
this.y = 350; //Math.random()*700;
this.vx = 0; //Math.random()*8-4;
this.vy = 0; //Math.random()*8-4;
this.width = w;
this.height = h;
this.rotatespeed = 0.01;
this.rotate = 40;
}
Sprite.prototype.drawSprite = function(ctx) {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.rotate);
ctx.drawImage(this.img, 0, 0, this.img.width, this.img.height, -this.width / 2, -this.height / 2, this.width, this.height);
ctx.restore();
}
Sprite.prototype.updateSprite = function() {
this.x += this.vx;
this.y += this.vy;
this.rotate += this.rotatespeed;
if (this.x > 700)
this.vx = -this.vx;
if (this.x < 0)
this.vx = -this.vy;
if (this.y > 700)
this.vy = -this.vy;
if (this.y < 0)
this.vy = -this.vy;
}
Sprite.prototype.mouseEventListener = function(evt, type) {
//console.log("Hello");
}
//------------------------------------------
////GLOBAL VARIALBES
var setIntervalAmount = 200;
var scrollAmount = 0.5;
var game;
function Game() {
this.camera = new Object();
this.camera.x = -350;
this.camera.y = -350;
this.camera.scale = 1;
this.camera.rotate = 0;
this.canvas = document.createElement("canvas");
document.body.appendChild(this.canvas);
this.canvas.id = "mycanvas";
this.canvas.width = 700;
this.canvas.height = 700;
this.context = this.canvas.getContext("2d");
var ctx = this.context;
ctx.canvas.addEventListener('mousemove', function(event) {
var mouseX = event.clientX - ctx.canvas.offsetLeft;
var mouseY = event.clientY - ctx.canvas.offsetTop;
var canvasX = mouseX * ctx.canvas.width / ctx.canvas.clientWidth;
var canvasY = mouseY * ctx.canvas.height / ctx.canvas.clientHeight;
//console.log(canvasX+" | "+canvasY);
});
this.objects = new Array();
}
Game.prototype.handleMouse = function(evt, type) {
for (var i = 0; i < this.objects.length; i++) {
this.objects[i].mouseEventListener(evt, type);
}
};
Game.prototype.gameLoop = function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width / 2, this.canvas.height / 2);
this.context.scale(this.camera.scale, this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x, this.camera.y);
for (var i = 0; i < this.objects.length; i++) {
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
}
/*Game.prototype.drawGame = function()
{
var gameLoop = setInterval(function(){
this.context.clearRect(0,0,this.canvas.width, this.canvas.height);
this.context.save();
this.context.translate(this.canvas.width/2, this.canvas.height/2);
this.context.scale(this.camera.scale,this.camera.scale);
this.context.rotate(this.camera.rotate);
this.context.translate(this.camera.x,this.camera.y);
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].updateSprite();
this.objects[i].drawSprite(this.context);
}
this.context.restore();
},setIntervalAmount);
}*/
function mouseWheelListener() {
var evt = window.event;
console.log(evt.wheelDelta);
if (evt.wheelDelta < 0)
game.camera.scale /= (1 + scrollAmount);
else
game.camera.scale *= (1 + scrollAmount);
}
function mouseDownListener() {
var evt = window.event;
var type = "down"
game.handleMouse(evt, type);
}
function mouseUpListener() {
var evt = window.event;
var type = "up"
game.handleMouse(evt, type);
}
function mouseMoveListener() {
var evt = window.event;
var type = "move"
game.handleMouse(evt, type);
}
//------------------
window.addEventListener('load', function(event) {
startgame();
});
var dog = new Image();
dog.src = "https://i.stack.imgur.com/W0mIA.png";
function startgame() {
game = new Game();
for (var i = 0; i < 1; i++)
game.objects.push(new Sprite(dog, 250, 250));
setInterval(function() {
game.gameLoop();
}, setIntervalAmount);
document.getElementById("mycanvas").addEventListener("wheel", mouseWheelListener);
document.getElementById("mycanvas").addEventListener("mousedown", mouseDownListener);
document.getElementById("mycanvas").addEventListener("mouseup", mouseUpListener);
document.getElementById("mycanvas").addEventListener("mousemove", mouseMoveListener);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加