css, hold, next, fix rotate
This commit is contained in:
		@ -1,11 +1,51 @@
 | 
				
			|||||||
 * {
 | 
					 * {
 | 
				
			||||||
     background: #000;
 | 
					 | 
				
			||||||
    padding: 0;
 | 
					    padding: 0;
 | 
				
			||||||
    margin: 0;
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    color: white;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 canvas {
 | 
					body {
 | 
				
			||||||
     background: #000;
 | 
					    background-image: url("../images/bg.jpg");
 | 
				
			||||||
 | 
					    background-size: cover;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					canvas {
 | 
				
			||||||
    display: block;
 | 
					    display: block;
 | 
				
			||||||
     margin: 0 auto;
 | 
					    flex-shrink: 0;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.columns {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: row;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.side {
 | 
				
			||||||
 | 
					    flex-grow: 2;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.rows {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    margin: 5% 2%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hold {
 | 
				
			||||||
 | 
					    max-width: 120px;
 | 
				
			||||||
 | 
					    height: initial;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.stats {
 | 
				
			||||||
 | 
					    margin: 10% 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.matrix {
 | 
				
			||||||
 | 
					    max-width: 200px;
 | 
				
			||||||
 | 
					    margin: 5% 2%;
 | 
				
			||||||
 | 
					    border: 0.5px solid grey;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.next {
 | 
				
			||||||
 | 
					    max-width: 120px;
 | 
				
			||||||
 | 
					    margin: 5% 2%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								images/bg.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/bg.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 218 KiB  | 
							
								
								
									
										15
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								index.html
									
									
									
									
									
								
							@ -8,6 +8,19 @@
 | 
				
			|||||||
    <script type="text/javascript" src="js/webtris.js"></script>
 | 
					    <script type="text/javascript" src="js/webtris.js"></script>
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
<canvas id="matrix" width="200" height="400">Votre navigateur ne supporte pas HTML5, veuillez le mettre à jour pour jouer.</canvas>
 | 
					    <div class="columns">
 | 
				
			||||||
 | 
					        <div class="side"></div>
 | 
				
			||||||
 | 
					        <div class="rows">
 | 
				
			||||||
 | 
					            <canvas id="hold" class="hold" width="120" height="120"></canvas>
 | 
				
			||||||
 | 
					            <div class="stats">
 | 
				
			||||||
 | 
					                SCORE: 123123123123<br/>
 | 
				
			||||||
 | 
					                HIGH SCORE:<br/>
 | 
				
			||||||
 | 
					                TIME:<br/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <canvas id="matrix" class="matrix" width="200" height="400">Votre navigateur ne supporte pas HTML5, veuillez le mettre à jour pour jouer.</canvas>
 | 
				
			||||||
 | 
					        <canvas id="next" class="next" width="120" height="400"></canvas>
 | 
				
			||||||
 | 
					        <div class="side"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										108
									
								
								js/webtris.js
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								js/webtris.js
									
									
									
									
									
								
							@ -2,7 +2,7 @@ Array.prototype.add = function(other) {
 | 
				
			|||||||
    return this.map((x, i) => x + other[i])
 | 
					    return this.map((x, i) => x + other[i])
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
Array.prototype.rotate = function(spin) {
 | 
					Array.prototype.rotate = function(spin) {
 | 
				
			||||||
    return [spin*pos[1], pos[0]]
 | 
					    return [-spin*this[1], spin*this[0]]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
Array.prototype.sample = function() {
 | 
					Array.prototype.sample = function() {
 | 
				
			||||||
    return this.splice(Math.floor(Math.random()*this.length), 1)[0]
 | 
					    return this.splice(Math.floor(Math.random()*this.length), 1)[0]
 | 
				
			||||||
@ -10,10 +10,12 @@ Array.prototype.sample = function() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MINO_SIZE = 20
 | 
					const MINO_SIZE = 20
 | 
				
			||||||
const MATRIX_LINES = 20
 | 
					 | 
				
			||||||
const MATRIX_COLLUMNS = 10
 | 
					 | 
				
			||||||
const NEXT_PIECES = 5
 | 
					const NEXT_PIECES = 5
 | 
				
			||||||
const INIT_POSITION = [4, 0]
 | 
					const MATRIX_LINES = 20
 | 
				
			||||||
 | 
					const MATRIX_COLUMNS = 10
 | 
				
			||||||
 | 
					const HELD_PIECE_POSITION = [2, 2]
 | 
				
			||||||
 | 
					const FALLING_PIECE_POSITION = [4, 0]
 | 
				
			||||||
 | 
					const NEXT_PIECES_POSITIONS = Array.from({length: NEXT_PIECES}, (v, k) => [2, k*4+2])
 | 
				
			||||||
const LOCK_DELAY = 500
 | 
					const LOCK_DELAY = 500
 | 
				
			||||||
const FALL_DELAY = 1000
 | 
					const FALL_DELAY = 1000
 | 
				
			||||||
const AUTOREPEAT_DELAY = 300
 | 
					const AUTOREPEAT_DELAY = 300
 | 
				
			||||||
@ -24,8 +26,8 @@ const MOVEMENT = {
 | 
				
			|||||||
    DOWN: [0, 1]
 | 
					    DOWN: [0, 1]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
const SPIN = {
 | 
					const SPIN = {
 | 
				
			||||||
    CW: -1,
 | 
					    CW: 1,
 | 
				
			||||||
    CCW: 1
 | 
					    CCW: -1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
const T_SPIN = {
 | 
					const T_SPIN = {
 | 
				
			||||||
    NULL: "",
 | 
					    NULL: "",
 | 
				
			||||||
@ -50,7 +52,7 @@ const SCORES = [
 | 
				
			|||||||
shapes = []
 | 
					shapes = []
 | 
				
			||||||
class Tetromino {
 | 
					class Tetromino {
 | 
				
			||||||
    constructor() {
 | 
					    constructor() {
 | 
				
			||||||
        this.pos = INIT_POSITION
 | 
					        this.pos = FALLING_PIECE_POSITION
 | 
				
			||||||
        this.orientation = 0
 | 
					        this.orientation = 0
 | 
				
			||||||
        this.rotated_last = false
 | 
					        this.rotated_last = false
 | 
				
			||||||
        this.rotation_point_5_used = false
 | 
					        this.rotation_point_5_used = false
 | 
				
			||||||
@ -66,7 +68,7 @@ class Tetromino {
 | 
				
			|||||||
                [[0, 0], [ 1, 0], [ 1, -1], [0,  2], [ 1,  2]],
 | 
					                [[0, 0], [ 1, 0], [ 1, -1], [0,  2], [ 1,  2]],
 | 
				
			||||||
                [[0, 0], [ 1, 0], [ 1,  1], [0, -2], [ 1, -2]],
 | 
					                [[0, 0], [ 1, 0], [ 1,  1], [0, -2], [ 1, -2]],
 | 
				
			||||||
                [[0, 0], [-1, 0], [-1, -1], [0,  2], [-1,  2]],
 | 
					                [[0, 0], [-1, 0], [-1, -1], [0,  2], [-1,  2]],
 | 
				
			||||||
                [[0, 0], [-1, 0], [-1,  1], [0, -2], [-1, -2]],
 | 
					                [[0, 0], [-1, 0], [-1,  1], [0,  2], [-1, -2]],
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!shapes.lenght)
 | 
					        if (!shapes.lenght)
 | 
				
			||||||
@ -134,49 +136,57 @@ class Tetromino {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function draw_mino(context, x, y, color) {
 | 
					function draw_mino(context, x, y, color) {
 | 
				
			||||||
    context.fillStyle = color
 | 
					    context.fillStyle = color
 | 
				
			||||||
    context.fillRect(x*MINO_SIZE, y*MINO_SIZE, MINO_SIZE, MINO_SIZE);
 | 
					    context.fillRect(x*MINO_SIZE, y*MINO_SIZE, MINO_SIZE, MINO_SIZE)
 | 
				
			||||||
    context.strokeStyle = "rgba(255, 255, 255, 128)";
 | 
					    context.lineWidth = 0.5
 | 
				
			||||||
    context.strokeRect(x*MINO_SIZE, y*MINO_SIZE, MINO_SIZE, MINO_SIZE);
 | 
					    context.strokeStyle = "white"
 | 
				
			||||||
 | 
					    context.strokeRect(x*MINO_SIZE, y*MINO_SIZE, MINO_SIZE, MINO_SIZE)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Matrix {
 | 
					class Matrix {
 | 
				
			||||||
    constructor() {
 | 
					    constructor(context) {
 | 
				
			||||||
        this.cells = Array.from(Array(MATRIX_COLLUMNS), y => Array(MATRIX_LINES))
 | 
					        this.context = context
 | 
				
			||||||
 | 
					        this.cells = Array.from({length: MATRIX_COLUMNS}, (v, k) => Array(MATRIX_LINES))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    cell_is_occupied(x, y) {
 | 
					    cell_is_occupied(x, y) {
 | 
				
			||||||
        return 0 <= x && x < MATRIX_COLLUMNS && y < MATRIX_LINES ? this.cells[x][y] : true
 | 
					        return 0 <= x && x < MATRIX_COLUMNS && y < MATRIX_LINES ? this.cells[x][y] : true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    space_to_move(piece_pos, minoes_pos) {
 | 
					    space_to_move(piece_pos, minoes_pos) {
 | 
				
			||||||
        for (const abs_mino_pos of minoes_pos.map(pos => pos.add(piece_pos))) {
 | 
					        for (const pos of minoes_pos) {
 | 
				
			||||||
            if (this.cell_is_occupied(...abs_mino_pos))
 | 
					            if (this.cell_is_occupied(...pos.add(piece_pos)))
 | 
				
			||||||
                return false
 | 
					                return false
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return true
 | 
					        return true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    draw(context) {
 | 
					    draw() {
 | 
				
			||||||
        // grid
 | 
					        // grid
 | 
				
			||||||
        context.strokeStyle = "rgba(128, 128, 128, 128)";
 | 
					        const width = MATRIX_COLUMNS*MINO_SIZE
 | 
				
			||||||
        context.beginPath();
 | 
					        const height = MATRIX_LINES*MINO_SIZE
 | 
				
			||||||
        for (var x = 0; x <= MATRIX_COLLUMNS*MINO_SIZE; x += MINO_SIZE) {
 | 
					        this.context.clearRect(0, 0, width, height)
 | 
				
			||||||
            context.moveTo(x, 0);
 | 
					        this.context.strokeStyle = "rgba(128, 128, 128, 128)"
 | 
				
			||||||
            context.lineTo(x, matrixCanvas.height);
 | 
					        this.context.lineWidth = 0.5
 | 
				
			||||||
 | 
					        this.context.beginPath()
 | 
				
			||||||
 | 
					        for (var x = 0; x <= width; x += MINO_SIZE) {
 | 
				
			||||||
 | 
					            this.context.moveTo(x, 0);
 | 
				
			||||||
 | 
					            this.context.lineTo(x, height);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (var y = 0; y <= MATRIX_LINES*MINO_SIZE; y += MINO_SIZE) {
 | 
					        for (var y = 0; y <= height; y += MINO_SIZE) {
 | 
				
			||||||
            context.moveTo(0, y);
 | 
					            this.context.moveTo(0, y);
 | 
				
			||||||
            context.lineTo(matrixCanvas.width, y);
 | 
					            this.context.lineTo(width, y);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        context.stroke();
 | 
					        this.context.stroke()
 | 
				
			||||||
 | 
					        // falling piece
 | 
				
			||||||
 | 
					        falling_piece.draw(this.context)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function move(movement) {
 | 
					function move(movement) {
 | 
				
			||||||
    const test_pos = tetro.pos.add(movement)
 | 
					    const test_pos = falling_piece.pos.add(movement)
 | 
				
			||||||
    if (matrix.space_to_move(test_pos, tetro.minoes_pos)) {
 | 
					    if (matrix.space_to_move(test_pos, falling_piece.minoes_pos)) {
 | 
				
			||||||
        tetro.pos = test_pos
 | 
					        falling_piece.pos = test_pos
 | 
				
			||||||
        return true
 | 
					        return true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
@ -185,14 +195,14 @@ function move(movement) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function rotate(spin) {
 | 
					function rotate(spin) {
 | 
				
			||||||
    const text_minoes_pos = tetro.minoes_pos.map(pos => [spin*pos[1], pos[0]])
 | 
					    const test_minoes_pos = falling_piece.minoes_pos.map(pos => pos.rotate(spin))
 | 
				
			||||||
    rotation_point = 0
 | 
					    rotation_point = 0
 | 
				
			||||||
    for (const movement of tetro.srs[spin==SPIN.CW?"CW":"CCW"][tetro.orientation]) {
 | 
					    for (const movement of falling_piece.srs[spin==SPIN.CW?"CW":"CCW"][falling_piece.orientation]) {
 | 
				
			||||||
        const test_pos = [tetro.pos[0]+movement[0], tetro.pos[1]+movement[1]]
 | 
					        const test_pos = falling_piece.pos.add(movement)
 | 
				
			||||||
        if (matrix.space_to_move(test_pos, text_minoes_pos)) {
 | 
					        if (matrix.space_to_move(test_pos, test_minoes_pos)) {
 | 
				
			||||||
            tetro.pos = test_pos
 | 
					            falling_piece.pos = test_pos
 | 
				
			||||||
            tetro.minoes_pos = text_minoes_pos
 | 
					            falling_piece.minoes_pos = test_minoes_pos
 | 
				
			||||||
            tetro.orientation = (tetro.orientation - spin + 4) % 4
 | 
					            falling_piece.orientation = (falling_piece.orientation + spin + 4) % 4
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        rotation_point++
 | 
					        rotation_point++
 | 
				
			||||||
@ -261,9 +271,9 @@ function autorepeat() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function keyDownHandler(e) {
 | 
					function keyDownHandler(e) {
 | 
				
			||||||
 | 
					    if (e.key in actions) {
 | 
				
			||||||
        if (!pressedKeys.has(e.key)) {
 | 
					        if (!pressedKeys.has(e.key)) {
 | 
				
			||||||
            pressedKeys.add(e.key)
 | 
					            pressedKeys.add(e.key)
 | 
				
			||||||
        if (e.key in actions) {
 | 
					 | 
				
			||||||
            action = actions[e.key]
 | 
					            action = actions[e.key]
 | 
				
			||||||
            action()
 | 
					            action()
 | 
				
			||||||
            if (repeatableActions.includes(action)) {
 | 
					            if (repeatableActions.includes(action)) {
 | 
				
			||||||
@ -284,8 +294,8 @@ function keyDownHandler(e) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function keyUpHandler(e) {
 | 
					function keyUpHandler(e) {
 | 
				
			||||||
    pressedKeys.delete(e.key)
 | 
					 | 
				
			||||||
    if (e.key in actions) {
 | 
					    if (e.key in actions) {
 | 
				
			||||||
 | 
					        pressedKeys.delete(e.key)
 | 
				
			||||||
        action = actions[e.key]
 | 
					        action = actions[e.key]
 | 
				
			||||||
        if (actionsToRepeat.includes(action)) {
 | 
					        if (actionsToRepeat.includes(action)) {
 | 
				
			||||||
            actionsToRepeat.splice(actionsToRepeat.indexOf(action), 1)
 | 
					            actionsToRepeat.splice(actionsToRepeat.indexOf(action), 1)
 | 
				
			||||||
@ -302,18 +312,24 @@ function keyUpHandler(e) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function draw() {
 | 
					function draw() {
 | 
				
			||||||
    matrixContext.clearRect(0, 0, MATRIX_COLLUMNS*MINO_SIZE, MATRIX_LINES*MINO_SIZE);
 | 
					    held_piece.draw(holdContext)
 | 
				
			||||||
    matrix.draw(matrixContext)
 | 
					    matrix.draw()
 | 
				
			||||||
    tetro.draw(matrixContext)
 | 
					    next_pieces.map(piece => piece.draw(nextContext))
 | 
				
			||||||
    requestAnimationFrame(draw)
 | 
					    requestAnimationFrame(draw)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
window.onload = function() {
 | 
					window.onload = function() {
 | 
				
			||||||
    matrixCanvas = document.getElementById("matrix");
 | 
					    holdContext = document.getElementById("hold").getContext("2d")
 | 
				
			||||||
    matrixContext = matrixCanvas.getContext("2d");
 | 
					    matrixContext = document.getElementById("matrix").getContext("2d")
 | 
				
			||||||
 | 
					    nextContext = document.getElementById("next").getContext("2d")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    matrix = new Matrix()
 | 
					    matrix = new Matrix(matrixContext)
 | 
				
			||||||
    tetro = new Tetromino()
 | 
					    held_piece = new Tetromino()
 | 
				
			||||||
 | 
					    held_piece.pos = HELD_PIECE_POSITION
 | 
				
			||||||
 | 
					    falling_piece = new Tetromino()
 | 
				
			||||||
 | 
					    falling_piece.pos = FALLING_PIECE_POSITION
 | 
				
			||||||
 | 
					    next_pieces = Array.from({length: NEXT_PIECES}, (v, k) => new Tetromino())
 | 
				
			||||||
 | 
					    next_pieces.map((piece, i, array) => piece.pos = NEXT_PIECES_POSITIONS[i])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    document.addEventListener("keydown", keyDownHandler, false);
 | 
					    document.addEventListener("keydown", keyDownHandler, false);
 | 
				
			||||||
    document.addEventListener("keyup", keyUpHandler, false);
 | 
					    document.addEventListener("keyup", keyUpHandler, false);
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user