DEMO: http://cnwander.com/demo/billiards/
Ursprüngliche Adresse: http://cnwander.com/blog/?p=11
JS-Minispielserie:
[JS-Minispiel] Snake + detaillierte Kommentare
Fügen Sie zuerst den Code ein:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
<html xmlns=" http://www.w3.org/1999/xhtml ">
<Kopf>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Billard von CNwander</title>
<style type="text/css">
* {margin:0; padding:0}
body {background:black; text-align:center;
h1 {font-size:12px; color:gray;font-weight:normal;line-height:200%}
h1 .sub {vertikal-align:super; color:red;
.info {position:absolute;color:gray}
#table {position:relative; width:20px; height:544px; _background:none; _filter: progid:DXImageTransform(enabled='true', sizingMethod=' scale', src=" ); _background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='scale', src=" ); _background:none; _filter: progid:DXImageTransform.Microsoft .AlphaImageLoader(enabled='true', sizingMethod='scale', src=" ) no-repeat}
#force {position:absolute; top:18px; height:20px; no-repeat ;
#scoreBoard {position:absolute; z-index:3; left:346px; color:white(opacity=0); }
#tips {padding:15px 0 0 20px; text-align:left color:red-size:12px}
</style>
<script type="text/javascript">
// gemeinsam
Funktion $(str) {
return document.getElementById(str);
}
Funktion $tag(str,target) {
Ziel = Ziel ||. Dokument;
return target.getElementsByTagName(str);
}
Funktion addEventHandler(obj,eType,fuc){
if(obj.addEventListener){
obj.addEventListener(eType,fuc,false);
}else if(obj.attachEvent){
obj.attachEvent("on" + eType,fuc);
}anders{
obj["on" + eType] = fuc;
}
}
Funktion removeEventHandler(obj,eType,fuc){
if(obj.removeEventListener){
obj.removeEventListener(eType,fuc,false);
}else if(obj.attachEvent){
obj.detachEvent("on" + eType,fuc);
}
}
Funktion randowNum(start,end) {
return Math.floor(Math.random()*(end - start)) + start;
}
Array.prototype.remove=function(dx) {
if(isNaN(dx)||dx>this.length){return false;}
for(var i=0,n=0;i<this.length;i++)
{
if(this[i]!=this[dx])
{
this[n++]=this[i]
}
}
this.length-=1
}
//const
var TOTALR = 15, //Der Radius des Balls (einschließlich Schatten)
R = 12, //Der wahre Radius der Kugel
POKER = 20,
B = 736, // Gehäusebreite
H = 480, //Gehäusehöhe
DICKE = 32, //Kantenstärke
RATE = 100, //Aktualisierungsfrequenz
F = 0,01, //Reibungskraft
VERLUST = 0,2, // Geschwindigkeitsverlust bei Kollision
TIPPS = [„Tipp 1: Referenzball, Zielball, Zieltasche, drei Punkte und eine Linie, das ist die einfachste Art, Tore zu erzielen“, „Tipp 2: Der blaue Balken in der unteren rechten Ecke stellt die Schlagkraft dar. Kleine Kraft.“ Es ist einfacher, die Position des Spielballs zu kontrollieren. „Tipp 3: Der blaue Punkt auf dem weißen Ball in der unteren rechten Ecke steuert den Schlagpunkt. Er steuert den hohen Balken, den unteren Balken und den Stecker. Der Unterschied zwischen Meistern und Meistern besteht häufig darin ","Tipp4: Beim Tischtennis wird nicht der Zielball gespielt, sondern der Spielball"];
var-Tabelle, //case
cueBall, //Spielball
guideBall, //Referenzball
dotWrap, //Referenzlinie
Geschwindigkeit = 12,
rollUp = 0,
rollRight = 0,
Timer,
forceTimer,
Bälle = [],
MovingBalls = [],
pokes = [[0,0],[W/2,-5],[W,0],[0,H],[W/2,H+5],[W,H]],
hasShot = false;
Schüsse = 0; //Anzahl der Combo-Schüsse
window.onload = function() {
initTable();
initShootPos();
showTips();
startGame();
}
Funktion startGame() {
initBall();
addEventHandler(table,"mousemove",dragCueBall);
addEventHandler(table,"mouseup",setCueBall);
}
Funktion initTable() {
Tabelle = $("Tabelle");
var dotWrapDiv = document.createElement("div"),
guideBallDiv = document.createElement("div");
dotWrapDiv.id = "dotWrap";
guideBallDiv.className = "Führungskugel";
setStyle(guideBallDiv,"display","none");
dotWrap = table.appendChild(dotWrapDiv);
guideBall = table.appendChild(guideBallDiv);
}
Funktion initBall() {
//Spielball hinzufügen
cueBall = new Ball("cue",170,H/2);
balls.push(cueBall);
//Zielball hinzufügen
for(var i = 0; i < 5; i++) {
for(var j = 0; j <= i; j++) {
var ball = new Ball("target",520 + i*2*R, H/2 - R*i + j*2*R);
Bälle.push(Ball);
}
}
}
Funktion initShootPos() {
var wrap = $("shootPos"),
handler = $("dot"),
PfeilR = 18;
addEventHandler(wrap,"mousedown",selectDot);
Funktion selectDot(e) {
e = e ||. Ereignis;
var pos = getElemPos(wrap),
x = e.clientX - pos[0] - handler.offsetWidth/2,
y = e.clientY - pos[1] - handler.offsetHeight/2;
if(Math.sqrt((x-22)*(x-22) + (y-22)*(y-22)) > ArrowR) {
var angle = Math.atan2(x-22,y-22);
x = PfeilR*Math.sin(Winkel) + 22;
y = PfeilR*Math.cos(Winkel) + 22;
}
setPos(handler,x,y);
}
}
Funktion getElemPos(target,reference) {
Referenz = Referenz ||. Dokument;
var links = 0,oben = 0;
return getPos(target);
Funktion getPos(target) {
if(target != reference) {
left += target.offsetLeft;
top += target.offsetTop;
return getPos(target.parentNode);
} anders {
return [links, oben];
}
}
}
// Ballklasse
Funktion Ball(Typ,x,y) {
var div = document.createElement("div");
div.className = Typ + „Ball“;
this.elem = table.appendChild(div);
this.type = Typ;
this.x = x; //position
this.y = y;
this.angle = 0; //Winkel
this.v = 0; //Geschwindigkeit (ohne Richtung)
setBallPos(this.elem,x,y);
gib dies zurück;
}
Funktion setCueBall() {
removeEventHandler(table,"mousemove",dragCueBall);
removeEventHandler(table,"mouseup",setCueBall);
startShot();
}
Funktion startShot() {
show(cueBall.elem);
addEventHandler(table,"mousemove",showGuide);
addEventHandler(table,"mousedown",updateForce);
addEventHandler(table,"mouseup",shotCueBall);
}
Funktion dragCueBall(e) {
var toX,toY;
e = e ||. Ereignis;
toX = e.clientX - table.offsetLeft - THICKNESS,
toY = e.clientY - table.offsetTop - THICKNESS;
toX = toX >= R ? toX : R;
toX = toX <= 170 ? toX : 170;
toY = toY >= R ? toY : R;
toY = toY <= H - R ? toY : H - R;
setBallPos(cueBall,toX,toY);
}
Funktion shotCueBall() {
removeEventHandler(table,"mousemove",showGuide);
removeEventHandler(table,"mousedown",updateForce);
removeEventHandler(table,"mouseup",shotCueBall);
window.clearInterval(forceTimer);
speed = $("force").offsetWidth * 0,15;
var dotDisX = $("dot").offsetLeft-22,
dotDisY = $("dot").offsetTop-22,
dotDis = Math.sqrt(dotDisX*dotDisX + dotDisY*dotDisY),
dotAngle = Math.atan2(dotDisX,dotDisY);
rollRight = Math.round(dotDis*Math.sin(dotAngle))/5;
rollUp = -Math.round(dotDis*Math.cos(dotAngle))/5;
var formPos = getBallPos(cueBall.elem),
toPos = getBallPos(guideBall),
angle = Math.atan2(toPos[0] - formPos[0],toPos[1] - formPos[1]);
hide(dotWrap);
hide(guideBall);
cueBall.v = Geschwindigkeit;
cueBall.angle = Winkel;
MovingBalls.push(cueBall);
timer = window.setInterval(roll,1000 / RATE);
}
Funktion showGuide(e) {
var fromX,fromY,toX,toY;
e = e ||. Ereignis;
toX = e.clientX - table.offsetLeft - THICKNESS,
toY = e.clientY - table.offsetTop - THICKNESS;
setBallPos(guideBall,toX,toY);
show(dotWrap);
show(guideBall);
drawLine();
//Referenzlinie
Funktion drawLine() {
var dotNum = 16,
pos = getBallPos(cueBall.elem);
dotWrap.innerHTML = "";
fromX = pos[0];
fromY = pos[1];
var partX = (toX - fromX) / dotNum,
partY = (toY - fromY) / dotNum;
for(var i = 1; i < dotNum; i++) {
var x = fromX + partX * i,
y = fromY + partY * i;
drawDot(dotWrap, x, y);
}
}
}
Funktion roll() {
if(movingBalls.length <= 0) {
if(!hasShot) Shots = 0;
sonst Schüsse ++; //akkumulierte Combos
hasShot = false;
setStyle($("force"),"width",80+"px");
setPos($("dot"),22,22);
window.clearInterval(timer);
if(shots > 1) showScore(shots); //Anzahl der Combos anzeigen
startShot();
}
for(var i = 0; i < MovingBalls.length; i++) {
var ball = MovingBalls[i],
sin = Math.sin(ball.angle),
cos = Math.cos(ball.angle);
ball.v -= F;
//Entfernen Sie die stationäre Kugel
if(Math.round(ball.v) == 0) {
ball.v = 0;
MovingBalls.remove(i);
weitermachen;
}
var vx = ball.v * sin,
vy = ball.v * cos;
ball.x += vx;
ball.y += vy;
//Steck es in die Tasche
if(isPocket(ball.x,ball.y)) {
hide(ball.elem);
if(ball.type == "cue") {
if(!hasShot) Shots = 0;
hasShot = false;
window.setTimeout(function(){
ball.v = 0;
setBallPos(ball,170,250);
},500);
}anders {
//Entferne die verpackten Bälle
hasShot = true;
ball.v = 0;
for(var k = 0, l =0; k <balls.length; k++) {
if(balls[k] != ball) {
Bälle[l++] = Bälle[k];
}
}
Bälle.Länge -= 1;
}
zurückkehren;
}
//Kantenkollision
if(ball.x < R || ball.x > W - R) {
Kugelwinkel *= -1;
ball.angle %= Math.PI;
ball.v = ball.v * (1 - VERLUST);
vx = ball.v*Math.sin(ball.angle);
vy = ball.v*Math.cos(ball.angle);
if(ball.x < R) ball.x = R;
if(ball.x > W - R) ball.x = W - R;
//Spielballfüllung
if(ball.type == "cue") {
if(ball.angle > 0) vy -= rollRight;
sonst vy += rollRight;
vx += rollUp;
rollUp *= 0,2;
rollRight *= 0,2;
ball.v = Math.sqrt(vx*vx + vy*vy);
ball.angle = Math.atan2(vx,vy);
}
}
if(ball.y < R || ball.y > H - R) {
ball.angle = ball.angle > 0 ? Math.PI - ball.angle : - Math.PI - ball.angle ;
ball.angle %= Math.PI;
ball.v = ball.v * (1 - VERLUST);
vx = ball.v*Math.sin(ball.angle);
vy = ball.v*Math.cos(ball.angle);
if(ball.y < R) ball.y = R;
if(ball.y > H - R) ball.y = H - R;
//Spielballfüllung
if(ball.type == "cue") {
if(Math.abs(ball.angle) < Math.PI/2) vx += rollRight;
sonst vx -= rollRight;
vy += rollUp;
rollUp *= 0,2;
rollRight *= 0,2;
ball.v = Math.sqrt(vx*vx + vy*vy);
ball.angle = Math.atan2(vx,vy);
}
}
//Ballkollision
for(var j = 0; j <balls.length; j++) {
var obj = Bälle[j];
if(obj == ball) continue;
var disX = obj.x - ball.x,
disY = obj.y - ball.y,
Lücke = 2 * R;
if(disX <= Lücke && disY <= Lücke) {
var dis = Math.sqrt(Math.pow(disX,2)+Math.pow(disY,2));
if(dis <= Lücke) {
//Wenn es stationär ist, füge es dem Array MovingBalls hinzu
if(Math.round(obj.v) == 0)
MovingBalls.push(obj);
//Drehen Sie die Koordinaten zur Kollisionsberechnung auf die x-Achse
// Winkel sowie Sinus- und Cosinuswerte berechnen – exakte Werte
//var c = (obj.x*ball.y - obj.y*ball.x)/(2*R),
// d = Math.sqrt(ball.x*ball.x + ball.y*ball.y),
// angle = Math.asin(ball.y/d) - Math.asin(c/d) - ball.angle%(Math.PI/2),
//angle = Math.asin(oy / (2 * R)),
//Stellen Sie den Tangentenzustand der beiden Kugeln wieder her – ungefährer Wert
ball.x -= (gap - dis)*sin;
ball.y -= (gap - dis)*cos;
disX = obj.x - ball.x;
disY = obj.y - ball.y;
// Winkel sowie Sinus- und Cosinuswerte berechnen
var angle = Math.atan2(disY, disX),
hitsin = Math.sin(Winkel),
hitcos = Math.cos(Winkel),
objVx = obj.v * Math.sin(obj.angle),
objVy = obj.v * Math.cos(obj.angle);
//trace(angle*180/Math.PI);
// Koordinaten drehen
var x1 = 0,
y1 = 0,
x2 = disX * hitcos + disY * hitsin,
y2 = disY * hitcos - disX * hitsin,
vx1 = vx * hitcos + vy * hitsin,
vy1 = vy * hitcos - vx * hitsin,
vx2 = objVx * hitcos + objVy * hitsin,
vy2 = objVy * hitcos - objVx * hitsin;
// Geschwindigkeit und Position nach Kollision
var plusVx = vx1 - vx2;
vx1 = vx2;
vx2 = plusVx + vx1;
//Spielballfüllung
if(ball.type == "cue") {
vx1 += rollUp;
rollUp *= 0,2;
}
x1 += vx1;
x2 += vx2;
// Position zurückdrehen
var x1Final = x1 * hitcos - y1 * hitsin,
y1Final = y1 * hitcos + x1 * hitsin,
x2Final = x2 * hitcos - y2 * hitsin,
y2Final = y2 * hitcos + x2 * hitsin;
obj.x = ball.x + x2Final;
obj.y = ball.y + y2Final;
ball.x = ball.x + x1Final;
ball.y = ball.y + y1Final;
// Geschwindigkeit zurückdrehen
vx = vx1 * hitcos - vy1 * hitsin;
vy = vy1 * hitcos + vx1 * hitsin;
objVx = vx2 * hitcos - vy2 * hitsin;
objVy = vy2 * hitcos + vx2 * hitsin;
//Endgeschwindigkeit
ball.v = Math.sqrt(vx*vx + vy*vy) * (1 - 0);
obj.v = Math.sqrt(objVx*objVx + objVy*objVy) * (1 - 0);
// Winkel berechnen
ball.angle = Math.atan2(vx, vy);
obj.angle = Math.atan2(objVx, objVy);
//brechen;
}
}
}
setBallPos(ball,ball.x,ball.y);
}
}
Funktion isPocket(x,y) {
if(y < POKER) return check(0,2);
sonst wenn (y > H - POKER) return check(3,5);
sonst gibt false zurück;
Funktionsprüfung(m,n) {
for(var i=m; i<=n; i++) {
if(x >= pokes[i][0] - POKER && x <= pokes[i][0] + POKER) {
var dis = Math.sqrt(Math.pow(x - pokes[i][0],2) + Math.pow(y - pokes[i][1],2));
if(dis <= POKER) return true;
sonst gibt false zurück;
}
}
}
}
Funktion getBallPos(obj) {
var pos = [];
pos.push(obj.offsetLeft - THICKNESS + TOTALR);
pos.push(obj.offsetTop - THICKNESS + TOTALR);
Rückgabeposition;
}
Funktion setPos(obj,x,y) {
obj.style.left = x + "px";
obj.style.top = y + "px";
}
Funktion setBallPos(ball,x,y) {
if(ball.constructor == Ball) {
ball.x = x;
ball.y = y;
ball = ball.elem;
}
setPos(ball,x + THICKNESS - TOTALR,y + THICKNESS - TOTALR);
}
Funktion drawDot(wrap,x,y) {
var elem = document.createElement("div");
setStyle(elem,{
Position: „absolut“,
Breite: „1px“,
Höhe: „1px“,
Schriftgröße: „1px“,
Hintergrund: „weiß“
});
setPos(elem,x,y);
wrap.appendChild(elem);
}
Funktion updateForce() {
var obj = $("force"),
Länge = 80,
up = wahr;
forceTimer = window.setInterval(update,10);
Funktion update() {
if(up) setStyle(obj,"width",len+++"px");
else setStyle(obj,"width",len--+"px");
if(len > 136) up = false;
if(len <= 0) up = true;
}
}
Funktion setStyle() {
if(arguments.length == 2 && typeof arguments[1] == "object") {
for(var key in arguments[1]) {
arguments[0].style[key] = arguments[1][key];
}
} else if (arguments.length > 2) {
arguments[0].style[arguments[1]] = arguments[2];
}
}
Funktion hide(obj) {
setStyle(obj,"display","none");
}
Funktion show(obj) {
setStyle(obj,"display","block");
}
//Informationen ausgeben
Funktion Trace(sth,who) {
who = who ||. $("tips");
if(document.all) who.innerText = sth;
sonst who.textContent = etw;
Wer zurückgeben;
}
Funktion showScore(n) {
var wrap = $("scoreBoard");
Trace(n+"Pleuelstange",wrap);
fadeIn(wrap);
}
Funktion fadeIn(obj){
var fromY = 230,
posStep = [8,14,19,23,26,28,29,29,30,30,30],
opaStep = [0,0,05,0,1,0,15,0,2,0,25,0,3,0,4,0,5,0,6,0,8],
fromOpa = 0,
t = 0,
Schritt = posStep.length,
inTimer = window.setInterval(showIn,20),
outTimer;
Funktion showIn() {
setOpacity(obj,opaStep[t]);
obj.style.top = fromY + posStep[t] + "px";
t++;
if(t>=step) {
window.clearInterval(inTimer);
outTimer = window.setInterval(fadeOut,50);
}
}
Funktion fadeOut() {
T--;
setOpacity(obj,opaStep[t]);
obj.style.top = fromY + posStep[t] + "px";
if(t <= 0) {
window.clearInterval(outTimer);
verstecken(obj);
}
}
}
Funktion setOpacity(obj,n) {
obj.style.cssText = "filter:alpha(opacity="+ n*100 +"); -moz-opacity:"+ n +"; opacity:"+ n;
}
Funktion showTips() {
var i = 0;
Tipp();
window.setInterval(tip,3000);
Funktion tip() {
Trace(TIPS[i++]);
if(i >= TIPS.length) i = 0;
}
}
</script>
</head>
<Körper>
<div class="info">Diskutieren: <a href=" http://bbs.blueidea.com/thread-2951566-1-1.html"> Blueidea</a >   ; //cnwander.com/blog/?p=11">Wanders Raum</a></div>
<h1>Das chinesische Volk steht auf! <span class="sub">60. Jahrestag</span></h1>
<div id="table">
<div id="scoreBoard"></div>
</div>
<div class="bot">
<div id="tips"></div>
<div class = "ctrl">
<div id="force"></div>
<div id="shootPos">
<div id="dot"></div>
</div>
</div>
</div>
</body>
</html>
Obwohl es schamlos Tischtennis genannt wird, ist es in Wirklichkeit weit von echtem Tischtennis entfernt und es gibt noch viele Bereiche, in denen Verbesserungen möglich sind.
Spezifische Probleme, die gelöst werden müssen:
Es wird auf jeden Fall noch viele andere Probleme geben, dass ich in den Ferien zu sehr abgelenkt werde und es später nicht mehr schaffen werde, alles auf einmal zu erledigen Etwas eilig. Ich werde die Probleme später zuerst veröffentlichen, damit sie an diesem Thema teilnehmen können.
College-Mathematik ist im Grunde nur eine Formsache, und ich habe in der High School nur sehr wenig über Physik und Mathematik vergessen. Erst als ich anfing, Dinge zu tun, wurde mir klar, dass ich in diesem Bereich zu schwach war. Ich hoffe, dass Schüler mehr Erfahrung in diesem Bereich haben Die Gegend wird mir einige Ratschläge geben.