HTML5-Tutorium: Canvas: MiniPong 04: Unterschied zwischen den Versionen
Kowa (Diskussion | Beiträge) |
Kowa (Diskussion | Beiträge) |
||
| Zeile 7: | Zeile 7: | ||
Im dritten Teil des Tutoriums wird beschrieben, wie man MiniPong mit Hilfe einer einzigen JavaScript-Datei erstellt. | Im dritten Teil des Tutoriums wird beschrieben, wie man MiniPong mit Hilfe einer einzigen JavaScript-Datei erstellt. | ||
[[Kowarschick|Wolfgang Kowarschick]] bezeichnet so eine Datei als „Moloch-Datei“ (Moloch = Monstrum, Ungeheuer, alles verschlingende Bestie). | [[Kowarschick|Wolfgang Kowarschick]] bezeichnet so eine Datei als „Moloch-Datei“ (Moloch = Monstrum, Ungeheuer, alles verschlingende Bestie). | ||
=Vorgehensweise= | |||
==Neues Projekt anlegen== | |||
Legen Sie ein neues Projekt an: | |||
# <code>Datei</code> → <code>Neu</code> → <code>Statisches Web-Projekt</code> | |||
# Project name: <code>MiniPong02</code> → <code>Fertigstellen</code> | |||
==Dateien erstellen== | |||
Kopieren Sie die Datei <code>css/Main.css</code> von [[HTML5-Tutorium: Canvas: MiniPong 01|Teil 1]] des Tutoriums | |||
und erstellen Sie die Dateien <code>js/Main.js</code> sowie <code>index.html</code> neu. | |||
===<code>index.html</code>=== | |||
<source lang="html4strict"> | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<title>HTML5-Tutorium: Canvas: MiniPong 01</title> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> | |||
<!-- | |||
<link rel="stylesheet" href="css/all.min.css" /> | |||
<script type="text/javascript" src="js/all.min.js" ></script> | |||
--> | |||
<link rel="stylesheet" href="css/main.css" /> | |||
<script type="text/javascript" src="js/main.js" ></script> | |||
</head> | |||
<body onload="init()"> | |||
<p id="d_score">Punktestand</p> | |||
<canvas id="d_canvas"> | |||
Your browser does not support canvas! | |||
</canvas> | |||
<form id="d_form"> | |||
<input id="d_start_stop" type="button" onmousedown="startGame()"> | |||
</form> | |||
</body> | |||
</html> | |||
</source> | |||
===<code>main.js</code>=== | |||
<source lang="javascript"> | |||
// constants | |||
var FPS = 50; | |||
var KEY_LEFT = 37; | |||
var KEY_RIGHT = 39; | |||
var BALL_COLOR = "#55AA55"; | |||
var PADDLE_COLOR = "#666666"; | |||
var TOLERANCE = 1; | |||
var PADDING = 5; | |||
// canvas | |||
var v_canvas; | |||
var v_context; | |||
var v_width = 400; | |||
var v_height = 300; | |||
// paddle | |||
var v_paddle_width = 50; | |||
var v_paddle_height = 8; | |||
var v_paddle_dx; | |||
var v_paddle_dx_start = 250; // pixel per seconds | |||
var v_paddle_ax = 10; // pixel per seconds | |||
var v_paddle_friction = 20; | |||
var v_paddle_x; | |||
var v_paddle_y; | |||
// ball | |||
var v_ball_r = 8; | |||
var v_ball_x; | |||
var v_ball_y; | |||
var v_ball_dx; | |||
var v_ball_dy = 160; // pixels per seconds | |||
// score | |||
var v_score ; | |||
// timer | |||
var v_interval; | |||
// initialization | |||
function init() | |||
{ | |||
v_canvas = document.getElementById("d_canvas"); | |||
v_canvas.width = v_width; | |||
v_canvas.height = v_height; | |||
v_context = v_canvas.getContext("2d"); | |||
m_reset(); | |||
} | |||
function m_reset() | |||
{ | |||
v_context.clearRect(0, 0, v_width, v_height); | |||
document.getElementById("d_start_stop").value = "Start"; | |||
document.getElementById("d_start_stop").onmousedown = m_start_game; | |||
v_paddle_x = (v_width - v_paddle_width) / 2; | |||
v_paddle_y = v_height - v_paddle_height - PADDING; | |||
v_paddle_dx = 0 | |||
v_ball_x = (v_width - v_ball_r) / 2; | |||
v_ball_y = v_ball_r + PADDING; | |||
v_ball_dx = (Math.random()*4 - 2) * FPS; | |||
m_draw(); | |||
} | |||
function m_start_game() | |||
{ | |||
v_score = 0; | |||
document.onkeydown = m_move_paddle; | |||
document.onkeyup = m_stop_paddle; | |||
document.getElementById("d_start_stop").value = "Stop"; | |||
document.getElementById("d_start_stop").onmousedown = m_stop_game; | |||
document.getElementById('d_score').firstChild.nodeValue = 'Spiel gestartet'; | |||
v_interval = window.setInterval("m_redraw()", 1000/FPS); | |||
} | |||
function m_stop_game() | |||
{ | |||
window.clearInterval(v_interval); | |||
document.onkeydown = null; | |||
document.onkeyup = null; | |||
m_reset(); | |||
} | |||
function m_draw() | |||
{ | |||
v_context.beginPath(); | |||
v_context.arc(v_ball_x, v_ball_y, v_ball_r, 0, 2*Math.PI, true); | |||
v_context.fillStyle = BALL_COLOR; | |||
v_context.fill(); | |||
v_context.beginPath(); | |||
v_context.fillStyle = PADDLE_COLOR; | |||
v_context.rect (v_paddle_x, v_paddle_y, v_paddle_width, v_paddle_height); | |||
v_context.fill(); | |||
} | |||
function m_redraw() | |||
{ | |||
// clear canvas (before ball and paddle are moved) | |||
v_context.clearRect | |||
(v_ball_x-v_ball_r-TOLERANCE, v_ball_y-v_ball_r-TOLERANCE, | |||
2*(v_ball_r+TOLERANCE), 2*(v_ball_r+TOLERANCE) | |||
); | |||
v_context.clearRect | |||
(v_paddle_x-TOLERANCE, v_paddle_y-TOLERANCE, | |||
v_paddle_width+2*TOLERANCE, v_paddle_height+2*TOLERANCE | |||
); | |||
// collision detection | |||
if (v_ball_x <= v_ball_r || v_ball_x >= v_width - v_ball_r) | |||
v_ball_dx = -v_ball_dx; | |||
if (v_ball_y <= v_ball_r) | |||
v_ball_dy = -v_ball_dy; | |||
if (v_ball_y - 2*v_ball_r > v_height) | |||
{ | |||
m_stop_game(); | |||
return; | |||
} | |||
if ( v_ball_y + v_ball_r >= v_paddle_y | |||
&& v_ball_y + v_ball_r <= v_paddle_y + v_paddle_height | |||
&& v_ball_x + 0.5*v_ball_r >= v_paddle_x | |||
&& v_ball_x - 0.5*v_ball_r <= v_paddle_x + v_paddle_width | |||
) | |||
{ | |||
v_ball_dy = -v_ball_dy; | |||
v_ball_dx += v_paddle_friction*v_paddle_dx; | |||
document.getElementById('d_score').firstChild.nodeValue = 'Punkte: ' + ++v_score; | |||
}; | |||
// move ball | |||
v_ball_x += v_ball_dx/FPS; | |||
v_ball_y += v_ball_dy/FPS; | |||
// move paddle | |||
if ( (v_paddle_dx < 0 && v_paddle_x > 0) | |||
|| (v_paddle_dx > 0 && v_paddle_x + v_paddle_width < v_width) | |||
) | |||
{ | |||
v_paddle_x += v_paddle_dx; | |||
v_paddle_dx += v_paddle_ax/FPS *(v_paddle_dx > 0 ? 1 : -1); | |||
}; | |||
m_draw(); | |||
} | |||
function m_move_paddle(p_event) | |||
{ | |||
if (v_paddle_dx == 0) | |||
{ | |||
if (p_event.keyCode == KEY_LEFT) | |||
v_paddle_dx = -v_paddle_dx_start/FPS; | |||
else if (p_event.keyCode == KEY_RIGHT) | |||
v_paddle_dx = +v_paddle_dx_start/FPS; | |||
}; | |||
} | |||
function m_stop_paddle(p_event) | |||
{ | |||
v_paddle_dx = 0; | |||
} | |||
</source> | |||
==Anwendung testen== | |||
Testen Sie Ihre Anwendung in gewohnter Weise. | |||
=Quellen= | =Quellen= | ||
Version vom 17. Oktober 2011, 16:41 Uhr
Dieser Artikel wird derzeit von einem Autor gründlich bearbeitet. Die Inhalte sind daher evtl. noch inkonsistent.
Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:
| Korrektheit: 3 (zu größeren Teilen überprüft) |
Umfang: 3 (einige wichtige Fakten fehlen) |
Quellenangaben: 5 (vollständig vorhanden) |
Quellenarten: 5 (ausgezeichnet) |
Konformität: 5 (ausgezeichnet) |
HTML-Tutorium: MiniPong
MiniPong: | Teil 1 | Teil 2 | Teil 3 | Teil 4 | Teil 5
Musterlösung: Minipong
(alle Dateien, SVN: alle Dateien)
Ziel
Im dritten Teil des Tutoriums wird beschrieben, wie man MiniPong mit Hilfe einer einzigen JavaScript-Datei erstellt. Wolfgang Kowarschick bezeichnet so eine Datei als „Moloch-Datei“ (Moloch = Monstrum, Ungeheuer, alles verschlingende Bestie).
Vorgehensweise
Neues Projekt anlegen
Legen Sie ein neues Projekt an:
Datei→Neu→Statisches Web-Projekt- Project name:
MiniPong02→Fertigstellen
Dateien erstellen
Kopieren Sie die Datei css/Main.css von Teil 1 des Tutoriums
und erstellen Sie die Dateien js/Main.js sowie index.html neu.
index.html
<!DOCTYPE html>
<html>
<head>
<title>HTML5-Tutorium: Canvas: MiniPong 01</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<!--
<link rel="stylesheet" href="css/all.min.css" />
<script type="text/javascript" src="js/all.min.js" ></script>
-->
<link rel="stylesheet" href="css/main.css" />
<script type="text/javascript" src="js/main.js" ></script>
</head>
<body onload="init()">
<p id="d_score">Punktestand</p>
<canvas id="d_canvas">
Your browser does not support canvas!
</canvas>
<form id="d_form">
<input id="d_start_stop" type="button" onmousedown="startGame()">
</form>
</body>
</html>
main.js
// constants
var FPS = 50;
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var BALL_COLOR = "#55AA55";
var PADDLE_COLOR = "#666666";
var TOLERANCE = 1;
var PADDING = 5;
// canvas
var v_canvas;
var v_context;
var v_width = 400;
var v_height = 300;
// paddle
var v_paddle_width = 50;
var v_paddle_height = 8;
var v_paddle_dx;
var v_paddle_dx_start = 250; // pixel per seconds
var v_paddle_ax = 10; // pixel per seconds
var v_paddle_friction = 20;
var v_paddle_x;
var v_paddle_y;
// ball
var v_ball_r = 8;
var v_ball_x;
var v_ball_y;
var v_ball_dx;
var v_ball_dy = 160; // pixels per seconds
// score
var v_score ;
// timer
var v_interval;
// initialization
function init()
{
v_canvas = document.getElementById("d_canvas");
v_canvas.width = v_width;
v_canvas.height = v_height;
v_context = v_canvas.getContext("2d");
m_reset();
}
function m_reset()
{
v_context.clearRect(0, 0, v_width, v_height);
document.getElementById("d_start_stop").value = "Start";
document.getElementById("d_start_stop").onmousedown = m_start_game;
v_paddle_x = (v_width - v_paddle_width) / 2;
v_paddle_y = v_height - v_paddle_height - PADDING;
v_paddle_dx = 0
v_ball_x = (v_width - v_ball_r) / 2;
v_ball_y = v_ball_r + PADDING;
v_ball_dx = (Math.random()*4 - 2) * FPS;
m_draw();
}
function m_start_game()
{
v_score = 0;
document.onkeydown = m_move_paddle;
document.onkeyup = m_stop_paddle;
document.getElementById("d_start_stop").value = "Stop";
document.getElementById("d_start_stop").onmousedown = m_stop_game;
document.getElementById('d_score').firstChild.nodeValue = 'Spiel gestartet';
v_interval = window.setInterval("m_redraw()", 1000/FPS);
}
function m_stop_game()
{
window.clearInterval(v_interval);
document.onkeydown = null;
document.onkeyup = null;
m_reset();
}
function m_draw()
{
v_context.beginPath();
v_context.arc(v_ball_x, v_ball_y, v_ball_r, 0, 2*Math.PI, true);
v_context.fillStyle = BALL_COLOR;
v_context.fill();
v_context.beginPath();
v_context.fillStyle = PADDLE_COLOR;
v_context.rect (v_paddle_x, v_paddle_y, v_paddle_width, v_paddle_height);
v_context.fill();
}
function m_redraw()
{
// clear canvas (before ball and paddle are moved)
v_context.clearRect
(v_ball_x-v_ball_r-TOLERANCE, v_ball_y-v_ball_r-TOLERANCE,
2*(v_ball_r+TOLERANCE), 2*(v_ball_r+TOLERANCE)
);
v_context.clearRect
(v_paddle_x-TOLERANCE, v_paddle_y-TOLERANCE,
v_paddle_width+2*TOLERANCE, v_paddle_height+2*TOLERANCE
);
// collision detection
if (v_ball_x <= v_ball_r || v_ball_x >= v_width - v_ball_r)
v_ball_dx = -v_ball_dx;
if (v_ball_y <= v_ball_r)
v_ball_dy = -v_ball_dy;
if (v_ball_y - 2*v_ball_r > v_height)
{
m_stop_game();
return;
}
if ( v_ball_y + v_ball_r >= v_paddle_y
&& v_ball_y + v_ball_r <= v_paddle_y + v_paddle_height
&& v_ball_x + 0.5*v_ball_r >= v_paddle_x
&& v_ball_x - 0.5*v_ball_r <= v_paddle_x + v_paddle_width
)
{
v_ball_dy = -v_ball_dy;
v_ball_dx += v_paddle_friction*v_paddle_dx;
document.getElementById('d_score').firstChild.nodeValue = 'Punkte: ' + ++v_score;
};
// move ball
v_ball_x += v_ball_dx/FPS;
v_ball_y += v_ball_dy/FPS;
// move paddle
if ( (v_paddle_dx < 0 && v_paddle_x > 0)
|| (v_paddle_dx > 0 && v_paddle_x + v_paddle_width < v_width)
)
{
v_paddle_x += v_paddle_dx;
v_paddle_dx += v_paddle_ax/FPS *(v_paddle_dx > 0 ? 1 : -1);
};
m_draw();
}
function m_move_paddle(p_event)
{
if (v_paddle_dx == 0)
{
if (p_event.keyCode == KEY_LEFT)
v_paddle_dx = -v_paddle_dx_start/FPS;
else if (p_event.keyCode == KEY_RIGHT)
v_paddle_dx = +v_paddle_dx_start/FPS;
};
}
function m_stop_paddle(p_event)
{
v_paddle_dx = 0;
}
Anwendung testen
Testen Sie Ihre Anwendung in gewohnter Weise.
Quellen
- Braun (2011): Herbert Braun; Webanimationen mit Canvas; in: c't Webdesign; Band: 2011; Seite(n): 44–48; Verlag: Heise Zeitschriften Verlag; Adresse: Hannover; 2011; Quellengüte: 5 (Artikel)
- Kowarschick (MMProg): Wolfgang Kowarschick; Vorlesung „Multimedia-Programmierung“; Hochschule: Hochschule Augsburg; Adresse: Augsburg; Web-Link; 2018; Quellengüte: 3 (Vorlesung)
- Musterlösungen, Musterlösungen (SVN)
