4 <title>HTML5 Test</title>
5 <link rel="stylesheet" href="http://sfpg.seesaa.net/styles-index.css" type="text/css" />
6 <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
7 <style type="text/css">
10 <!--<script type="text/javascript" src="http://sfpg.up.seesaa.net/scripts/jquery-1.4.4.min.js"></script>
11 <script type="text/javascript">
13 var _gaq = _gaq || [];
14 _gaq.push(['_setAccount', 'UA-15457703-1']);
15 _gaq.push(['_setDomainName', '.seesaa.net']);
16 _gaq.push(['_trackPageview']);
19 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
20 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
21 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
28 <canvas id="disp01" width="320" height="240" ></canvas>
31 <button type="button" id="start" disabled="true">開始</button>
32 <button type="button" id="stop" disabled="true" >停止</button>
34 <script type="text/javascript">
42 var ctx_main = $("#disp01")[0].getContext("2d");
43 var screenWidth = $("#disp01")[0].width;
44 var screenHeight = $("#disp01")[0].height;
46 var backBuffer = $("<canvas>")[0];
47 backBuffer.width = width + 160;
48 backBuffer.height = height + 120;
49 var ctx = backBuffer.getContext("2d");
51 var renderTimerId = undefined;
52 var mainTimerId = undefined;
56 function Ball(x, y, radius, xSpeed, ySpeed,index,color) {
68 // Ball.prototype.init = function (x, y, radius,xSpeed,ySpeed,index) {
71 // this.xSpeed = xSpeed;
72 // this.ySpeed = ySpeed;
73 // this.radius = radius;
74 // this.index = index;
75 // this.enable = true;
78 Ball.prototype.move = function () {
81 this.x += this.xSpeed;
83 if ((this.x + this.radius) > width) {
84 this.x = width - this.radius;
85 this.xSpeed = -(this.xSpeed);
88 if (this.x < this.radius) {
89 this.x = this.radius; // -this.x;
90 this.xSpeed = -(this.xSpeed);
93 this.y += this.ySpeed;
95 if ((this.y + this.radius) > height) {
96 this.y = height - this.radius;
97 this.ySpeed = -this.ySpeed ;
100 if (this.y < this.radius) {
101 this.y = this.radius;
102 this.ySpeed = -this.ySpeed ;
106 Ball.prototype.draw = function (pctx) {
107 var fillStyle = pctx.fillStyle;
108 //pctx.globalAlpha = 0.7;
109 pctx.fillStyle = this.color;
111 pctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
114 pctx.fillStyle = fillStyle;
115 //pctx.globalAlpha = 1.0;
118 Ball.prototype.checkCollision = function (other) {
119 if (Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2) < Math.pow(this.radius + other.radius, 2)) {
127 var balls = new Array(0);
131 this.array = new Array(0);
137 // indexの位置のタスクを置き換える
138 setNextTask: function (index, func) {
139 this.array[index] = func;
142 pushTask : function (func)
144 for (var i = 0; i < this.length; ++i) {
145 if (this.array[i] == null) {
146 this.array[i] = func;
150 this.array.push(func);
153 getArray: function () {
158 this.array.length = 0;
162 var tasks = new Tasks();
165 $(window).ready(function () {
166 ctx.fillStyle = "blue";
167 ctx.fillRect(0, 0, backBuffer.width, backBuffer.height);
168 ctx.setTransform(1, 0, 0, 1, sx, sy);
169 ctx.fillStyle = "white";
170 ctx.font = "12px 'MS ゴシック'";
171 ctx.fillText("なんちゃってボール反発です。", 0, 20, 240);
172 ctx.fillText("クリックするとボールが追加されます。", 0, 40, 240);
174 ctx_main.drawImage(backBuffer, sx, sy, width, height, 0, 0, screenWidth, screenHeight);
175 var color = ["#0030ff", "#0060ff", "#0090ff", "#00c0ff"];
178 $("#start").click(function () {
179 // renderTimerId = setInterval(render, 100);
180 tasks.pushTask(init);
182 for (var i = 0; i < 100; ++i) {
183 var rad = 1 + Math.random() * 10;
186 Math.random() * (width - rad * 2) + rad,
187 Math.random() * (height - rad * 2) + rad,
189 (Math.random() * 5 + 5) * (Math.random() >= 0.5 ? -1 : 1),
190 Math.random() * 4 + 9,
192 color[(Math.random() * 4) | 0]
196 mainTimerId = setTimeout(processMain, 50);
197 $("#stop")[0].disabled = false;
198 $("#start")[0].disabled = true;
202 $("#stop").click(function () {
203 // if (renderTimerId != undefined) {
204 // clearInterval(renderTimerId);
205 // renderTimerId = undefined;
207 if (mainTimerId != undefined) {
208 clearTimeout(mainTimerId);
209 mainTimerId = undefined;
214 $("#stop")[0].disabled = true;
215 $("#start")[0].disabled = false;
219 $("#disp01").click(function (e) {
220 if ($("#start")[0].disabled && balls.length < 300) {
221 var color = ["#ff3000", "#ff6000", "#ff9000", "#ffc000"];
222 var x = e.pageX - this.offsetLeft;
223 var y = e.pageY - this.offsetTop;
224 var rad = 1 + Math.random() * 10;
230 (Math.random() * 9) * (Math.random() >= 0.5 ? -1 : 1),
233 color[(Math.random() * 4) | 0]
239 // 準備ができたので開始ボタンを押せるようにする
240 $("#start")[0].disabled = false;
250 ctx_main.drawImage(backBuffer, sx, sy, width, height, 0, 0, screenWidth, screenHeight);
256 var ellapsedTime = 0;
257 function processMain() {
258 var startTime = new Date().getTime();
261 $(tasks.getArray()).each(function (taskIndex) {
268 ctx.fillStyle = "black";
269 ctx.fillRect(0, 0, width, height);
270 var endTime = new Date().getTime();
271 ellapsedTime = endTime - startTime;
272 period = 33 - (ellapsedTime) % 33;
273 mainTimerId = setTimeout(processMain, period);
277 function init(taskIndex)
279 ctx.fillStyle = "black";
280 ctx.fillRect(0, 0, width, height);
282 tasks.setNextTask(taskIndex, addCount);
283 tasks.pushTask(ballAction);
287 function addCount() {
288 var txt = "処理時間:" + ellapsedTime + "ms";
289 ctx.textBaseline = "top";
290 var textWidth = ctx.measureText(txt);
291 ctx.fillStyle = "black";
292 ctx.fillRect(0, 0, textWidth.width, 12);
293 ctx.fillStyle = "white";
294 ctx.fillText(txt, 0, 0, textWidth.width);
298 function ballAction() {
299 for (var i = 0, last = balls.length; i < last; ++i) {
300 var srcBall = balls[i];
303 for (var j = i + 1; j < last; ++j) {
304 if (srcBall.checkCollision(balls[j])) {
305 bound(srcBall, balls[j]);
312 function bound(src, dest) {
314 var srcMass = src.radius ;
315 var destMass = dest.radius ;
316 var totalMass = srcMass + destMass;
317 var boundRate = 1.95;
318 var c = { x: dest.x - src.x, y: dest.y - src.y };
321 var vs = Math.sqrt(c.x * c.x + c.y * c.y);
326 var dot = (src.xSpeed - dest.xSpeed) * c.x + (src.ySpeed - dest.ySpeed) * c.y;
329 if ((src.radius + dest.radius) > vs) {
330 var a = src.radius + dest.radius - vs;
332 // var m = (src.radius + dest.radius) / vs;
333 var ax = (c.x * a) / 2;
334 var ay = (c.y * a) / 2;
335 dest.x = dest.x + ax;
336 dest.y = dest.y + ay;
339 // while ((Math.pow(dest.x - src.x, 2) + Math.pow(dest.y - src.y, 2)) <= Math.pow(src.radius + dest.radius, 2)) {
351 var v = { x: boundRate * dot / totalMass * c.x, y: boundRate * dot / totalMass * c.y };
352 src.xSpeed = -destMass * v.x + src.xSpeed;
353 src.ySpeed = -destMass * v.y + src.ySpeed;
355 dest.xSpeed = srcMass * v.x + dest.xSpeed;
356 dest.ySpeed = srcMass * v.y + dest.ySpeed;
358 // src.x += src.xSpeed;
359 // src.y += src.ySpeed;
361 // dest.x += dest.xSpeed;
362 // dest.y += dest.ySpeed;