


Tutorial on making a simple table tennis game with HTML5_html5 tutorial tips
By the way, this is just a simple DEMO. I haven’t given much thought to gameplay, game rules, etc. If you are interested in refining it, you can refine it, such as refining the rules, game switches, adding a sound, refining the goal detection, and even more rigorous. Check the strength of the shot, the real friction of the table, etc. to make the game more like a game. I'm just giving you some programming ideas, just take a demo and it won't be very enjoyable to play~~
Snooker Game
There are two categories in the entire snooker game, one is the ball and the other is the auxiliary aiming line. If you want to make the game more complex, you can also abstract a shape class to detect collisions between the ball and corners and goals. The game I made uses the simplest wall collision detection, so there is no collision detection between balls and irregular shapes. If you want to play more complex collisions, you can poke about simple collision detection Cen An The speech was still very good. Okay, let’s do it step by step:
【Ball】
Post the code first:
[/code]var Ball = function(x, y, ismine){
this.x = x;
this.y = y;
this.ismine = ismine;
this.oldx = x;
this.oldy = y;
this.vx = 0;
this.vy = 0;
this.radius = ballRadius;
this.inhole = false;this.moving = true;
}
Ball.prototype = {
constructor:Ball,
_paint:function(){
var b = this.ismine ?document.getElementById("wb") : document.getElementById("yb")
if(b.complete) {
ctx.drawImage(b , this.x-this.radius , this.y-this .radius , 2*this.radius , 2*this.radius);
ctx.drawImage(b, this.x-this .radius , this.y-this.radius , 2*this.radius , 2*this.radius);
run:function(t){
this.oldx = this.x;
this.oldy = this.y;
this.vx = Math.abs(this.vx)<0.1? 0 : (this.vx>0? this.vx-mcl*t : this.vx mcl*t);
this.vy = Math.abs(this.vy)<0.1? 0 : (this.vy>0? this.vy-mcl*t : this.vy mcl*t);
// this.vx = this.vx> ;0? -mcl*t : mcl*t;
this.x = t * this.vx * pxpm;
this.y = t * this.vy * pxpm;
if((this.x<50 && this.y<50) || (this.x>370 && this.x<430 && this.y<50) || (this.x > 758 && this.y<50) || (this.x<46 && this.y>490) || (this.x>377 && this.x<420 && this.y>490) || (this.x > 758 && this.y>490)){
this.inhole = true;
if(this.ismine){
var that = this;
setTimeout(function(){
that.x = 202;
that.y = canvas.height/2;
that.vx = 0;
that.vy = 0;
that.inhole = false;
} , 500)
}
else {
document.getElementById("shotNum").innerHTML = parseInt(document.getElementById("shotNum").innerHTML) 1
}
}
else {
if(this.y > canvas.height - (ballRadius tbw) || this.y < (ballRadius tbw)){
this.y = this.y < (ballRadius tbw) ? (ballRadius tbw) : (canvas.height - (ballRadius tbw));
this.derectionY = !this.derectionY;
this.vy = -this.vy*0.6;
}
if(this.x > canvas.width - (ballRadius tbw) || this.x < (ballRadius tbw)){
this.x = this.x < (ballRadius tbw) ? (ballRadius tbw) : (canvas.width - (ballRadius tbw));
this.derectionX = !this.derectionX;
this.vx = -this.vx*0.6;
this.moving = false;
else {
}
}
}[/code]
Ball attributes: x, y ball position, vx, vy ball horizontal speed and vertical speed. , ismine represents whether it is a white ball or another ball (different balls draw different pictures in the _paint method), oldx, oldy are used to save the position of the ball in the previous frame, but they have not been used yet, it should be useful. There is nothing much to say about the _paint method. The _run method is to track the position of the ball and calculate the displacement increment and speed increment of the ball based on the time of each frame of the ball. mcl and pxpm are both constants, mcl is the friction force, and pxpm is approximately Calculate the pixel and reality conversion ratio. . . . Then there is collision detection. This is easy to understand. It calculates whether the position of the ball exceeds the boundary. If it exceeds, it will rebound. However, this kind of collision detection is very loose. If you really want to make a game, it is recommended to use something more complicated. There is also the method of stopping the ball according to its speed.
Copy code
this.display = false;
}
dotLine.prototype = {
constructor:dotLine,
_ready:function(){
this.length = Math .sqrt(Math.pow(this.y1 - this.y0 , 2) Math.pow(this.x1 - this.x0 , 2));
this.dotNum = Math.ceil(this.length/this. dotlength);
},
_paint:function(){
this._ready();
xadd = this.dotlength*(this.x1 - this.x0)/this.length;
yadd = this.dotlength*(this.y1 - this.y0)/this.length;
ctx.save();
ctx.beginPath();
for(var i=1; i<=this.dotNum;i ){
if(i%2!==0){
ctx.moveTo(this.x0 (i-1)*xadd , this.y0 (i-1) *yadd);
ctx.lineTo(this.x0 i*xadd , this.y0 i*yadd);
}
}
ctx.strokeStyle = "#FFF";
ctx .stroke();
ctx.beginPath();
ctx.arc(this.x1, this.y1, ballRadius-2, 0, 2*Math.PI);
ctx.stroke() ;
ctx.restore();
}
}
Just draw a dotted line. This is relatively simple. Get the position of the mouse and the position of the white ball, and then draw a distance between the two. line, and then it becomes a dotted line.
Copy code
for(var i=0;i
if(b1 !== b2 && !b1.inhole && !b2.inhole){
var rc = Math.sqrt(Math.pow( b1.x - b2.x , 2) Math.pow(b1.y - b2.y , 2));
if(Math.ceil(rc) < (b1.radius b2.radius)){
if(!b1.moving && !b2.moving) return;
//Get the speed increment after collision
var ax = ((b1.vx - b2.vx)*Math.pow((( b1.x - b2.x) , 2) (b1.vy - b2.vy)*(b1.x - b2.x)*(b1.y - b2.y))/Math.pow(rc , 2)
var ay = ((b1.vy - b2.vy)*Math.pow((b1.y - b2.y) , 2) (b1.vx - b2.vx)*(b1.x - b2. x)*(b1.y - b2.y))/Math.pow(rc , 2)
//Assign the speed increment to the collision ball
b1.vx = b1.vx-ax;
b1.vy = b1.vy-ay;
b2.vx = b2.vx ax;
b2.vy = b2.vy ay;
//Correct ball collision distance
var clength = ((b1.radius b2.radius)-rc)/2;
var cx = clength * (b1.x-b2.x)/rc;
var cy = clength * (b1.y- b2.y)/rc;
b1.x = b1.x cx;
b1.y = b1.y cy;
b2.x = b2.x-cx;
b2.y = b2.y-cy;
}
}
}
}
}
Traverse all the balls and calculate the distance between the centers of the two balls. If it is less than the sum of the radii of the two balls, a collision has occurred. If both small balls are stationary, no collision detection will be performed. Otherwise, the speed increment after collision will be calculated. The method of calculating the collision speed increment can be directly seen in Algorithm Design of Small Ball Collision, which explains It's quite detailed, and when combined, we get the series of formulas above.
Assign the speed increment to the collision ball. Because in the frame when the two balls collide, the two balls partially overlap, so the position correction must be performed. Otherwise, the small balls will always be in collision and then stick together. The principle of position correction is also simple. Calculate the distance between the two balls. Center distance, calculate the width of the overlapping area of the two balls through the Pythagorean theorem, and then divide the width by 2 and assign the new position to the ball. The new position is that the radius of the two balls is exactly equal to the distance between the centers of the balls.
【Mouse action】
if(balls[0].moving) return;
document.querySelector(".shotPower").style.display = "block";
document.querySelector(".shotPower").style.top = balls[0].y-60 "px";
document.querySelector(".shotPower").style.left = balls[0].x-40 "px";
document.getElementById("pow").className = "animate";
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - document.querySelector(".view").offsetLeft;
var y = event.clientY document.body.scrollTop document.documentElement.scrollTop - document.querySelector(".view").offsetTop;
dotline.display = true;
dotline.x0 = balls[0].x;
dotline.y0 = balls[0].y;
dotline.x1 = x;
dotline.y1 = y;
window.addEventListener("mouseup" , muHandle , false);
window.addEventListener("mousemove" , mmHandle , false);
function mmHandle(){
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - document.querySelector(".view").offsetLeft;
var y = event.clientY document.body.scrollTop document.documentElement.scrollTop - document.querySelector(".view").offsetTop;
dotline.x1 = x;
dotline.y1 = y;
}
function muHandle(){
var x = event.clientX document.body.scrollLeft document.documentElement.scrollLeft - document.querySelector(".view").offsetLeft;
var y = event.clientY document.body.scrollTop document.documentElement.scrollTop - document.querySelector(".view").offsetTop;
var angle = Math.atan((y - balls[0].y)/(x - balls[0].x));
var h = document.getElementById("pow").offsetHeight/document.getElementById("powbar").offsetHeight;
var v = 60*h;
document.getElementById("pow").style.height = h*100 "%"
balls[0].vx = x - balls[0].x>0 ? v*Math.abs(Math.cos(angle)) : -v*Math.abs(Math.cos(angle));
balls[0].vy = y - balls[0].y>0 ? v*Math.abs(Math.sin(angle)) : -v*Math.abs(Math.sin(angle));
document.getElementById("pow").className = "";
window.removeEventListener("mouseup" , muHandle , false);
window.removeEventListener("mousemove" , muHandle , false);
dotline.display = false;
document.querySelector(".shotPower").style.display = "none";
}
},false);
鼠标动作也比较简单,有js基础的基本上都没问题,就是鼠标按下后计算鼠标位置,然后产生辅助虚线,鼠标移动后修改辅助虚线的终点位置。鼠标按下的时候旁边产生一个力量计,我就只用用animation做动画了,然后鼠标按键抬起时通过计算力量计的大小来确定白球的速度,然后再分解成水平速度以及垂直速度赋给白球。同时取消鼠标移动以及鼠标抬起的事件绑定,把辅助虚线以及力量计隐藏。
【动画舞台】
ctx.clearRect(0,0,canvas.width,canvas.height)
var t1 = new Date();
var t = (t1 - t0)/1000;
collision();
balls.foreach(function(){
if(!this.inhole) this._run(t);
});
if(dotline.display){
dotline.x0 = balls[0].x;
dotline.y0 = balls[0].y;
dotline._paint();
}
t0 = t1;
if(!animateStop){
if("requestAnimationFrame" in window){
requestAnimationFrame(animate);
}
else if("webkitRequestAnimationFrame" in window){
webkitRequestAnimationFrame(animate);
}
else if("msRequestAnimationFrame" in window){
msRequestAnimationFrame(animate);
}
else if("mozRequestAnimationFrame" in window){
mozRequestAnimationFrame(animate);
}
else {
setTimeout(animate , 16);
}
}
}
这个就是游戏每一帧的逻辑处理现场,如果小球进洞了,就不再进行绘制,如果辅助虚线的display属性设成false,就不进行辅助虚线的绘制,还有就是计算每一帧的时间。 【常量与初始化】
var canvas = document.getElementById("cas");
var ctx = canvas.getContext('2d');
var mcl = 1 , collarg = 0.8 , ballRadius = 15 , t0 = 0 , balls=[] , tbw = 32 , animateStop = true , powAnimation = false;
var dotline;
pxpm = canvas.width/20;
window.onload = function(){
var myball = new Ball(202 , canvas.height/2 , true);
balls.push(myball);
for(var i=0;i<6;i ){
for(var j=0;j var other = new Ball(520 i*(ballRadius-2)*2 , (canvas.height-i*2*ballRadius)/2 ballRadius 2*ballRadius*j , false);
balls.push(other);
}
}
t0 = new Date();
dotline = new dotLine(0,0,0,0);
animateStop = false;
animate();
}
实例化所有小球,把小球全部按照规律摆好,然后获取当前时间,实例化辅助虚线,动画开始。
源码地址:https://github.com/whxaxes/canvas-test/tree/gh-pages/src/Game-demo/snooker

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Guide to Table Border in HTML. Here we discuss multiple ways for defining table-border with examples of the Table Border in HTML.

Guide to HTML margin-left. Here we discuss a brief overview on HTML margin-left and its Examples along with its Code Implementation.

This is a guide to Nested Table in HTML. Here we discuss how to create a table within the table along with the respective examples.

Guide to HTML Table Layout. Here we discuss the Values of HTML Table Layout along with the examples and outputs n detail.

Guide to the HTML Ordered List. Here we also discuss introduction of HTML Ordered list and types along with their example respectively

Guide to HTML Input Placeholder. Here we discuss the Examples of HTML Input Placeholder along with the codes and outputs.

Guide to Moving Text in HTML. Here we discuss an introduction, how marquee tag work with syntax and examples to implement.

Guide to HTML onclick Button. Here we discuss their introduction, working, examples and onclick Event in various events respectively.
