I'm messing around with JavaScript game development and I have an issue with loading sprites from an array. It works fine updating this "mob" class individually but when I use a for-loop to update them the sprite trails and repeats itself.
Here is the code associated with the sprite loader and also the code for the sprite itself.
MobLoader
function mobloader(){
var self = this;
for (c = 0; c < 3; c++){
var t = new enemy(rInt(10, 400), rInt(10,400));
enemies.push(t);
}
self.updatemobs = function(){
for (l = 0; l < enemies.length; l++){
enemies[l].updatemob();
}
}
}
Enemy Class (the weeds)
function enemy(x, y){
var self = this;
self.x = x;
self.y = y;
self.name = "Jake";
self.enemyspr = new sprite("grasstest.png", self.x, self.y, 40, 40, 1, 1, 0, false);
self.updatemob = function(){
for (s = 0; s < spells.length; s++){
if (spells[s].cy >= self.enemyspr.y && spells[s].cy <= self.enemyspr.y + self.enemyspr.h && spells[s].cx <= self.enemyspr.x + self.enemyspr.w && spells[s].cx >= self.enemyspr.x && self.enemyspr.active == true ){
self.enemyspr.active = false;
spells[s].spellspr.active = false;
}
}
self.enemyspr.update();
}
}
Basic Sprite Class
function sprite(src, x, y, w, h, f, l, a, loaded){
var self = this;
self.src = src;
self.x = x;
self.y = y;
self.w = w;
self.h = h;
self.cf = 0;
self.f = f;
self.cl = 0;
self.l = l;
self.active = true;
self.a = a;
self.cfps = 0;
self.fps = 10;
self.loaded = loaded;
self.spr = new Image();
self.spr.onload = function(){self.loaded = true;}
self.spr.src = self.src;
self.update = function(){
if (self.active == true){
self.cfps += 1;
if (self.cfps > self.fps && self.a == 1){
self.cfps = 0;
self.cf += 1;
if (self.cf >= self.f){
self.cf = 0;
}
}
if (self.a == 3){
if (self.f > 9){
self.cl = Math.floor(self.f / 10);
self.cf = self.f - (Math.floor(self.f / 10) * 10);
}
if (self.f <=9){
self.cf = self.f;
self.cl = self.l;
}
}
ctx.drawImage(self.spr, self.w * self.cf, self.h * self.cl, self.w, self.h, self.x, self.y, self.w, self.h);
}
}
}
Base Class Which Clears the Canvas With Each Refresh
function gameupdate(){
ctx.fillStyle = bgcolor;
ctx.fillRect(0, 0, c.width, c.height);
updategame();
}
setInterval(gameupdate, 16);
You need to clear the canvas before you redraw the frame.
I agree with the answer above. Check with a console.log to see if it is actully running, and if that doesn't work replace bgcolor with "rgb"255,255,0" just for testing, because somthing might be wrong there. Only other thing it could be is that you are spawning an entity every time he walks/frame updates. I highly, highly doubt that though.
Related
I am making a game where it's about clicking on the nearest yellow dot from the green dot.
I got a list named dots.
You can check out my codepen to see the code I'm using.
My problem is that when you're playing the game, sometimes some of the yellow dots are too close to each other. So I am thinking if it's possible to make a collision-detection or something else, to check if the yellow dots collides?
Here is a picture of my game...
I made a red circle around the problem:
The link to my codepen project: /lolkie02/pen/PJVOdy?editors=0010
If you wanna try the game, it only works through iPhone or Android browser since I made the buttons etc. 'touchstart' in the javascript.
function getDistance(obj1, obj2) {
return Math.floor(
Math.sqrt(Math.pow(obj1.cx - obj2.cx, 2) + Math.pow(obj1.cy - obj2.cy, 2))
);
}
function getRandomArbitrary(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function comparator(a, b) {
if (a[1] < b[1]) return -1;
if (a[1] > b[1]) return 1;
return 0;
}
function difference(source, toRemove) {
return source.filter(function(value) {
return toRemove.indexOf(value) == -1;
});
}
////////////////
// global vars
////////////////
var svg = document.getElementById("svg");
var dotMatrix = document.createElementNS(
"http://www.w3.org/2000/svg",
"circle"
);
var lineMatrix = document.createElementNS("http://www.w3.org/2000/svg", "line");
var screenW = window.innerWidth;
var screenH = window.innerHeight;
var totalDist = document.getElementById("distance");
////////////////
// line constructor
////////////////
function Line(x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.el = document.createElementNS("http://www.w3.org/2000/svg", "line");
this.class = "line";
this.update = function(x1, y1, x2, y2) {
this.el.setAttribute("x1", x1 || this.x1);
this.el.setAttribute("y1", y1 || this.y1);
this.el.setAttribute("x2", x2 || this.x2);
this.el.setAttribute("y2", y2 || this.y2);
this.setAttr("class", this.class);
};
this.setAttr = function(attr, value) {
this.el.setAttribute(attr, value);
};
this.append = function() {
svg.insertBefore(this.el, svg.firstChild);
};
}
////////////////
// dot constructor
////////////////
function Dot(r, cx, cy) {
this.r = r;
this.cx = cx;
this.cy = cy;
this.el = document.createElementNS("http://www.w3.org/2000/svg", "circle");
this.class = "dot";
this.update = function() {
this.el.setAttribute("r", this.r);
this.el.setAttribute("cx", this.cx);
this.el.setAttribute("cy", this.cy);
this.setAttr("class", this.class);
};
// activates a dot
this.activate = function() {
for (i = 0; i < dots.num; i++) {
dots.list[i].setAttr("data-selected", "false");
}
this.setAttr("data-selected", "true");
};
this.visited = function() {
this.setAttr("data-visited", "true");
};
// sets attribute to element
this.setAttr = function(attr, value) {
this.el.setAttribute(attr, value);
};
// gets attribute to element
this.getAttr = function(attr) {
return this.el.getAttribute(attr);
};
// appends element to svg and attaches event listeners
this.append = function() {
svg.appendChild(this.el);
this.el.addEventListener("touchstart", this.onClick);
};
// on click on element
this.onClick = function(event) {
//gets the id and the coords of the dot
var thisId = Number(event.target.getAttribute("data-id").substr(3, 2));
var thisCx = dots.list[thisId].cx;
var thisCy = dots.list[thisId].cy;
// calculates the distance between dots
var distances = [];
for (i = 0; i < dots.num; i++) {
distances[i] = [i, getDistance(dots.selected, dots.list[i])];
}
distances.sort(comparator);
distances.splice(0, 1);
var distancesLeft = [];
for (i = 0; i < distances.length; i++) {
if (dots.left.includes(distances[i][0])) {
distancesLeft.push(distances[i][0]);
}
}
//if the element is the nearest
if (thisId == distancesLeft[0] && dots.left.includes(thisId)) {
// calculates distances
var newDistance = getDistance(dots.list[thisId], dots.selected);
app.score.update(1); // punteggio x numero di poi
// app.score.update(newDistance); punteggio x distanza
//sets the active class to the selected dot
dots.list[thisId].activate();
dots.list[thisId].visited();
// creates the line
lines.list.push(
new Line(
dots.selected.cx,
dots.selected.cy,
dots.list[thisId].cx,
dots.list[thisId].cy
)
);
lines.list[lines.list.length - 1].update();
lines.list[lines.list.length - 1].append();
// creates the preview line
//TODO: eliminare le vecchie preline che rimangono vive
svg.addEventListener("mousemove", function prelineMove(e) {
mouseX = e.pageX;
mouseY = e.pageY;
app.preline.update(thisCx, thisCy, mouseX, mouseY);
});
//saves the selected dots coordinates
dots.selected.id = thisId;
dots.selected.cx = thisCx;
dots.selected.cy = thisCy;
//removes the dot from the list of remaining dots
for (i = 0; i < dots.left.length; i++) {
if (dots.left[i] === thisId) {
dots.left.splice(i, 1);
}
}
if (dots.left.length == 0) {
app.end(true);
}
} else {
app.end(false);
}
};
}
////////////////
// lines group
////////////////
var lines = {
list: []
};
////////////////
// dots group
////////////////
var dots = {};
dots.num = 20;
dots.list = [];
dots.start = 0;
dots.selected = {};
dots.selected.id = dots.start;
dots.left = [];
dots.preline;
////////////////
// app
////////////////
var app = {};
app.level = 2;
app.score = {};
app.score.number = 0;
app.score.el = document.getElementById("score");
app.score.update = function(score) {
app.score.number += score;
app.score.el.textContent = app.score.number;
};
app.score.reset = function() {
app.score.number = 0;
app.score.update(0);
};
app.results = function(points) {
if (points == "reset") {
sessionStorage.setItem("results", 0);
} else {
if (!sessionStorage.getItem("results")) {
sessionStorage.setItem("results", points);
} else {
var newscore = points;
sessionStorage.setItem("results", newscore);
}
}
};
app.launchScreen = function(lastScore, title, description, btnText) {
app.launchScreen.el = document.getElementById("launch-screen");
app.launchScreen.el.setAttribute("class", "is-visible");
var launchScreenTitle = document.getElementById("launch-screen__title");
launchScreenTitle.textContent = title;
var launchScreenDescription = document.getElementById(
"launch-screen__description"
);
launchScreenDescription.textContent = description;
app.launchScreen.btn = document.getElementById("start-btn");
app.launchScreen.btn.textContent = btnText;
app.launchScreen.btn.addEventListener("touchstart", function lauch() {
app.launchScreen.el.setAttribute("class", "");
app.start(app.level);
document.getElementById("score2").style.display = "block";
app.launchScreen.btn.removeEventListener("touchstart", lauch);
});
};
app.preline = new Line(0, 0, 200, 200);
app.preline.setAttr("id", "preline");
app.start = function(dotsNum) {
dots.num = dotsNum;
for (i = 0; i < dots.num; i++) {
var cx = getRandomArbitrary(45, screenW - 45);
var cy = getRandomArbitrary(45, screenH - 45);
dots.list[i] = new Dot(14, cx, cy);
dots.list[i].setAttr("data-id", "id-" + i);
dots.list[i].setAttr(
"style",
"animation-delay:" + i / 10 + "s; transform-origin: " + cx + 'px ' + cy + 'px;');
dots.list[i].update();
dots.list[i].append();
dots.left.push(i);
if (i == dots.start) {
dots.selected.cx = dots.list[dots.start].cx;
dots.selected.cy = dots.list[dots.start].cy;
dots.list[dots.start].setAttr("class", "dot dot--starting");
dots.left.splice(i, 1);
}
// adds the preline
app.preline.update(
dots.selected.cx,
dots.selected.cy,
dots.selected.cx,
dots.selected.cy
);
app.preline.append();
svg.addEventListener("mousemove", function prelineMove(e) {
mouseX = e.pageX;
mouseY = e.pageY;
app.preline.update(dots.selected.cx, dots.selected.cy, mouseX, mouseY);
});
}
// sets starting point
dots.list[dots.start].setAttr("data-selected", "true");
};
app.end = function(win) {
if (win) {
app.level += 2;
app.results(app.score.number);
} else {
app.level = 2;
}
dots.list = [];
dots.selected = {};
dots.left.length = 0;
svg.innerHTML = "";
if (win) {
app.launchScreen(
app.score.number,
"", //"Sådan!",
"", //"Din score er nu: " + sessionStorage.getItem("results") + ' Det næste level vil blive endnu hårdere.',
"NÆSTE LEVEL"
);
} else {
app.launchScreen(
0,
"", //"ARGH!",
"", //"Din endelige score blev: " + sessionStorage.getItem("results"),
"PRØV IGEN"
);
app.results("reset");
app.score.reset();
var score2 = document.getElementById('score2');
var number = score2.innerHTML;
number = 0;
score2.innerHTML = number;
document.getElementById("score2").style.display = "none";
}
};
app.launchScreen(
0,
"STIFINDER",
"Find den tætteste gule prik",
"SPIL"
);
$('.btn').on('touchstart',function(e,data) {
var score2 = document.getElementById('score2');
var number = score2.innerHTML;
number++;
score2.innerHTML = number;
});
Use Pythagorean theorem to determine whether the distance of the centers of two dots are closer (or equal) to the sum of their radii - in that case you have collision.
My answer to the similar question :https://stackoverflow.com/a/46973584/4154250
This question already has answers here:
Pass correct "this" context to setTimeout callback?
(6 answers)
Closed 7 years ago.
When I run the tick() function once it works flawlessly, but when I loop it using setInterval(this.tick,this.interval) all the functions in tick() give the following error: Uncaught TypeError: this.{a function} is not a function.
This is the full code:
function Particles(settings){
this.canvas = document.getElementById('particle-js');
this.context = this.canvas.getContext('2d');
this.fps = 60;
this.interval = 1000/this.fps;
this.TWO_PI = Math.PI*2;
this.mousePosition;
this.tick = function(){
console.log("tick");
this.drawNodes();
this.clear();
}
setInterval(this.tick,this.interval);
this.generateNodes = function generateNodes(){
var nodes = [];
for(var i = 0; i < 1; i++){
var node = {
origin: {
x: this.random(0, this.canvas.width),
y: this.random(0, this.canvas.height)
},
direction: this.random(0,359),
subNodes: []
}
for(var j = 0; j < this.random(1,8); j++){
var subNode = {
xOffset: this.random(-50,50),
yOffset: this.random(-50,50),
distance: function(){
var x = Math.pow(this.xOffset,2);
var y = Math.pow(this.yOffset,2);
return Math.sqrt(x + y);
}
}
while(subNode.distance() < 20){
subNode = {
xOffset: this.random(-50,50),
yOffset: this.random(-50,50),
distance: function(){
var x = Math.pow(this.xOffset,2);
var y = Math.pow(this.yOffset,2);
return Math.sqrt(x + y);
}
}
}
node.subNodes.push(subNode);
}
nodes.push(node);
}
console.log("generated: " + nodes.length);
return nodes;
}
this.canvas.addEventListener('mousemove', function(evt) {
if(evt.offsetX) {
mouseX = evt.offsetX;
mouseY = evt.offsetY;
}
else if(e.layerX) {
mouseX = evt.layerX;
mouseY = evt.layerY;
}
this.mousePos = {
x: mouseX,
y: mouseY
}
}, false);
this.drawNodes = function drawNodes(){
for(var k = 0; k < this.nodes.length; k++){
var current_node = this.nodes[k];
this.fillCircle(current_node.origin.x,current_node.origin.y, 3);
for(var l = 0; l < current_node.subNodes.length; l++){
var current_subNode = current_node.subNodes[l];
this.fillLine(current_node.origin.x,current_node.origin.y,current_node.origin.x + current_subNode.xOffset, current_node.origin.y + current_subNode.yOffset)
this.fillCircle(current_node.origin.x + current_subNode.xOffset, current_node.origin.y + current_subNode.yOffset, 2);
}
}
}
this.fillCircle = function fillCircle(x, y, radius, color){
if(color == undefined || color == false){
color = "black";
}
this.context.fillStyle = color;
this.context.beginPath();
this.context.arc(x,y,radius,0,this.TWO_PI,false);
this.context.fill();
}
this.fillLine = function fillLine(xFrom, yFrom, xTo, yTo, color){
if(color == undefined || color == false){
color = "black";
}
this.context.beginPath();
this.context.moveTo(xFrom,yFrom);
this.context.lineTo(xTo, yTo);
this.context.lineWidth = 1;
this.context.stroke();
}
this.clear = function clear(color){
if(color == undefined || color == false){
color = "white";
}
this.context.fillStyle = color;
this.context.fillRect(0,0,this.canvas.width,this.canvas.height);
}
this.random = function random(min, max){
return min+Math.round((max-min)*Math.random());
}
this.nodes = this.generateNodes();
}
The following is shown in console:
That's because the setTimeout callback function's context isn't bound to your object, try this instead:
setInterval(this.tick.bind(this), this.interval);
I want to draw circles on the screen but I want to store them in an array for later use in building a centipede type game. I am somewhat new to object in Javascript.
My object is Circles as below.
function Circles(x,y,r) {
var cX = x;
var cY = y;
var cR = r;
}
I want to create an array of say 50 circles that I can loop through and display to the screen because currently I have a square that moves around the screen that I can control with the left and right keys.
I want to redraw the array to the screen.
**How can I create the array?"
Code:
<script type="text/javascript">
var theCanvas=document.getElementById("myCanvas");
var canvasContext=theCanvas.getContext("2d");
var radX;
var radY;
var radR;
var context;
var numCircle = 50;
var circleArray = new Circles(50);
function Circles(x,y,r) {
var cX = x;
var cY = y;
var cR = r;
}
function clearCanvas() {
//context.clearRect(0,0,WIDTH,HEIGHT);
}
function drawCircle(x,y,r,context) {
context.beginPath();
context.arc(x,y,r,0,Math.PI*2,true);
context.closePath();
context.fill();
}
function getRandomColor() {
// creating a random number between 0 and 255 -- this will set the color of the random sized circle
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
// going from decimal to hex -- converts the int value to a hex for the color
var hexR = r.toString(16);
var hexG = g.toString(16);
var hexB = b.toString(16);
// making sure single character values are prepended with a "0"
if (hexR.length == 1) hexR = "0" + hexR;
if (hexG.length == 1) hexG = "0" + hexG;
if (hexB.length == 1) hexB = "0" + hexB;
// creating the hex value by concatenatening the string values
var hexColor = "#" + hexR + hexG + hexB;
return hexColor.toUpperCase();
}
function drawGameBottomLine() {
canvasContext.beginPath();
canvasContext.moveTo(0,530);
canvasContext.lineTo(450,530);
canvasContext.stroke();
}
function getRandomNum(x,y) {
radX = Math.random()*theCanvas.width;
radY = Math.random()*theCanvas.height;
}
function buildCircle() {
for(var i=0; i<numCircle; i++) {
do {
isDrawable = false;
radX = Math.random()*theCanvas.width;
radY = Math.random()*theCanvas.height;
radR = Math.random()*10+3;
if ((radX>5 && radX<435) && (radY>0 && radY<520)) {
circleArray.x[i] = radX;
circleArray.y[i] = radY;
circleArray.r[i] = radR;
isDrawable = true;
//canvasContext.fillStyle='#123321;'//getRandomColor();
//drawCircle(radX,radY,radR,canvasContext);
}
}
while (isDrawable == false);
}
}
function drawCircle(a) {
for(var i=0; i<numCircle; i++) {
canvasContext.fillStyle='#123321;'
drawCircle(circleArray.x[i],circleArray.y[i],circleArray.r[i],canvasContext);
}
}
drawGameBottomLine();
buildCircle();
drawCircles();
All of the code:
<!DOCTYPE HTML>
<html>
<head>
<style>
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" type="text/javascript"></script>
<script>
var context;
var rightKey = false;
var leftKey = false;
var upKey = false;
var downKey = false;
var block_x;
var block_y;
var block_h = 10;
var block_w = 10;
function init() {
//canvas = document.getElementById('myCanvas');
context = $('#myCanvas')[0].getContext('2d');
WIDTH = $('#myCanvas').width();
HEIGHT = $('#myCanvas').height();
block_x = WIDTH / 2 - 15;
block_y = HEIGHT /2 - 15;
setInterval('draw()', 25);
}
function clearCanvas() {
//context.clearRect(0,0,WIDTH,HEIGHT);
}
function rect(x,y,w,h) {
context.beginPath();
context.rect(x,y,w,h);
context.endPath();
}
function draw() {
clearCanvas();
if (rightKey)
block_x += 5;
else if (leftKey)
block_x -= 5;
if (upKey)
block_y -= 5;
else if (downKey)
block_y += 5;
if (block_x <= 0)
block_x = 0;
if ((block_x + block_w) >= WIDTH)
block_x = WIDTH - block_w;
if (block_y <= 0)
block_y = 0;
if ((block_y + block_h) >= HEIGHT)
block_y = HEIGHT - block_h;
context.fillRect(block_x,block_y,block_w,block_h);
}
function onKeyDown(evt) {
if (evt.keyCode == 39) rightKey = true;
else if (evt.keyCode == 37) leftKey = true;
if (evt.keyCode == 38) upKey = true;
else if (evt.keyCode == 40) downKey = true;
}
function onKeyUp(evt) {
if (evt.keyCode == 39) rightKey = false;
else if (evt.keyCode == 37) leftKey = false;
if (evt.keyCode == 38) upKey = false;
else if (evt.keyCode == 40) downKey = false;
}
$(document).keydown(onKeyDown);
$(document).keyup(onKeyUp);
</script>
</head>
<body onload="init();">
<canvas id="myCanvas" width="450" height="610" style="border:3px solid #c3c3c3;">
It appears that your browser does not support HTML5 and the canvas element.
</canvas>
<script type="text/javascript">
var theCanvas=document.getElementById("myCanvas");
var canvasContext=theCanvas.getContext("2d");
var radX;
var radY;
var radR;
var context;
var numCircle = 50;
var circleArray = new Circles(50);
function Circles(x,y,r) {
var cX = x;
var cY = y;
var cR = r;
}
function clearCanvas() {
//context.clearRect(0,0,WIDTH,HEIGHT);
}
function drawCircle(x,y,r,context) {
context.beginPath();
context.arc(x,y,r,0,Math.PI*2,true);
context.closePath();
context.fill();
}
function getRandomColor() {
// creating a random number between 0 and 255 -- this will set the color of the random sized circle
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
// going from decimal to hex -- converts the int value to a hex for the color
var hexR = r.toString(16);
var hexG = g.toString(16);
var hexB = b.toString(16);
// making sure single character values are prepended with a "0"
if (hexR.length == 1) hexR = "0" + hexR;
if (hexG.length == 1) hexG = "0" + hexG;
if (hexB.length == 1) hexB = "0" + hexB;
// creating the hex value by concatenatening the string values
var hexColor = "#" + hexR + hexG + hexB;
return hexColor.toUpperCase();
}
function drawGameBottomLine() {
canvasContext.beginPath();
canvasContext.moveTo(0,530);
canvasContext.lineTo(450,530);
canvasContext.stroke();
}
function getRandomNum(x,y) {
radX = Math.random()*theCanvas.width;
radY = Math.random()*theCanvas.height;
}
function buildCircle() {
for(var i=0; i<numCircle; i++) {
do {
isDrawable = false;
radX = Math.random()*theCanvas.width;
radY = Math.random()*theCanvas.height;
radR = Math.random()*10+3;
if ((radX>5 && radX<435) && (radY>0 && radY<520)) {
circleArray.x[i] = radX;
circleArray.y[i] = radY;
circleArray.r[i] = radR;
isDrawable = true;
//canvasContext.fillStyle='#123321;'//getRandomColor();
//drawCircle(radX,radY,radR,canvasContext);
}
}
while (isDrawable == false);
}
}
function drawCircle(a) {
for(var i=0; i<numCircle; i++) {
canvasContext.fillStyle='#123321;'
drawCircle(circleArray.x[i],circleArray.y[i],circleArray.r[i],canvasContext);
}
}
drawGameBottomLine();
buildCircle();
drawCircles();
</script>
</body>
</html>
It's really pretty simple. You just create an array with something like:
var anArray = [];
and then add objects to it:
anArray.push(object)
You might change your definition of a Circle to a simple factory function. Something like this would make everything pretty easy:
function Circle(x, y, r){
this.x = x;
this.y = y;
this.r = r;
}
// create an array
var anArray = [];
// make a circle instance
var aCircle = new Circle(100, 100, 20)
// you can now access the circle properties like this
aCircle.x
//add it to the array
anArray.push(aCircle)
//now this works too (the x coordinate of the first circle in the array):
anArray[0].x
I've added a fiddle with a working example pared down to the essentials: http://jsfiddle.net/markm/jxeh0kks/
You have a few errors in your code. The big one is that to access the objects in the array you need to specify the index of the array first.
//Don't do this:
circleArray.x[i] = radX;
// Do this:
circleArray[i].x = radX;
Okay, so I am developing a game in JavaScript. I have organized all the parts of the game in different JavaScript files. So, this is the Player.js file, every time I run this in my browser ( run from a html file of course), I come into this problem where the Player object flickers from a image to a transparent rectangle: heres the code:
function Player() {
this.frames = [];
this.right = true;
this.currentFrame = 0;
this.currentAction = "WALKING";
this.image = new Image();
this.x = 0;
this.y = 0;
this.setPosition = function(x, y) {
this.x = x;
this.y = y;
};
this.setVector = function(x, y) {
this.x += x;
this.y += y;
};
this.setAction = function(action) {
this.currentAction = action;
};
this.setRight = function(bool) {
this.right = bool;
}
this.draw = function(context) {
if(this.right == true) {
if(this.currentAction == "WALKING") {
this.frames = [ "res/playerRight.png" ];
}
} else if(this.right == false) {
if(this.currentAction == "WALKING") {
this.frames = [ "res/playerLeft.png" ];
}
}
if(this.currentFrame < this.frames.length) {
this.currentFrame += 1;
this.image.src = this.frames[this.currentFrame - 1];
context.drawImage(this.image, this.x,
this.y, 32, 32);
} else {
this.currentFrame = 0;
}
};
}
heres some images of what it does:
http://i.stack.imgur.com/1RcOC.png
http://i.stack.imgur.com/fxbNY.png
How about you preload all the images and you choose the correct one in your condition. Currently everytime you set the source the image is reloaded, and you are drawing it before it is ready.
// you can improve this part for your needs
var image1Loaded = false;
var image2Loaded = false;
this.preLoadImages = function (){
this.image1.onload = function (){
image1Loaded = true;
}
this.image2.onload = function (){
image2Loaded = true;
}
this.image1.src = "res/playerRight.png";
this.image2.src = "res/playerLeft.png";
}
now you can use the images directly in your draw method:
this.draw = function(context) {
var currentImage = "image1";
if(this.right == true) {
if(this.currentAction == "WALKING") {
currentImage = "image1";
}
} else if(this.right == false) {
if(this.currentAction == "WALKING") {
currentImage = "image2";
}
}
if(this.currentFrame < this.frames.length) {
this.currentFrame += 1;
var image = this[currentImage];
context.drawImage(image, this.x,
this.y, 32, 32);
} else {
this.currentFrame = 0;
}
};
Just make sure your images are already loaded before using them to draw on the canvas
Here's the bug:
if(this.currentFrame < this.frames.length) {
this.currentFrame += 1;
context.drawImage(); // <---------------- draw an image
} else {
this.currentFrame = 0; // <-------------- draw nothing!
}
So, let's run through this logic shall we. At the moment, frame length is 1.
currentFrame = 0
so we increment currentFrame
we draw the image
currentFrame = 1
currentFrame is not less than frames.length
we do not draw anything
we set current frame to 0
currentFrame = 0
so we increment currentFrame
we draw the image
repeat....
Result: flicker! If frame length is 2 it will flicker 33% of the time, if the frame length is 3 it will flicker 25% of the time etc.
The correct way to handle this:
this.currentFrame += 1;
if(this.currentFrame >= this.frames.length) {
this.currentFrame = 0;
}
this.image.src = this.frames[this.currentFrame]; // **
context.drawImage();
// **note: no need for -1 because currentFrame here is always
// less than frame.length
Or, if you're mathematical:
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
this.image.src = this.frames[this.currentFrame];
context.drawImage();
This is a start to do assignment for Uni. But for now on I have problem to manage to toggle between images. This is meant to be start for turn around match game. It suppose to be images and words and match them but I have problem so far with this toggle function. I have this code so far:
var myButton = new Image();
var mouseX = 0;
var mouseY = 0;
var backgroundImage = new Image();
var nothing = "num/w/2.png";
var something = "num/w/3.png";
function drawButton(buttonObj)
{
canvasContext.drawImage(buttonObj, buttonObj.x, buttonObj.y);
}
function checkIfInsideButtonCoordinates(buttonObj, mouseX, mouseY)
{
if(((mouseX > buttonObj.x) && (mouseX < (buttonObj.x + buttonObj.width))) && ((mouseY > buttonObj.y) && (mouseY < (buttonObj.y + buttonObj.height))))
{return true;}
else
{return false;}
}
$(function() {
var canvas = $("#canvas").get(0);
canvasContext = canvas.getContext('2d');
backgroundImage.src = "num/back.jpg";
$(backgroundImage).load(function() {
canvasContext.drawImage(backgroundImage, 0, 0);
myButton.x = 100;
myButton.y = 100;
myButton.width = 100;
myButton.height = 100;
myButton.src = something;
drawButton(myButton);
});
$("#canvas").click(function(eventObject) {
mouseX = eventObject.pageX - this.offsetLeft;
mouseY = eventObject.pageY - this.offsetTop;
if(checkIfInsideButtonCoordinates(myButton, mouseX, mouseY))
{
if(myButton.src = something)
{
myButton.src = nothing;
}
else if(myButton.src = nothing)
{
myButton.src = something;
}
drawButton(myButton);
}
});
});
Any idea why?Thank you.
jsfiddle
You need to make your = in the if statements ==.
if (myButton.src == something) {
myButton.src = nothing;
}
else if (myButton.src == nothing) {
myButton.src = something;
}