So, I want to create a minecraft website theme using HTML5. I am a bit shaky in HTML5/Javascript(haven't used it in a while), and I need some help. I am trying to calculate a number of 16x16px tiles that can fit on the screen. Then, randomly "generate a map" for the background of the screen. Then, I use the same 2 for loops that generate the map to fill the screen with the tiles(which are assigned picture paths during the generation process). The problem is, the canvas is pletely white. Can anyone pick out the problem, and give me any tips if possible? Thanks in advance! Here is my HTML5 code:
<!DOCTYPE html>
<html>
<head>
<title>Minecraft Background Check</title>
</head>
<body>
<canvas id="bg" style="position:fixed; top:0; left:0; border:1px solid #c3c3c3; width: 100%; height: 100%;"></canvas>
<script type="text/javascript">
"use strict";
var c = document.getElementById("bg");
var ctx = c.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var width = Math.ceil(window.innerWidth / 16);
var height = Math.ceil(window.innerHeight / 16);
for (var x=0;x<width;x++)
{
for(var y=0;y<height;y++)
{
var rand = Math.floor(Math.random()*11);
var texLoc = getImageNameFromRand(rand,y,height);
var img=new Image();
img.onload = function(){
return function() {
ctx.drawImage(img,x*16,y*16);
};
};
img.src=texLoc;
}
}
function getImageNameFromRand(rand,yVal,maxY)
{
var dirt = 'dirt.png';
var stone = 'stone.png';
var cobble = 'cobble.png';
var mosscobble = 'mosscobble.png';
var bedrock = 'bedrock.png';
if(yVal===0)
{
return dirt;
} else if(yVal<3)
{
if(rand < 7) {
return dirt; }
else {
return stone; }
} else if(yVal<5)
{
if(rand < 4) {
return dirt; }
else {
return stone; }
} else if(yVal<maxY-2)
{
if(rand === 0) {
return dirt; }
else if(rand < 4) {
return cobble; }
else if(rand < 5) {
return mosscobble; }
else {
return stone; }
} else if(yVal<maxY-1)
{
if(rand < 4) {
return bedrock; }
else {
return stone; }
} else if(yVal<maxY)
{
if(rand < 7) {
return bedrock; }
else {
return stone; }
} else {
return bedrock; }
return bedrock;
}
</script>
</body>
</html>
So, I want to create a minecraft website theme using HTML5. I am a bit shaky in HTML5/Javascript(haven't used it in a while), and I need some help. I am trying to calculate a number of 16x16px tiles that can fit on the screen. Then, randomly "generate a map" for the background of the screen. Then, I use the same 2 for loops that generate the map to fill the screen with the tiles(which are assigned picture paths during the generation process). The problem is, the canvas is pletely white. Can anyone pick out the problem, and give me any tips if possible? Thanks in advance! Here is my HTML5 code:
<!DOCTYPE html>
<html>
<head>
<title>Minecraft Background Check</title>
</head>
<body>
<canvas id="bg" style="position:fixed; top:0; left:0; border:1px solid #c3c3c3; width: 100%; height: 100%;"></canvas>
<script type="text/javascript">
"use strict";
var c = document.getElementById("bg");
var ctx = c.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var width = Math.ceil(window.innerWidth / 16);
var height = Math.ceil(window.innerHeight / 16);
for (var x=0;x<width;x++)
{
for(var y=0;y<height;y++)
{
var rand = Math.floor(Math.random()*11);
var texLoc = getImageNameFromRand(rand,y,height);
var img=new Image();
img.onload = function(){
return function() {
ctx.drawImage(img,x*16,y*16);
};
};
img.src=texLoc;
}
}
function getImageNameFromRand(rand,yVal,maxY)
{
var dirt = 'dirt.png';
var stone = 'stone.png';
var cobble = 'cobble.png';
var mosscobble = 'mosscobble.png';
var bedrock = 'bedrock.png';
if(yVal===0)
{
return dirt;
} else if(yVal<3)
{
if(rand < 7) {
return dirt; }
else {
return stone; }
} else if(yVal<5)
{
if(rand < 4) {
return dirt; }
else {
return stone; }
} else if(yVal<maxY-2)
{
if(rand === 0) {
return dirt; }
else if(rand < 4) {
return cobble; }
else if(rand < 5) {
return mosscobble; }
else {
return stone; }
} else if(yVal<maxY-1)
{
if(rand < 4) {
return bedrock; }
else {
return stone; }
} else if(yVal<maxY)
{
if(rand < 7) {
return bedrock; }
else {
return stone; }
} else {
return bedrock; }
return bedrock;
}
</script>
</body>
</html>
Share
Improve this question
asked Mar 7, 2012 at 1:12
Flafla2Flafla2
5457 silver badges12 bronze badges
3 Answers
Reset to default 3There is a lot going on here to explain. I tested the code below and got it to work, but I simply used one image over and over. Hopefully, this will work when merged with your code. Place the code, below, in place of your for loops (i.e., after var height and before function getImageNameFromRand).
First off, your code is defining all vars in the global namespace, so the img var is getting replaced each time through the original loop, along with its src and onload function ,etc. Furthermore, the x and y that increment the for loops get referenced through closure in the onload function, but because they are only incremented during the outside loop (not in the onload function) they are both set to their ending values during the onload call (the ending values when the original loop ran).
Also, try and put all your script into an anonymous function like (function () { YOUR CODE HERE } )(). This way you won't be adding to the global namespace with the local vars and the onload will have what it needs because of closure. I tested putting everything into the anonymous function and it worked for me.
Hopefully, I copied and pasted this all correctly. Please ment if it is off. Good Luck!!!
//Copy this code in place of your original "for" loop:
var imgs = [];
var imgIndex = 0;
for (var x = 0; x < width; x++){
for(var y = 0; y < height; y++){
var rand = Math.floor(Math.random() * 11);
var texLoc = getImageNameFromRand(rand, y, height);
imgs[imgIndex] = new Image();
imgs[imgIndex].onload = (function () {
var thisX = x * 16;
var thisY = y * 16;
return function () {
ctx.drawImage(this, thisX, thisY);
};
}());
imgs[imgIndex].src = texLoc;
imgIndex += 1;
}
}
When you do the following:
img.onload = function(){
return function() {
ctx.drawImage(img,x*16,y*16);
};
};
You are attempting to create a closure over img
so that inside of the onload
handler it will refer to the image that you created in that iteration of the loop.
But you aren't quite doing that. Instead, the onload
handler is just defining an anonymous function and then doing nothing.
img.onload = function(img){
return function() {
ctx.drawImage(img,x*16,y*16);
};
}(img);
If you change it so that you are immediately calling the anonymous function and passing in img
, then you will close over img
(from the for
loop context) and it will do what you want.
If the outer anonymous function isn't immediately called, then it will bee the onload handler for the image. And nothing will happen. Leading to a blank canvas.
The problem is that in your for loop, you are drawing the image over and over on top of each other. If you break out of the forloops entirely after the first run(x=0, y=0), you will see a single tile of your random image on position 0,0. When it goes through the entire double for loop, your last image is drawn on the bottom corner of the canvas, which creates the 'blank white canvas' you are seeing. You need to have it draw a 'pre filled' canvas of random tiles. This also means that your for loops need to be inside the onload() function because your background only gets drawn once, not hundreds/thousands of times.
Look for html5 canvas patterns/tiles then work from there.
also, your onload function doesn't need the inside function, you could have it as something like this:
img.onload = function(){
// - nested for loops
// -> generate a tile pattern to fit the entire canvas
// - ctx.drawImage()
};
Good luck!
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744193387a4562539.html
评论列表(0条)