テニスのようなゲームです。
ソースコード
<!DOCTYPE html> <html lang="ja"> <HEAD> <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <script src="http://api.html5media.info/1.1.4/html5media.min.js" type="text/javascript"></script> <script src="https://shiba-sub.sakuraweb.com/wp-content/themes/twentyeleven/js/flashcanvas.js" type="text/javascript"></script> <![endif]--> <meta charset="Shift_JIS"> <meta http-equiv="Content-Script-type" content="text/javascript"> <TITLE>テニス</TITLE> <style> p { font-size: 20px; } canvas { background-color: green; zoom: 0.8; } </style> </HEAD> <BODY> <p id="scoreboard">0</p> <canvas id="canvas1" width="300" height="400"></canvas> <form> <input type="button" value="開始" onclick="tstart()"> </form> <p id="message"></p> <script> var scoreboard; var message; var canvas; var contex; var canvasrect; var width; var height; var courtrect; var ball; var racket; var score; var timerid; var dxd; var nowMagniFication; var chgZoom; var ajust = 2; window.onload = init; // 初期処理 function init() { dxd=screen.deviceXDPI; nowMagniFication=dxd/96; chgZoom=nowMagniFication; zoom = 1.25/chgZoom; document.body.style.zoom = zoom; scoreboard = document.getElementById("scoreboard"); message = document.getElementById("message"); canvas = document.getElementById("canvas1"); context = canvas.getContext("2d"); context.fillStyle = "springgreen"; context.font = "20px serif"; context.textAlign = "center"; canvasrect = canvas.getBoundingClientRect(); width = canvas.width; height = canvas.height; courtrect = new Rectangle(0, 0, width, height); ball = new Ball(14, 14, 3); racket = new Racket(width/2, height-40, 40, 10); score = 0; timerid = -1; document.attachEvent("onmousemove", function (event) { racket.mousemoved(event); }); } function Ball(width, height, step) { this.rect = new Rectangle(0, 0, width, height); this.step = step; // 描画ごとの移動距離 this.r = width / 2; // 半径 this.direction = "se"; // 移動方向 this.reset = function() { this.rect.x = 0; this.rect.y = 0; this.direction = "sw"; }; this.move = function(x, y) { this.clear(); this.rect.x += this.step * x; this.rect.y += this.step * y; context.fillStyle = "yellow"; this.draw(); }; this.moveDirection = function() { switch (this.direction) { case "se": // 右下 this.move(1, 1); break; case "sw": // 左下 this.move(-1, 1); break; case "nw": // 左上 this.move(-1, -1); break; case "ne": // 右上 this.move(1, -1); break; } }; this.turn = function() { switch (this.rect.outside(courtrect)) { case "west": if (this.direction == "sw") { this.direction = "se"; } else if (this.direction == "nw") { this.direction = "ne"; } break; case "east": if (this.direction == "se") { this.direction = "sw"; } else if (this.direction == "ne") { this.direction = "nw"; } break; case "north": if (this.direction == "ne") { this.direction = "se"; } else if (this.direction == "nw") { this.direction = "sw"; } break; } }; this.hit = function() { if (this.south() && this.rect.collision(racket.rect)) { scoreboard.innerHTML = ++score; if (this.direction == "se") { this.direction = "ne"; } else if (this.direction == "sw") { this.direction = "nw"; } } }; this.south = function() { return this.direction == "se" || this.direction == "sw"; }; this.beyondSouth = function() { return this.rect.outside(courtrect) == "south"; }; this.clear = function() { context.clearRect(this.rect.x, this.rect.y,this.rect.width, this.rect.height); } this.draw = function() { context.beginPath(); context.arc(this.rect.x + this.r, this.rect.y + this.r, this.r, 0, Math.PI*2, false); context.fill(); } } function Racket(x, y, width, height) { this.rect = new Rectangle(x, y, width, height); this.mousemoved = function(event) { this.clear(); this.rect.x = event.clientX - canvasrect.left - this.rect.width / 2; this.draw(); }; this.clear = function() { context.clearRect(this.rect.x, this.rect.y, this.rect.width, this.rect.height); }; this.draw = function() { context.fillStyle = "silver"; context.fillRect(this.rect.x, this.rect.y, this.rect.width, this.rect.height); }; } function Rectangle(x, y, width, height) { this.x = x; // 左上の頂点のx 座標 this.y = y; // 左上の頂点のy 座標 this.width = width; // 横の長さ this.height = height; // 縦の長さ this.outside = function(rect) { if (this.x < rect.x) { return "west"; } else if (this.x + this.width > (rect.x + rect.width)) { return "east"; } else if (this.y < rect.y) { return "north"; } else if (this.y + this.height > (rect.y + rect.height)) { return "south"; } else { return "inside"; } }; this.collision = function(rect) { return this.overlap(this.x, this.width,rect.x, rect.width) && this.overlap(this.y, this.height,rect.y, rect.height); }; this.overlap = function(a, alen, b, blen) { if (a < b) { return b - ajust <= a + alen; } else { return a - ajust <= b + blen; } }; } function gameOver() { ball.clear(); message.innerHTML = "ゲームオーバー"; clearInterval(timerid); timerid = -1; } function tstart() { if (timerid == -1) { message.innerHTML = ""; scoreboard.innerHTML = "0"; ball.reset(); score = 0; timerid = setInterval(function() { if (ball.beyondSouth()) { gameOver(); } else { ball.turn(); ball.hit(); ball.moveDirection(); } }, 25); } } </script> </BODY> </HTML>
実行はこちらから。