我正在p5.js中制作3D俄罗斯方块.但是现在我有一个错误,使这些错误从底部掉了!我不确定为什么会这样,因为我写了一个函数“ fallingPieceIsLegal”来防止这种情况.非常感谢你的帮助!
//Audrey Zheng
//3D Tetris
var cx;
var cy;
// set board dimensions and margin
var rows = 15;
var cols = 10;
var margin = 50;
let emptyColor;
//make board
var state = new Array();
for (var i = 0; i < cols; i ++) {
state.push(emptyColor);
}
var board = new Array();
for (var i = 0; i< rows; i ++) {
board.push(state);
}
//seven "standard" pieces (tetrominoes)
var iPiece = [
[ true,true,true]
];
var jPiece = [
[ true,false,false ],[ true,true]
];
var lPiece = [
[ false,true],true]
];
var oPiece = [
[ true,true]
];
var sPiece = [
[ false,false ]
];
var tPiece = [
[ false,true]
];
var zPiece = [
[ true,[ false,true]
];
var tetrisPieces = [ iPiece,jPiece,lPiece,oPiece,sPiece,tPiece,zPiece ];
var tetrisPieceColors = [ "green","pink","orange","yellow","purple","blue","red" ];
//the falling piece
var fallingPiece;
var fallingPieceCols;
var fallingPieceCol;
var fallingPieceRow;
function setup() {
frameRate(10);
createCanvas(550,800);
background(220);
// osc = new p5.TriOsc();
// osc.freq(880.0);
// osc.amp(0.1);
// osc.start();
cx = width/2;
cy = width/2;
newFallingPiece();
//fallingPieceIsLegal();
}
function draw() {
fill(255,255,220);
rect(0,width,height);
emptyColor = color(255,63);
drawBoard(rows,cols,450,675);
placeFallingPiece();
rectMode(CORNER);
drawFallingPiece();
if (moveFallingPiece(-1,0) == false) {
placeFallingPiece();
newFallingPiece();
}
}
function newFallingPiece(){
fallingPiece = random(tetrisPieces);
fallingPieceCols = fallingPiece[0].length;
fallingPieceCol = cols/2 - Math.floor(fallingPieceCols/2);
fallingPieceRow = 0;
//console.log(fallingPiece);
}
function placeFallingPiece() {
for (var r = 0; r < fallingPiece.length; r ++) {
for (var c = 0; c < fallingPiece[0].length; c ++) {
if (fallingPiece[r][c]) {
board[r + fallingPieceRow][c + fallingPieceCol] = "magenta";
}
//print("hi");
}
}
}
function drawFallingPiece() {
for (var r = 0; r < fallingPiece.length; r ++) {
for (var c = 0; c < fallingPiece[0].length; c ++) {
if (fallingPiece[r][c]) {
var bnds = getCellBounds(r + fallingPieceRow,c + fallingPieceCol,675);
fill(255);
rect(bnds[0],bnds[2],45,45);
var tetrisCube = new cube(bnds[0],true);
//systems.push(tetrisCube);
tetrisCube.display();
//fill(230,245,255);
rect(bnds[0],45);
}
//print("hi");
}
}
}
function fallingPieceIsLegal() {
for (var r = 0; r < fallingPiece.length; r++) {
for (var c = 0; c < fallingPieceCols; c++) {
if (fallingPiece[r][c] == true) {
if ((c + fallingPieceCol > cols - 1) || (c + fallingPieceCol < 0)) {
return false;
}
if (r + fallingPieceRow > rows -1) {
return false;
}
}
}
}
return true;
}
function moveFallingPiece(drow,dcol) {
if ((drow == 0) && (dcol == -1)) { //move left
fallingPieceCol -= 1;
if (fallingPieceIsLegal() == false) {
fallingPieceCol += 1;
print('hi');
}
}
if ((drow == 0) && (dcol == 1)) { //move right
fallingPieceCol += 1;
if (fallingPieceIsLegal() == false) {
print("yo");
fallingPieceCol -= 1;
}
}
if ((drow == -1) && (dcol == 0)) { //move down
fallingPieceRow += 1;
if (fallingPieceIsLegal() == false) {
fallingPieceRow -= 1;
return false;
}
return true;
}
}
function rotate1(L) {
var result = [];
var a;
for (var col = L[0].length -1; col > -1; col--) {
//print("yeet");
var result1 = [];
for (var row = 0; row < L.length; row++) {
a = L[row][col];
result1.push(a);
print(a);
}
result.push(result1);
}
return result;
}
function rotateFallingPiece() {
fallingPiece = rotate1(fallingPiece);
fallingPieceCols = fallingPiece[0].length;
if (fallingPieceIsLegal == false) {
for (var i = 0; i < 3; i ++) {
fallingPiece = rotate1(fallingPiece);
fallingPieceCols = fallingPiece[0].length;
}
}
print(fallingPiece);
}
function getCellBounds(row,col,height) {
var gridWidth = width - 2 * margin;
var gridHeight = height - 2 * margin;
var x0 = margin + width * col/ cols;
var x1 = margin + width * (col + 1)/ cols;
var y0 = margin + height * row / rows;
var y1 = margin + height * (row + 1)/ rows;
return [x0,x1,y0,y1];
}
//console.log(getCellBounds(0,600));
function drawBoard(rows,height) {
for (var row = 0; row < rows; row ++) {
for (var col = 0; col < cols; col++) {
drawCell(row,height);
}
}
}
function drawCell(row,height) {
var bounds = getCellBounds(row,height);
x0 = bounds[0];
x1 = bounds[1];
y0 = bounds[2];
y1 = bounds[3];
rectMode(CORNER);
var cellCube = new cube(x0,false);
cellCube.display();
//quad(x0,x0,y0 + 40,x0+40,y0+40,x0 + 40,y0 );
}
function cube(x,y,isSolid) { //the cube
this.x = x;
this.y = y;
this.width = 45;
this.NW =[this.x,this.y];
this.NE = [x+this.width,this.y];
this.SE = [this.x+this.width,y+this.width];
this.SW = [this.x,y+this.width];
this.larger = new square(x,this.width,this.width);
this.smaller = new square(x + (cx -x) * 0.25,y + (cy - y) *0.25,this.width * 0.75,this.width * 0.75);
this.NWs =[(this.x + (cx - this.x) * 0.20),this.y + (cy - this.y) * 0.20];
this.NEs = [(this.x + (cx - this.x) * 0.20) + (this.width * 0.8),this.y + (cy - this.y) * 0.20];
this.SEs = [(this.x + (cx - this.x) * 0.20) + (this.width * 0.8),this.y + (cy - this.y) * 0.20 + (this.width * 0.8)];
this.SWs = [(this.x + (cx - this.x) * 0.20),this.y + (cy - this.y) * 0.20 +(this.width * 0.8)];
this.display = function() {
//rect(this.x,this.y,this.width);
//rect(this.x + (cx - this.x) * 0.20,this.y + (cy - this.y) * 0.20,this.width * 0.8,this.width * 0.8);
stroke(127);
//bigger square
line(this.x,this.x + this.width,this.y);
line(this.x,this.x,this.y + this.width);
line(this.x + this.width,this.y + this.width);
line(this.x,this.y+ this.width,this.y + this.width);
//smaller square
line(this.x + (cx - this.x) * 0.20,(this.x + (cx - this.x) * 0.20 )+ this.width * 0.8,this.y + (cy - this.y) * 0.20);
line(this.x + (cx - this.x) * 0.20,this.x + (cx - this.x) * 0.20,this.y + (cy - this.y) * 0.20 + this.width * 0.8);
line(this.x + (cx - this.x) * 0.20 + this.width * 0.8,this.x + (cx - this.x) * 0.20 + this.width * 0.8,this.y + (cy - this.y) * 0.20 + this.width * 0.8);
line(this.x + (cx - this.x) * 0.20,this.y + (cy - this.y) * 0.20 + this.width * 0.8,this.y + (cy - this.y) * 0.20 + this.width * 0.8);
if (isSolid == false) {
line(this.NW[0],this.NW[1],this.NWs[0],this.NWs[1]);
line(this.NE[0],this.NE[1],this.NEs[0],this.NEs[1]);
line(this.SE[0],this.SE[1],this.SEs[0],this.SEs[1]);
line(this.SW[0],this.SW[1],this.SWs[0],this.SWs[1]);
}
if (isSolid) {
noStroke();
fill(230);
quad(this.SW[0],this.SE[0],this.SEs[1],this.SWs[1]); //bottom
quad(this.NE[0],this.NEs[1],this.SE[1]); // right
quad(this.NW[0],this.NWs[1],this.SWs[1],this.SW[0],this.SW[1]); //fill left
quad(this.NE[0],this.NW[0],this.NW[1]); //fill top
fill(240);
quad(this.NE[0],this.NW[1]);
}
};
}
function square(x,w,h) {
this.x = x;
this.y = y;
this.width = w;
this.height = h;
this.getCorners = function() {
var NW =[x-w/2,y-h/2];
//print(NW);
var NE = [x+w/2,y-h/2];
var SE = [x+w/2,y-h/2];
var SW = [x-w/2,y+h/2];
return [NW,NE,SE,SW];
};
}
function keyPressed() {
if (keyCode == LEFT_ARROW) {
moveFallingPiece(0,-1);
}
if (keyCode == RIGHT_ARROW) {
moveFallingPiece(0,1);
}
if (keyCode == DOWN_ARROW) {
moveFallingPiece(-1,0);
}
if (keyCode == UP_ARROW) {
rotateFallingPiece();
}
}
<!DOCTYPE html>
<html>
<head>
<Meta charset="UTF-8">
<title>p5.js vers 0.7.1,Edit index.html to Change This Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/addons/p5.dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/addons/p5.sound.js"></script>
<script src="sketch.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
placeFallingPiece函数与drawFallingPiece非常相似,只是不绘制单元格,而是将fallingPiece的相应单元格与fallingPieceColor一起加载到板上.这样,将棋子放置在板上.
您可能想要简化或重新开始解决您的问题.
(您以后总是可以使它变得更复杂,但是,如果您不能按需使用它,那么最好先进行轻松的调整/更改).
不幸的是,我无法为每个问题提供摘要,但是我可以指出一些可能有助于您修复错误的内容:
>您已经有一个条件可以检查下降片是否在底部并且可以正常工作:if(moveFallingPiece(-1,0)== false){
>目前,您只有一个零件,当它到达底部时,您会将其“回收”为新零件(更改为Tetris零件类型并将行重置为0):您可能想创建一个数组来存储具有堕落.这样,您可以选择停止更新该行(阻止它们下降),但继续在屏幕上渲染它们,并解决了哪一部分作为连续的最后一行连接的逻辑
>代码非常tighly coupled.您可能希望重新组织对象,以便更轻松地处理多个零件,每个零件都有零件.
(例如,创建class and instances (objects),解决所有冲突(与屏幕底部或其他部分的冲突),并在检测到冲突时将多个对象添加到数组中,以形成完整的行(增益点)或堆叠起来)
我建议先使用p5.js制作2D版本,然后将p5.js渲染器更改为WEBGL并将您的rect()调用替换为box()
调用(考虑到它们是从中心绘制的,并使用push()/ pop ()调用,以隔离每个box的坐标空间). (在该行的下方,您可能希望查看MVC模式,并将渲染/视图与数据和控制逻辑分开,如果需要,可以从2D更改为3D Tetris)