上个周末,我一直在研究这个基本的积木游戏,我对此感到非常自豪。我确实认为它可以在许多地方得到改进,例如,由于我设计糟糕的瓷砖加载而导致的性能问题等等。
/** Here are few instructions before you start...
* IMPORTANT (ON KHANACADEMY ONLY): When you make changes to the code, all tiles will be black.
* Just hit the restart button to fix that.
*
* CONTROLS:
* MOUSE - Move around the current selected tile.
* LEFT MOUSE BUTTON - Add a tile to the screen.
* RIGHT MOUSE BUTTON - Delete a tile from the screen.
* CONTROL KEY - Change the block type.
* WASD or LEFT RIGHT DOWN UP - Move around the map.
*/
/* Global program constants */
var CURSOR_FONT = createFont("monospace", 15);
var BACKGROUND_COLOR = color(0, 0, 255);
var HITBOX_COLOR = color(255, 255, 255);
var CLOUD_COLOR = color(255, 255, 255);
var SUN_COLOR1 = color(194, 181, 33);
var SUN_COLOR2 = color(255, 140, 0);
var SUN_WIDTH = 100;
var SUN_HEIGHT = 100;
var TILE_SIZE = 10;
var COLORS = [
color(180, 120, 20),
color(20, 150, 20),
color(100, 100, 100),
color(240, 200, 10),
color(5, 44, 117),
color(255, 255, 255),
color(110, 70, 10),
color(10, 210, 20),
];
var TILE_TYPES = [
"Dirt",
"Grass",
"Stone",
"Sand",
"Water",
"Snow",
"Wood",
"Leaves",
];
/* Variables concerning map movement */
var movingUp = false;
var movingDown = false;
var movingLeft = false;
var movingRight = false;
/* Array containing cloud data */
var cloudArray = [];
/* Current selected color */
var selectedColor = 0;
/* Array contaning all tile data */
var tileArray = [];
/* Variables controlling the sun's position */
var sunYChange = -0.5;
var SUN_X_POS = 189;
var sunYPos = 200;
/* Render the day and night cycle*/
var renderDayNightCycle = function() {
noStroke();
fill(SUN_COLOR2);
rect(SUN_X_POS, sunYPos, 45, 45);
fill(SUN_COLOR1);
rect(SUN_X_POS+5, sunYPos+5, 35, 35);
sunYPos += sunYChange;
if(sunYPos <= -50) {
sunYChange = 0.5;
}
if(sunYPos >= 450) {
sunYChange = -0.5;
}
};
/* Generate new terrain for the world */
var generateTerrain = function() {
var c = random(1, 3);
var blockY = 300;
for(var x = -1500; x <= 1500; x += TILE_SIZE) {
tileArray.push([]);
var rb = round(random(-1, 0));
tileArray.push({
xPos: x,
yPos: blockY+TILE_SIZE*rb,
colr: COLORS[1],
});
if(rb === -1) {
tileArray.push({
xPos: x,
yPos: blockY,
colr: COLORS[0],
});
}
if(random() >= random()*random()/random()+random()) {
var m = round(random(2, 6));
for(var h = blockY-TILE_SIZE; h >= blockY-TILE_SIZE*m; h -= TILE_SIZE) {
tileArray.push({
xPos: x,
yPos: h,
colr: COLORS[6],
});
}
for(var i = 0; i <= 1; i++) {
tileArray.push({
xPos: x,
yPos: blockY-TILE_SIZE*(m+i)-TILE_SIZE,
colr: COLORS[7],
});
}
tileArray.push({
xPos: x+TILE_SIZE,
yPos: blockY-TILE_SIZE*m-TILE_SIZE,
colr: COLORS[7]
});
tileArray.push({
xPos: x-TILE_SIZE,
yPos: blockY-TILE_SIZE*m-TILE_SIZE,
colr: COLORS[7]
});
}
for(var y = blockY; y <= blockY+TILE_SIZE*round(random(2, 4)); y += TILE_SIZE) {
tileArray.push({
xPos: x,
yPos: y+TILE_SIZE,
colr: COLORS[0],
});
}
for(var y = blockY+TILE_SIZE*round(c); y <= blockY+TILE_SIZE*random(18, 22); y += TILE_SIZE) {
tileArray.push({
xPos: x,
yPos: y+TILE_SIZE,
colr: COLORS[2],
});
}
blockY += (ceil(random(-1, 1)/TILE_SIZE)*TILE_SIZE)*round(random(-2, 2));
}
};
/* Initalize the array of clouds */
var generateClouds = function() {
for(var i = 0; i <= round(random(2, 12)); i++) {
cloudArray.push({
xPos: random(50, 350),
yPos: random(50, 150),
w: random(30, 60),
h: random(10, 20),
});
}
};
/* Draw the background */
var drawBackground = function() {
for(var c = cloudArray.length-1; c >= 0; c--) {
var cloud = cloudArray[c];
noStroke();
fill(CLOUD_COLOR);
rect(cloud.xPos, cloud.yPos, cloud.w, cloud.h);
cloud.xPos += random(0.01, 0.09);
if(cloud.xPos >= 400) {
cloud.xPos = 0-cloud.w;
}
}
};
/* Draw a hitbox over the selected position */
var drawHitbox = function(x, y) {
noCursor();
fill(HITBOX_COLOR);
textFont(CURSOR_FONT);
text("+", mouseX-1, mouseY+4);
noFill();
strokeWeight(1);
stroke(HITBOX_COLOR);
rect(x, y, TILE_SIZE, TILE_SIZE);
};
/* Add a block to the screen */
var addBlock = function(x, y) {
drawHitbox(x, y);
if(mouseIsPressed && mouseButton === LEFT) {
if(x >= 20 && y >= 20) {
tileArray.push({
xPos: x,
yPos: y,
colr: COLORS[selectedColor],
});
}
}
};
/* Delete a block from the screen */
var deleteBlock = function(x, y) {
drawHitbox(x, y);
if(mouseIsPressed && mouseButton === RIGHT) {
for(var t = tileArray.length-1; t >= 0; t--) {
var tile = tileArray[t];
if(x === tile.xPos && y === tile.yPos) {
tileArray.splice(t, 1);
}
}
}
};
/* Render the tileArray */
var renderTiles = function() {
for(var t = tileArray.length-1; t >= 0; t--) {
var tile = tileArray[t];
noStroke();
fill(tile.colr);
rect(tile.xPos, tile.yPos, TILE_SIZE, TILE_SIZE);
}
};
/* Check for specific key actions */
var checkForKeyActions = function() {
keyPressed = function() {
if(keyCode === LEFT || keyCode === 65) {
movingLeft = true;
}
if(keyCode === RIGHT || keyCode === 68) {
movingRight = true;
}
if(keyCode === UP || keyCode === 87) {
movingUp = true;
}
if(keyCode === DOWN || keyCode === 83) {
movingDown = true;
}
if(keyCode === CONTROL) {
selectedColor++;
if(selectedColor >= COLORS.length) {
selectedColor = 0;
}
}
};
keyReleased = function() {
if(keyCode === LEFT || keyCode === 65) {
movingLeft = false;
}
if(keyCode === RIGHT || keyCode === 68) {
movingRight = false;
}
if(keyCode === UP || keyCode === 87) {
movingUp = false;
}
if(keyCode === DOWN || keyCode === 83) {
movingDown = false;
}
};
if(movingUp) {
for(var t = tileArray.length-1; t >= 0; t--) {
var tile = tileArray[t];
tile.yPos += TILE_SIZE;
}
}
if(movingDown) {
for(var t = tileArray.length-1; t >= 0; t--) {
var tile = tileArray[t];
tile.yPos -= TILE_SIZE;
}
}
if(movingLeft) {
for(var t = tileArray.length-1; t >= 0; t--) {
var tile = tileArray[t];
tile.xPos += TILE_SIZE;
}
}
if(movingRight) {
for(var t = tileArray.length-1; t >= 0; t--) {
var tile = tileArray[t];
tile.xPos -= TILE_SIZE;
}
}
};
/* Draw the current selected tile */
var drawSelectedTile = function() {
strokeWeight(1.5);
stroke(255, 255, 255);
fill(COLORS[selectedColor]);
rect(5, 5, 15, 15);
fill(255, 255, 255);
textFont(CURSOR_FONT);
text(TILE_TYPES[selectedColor], 25, 17.4);
};
/* Load the world and clouds before the draw loop begins */
generateTerrain();
generateClouds();
/* Main draw loop */
draw = function() {
/* Reset the background on each loop */
background(BACKGROUND_COLOR);
/* Render the day/night cycle */
renderDayNightCycle();
/* Draw the background clouds */
drawBackground();
/* Render the tiles */
renderTiles();
/* Draw the current selected tile */
drawSelectedTile();
/* Check for certain key actions */
checkForKeyActions();
/* Check if the user wants to add a block */
addBlock(ceil(mouseX/TILE_SIZE)*TILE_SIZE-TILE_SIZE,
ceil(mouseY/TILE_SIZE)*TILE_SIZE-TILE_SIZE);
/* Check if the user wants to delete a block */
deleteBlock(ceil(mouseX/TILE_SIZE)*TILE_SIZE-TILE_SIZE,
ceil(mouseY/TILE_SIZE)*TILE_SIZE-TILE_SIZE);
/* Draw a hitbox over the current selected block */
drawHitbox(ceil(mouseX/TILE_SIZE)*TILE_SIZE-TILE_SIZE,
ceil(mouseY/TILE_SIZE)*TILE_SIZE-TILE_SIZE);
};
我知道还有很多需要改进的地方,那么还有什么可以改进的呢?您可以在这里找到播放它的链接:这里。
发布于 2014-11-11 17:13:40
您的代码比我上次查看它时有了很大的改进。9~10成熟!我确实有一些评论,我只会按它们出现的顺序来讨论它们。
RIGHT MOUSE BUTTON - Delete a tile from the screen.
不是所有的电脑都有鼠标右键。例如,假设有人在使用Mac?
var SUN_COLOR1 = color(194, 181, 33);
var SUN_COLOR2 = color(255, 140, 0);
我认为你最好把这些颜色称为它们是什么,而不是叫它们COLOR1
和COLOR2
。backgroundColor
和foregroundColor
在这里会更有意义。
var COLORS = [
color(180, 120, 20),
color(20, 150, 20),
color(100, 100, 100),
color(240, 200, 10),
color(5, 44, 117),
color(255, 255, 255),
color(110, 70, 10),
color(10, 210, 20),
];
当第一次遇到这种情况时,读者并不清楚这些颜色将用于什么。我想也许他们会在某个时候被随机分配。如果是这样的话,randomColors
将是一个更好的名字。但是,从代码中可以看出,在呈现任何瓷砖时都会使用它们。看起来,selectedColor
、TILE_TYPES
数组和COLORS
数组之间有某种关系。不幸的是,从代码中很难理解确切的关系。
这表明,最好是有某种类型的Tile
对象,其中包含有关其名称和颜色的信息,以及任何其他必要的重要信息。以面向对象的方式编写Javascript有些困难,因为这些特性没有像它们内置到更传统的语言(如Java )中那样被内置到语言中,但是仍然可以这样做,这将提高代码的可读性。
var CLOUD_COLOR = color(255, 255, 255);
var SUN_COLOR1 = color(194, 181, 33);
var SUN_COLOR2 = color(255, 140, 0);
var movingDown = false;
var movingLeft = false;
var movingRight = false;
选择一种命名风格并坚持下去。不要将ALLCAPITAL变量命名与camelCase混合。尽可能始终如一地编写代码是很重要的。对于Javascript,大多数人建议您执行camelCase中的所有变量。
var generateTerrain = function() {
在这个函数中有很多事情发生,很难精确地跟踪地形是如何产生的。如果您能够理解几个月后查看这段代码时所发生的事情的确切流程,我会感到惊讶。只是我不喜欢的几件:
var c = random(1, 3);
var blockY = 300;
for(var x = -1500; x <= 1500; x += TILE_SIZE) {
所有这些数字似乎都是神奇的数字,应该有描述它们含义的可变名称。
if(random() >= random()*random()/random()+random()) {
我甚至不会试图弄清楚这是在做什么,但它看起来真的很复杂和迟钝。
for(var y = blockY; y <= blockY+TILE_SIZE*round(random(2, 4)); y += TILE_SIZE) {
for(var y = blockY+TILE_SIZE*round(c); y <= blockY+TILE_SIZE*random(18, 22); y += TILE_SIZE) {
再说一遍,不知道这些台词意味着什么。像这样的事情使得我们很难知道用来生成地形的规则。至少应该有一些评论来解释地形生成的各个阶段。然而,我认为,如果您重组功能,使用更多的描述性名称和更清晰的逻辑,这应该是可以理解的,没有很多评论。
/* Draw the background */
var drawBackground = function() {
像上面这样的评论是多余和不必要的。评论通常应该解释为什么你在做某事,而不是你在做什么。这方面的例外是解释一条难以理解的代码行。
draw = function() {
我真的很喜欢把所有的东西都分割成自己的方法。这个方法很容易理解,以后也很容易修改。这是一种很好的做事方法。
发布于 2014-11-11 21:37:15
我喜欢这个项目,
我肯定会创建一个帮助函数来创建这样的瓷砖:
function createTile( x, y, color ){
tileArray.push({
x: x,
y: y,
color: color,
});
}
注意,我会将xPos
放到x
中,因为每个人都正确地解析了x
,并且我将colr
改为color
,因为colr
看起来很奇怪。
然后,您的generateTerrain
函数变得更加可读性更强,它实际上邀请读者开始与世界世代打交道:
for(var x = -1500; x <= 1500; x += TILE_SIZE) {
tileArray.push([]);
var rb = round(random(-1, 0));
tileArray.push( createTile( x, blockY+TILE_SIZE*rb, COLORS[1] ) );
if(rb === -1) {
tileArray.push( createTile( x, blockY, COLORS[0] ) );
}
//etc etc etc
我建议的另一个改变是通过命名颜色来使颜色更直观:
var tiles = {
'dirt': color(180, 120, 20), //0
'grass': color(20, 150, 20), //1
'stone': color(100, 100, 100), //2
'sand': color(240, 200, 10), //3
'water': color(5, 44, 117), //4
'snow': color(255, 255, 255), //5
'wood': color(110, 70, 10), //6
'leaves': color(10, 210, 20), //7
};
var TILE_TYPES = Object.keys( tiles );
然后,在代码中,您可以替换以下颜色语句:
for(var y = blockY; y <= blockY+TILE_SIZE*round(random(2, 4)); y += TILE_SIZE) {
tileArray.push( newTile( x, y+TILE_SIZE, tiles.dirt ) );
}
for(var y = blockY+TILE_SIZE*round(c); y <= blockY+TILE_SIZE*random(18, 22); y += TILE_SIZE) {
tileArray.push( newTile( x, y+TILE_SIZE, tiles.stone ) );
}
至于背景,请查看以下内容:http://cssdeck.com/labs/4ksohwya --可能需要一段时间才能理解背景是如何完成的,但这是非常值得的。
https://codereview.stackexchange.com/questions/69495
复制相似问题