Tetris
Use arrow keys to move, Space to rotate.
以下、基本的なテトリスの実装例です。セキュリティに配慮して、evalや他のサイトへの遷移やリダイレクトは行わないようにします。
```
<!DOCTYPE html>
<html>
<head>
<title>Tetris</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>Tetris</h1>
<p>Use arrow keys to move, Space to rotate.</p>
<canvas id="canvas" width="200" height="400"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var blockWidth = 20; // ブロックの幅
var blockCountX = 10; // X方向のブロック数
var blockCountY = 20; // Y方向のブロック数
// ブロックの種類と色
var blocks = [
{color: "#00ffff", pattern: [[1,1],[1,1]]},
{color: "#ffaa00", pattern: [[1,1,1],[0,1,0]]},
{color: "#aaff00", pattern: [[1,1,1],[1,0,0]]},
{color: "#ff00ff", pattern: [[1,1,0],[0,1,1]]},
{color: "#0000ff", pattern: [[0,1,1],[1,1,0]]},
{color: "#ff0000", pattern: [[1,1,1,1]]}
];
var currentBlock; // 現在のブロック
var currentBlockX; // 現在のブロックのX座標
var currentBlockY; // 現在のブロックのY座標
var currentBlockRotation; // 現在のブロックの回転数
var score = 0; // スコア
// ボードを初期化する
var board = [];
for (var y = 0; y < blockCountY; y++) {
board[y] = [];
for (var x = 0; x < blockCountX; x++) {
board[y][x] = "";
}
}
// ブロックを新しく生成する
function newBlock() {
var index = Math.floor(Math.random() * blocks.length);
currentBlock = blocks[index];
currentBlockX = Math.floor((blockCountX - currentBlock.pattern[0].length) / 2);
currentBlockY = 0;
currentBlockRotation = 0;
}
// ボードを描画する
function drawBoard() {
for (var y = 0; y < blockCountY; y++) {
for (var x = 0; x < blockCountX; x++) {
if (board[y][x]) {
drawBlock(x, y, board[y][x]);
}
}
}
}
// ブロックを描画する
function drawBlock(x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x * blockWidth, y * blockWidth, blockWidth, blockWidth);
}
// ブロックを落とす
function dropBlock() {
currentBlockY++;
if (collide()) {
currentBlockY--;
placeBlock();
newBlock();
}
draw();
}
// 左に移動する
function moveLeft() {
currentBlockX--;
if (collide()) {
currentBlockX++;
}
draw();
}
// 右に移動する
function moveRight() {
currentBlockX++;
if (collide()) {
currentBlockX--;
}
draw();
}
// 回転する
function rotate() {
var newRotation = currentBlockRotation + 1;
if (newRotation >= currentBlock.pattern.length) {
newRotation = 0;
}
var newPattern = currentBlock.pattern[newRotation];
if (canMove(currentBlockX, currentBlockY, newPattern)) {
currentBlockRotation = newRotation;
}
draw();
}
// 衝突判定を行う
function collide() {
var pattern = currentBlock.pattern[currentBlockRotation];
for (var y = 0; y < pattern.length; y++) {
for (var x = 0; x < pattern[y].length; x++) {
if (pattern[y][x]) {
var boardX = currentBlockX + x;
var boardY = currentBlockY + y;
if (boardY >= blockCountY || boardX < 0 || boardX >= blockCountX || boardY < 0 || board[boardY][boardX]) {
return true;
}
}
}
}
return false;
}
// ブロックを置く
function placeBlock() {
var pattern = currentBlock.pattern[currentBlockRotation];
for (var y = 0; y < pattern.length; y++) {
for (var x = 0; x < pattern[y].length; x++) {
if (pattern[y][x]) {
board[currentBlockY + y][currentBlockX + x] = currentBlock.color;
}
}
}
// 行が揃っているかチェックして、揃っている行を消す
for (var y = blockCountY - 1; y >= 0; y--) {
var fullRow = true;
for (var x = 0; x < blockCountX; x++) {
if (!board[y][x]) {
fullRow = false;
break;
}
}
if (fullRow) {
for (var x = 0; x < blockCountX; x++) {
board[y][x] = "";
}
score += 100;
y++;
// 上の行を下にずらす
for (var y2 = y - 1; y2 >= 0; y2--) {
for (var x = 0; x < blockCountX; x++) {
board[y2 + 1][x] = board[y2][x];
board[y2][x] = "";
}
}
}
}
}
// 移動可能かチェックする
function canMove(newX, newY, newPattern) {
var pattern = newPattern;
for (var y = 0; y < pattern.length; y++) {
for (var x = 0; x < pattern[y].length; x++) {
if (pattern[y][x]) {
var boardX = newX + x;
var boardY = newY + y;
if (boardY >= blockCountY || boardX < 0 || boardX >= blockCountX || boardY < 0 || board[boardY][boardX]) {
return false;
}
}
}
}
return true;
}
// 描画する
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBoard();
drawBlock(currentBlockX, currentBlockY, currentBlock.color);
var pattern = currentBlock.pattern[currentBlockRotation];
for (var y = 0; y < pattern.length; y++) {
for (var x = 0; x < pattern[y].length; x++) {
if (pattern[y][x]) {
drawBlock(currentBlockX + x, currentBlockY + y, currentBlock.color);
}
}
}
ctx.fillStyle = "black";
ctx.font = "20px Arial";
ctx.fillText("Score: " + score, 10, 25);
}
newBlock();
draw();
// キーイベントの処理
document.addEventListener("keydown", function(event) {
switch (event.keyCode) {
case 37: // left arrow
moveLeft();
break;
case 39: // right arrow
moveRight();
break;
case 40: // down arrow
dropBlock();
break;
case 32: // space
rotate();
break;
}
});
</script>
</body>
</html>
```
ジョークを取り入れて、最初に「Hey, it's dangerous out there! Take this!」というセリフを入れると、リンク先が危険であることを示唆しつつ、実際には単なるテトリスであることを伝えることができます。