Creating a card matching game - javascript

I want to create a card matching game but I have an issue showing the images that are supposed to be hidden. When I click on a card, the path of the image shows instead of the actual image.
Here are all the codes that I have written:
div#card_board {
background: #ccc;
border: #999 1px solid;
width: 710px;
height: 600px;
padding: 24px;
margin: 0px auto;
}
div#card_board>div {
background: url(cardQtion.jpg) no-repeat;
background-size: 100%;
border: #000 1px solid;
width: 114px;
height: 132px;
float: left;
margin: 10px;
padding: 20px;
font-size: 64px;
cursor: pointer;
text-align: center;
}
<script>
var cardArray = new Array();
cardArray[0] = new Image();
cardArray[0].src = 'cardA.jpg';
cardArray[1] = new Image();
cardArray[1].src = 'cardA.jpg';
cardArray[2] = new Image();
cardArray[2].src = 'cardB.jpg';
cardArray[3] = new Image();
cardArray[3].src = 'cardB.jpg';
cardArray[4] = new Image();
cardArray[4].src = 'cardC.jpg';
cardArray[5] = new Image();
cardArray[5].src = 'cardC.jpg';
cardArray[6] = new Image();
cardArray[6].src = 'cardD.jpg';
cardArray[7] = new Image();
cardArray[7].src = 'cardD.jpg';
cardArray[8] = new Image();
cardArray[8].src = 'cardE.jpg';
cardArray[9] = new Image();
cardArray[9].src = 'cardE.jpg';
cardArray[10] = new Image();
cardArray[10].src = 'cardF.jpg';
cardArray[11] = new Image();
cardArray[11].src = 'cardF.jpg';
var cardVal = [];
var cardIDs = [];
var cardBackFace = 0;
Array.prototype.cardMix = function() {
var i = this.length,
j, temp;
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
}
function newBoard() {
cardBackFace = 0;
var output = "";
cardArray.cardMix();
for (var i = 0; i < cardArray.length; i++) {
output += '<div id="card_' + i + '" onclick="cardBackcard(this,\'' + cardArray[i].src + '\')"></div>';
}
document.getElementById('card_board').innerHTML = output;
}
function cardBackcard(tile, val) {
if (tile.innerHTML == "" && cardVal.length < 2) {
tile.style.background = '#FFF';
tile.innerHTML = val;
if (cardVal.length == 0) {
cardVal.push(val);
cardIDs.push(tile.id);
} else if (cardVal.length == 1) {
cardVal.push(val);
cardIDs.push(tile.id);
if (cardVal[0] == cardVal[1]) {
cardBackFace += 2;
cardVal = [];
cardIDs = [];
if (cardBackFace == cardArray.length) {
alert("Board cleared... generating new board");
document.getElementById('card_board').innerHTML = "";
newBoard();
}
} else {
function card2Back() {
var card_1 = document.getElementById(cardIDs[0]);
var card_2 = document.getElementById(cardIDs[1]);
card_1.style.background = 'url(cardQtion.jpg) no-repeat';
card_1.innerHTML = "";
card_2.style.background = 'url(cardQtion.jpg) no-repeat';
card_2.innerHTML = "";
cardVal = [];
cardIDs = [];
}
setTimeout(card2Back, 700);
}
}
}
}
</script>
<body>
<div id="card_board"></div>
<script>
newBoard();
</script>
</body>

