Bounce is now better
This commit is contained in:
		
							
								
								
									
										97
									
								
								Ball.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								Ball.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,97 @@
 | 
			
		||||
class Ball {
 | 
			
		||||
    constructor(ctx, bar) {
 | 
			
		||||
        this.ctx = ctx;
 | 
			
		||||
        this.bar = bar;
 | 
			
		||||
        this.size = 15;
 | 
			
		||||
 | 
			
		||||
        this.moving = false;
 | 
			
		||||
        this.x = this.bar.x + (this.bar.w) / 2;
 | 
			
		||||
        this.y = this.bar.y - this.size -1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this.speed = 5;
 | 
			
		||||
        // this.angle = 90;
 | 
			
		||||
        this.bounce(220,340);
 | 
			
		||||
 | 
			
		||||
        this.color = 'red';
 | 
			
		||||
 | 
			
		||||
        this.limits = {
 | 
			
		||||
            l: this.size,
 | 
			
		||||
            t: this.size,
 | 
			
		||||
            r: this.ctx.canvas.width - this.size,
 | 
			
		||||
            b: this.ctx.canvas.height
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    start() {
 | 
			
		||||
        this.moving = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        if (this.move()) {
 | 
			
		||||
            this.draw();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    draw() {
 | 
			
		||||
        this.ctx.beginPath();
 | 
			
		||||
        this.ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI, false);
 | 
			
		||||
        this.ctx.fillStyle = this.color;
 | 
			
		||||
        this.ctx.fill();
 | 
			
		||||
        this.ctx.lineWidth = 1;
 | 
			
		||||
        this.ctx.strokeStyle = '#003300';
 | 
			
		||||
        this.ctx.stroke();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    move() {
 | 
			
		||||
        if (this.moving) {
 | 
			
		||||
            this.x += this.speed * Math.cos(this.angle);
 | 
			
		||||
            this.y += this.speed * Math.sin(this.angle);
 | 
			
		||||
 | 
			
		||||
            // Escaped from the pad
 | 
			
		||||
            if (this.y > this.limits.b) {
 | 
			
		||||
                this.moving = false;
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( (this.y + this.size) > this.bar.y && this.x > this.bar.x && this.x < (this.bar.x + this.bar.w) ) {
 | 
			
		||||
                // Down (Bar)
 | 
			
		||||
                this.bounce(220,340);
 | 
			
		||||
            } else {
 | 
			
		||||
                if ( this.x < this.limits.l ) {
 | 
			
		||||
                    // Left wall
 | 
			
		||||
                    if (this.angle<this.g2r(180)) this.bounce(20,70); // It was going DOWN
 | 
			
		||||
                    else this.bounce(290,340); // It was going UP
 | 
			
		||||
                } else
 | 
			
		||||
                if ( this.x > this.limits.r ) {
 | 
			
		||||
                    // Right wall
 | 
			
		||||
                    if (this.angle<this.g2r(180)) this.bounce(110,160); // It was going DOWN
 | 
			
		||||
                    else this.bounce(200,250); // It was going UP
 | 
			
		||||
                } else
 | 
			
		||||
                if ( this.y < this.limits.t ) {
 | 
			
		||||
                    // Top Wall
 | 
			
		||||
                    this.bounce(20,140);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this.x = this.bar.x + (this.bar.w) / 2;
 | 
			
		||||
            this.y = this.bar.y - this.size -1;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bounce(min,max) {
 | 
			
		||||
        this.angle = this.g2r( Math.floor(Math.random() * (max-min)) + min );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g2r(deg) {
 | 
			
		||||
        console.log((360+deg)%360);
 | 
			
		||||
        return ( ((360+deg)%360) * Math.PI) / 180.0; 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    r2g(rad) {
 | 
			
		||||
        return rad*180 / Math.PI;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								Bar.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Bar.js
									
									
									
									
									
								
							@ -13,9 +13,9 @@ class Bar {
 | 
			
		||||
    }
 | 
			
		||||
    reset() {
 | 
			
		||||
        this.x = (this.ctx.canvas.width - this.w) / 2;
 | 
			
		||||
        this.y = (this.ctx.canvas.height - this.h * 2);
 | 
			
		||||
        this._y = (this.ctx.canvas.height - this.h * 2);
 | 
			
		||||
 | 
			
		||||
        this._y = this.ctx.canvas.height + 10;
 | 
			
		||||
        this.y = this.ctx.canvas.height + 10;
 | 
			
		||||
    }
 | 
			
		||||
    update() {
 | 
			
		||||
        this.move();
 | 
			
		||||
@ -46,10 +46,10 @@ class Bar {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    draw() {
 | 
			
		||||
        if (this._y != this.y) this._y--;
 | 
			
		||||
        if (this._y < this.ctx.canvas.height) {
 | 
			
		||||
        if (this.y != this._y) this.y--;
 | 
			
		||||
        if (this.y < this.ctx.canvas.height) {
 | 
			
		||||
            this.ctx.fillStyle = 'black';
 | 
			
		||||
            this.ctx.fillRect(this.x, this._y, this.w, this.h);
 | 
			
		||||
            this.ctx.fillRect(this.x, this.y, this.w, this.h);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								GameOver.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								GameOver.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
class GameOver {
 | 
			
		||||
    constructor(ctx) {
 | 
			
		||||
        this.ctx = ctx;
 | 
			
		||||
        this.x = ctx.canvas.width;
 | 
			
		||||
        this.y = ctx.canvas.height / 2 - 48;
 | 
			
		||||
    }
 | 
			
		||||
    update() {
 | 
			
		||||
        this.centerText('GAME OVER', this.y, '48px', 'Consolas', 'Black');
 | 
			
		||||
    }
 | 
			
		||||
    centerText(txt, y, s, f, c) {
 | 
			
		||||
        this.ctx.font = s + ' ' + f;
 | 
			
		||||
        this.ctx.fillStyle = 'Black';
 | 
			
		||||
        let x = (this.ctx.canvas.width - this.ctx.measureText(txt).width) / 2;
 | 
			
		||||
        this.ctx.fillText(txt, x, y);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								Lives.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Lives.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
class Lives {
 | 
			
		||||
    constructor(ctx) {
 | 
			
		||||
        this.ctx = ctx;
 | 
			
		||||
        this.reset();
 | 
			
		||||
 | 
			
		||||
        this.ctx.font = "30px Consolas";
 | 
			
		||||
        let m = ctx.measureText('Score: 00000');
 | 
			
		||||
        this.x = ctx.canvas.width - m.width;
 | 
			
		||||
        this.y = 20;
 | 
			
		||||
    }
 | 
			
		||||
    reset() {
 | 
			
		||||
        this.lives = 3;
 | 
			
		||||
    }
 | 
			
		||||
    lost() {
 | 
			
		||||
        this.lives--;
 | 
			
		||||
        return this.lives==0;
 | 
			
		||||
    }
 | 
			
		||||
    update() {
 | 
			
		||||
        if (this.y != 60) this.y++;
 | 
			
		||||
        if (this.y > 0) {
 | 
			
		||||
            let txt = (String.fromCharCode(parseInt('26A1', 16))+" ").repeat(this.lives);
 | 
			
		||||
 | 
			
		||||
            this.ctx.font = "30px Consolas";
 | 
			
		||||
            this.ctx.fillStyle = 'Green';
 | 
			
		||||
            this.ctx.fillText(txt, this.x, this.y);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -9,8 +9,11 @@
 | 
			
		||||
    </style>
 | 
			
		||||
    <script src="Key.js"></script>
 | 
			
		||||
    <script src="Intro.js"></script>
 | 
			
		||||
    <script src="GameOver.js"></script>
 | 
			
		||||
    <script src="Score.js"></script>
 | 
			
		||||
    <script src="Lives.js"></script>
 | 
			
		||||
    <script src="Bar.js"></script>
 | 
			
		||||
    <script src="Ball.js"></script>
 | 
			
		||||
    <script src="index.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								index.js
									
									
									
									
									
								
							@ -17,29 +17,38 @@ function init() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // -------------------------------------------------------------------
 | 
			
		||||
    let gstate = 1;
 | 
			
		||||
    let gstate = 0;
 | 
			
		||||
    let key = new Key(controls);
 | 
			
		||||
    let intro = new Intro(ctx);
 | 
			
		||||
    let gameOver = new GameOver(ctx);
 | 
			
		||||
    let score = new Score(ctx);
 | 
			
		||||
    let lives = new Lives(ctx);
 | 
			
		||||
    let bar = new Bar(ctx, key);
 | 
			
		||||
    let balls = [];
 | 
			
		||||
    newGame();
 | 
			
		||||
 | 
			
		||||
    function controls(e) {
 | 
			
		||||
        switch (gstate) {
 | 
			
		||||
            case 0: // Waiting to start
 | 
			
		||||
                if (e.code=='Space') newGame();
 | 
			
		||||
                if (e.code == 'Space') newGame();
 | 
			
		||||
                break;
 | 
			
		||||
            case 1: // Playing...
 | 
			
		||||
                if (e.code == 'Space' && balls.length>0) balls[balls.length - 1].start();
 | 
			
		||||
                else
 | 
			
		||||
                    if (e.code == 'KeyX') { balls.push(new Ball(ctx, bar)); balls[balls.length - 1].start(); }
 | 
			
		||||
                break;
 | 
			
		||||
            case 2: // Game Over
 | 
			
		||||
                if (e.code=='Space') newGame();
 | 
			
		||||
                if (e.code == 'Space') newGame();
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function newGame() {
 | 
			
		||||
        gstate = 1;
 | 
			
		||||
        lives.reset();
 | 
			
		||||
        score.reset();
 | 
			
		||||
        bar.reset();
 | 
			
		||||
        balls.push(new Ball(ctx, bar));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function refresh() {
 | 
			
		||||
@ -48,51 +57,23 @@ function init() {
 | 
			
		||||
                intro.update();
 | 
			
		||||
                break;
 | 
			
		||||
            case 1: // Playing...
 | 
			
		||||
            case 2:
 | 
			
		||||
 | 
			
		||||
                if(gstate==2) {
 | 
			
		||||
                    gameOver.update();
 | 
			
		||||
                } else {
 | 
			
		||||
                    bar.update();
 | 
			
		||||
                    balls = balls.filter(ball => ball.update());
 | 
			
		||||
                    if (balls.length==0) {
 | 
			
		||||
                        if ( lives.lost() ) gstate=2;
 | 
			
		||||
                        else balls.push(new Ball(ctx, bar));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                score.update();
 | 
			
		||||
                break;
 | 
			
		||||
            case 2: // Game Over
 | 
			
		||||
                lives.update();
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ball {
 | 
			
		||||
    constructor(x, y, speed, angle) {
 | 
			
		||||
        this.x = x;
 | 
			
		||||
        this.y = y;
 | 
			
		||||
        this.speed = speed;
 | 
			
		||||
        this.angle = angle;
 | 
			
		||||
        this.color = 'black';
 | 
			
		||||
        this.size = 20;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        this.move();
 | 
			
		||||
        this.draw();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    draw() {
 | 
			
		||||
        this.ctx.fillStyle = this.color;
 | 
			
		||||
        this.ctx.fillRect(this.x, this.y, this.size, this.size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    move() {
 | 
			
		||||
        this.x += this.speed * Math.cos(this.angle);
 | 
			
		||||
        this.y += this.speed * Math.sin(this.angle);
 | 
			
		||||
 | 
			
		||||
        if (this.x < 0 || this.x > this.ctx.canvas.width || this.y < 0 || this.y > this.ctx.canvas.height)
 | 
			
		||||
            this.bounce();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bounce() {
 | 
			
		||||
        this.angle += 180;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user