テニスのようなゲームです。
ソースコード
<!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>
実行はこちらから。