You have some less than optimal code and frankly mine is only a refactor of that and has much that can be improved - study up.
Given that, here is the refactor:
I really dislike event in markup SO I moved that click handler invocation right into the code.
I saw two sets of JavaScript in your page why? I simply put them both in one.(see the last line of this).
Your array of images thing was not working and verbose so I used an array of names and created an array of images from that.
Insertion of an element is different than text so I used tile.appendChild(cardArray[cardIndex]); instead
Code:
// create an array of card images
var cardArray = [];
var cards = ['cardA.jpg', 'cardB.jpg', 'cardC.jpg', 'cardD.jpg', 'cardE.jpg', 'cardF.jpg'];
for (var i = 0; i < cards.length; i++) {
var im = new Image();
im.src = cards[i];
im.alt = cards[i];
cardArray.push(im);
cardArray.push(im);
}
var cardVal = [];
var cardIDs = [];
var cardBackFace = 0;
Array.prototype.cardMix = function() {
var i = this.length,
j, temp;
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
}
function newBoard() {
cardBackFace = 0;
var output = "";
cardArray.cardMix();
for (var i = 0; i < cardArray.length; i++) {
output += '<div id="card_' + i + '" class="cardcontainer" data-card="' + i + '"></div>';
}
document.getElementById('card_board').innerHTML = output;
var classname = document.getElementsByClassName("cardcontainer");
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('click', cardBackcard, false);
}
}
function card2Back() {
var card_1 = document.getElementById(cardIDs[0]);
var card_2 = document.getElementById(cardIDs[1]);
card_1.style.background = "url('cardQtion.jpg') no-repeat";
card_1.innerHTML = "";
card_2.style.background = "url('cardQtion.jpg') no-repeat";
card_2.innerHTML = "";
cardVal = [];
cardIDs = [];
}
function cardBackcard() {
// these used to be in the HTML as parameters, I refactored to pass `this`
// and then use the attribute which is the index of the card it had
var tile = this;
//multiply by 1 to get number, could use parseInt but I did not
var cardIndex = this.getAttribute("data-card") *1;
if (!(tile.innerHTML == "" && cardVal.length < 2)) return;
tile.style.background = '#FFF';
tile.appendChild(cardArray[cardIndex]);
if (!(cardVal.length == 0 && cardVal[0] == cardVal[1])) return;
cardVal.push(cardIndex);
cardIDs.push(tile.id);
if (cardVal.length == 1) {
if (cardVal[0] == cardVal[1]) {
cardBackFace += 2;
cardVal = [];
cardIDs = [];
if (cardBackFace == cardArray.length) {
alert("Board cleared... generating new board");
document.getElementById('card_board').innerHTML = "";
newBoard();
}
} else {
setTimeout(card2Back, 700);
}
}
}
newBoard();

Related

image url shown where image should be

