以下は1つのhtmlファイルで実装したTetrisのサンプルコードです。セキュリティ脆弱性がある処理は行っていないため、安全に動作するわけではありません。また、ジョークとして"Game over"の画面では"Game over, man!"というエイリアンの名言を使用しました。
```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Tetris</title>
<style>
#screen {
background-color: #000;
width: 300px;
height: 600px;
position: relative;
overflow: hidden;
}
#score {
color: #fff;
font-size: 25px;
text-align: center;
}
.block {
position: absolute;
width: 30px;
height: 30px;
}
</style>
</head>
<body onload="startTetris()">
<div id="screen">
<div id="score"></div>
</div>
<script>
// テトリスの状態を管理するオブジェクト
var tetris = {
// ボードの大きさ
boardSize: [10, 20],
// 現在のスコア
score: 0,
// ボードに配置されるブロック
board: [],
// 落下中のブロック
currentBlock: null,
// 落下速度
speed: 1000,
// ゲームが進行中かどうか
isPlaying: false,
// ボードの描画
drawBoard: function() {
var screen = document.getElementById("screen");
// 以前のボードをクリア
while (screen.firstChild) {
screen.removeChild(screen.firstChild);
}
// ブロックを描画
for (var x = 0; x < this.boardSize[0]; x++) {
for (var y = 0; y < this.boardSize[1]; y++) {
if (this.board[x][y]) {
var block = document.createElement("div");
block.className = "block";
block.style.left = x * 30 + "px";
block.style.top = y * 30 + "px";
block.style.backgroundColor = this.board[x][y];
screen.appendChild(block);
}
}
}
},
// ブロックを生成
createBlock: function() {
var blocks = [
[[1, 0], [1, 1], [0, 1]],
[[0, 0], [1, 0], [2, 0], [3, 0]],
[[0, 1], [1, 1], [2, 1], [2, 0]],
[[0, 0], [0, 1], [1, 1], [1, 0]],
[[0, 1], [1, 1], [1, 0], [2, 0]],
[[0, 0], [1, 0], [1, 1], [2, 1]],
[[0, 0], [0, 1], [0, 2], [1, 1]]
];
var block = blocks[Math.floor(Math.random() * blocks.length)];
var color = ["#ff0", "#0ff", "#f0f", "#0f0", "#f00", "#00f", "#0ff"][Math.floor(Math.random() * 7)];
for (var i = 0; i < block.length; i++) {
block[i][0] += Math.floor((this.boardSize[0] - 4) / 2);
}
this.currentBlock = {block: block, color: color, pos: [0, 0]};
return this.currentBlock;
},
// ブロックを落下させる
dropBlock: function() {
if (!this.currentBlock) {
this.createBlock();
}
if (this.checkCollision(0, 1)) {
this.setBlock();
this.currentBlock = null;
} else {
this.currentBlock.pos[1]++;
}
this.drawBoard();
},
// ブロックを回転させる
rotateBlock: function() {
var block = this.currentBlock.block;
var newBlock = [];
for (var i = 0; i < block.length; i++) {
newBlock.push([block[i][1], -block[i][0]]);
}
if (!this.checkCollision(0, 0, newBlock)) {
this.currentBlock.block = newBlock;
this.drawBoard();
}
},
// ブロックを移動する
moveBlock: function(x, y) {
if (!this.checkCollision(x, y)) {
this.currentBlock.pos[0] += x;
this.currentBlock.pos[1] += y;
this.drawBoard();
}
},
// ブロックを固定する
setBlock: function() {
var block = this.currentBlock.block;
for (var i = 0; i < block.length; i++) {
this.board[block[i][0]][block[i][1]] = this.currentBlock.color;
}
this.clearLine();
},
// ラインを消す
clearLine: function() {
for (var y = 0; y < this.boardSize[1]; y++) {
var count = 0;
for (var x = 0; x < this.boardSize[0]; x++) {
if (this.board[x][y]) {
count++;
}
}
if (count == this.boardSize[0]) {
this.score++;
for (var x = 0; x < this.boardSize[0]; x++) {
for (var i = y; i > 0; i--) {
this.board[x][i] = this.board[x][i - 1];
}
this.board[x][0] = null;
}
}
}
document.getElementById("score").innerHTML = "SCORE: " + this.score;
},
// 衝突判定
checkCollision: function(x, y, block) {
block = block || this.currentBlock.block;
for (var i = 0; i < block.length; i++) {
var bX = block[i][0] + this.currentBlock.pos[0] + x;
var bY = block[i][1] + this.currentBlock.pos[1] + y;
if (bX < 0 || bX >= this.boardSize[0] || bY < 0 || bY >= this.boardSize[1] || this.board[bX][bY]) {
return true;
}
}
return false;
}
};
// キーボードイベント
document.onkeydown = function(e) {
if (!tetris.isPlaying) {
return;
}
switch (e.keyCode) {
case 37: // 左
tetris.moveBlock(-1, 0);
break;
case 38: // 上
tetris.rotateBlock();
break;
case 39: // 右
tetris.moveBlock(1, 0);
break;
case 40: // 下
tetris.dropBlock();
break;
}
};
// Tetrisの開始
function startTetris() {
// ボードの初期化
for (var x = 0; x < tetris.boardSize[0]; x++) {
tetris.board[x] = [];
for (var y = 0; y < tetris.boardSize[1]; y++) {
tetris.board[x][y] = null;
}
}
// ゲームの開始
tetris.isPlaying = true;
setInterval(function() {
tetris.dropBlock();
if (tetris.checkCollision(0, 0)) {
tetris.isPlaying = false;
alert("Game over, man!");
}
}, tetris.speed);
}
</script>
</body>
</html>
```