I have a board game and when the user clicks on one of the boxes, it flips over and shows the letter. I wanted to instead have an image displayed when the user clicks instead of a letter. I have an array that holds all of the letters but when replaced with a imageurl, it just shows the url instead of the image. I will paste the html,css and js down below.
js
var memory_array = ["./naruto.gif ", "A", "B", "B", "C", "C", "D", "D"];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
Array.prototype.memory_tile_shuffle = function() {
var i = this.length,
j,
temp;
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
};
function newBoard() {
tiles_flipped = 0;
var output = "";
memory_array.memory_tile_shuffle();
for (var i = 0; i < memory_array.length; i++) {
output +=
'<div id="tile_' +
i +
'" onclick="memoryFlipTile(this,\'' +
memory_array[i] +
"')\"></div>";
}
document.getElementById("memory_board").innerHTML = output;
}
function memoryFlipTile(tile, val) {
//if the title is empty and array = 0 then the rest of code will perform
if (tile.innerHTML == "" && memory_values.length < 2) {
//the tile selected will have a white background and the val will be produced
tile.style.background = "#FFF";
tile.innerHTML = val;
//if the array equal = 0
if (memory_values.length == 0) {
//push the val and the title id to their respective arrays
memory_values.push(val);
memory_tile_ids.push(tile.id);
//if the array equal = 1
} else if (memory_values.length == 1) {
//push the val and the title id to their respective arrays
memory_values.push(val);
memory_tile_ids.push(tile.id);
//if memory_values values are the same
if (memory_values[0] == memory_values[1]) {
tiles_flipped += 2;
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
// Check to see if the whole board is cleared
if (tiles_flipped == memory_array.length) {
alert("Board cleared... generating new board");
document.getElementById("memory_board").innerHTML = "";
newBoard();
}
} else {
// if the two flip tiles aren't of the same value
function flip2Back() {
// Flip the 2 tiles back over
var tile_1 = document.getElementById(memory_tile_ids[0]);
var tile_2 = document.getElementById(memory_tile_ids[1]);
tile_1.style.background = "orangered";
tile_1.innerHTML = "";
tile_2.style.background = "orangered";
tile_2.innerHTML = "";
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
}
setTimeout(flip2Back, 700);
}
}
}
}
html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="app.js"></script>
</head>
<body>
<div id="memory_board"> </div>
<script>
newBoard();
</script>
</body>
</html>
CSS
<style>
div#memory_board {
background: #CCC;
border: #999 1px solid;
width: 800px;
height: 540px;
padding: 24px;
margin: 0px auto;
}
div#memory_board>div {
background: orangered;
border: #000 1px solid;
width: 71px;
height: 71px;
float: left;
margin: 10px;
padding: 20px;
font-size: 64px;
cursor: pointer;
text-align: center;
}
</style>
You can create new image and set the src value from the array of image. Also set the width and height.
var img= new Image();
img.src = val;
img.width="50";
img.height="50";
tile.appendChild(img);
See the snippet below:
div#memory_board {
background: #CCC;
border: #999 1px solid;
width: 800px;
height: 540px;
padding: 24px;
margin: 0px auto;
}
div#memory_board>div {
background: orangered;
border: #000 1px solid;
width: 71px;
height: 71px;
float: left;
margin: 10px;
padding: 20px;
font-size: 64px;
cursor: pointer;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="memory_board"> </div>
<script>
var memory_array = ["http://www.clker.com/cliparts/b/6/1/0/124223379411527084631_Train_(1967-1979).svg.med.png", "http://www.clker.com/cliparts/b/6/1/0/124223379411527084631_Train_(1967-1979).svg.med.png", "http://www.clker.com/cliparts/Y/y/T/n/Z/Q/number-2-md.png", "http://www.clker.com/cliparts/Y/y/T/n/Z/Q/number-2-md.png", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQo95Lf_9XG0mf3Tb_lfMDUDXiywIdpiiCb5jUSTyOi5ACJXa3C6w", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQo95Lf_9XG0mf3Tb_lfMDUDXiywIdpiiCb5jUSTyOi5ACJXa3C6w", "http://www.clker.com/cliparts/K/w/R/r/V/Z/number-4-hi.png", "http://www.clker.com/cliparts/K/w/R/r/V/Z/number-4-hi.png"];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
Array.prototype.memory_tile_shuffle = function() {
var i = this.length,
j,
temp;
while (--i > 0) {
j = Math.floor(Math.random() * (i + 1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
};
function newBoard() {
tiles_flipped = 0;
var output = "";
memory_array.memory_tile_shuffle();
for (var i = 0; i < memory_array.length; i++) {
output +=
'<div id="tile_' +
i +
'" onclick="memoryFlipTile(this,\'' +
memory_array[i] +
"')\"></div>";
}
document.getElementById("memory_board").innerHTML = output;
}
function memoryFlipTile(tile, val) {
//if the title is empty and array = 0 then the rest of code will perform
if (tile.innerHTML == "" && memory_values.length < 2) {
//the tile selected will have a white background and the val will be produced
tile.style.background = "#FFF";
var img= new Image();
img.src = val;
img.width="50";
img.height="50";
tile.appendChild(img);
//if the array equal = 0
if (memory_values.length == 0) {
//push the val and the title id to their respective arrays
memory_values.push(val);
memory_tile_ids.push(tile.id);
//if the array equal = 1
} else if (memory_values.length == 1) {
//push the val and the title id to their respective arrays
memory_values.push(val);
memory_tile_ids.push(tile.id);
//if memory_values values are the same
if (memory_values[0] == memory_values[1]) {
tiles_flipped += 2;
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
// Check to see if the whole board is cleared
if (tiles_flipped == memory_array.length) {
alert("Board cleared... generating new board");
document.getElementById("memory_board").innerHTML = "";
newBoard();
}
} else {
// if the two flip tiles aren't of the same value
function flip2Back() {
// Flip the 2 tiles back over
var tile_1 = document.getElementById(memory_tile_ids[0]);
var tile_2 = document.getElementById(memory_tile_ids[1]);
tile_1.style.background = "orangered";
tile_1.innerHTML = "";
tile_2.style.background = "orangered";
tile_2.innerHTML = "";
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
}
setTimeout(flip2Back, 700);
}
}
}
}
newBoard();
</script>
</body>
</html>
You can also test it here
Your code doesn't see the difference between a string representing a url, and a string with some text in it. It's both strings. So, in order to display the image, you'd need to do one of the following:
Create an <img> element, and set that elements src attribute to the url.
Add some css to make the element have a background-image with the url you have, and style that accordingly.
EDIT. Let's just do the first method, because it's a bit easier. The following will create an image with the correct source:
var imageElement = new Image();
imageElement.src = url;
and then we can put it inside an element, for example, putting it inside tile would be
tile.appendChild(imageElement);
EDIT 2. To transform the array of urls into an array of images, one could simply do this:
// your array of urls
var url_array = ["./naruto.gif","fakepath/pikachu.gif"];
// this will create a new array with the same length as url_array
var memory_array = new Array(url_array.length);
// loop through it to put the images in memory_array
for(var i = 0; i < memory_array.length; ++i){
memory_array[i] = new Image();
memory_array[i].src = url_array[i];
}
// now memory_array contains the right images with source set

How do I style this code using html and css?

The code below is for listing blogger posts within a Label Name, if the post has the specific Label Name it will be shown in this list. I would like to be able to change the appearance of how everything is displayed by changing where the post image would look, and where the title would look, change background color, add borders, shadows change the font etc ...(I know how to change the appearance with css, but I do not know how to integrate the code below with css and html) At the moment the code shows the title and the right of the title the image.
var startIndex = 1;
var maxResults = 5;
var allResults = [];
function sendQuery12()
{
var scpt = document.createElement("script");
scpt.src = "https://levon-ltr.blogspot.com//feeds/posts/summary?alt=json&callback=processPostList12&start-index=" + startIndex + "&max-results=" + maxResults;
document.body.appendChild(scpt);
}
function printArrayResults(root)
{
//Sort Alphebetically
allResults.sort(function(a, b){
var a_string = a.children[0].textContent ;
var b_string = b.children[0].textContent ;
if(a_string < b_string) return -1;
if(a_string > b_string) return 1;
return 0;
})
var elmt = document.getElementById("postList12");
for (index = 0; index < allResults.length; index++) {
elmt.appendChild(allResults[index]);
}
}
function processPostList12(root)
{
var elmt = document.getElementById("postList12");
if (!elmt)
return;
var feed = root.feed;
if (feed.entry.length > 0)
{
for (var i = 0; i < feed.entry.length; i++)
{
var entry = feed.entry[i];
var title = entry.title.$t;
var date = entry.published.$t;
if( entry.media$thumbnail != undefined ){
var imageThumb = entry.media$thumbnail.url ;
} else {
var imageThumb = 'https://i.imgur.com/PqPqZQN.jpg' ;
}
for (var j = 0; j < entry.link.length; j++)
{
if (entry.link[j].rel == "alternate")
{
var url = entry.link[j].href;
if (url && url.length > 0 && title && title.length > 0)
{
var liE = document.createElement("li");
var a1E = document.createElement("a");
var postImage = document.createElement("img");
a1E.href = url;
a1E.textContent = title;
postImage.src = imageThumb;
liE.appendChild(a1E);
liE.appendChild(postImage);
//elmt.appendChild(liE);
allResults.push(liE);
}
break;
}
}
}
if (feed.entry.length >= maxResults)
{
startIndex += maxResults;
sendQuery12();
} else {
printArrayResults();
}
}
}
sendQuery12();
<div>
<ul id="postList12"></ul>
</div>
This creates stuff you can style with CSS. For example:
#postList12 li {
border: 1px solid blue;
}
Use the inspector in your browser to see what it makes. If you want to change the order of elements or add new ones you’ll have to edit the script to do that.

How to fix these from moving

I recently asked how to use a progress bar, no one answered so I made up a custom progress bar, Its perfect but the [ ] expand out every new increment, is this due to the font width? or is it fixable? I used because it would have expanded in the first place.
<script type="text/javascript">
var imgsb = new Array("[/ ]","[// ]","[/// ]","[//// ]","[///// ]","[///// ]","[////// ]","[/////// ]","[//////// ]","[///////// ]","[///////// ]","[////////// ]","[/////////// ]","[//////////// ]","[///////////// ]","[////////////// ]","[/////////////// ]","[//////////////// ]","[///////////////// ]","[////////////////// ]","[/////////////////// ]","[//////////////////// ]","[///////////////////// ]","[////////////////////// ]","[///////////////////////]");
altb = new Array();
var currentAdb = 0;
var imgCtb = 25;
function cycleb() {
if (currentAdb == imgCtb) {
currentAdb = 0;
}
document.getElementById('adLinkb').innerHTML = imgsb[currentAdb];
currentAdb++;
}
window.setInterval("cycleb()",500);
</script>
<div style="font-size:12px;color:#fff;font-family:monospace;" id="adLinkb">[/ ]</div>
See how much cleaner this looks:
var currentAdb = 0;
var imgCtb = 25;
function cycleb() {
var output = '[';
for (var i = 0; i < imgCtb; i++) {
output += i > currentAdb ? ' ' : '/';
}
output += ']';
document.getElementById('adLinkb').innerHTML = output;
++currentAdb;
if(currentAdb == imgCtb) {
window.clearInterval(myInterval);
}
}
var myInterval = window.setInterval(cycleb, 500);
#adLinkb {
font-size: 12px;
color: #000;
font-family: monospace;
}
<div id="adLinkb"></div>
#Dave Goten answered this
Thank you all for helping me.
<script type="text/javascript">
var imgsb = new Array("[/ ]","[// ]","[/// ]","[//// ]","[///// ]","[///// ]","[////// ]","[/////// ]","[//////// ]","[///////// ]","[///////// ]","[////////// ]","[/////////// ]","[//////////// ]","[///////////// ]","[////////////// ]","[/////////////// ]","[//////////////// ]","[///////////////// ]","[////////////////// ]","[/////////////////// ]","[//////////////////// ]","[///////////////////// ]","[////////////////////// ]","[///////////////////////]");
altb = new Array();
var currentAdb = 0;
var imgCtb = 25;
function cycleb() {
if (currentAdb == imgCtb) {
currentAdb = 0;
}
document.getElementById('adLinkb').innerHTML = imgsb[currentAdb];
currentAdb++;
}
window.setInterval("cycleb()",500);
</script>
<div style="font-size:12px;color:#fff;font-family:monospace;" id="adLinkb">[/ ]</div>

Plugin Freewall, cannot get wall function to work

I am trying to create a grid style layout for my homepage that pulls random information every time the user loads the page. I have created the function but cannot even get it to display the wall items.
Here is the code I am using. Please point me in the right direction and I will be able to solve it but I cannot find my issue right now.
$(function() {
var temp = "<div class='bubble eventBrick' id='{brickID}' style='width:{width}px; height: {height}px;'><div class='rectangle' style='background: {ribbonColor};'><h2>{brickInfo}</h2></div><div class='triangle-l'><div class='info' style='border-color: transparent {triColor} transparent transparent;'></div> <!-- Left triangle --></div>";
var w = 1, h = 1, html = '', limitEventItem = 16, podcastBrick = 1, longBrick = 3;
var wallBricks = [
'podBrick',
'longBrick',
'trackBrick',
'newsBrick',
'socialBrick',
'photoBrick'
]
var wallBrickList = new Array();
var total = limitEventItem;
var trackBrickLimit = 3;
var newsBrickLimit = 3;
var socialBrickLimit = 3;
var photoBrickLimit = 3;
var eventWall = new freewall("#eventWall");
eventWall.reset({
selector: '.eventBrick',
animate: true,
cellW: 156.5,
cellH: 136,
delay: 15,
gutterX: 24,
gutterY: 10,
onResize: function(){
eventWall.fitZone();
}
});
for (t = 0; t <= trackBrickLimit; t++){
h = 1;
w = 1;
html += temp.replace(/\{height\}/g, h*100).replace(/\{width\}/g, w*100).replace("{brickInfo}", "Track Item").replace("{ribbonColor}", "#7f9db9").replace("{triColor}", "#7f9db9");
$("#eventWall").html(html);
html = '';
}
for (n = 0; n <= newsBrickLimit; n++) {
h = 1;
w = 1;
html += temp.replace(/\{height\}/g, h*100).replace(/\{width\}/g, w*100).replace("{brickInfo}", "News Item").replace("{ribbonColor}", "#FF9933").replace("{triColor}", "#FF9933");
$("#eventWall").html(html);
html = '';
}
for (s = 0; s <= socialBrickLimit; s++) {
h = 1;
w = 1;
html += temp.replace(/\{height\}/g, h*100).replace(/\{width\}/g, w*100).replace("{brickInfo}", "Social Item").replace("{ribbonColor}", "#3366FF").replace("{triColor}", "#3366FF");
$("#eventWall").html(html);
html = '';
}
for (p = 0; p <= photoBrickLimit; p++) {
h = 1;
w = 1;
html += temp.replace(/\{height\}/g, h*100).replace(/\{width\}/g, w*100).replace("{brickInfo}", "Photo Item").replace("{ribbonColor}", "#33FF00").replace("{triColor}", "#33FF00");
$("#eventWall").html(html);
html = '';
}
eventWall.fitZone((600), (815));
function randomList(total) {
var brickLimit = total;
var brickTotal = 0;
var news = Math.floor((Math.random()*4) +1);
brickTotal += news;
if (brickTotal <= 2) {
var social = Math.floor((Math.random()*4)+1);
var tracks = Math.floor((Math.random()*4)+1);
brickTotal = brickTotal + social + tracks;
if (brickTotal <= 10) {
extraBanner = 1;
var photo = brickTotal - total - 1;
} else {
var photo = brickTotal - total - 1;
}
} else {
var social = Math.floor((Math.random()*3)+1);
var photo = Math.floor((Math.random()*3)+1);
var tracks = brickLimit - news - photo - social;
}
var brickCount = new Object()
brickCount[0] = track;
brickCount[1] = news;
brickCount[2] = social;
brickCount[3] = photo;
return brickCount;
}
});
If I am missing a concept please tell me the concept, where I can learn more and examples so I might be able to rework this by myself.
Please check with the selector:
<div class='bubble {eventBrick}Brick'
and
selector: '.eventBrick',

Drawing multiple random canvas images in a loop

I'm trying to draw a grid with random images assigned to each square. I'm having trouble with the draw sequence and potentially closure issues with the Javascript variables. Any help is appreciated.
var tileSize = 30;
var drawCanvasImage = function(ctx,tile,x,y) {
return function() {
ctx.drawImage(tile,x,y);
console.log("x = " + x + "/ y = " + y);
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
for (var i=0; i<=10; i++) {
for (var j=0; j<=20; j++) {
rand = Math.floor(Math.random()*3 + 1);
x = i * tileSize;
y = j * tileSize;
if (rand == 1) {
grass.onload = drawCanvasImage(ctx,grass,x,y);
} else if (rand == 2) {
sea.onload = drawCanvasImage(ctx,sea,x,y);
} else {
woods.onload = drawCanvasImage(ctx,woods,x,y);
}
}
}
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
}
//function called by the onload event in the html body tag
function draw() {
var ctx = document.getElementById("grid").getContext('2d');
grid(ctx); //a function to draw the background grid - works fine
textures(ctx);
}
The current result is three drawn tiles, all at the position of x = 300 (equivalent to the i loop of 10 * the tileSize of 30) and a random y position.
After following a lead and accounting for (maybe?) closure issues by creating the variable drawCanvasImage, I at least got those three tiles to draw.
----Edit----
Working Code - Revision 2:
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
rand = Math.floor(Math.random()*4 + 1);
if (rand == 1) {
terrainArray[i][j] = 3;
} else if (rand == 2) {
terrainArray[i][j] = 2;
} else if (rand == 3) {
terrainArray[i][j] = 1;
} else {
terrainArray[i][j] = 0;
}
}
}
}
var drawTerrain = function(ctx,tile,landUseValue) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == landUseValue) {
ctx.drawImage(tile,i*tileSize,j*tileSize);
}
}
}
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
var desert = new Image();
grass.onload = drawTerrain(ctx,grass,3);
sea.onload = drawTerrain(ctx,sea,0);
woods.onload = drawTerrain(ctx,woods,2);
desert.onload = drawTerrain(ctx,desert,1);
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
desert.src = "textures/desert.png";
}
You're rewriting the onloads of the three images in every iteratiom. So, it will only execute the last-added onload f or every image.
Suggestion: run your drawing method only after the thred are loaded(and them just call drawCanvasImage every iteration without an .onload=)
Even better:store the randoms in an array, have each image independantly walk through the array on load and add copies of only itself wherever applicable .
Improvement to rev 2
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
rand = Math.floor(Math.random()*4 + 1);
terrainArray[i][j] = 4-rand;
//OR: replace above two lines with terrainArray[i][j]=Math.floor(Math.random()*4 + 1);. There's no need to have them in exactly reverse order.
}
}
}
var drawTerrain = function(ctx,tile,landUseValue) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == landUseValue) {
ctx.drawImage(tile,i*tileSize,j*tileSize);
}
}
}
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
var desert = new Image();
grass.onload = drawTerrain(ctx,grass,3);
sea.onload = drawTerrain(ctx,sea,0);
woods.onload = drawTerrain(ctx,woods,2);
desert.onload = drawTerrain(ctx,desert,1);
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
desert.src = "textures/desert.png";
}
To make it even more flexible, you could use an array to store the images, and then use length. This way, if you want to add another image, all you have to do is modify the array.
var srcArray=["textures/grass.png","textures/sea.png","textures/woods.png","textures/desert.png"];
var imgArray=[];
var terrainArray=[];
function textures(ctx){
randomArray();
for(var i=0;i<srcArray.length;i++){
imgArray[i]=new Image();
imgArray[i].src=srcArray[i];
imgArray[i].onload=drawTerrain(ctx,i);
}
}
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
terrainArray[i][j]=Math.floor(Math.random()*srcArray.length);
}
}
}
var drawTerrain = function(ctx,index) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == index) {
ctx.drawImage(imgArray[index],i*tileSize,j*tileSize);
}
}
}
}
}
So now, all you have to do is call terrain(ctx) when you want to load all the images. And, whenever you want to add an image to the list of images, just add it to the array up top. You won't have to dig deeper and modify the random values and whatnot.
It's because every time you do a loop, you assign a new function to [image].onload, overwriting the previous one. That's how you end up with only three images.
This should work:
if (rand == 1) {
grass.addEventlistener('load', drawCanvasImage(ctx,grass,x,y), false);
} else if (rand == 2) {
sea.addEventlistener('load', drawCanvasImage(ctx,sea,x,y), false);
} else {
woods.addEventlistener('load', drawCanvasImage(ctx,woods,x,y), false);
}
Here you just add a new listener for every loop.

Categories

Resources