简体   繁体   中英

Reposition ball when hit. HTML5 Canvas javascript

I'm working on a soccer webcam game in Canvas, still using headtrackr (https://github.com/auduno/headtrackr)

Here it is online; http://www.chrissnoek.com/ubicomp/webcam.html

so far I managed to check if my rectangle hits my ball, then the counter goes +1

The only thing is, I can't reposition my ball if the rectangle hits it.

I tried it this way, but the ball constantly redrawn, so as the rectangle.

 bal.x = Math.floor(Math.random()* (640) + 20);
 bal.y = Math.floor(Math.random()* (120) + 20);

But that doesn't work. Here is my full code;

Any suggestions to move the ball when it is hit?

<!doctype html>
<html lang="en">
    <head>
        <title>facetracking</title>
        <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
        <meta charset="utf-8">

        <script src="js/animate.js"></script>
        <script src="js/delta.js"></script>

        <script src="./js/headtrackr.js"></script>
    </head>

    <body>
        <span id="counter">0</span>

        <canvas id="compare" width="640" height="480" style="display:none"></canvas>
        <video id="vid" autoplay loop width="640" height="480" style="width: 640px"></video>
        <canvas id="overlay" width="640" height="480"></canvas>
        <canvas id="Baloverlay" width="640" height="480"></canvas>
        <canvas id="bal" width="640" height="480"></canvas>
        <canvas id="debug" width="640" height="480"></canvas>

        <p id='gUMMessage'></p>
        <p>Status : <span id='headtrackerMessage'></span></p>
        <p>
            <input type="button" onclick="htracker.stop();htracker.start();" value="reinitiate facedetection"></input>
            <br/><br/>
            <input type="checkbox" onclick="showProbabilityCanvas()" value="asdfasd"></input>Show probability-map
        </p>

        <script>
          // set up video and canvas elements needed

            var videoInput = document.getElementById('vid');
            var canvasInput = document.getElementById('compare');
            var canvasOverlay = document.getElementById('overlay');
            var balOverlay = document.getElementById('bal');
            var debugOverlay = document.getElementById('debug');
            var overlayContext = canvasOverlay.getContext('2d');
            var balOverlay = document.getElementById('Baloverlay');
            var balContext = balOverlay.getContext('2d');
            var counter = document.getElementById('counter'),
                count = 0;

            canvasOverlay.style.position = "absolute";
            canvasOverlay.style.top = '0px';
            canvasOverlay.style.zIndex = '100001';
            canvasOverlay.style.display = 'block';
            balOverlay.style.position = "absolute";
            balOverlay.style.top = '0px';
            balOverlay.style.zIndex = '100002';
            balOverlay.style.display = 'block';
            debugOverlay.style.position = "absolute";
            debugOverlay.style.top = '0px';
            debugOverlay.style.zIndex = '100003';
            debugOverlay.style.display = 'none';

            // add some custom messaging
            statusMessages = {
                "whitebalance" : "checking for stability of camera whitebalance",
                "detecting" : "Detecting face",
                "hints" : "Hmm. Detecting the face is taking a long time",
                "redetecting" : "Lost track of face, redetecting",
                "lost" : "Lost track of face",
                "found" : "Tracking face"
            };

            supportMessages = {
                "no getUserMedia" : "Unfortunately, <a href='http://dev.w3.org/2011/webrtc/editor/getusermedia.html'>getUserMedia</a> is not supported in your browser. Try <a href='http://www.opera.com/browser/'>downloading Opera 12</a> or <a href='http://caniuse.com/stream'>another browser that supports getUserMedia</a>. Now using fallback video for facedetection.",
                "no camera" : "No camera found. Using fallback video for facedetection."
            };


            document.addEventListener("headtrackrStatus", function(event) {
                if (event.status in supportMessages) {
                    var messagep = document.getElementById('gUMMessage');
                    messagep.innerHTML = supportMessages[event.status];
                } else if (event.status in statusMessages) {
                    var messagep = document.getElementById('headtrackerMessage');
                    messagep.innerHTML = statusMessages[event.status];
                }
            }, true);

            // the face tracking setup
            var htracker = new headtrackr.Tracker({altVideo : {ogv : "./media/capture5.ogv", mp4 : "./media/capture5.mp4"}, calcAngles : true, ui : false, headPosition : false, debug : debugOverlay});
            htracker.init(videoInput, canvasInput);
            htracker.start();

            // for each facetracking event received draw rectangle around tracked face on canvas

            document.addEventListener("facetrackingEvent", function( event ) {
                // clear canvas
                overlayContext.clearRect(0,0,640,480);
                // once we have stable tracking, draw rectangle

                if (event.detection == "CS") {
                    overlayContext.translate(event.x, event.y)
                    //overlayContext.rotate(event.angle-(Math.PI/2));
                    overlayContext.strokeStyle = "#00CC00";
                    overlayContext.strokeRect((-(event.width/2)) >> 0, (-(event.height/2)) >> 0, event.width, event.height);
                    //overlayContext.rotate((Math.PI/2)-event.angle);
                    overlayContext.translate(-event.x, -event.y);
                    var bal = new ball();
                    lookForBallInbound(event.x, event.y, event.width, event.height);
                }
            });

            // turn off or on the canvas showing probability
            function showProbabilityCanvas() {
                var debugCanvas = document.getElementById('debug');
                if (debugCanvas.style.display == 'none') {
                    debugCanvas.style.display = 'block';
                } else {
                    debugCanvas.style.display = 'none';
                }
            }

            /*==============================================
            //////////  KIJK OF BAL BINNEN VAK VALT ////////
            ==============================================*/

            function lookForBallInbound(boxX,boxY,boxWidth,boxHeight) {  
                var rightCornerX = boxX - (boxWidth / 2),
                        topY = boxY - (boxHeight / 2);

                if(rightCornerX <= xxx){
                    if((rightCornerX + boxWidth) <= xxx) {
                        return false;
                    } else {
                        // balls is in the box at the x axis
                        // Now check for Y
                        if (topY <= yyy) {
                            // Top is also inbound, => AWESOME <=

                            /*========================================
                                    RECALCULATE BALL POSITION
                            ========================================*/

                            bal.x = Math.floor(Math.random()* (640) + 20);
                            bal.y = Math.floor(Math.random()* (120) + 20);

                            /*========================================
                                    INCREASE AND OUTPUT COUNTER
                            ========================================*/

                            count++;

                            counter.innerHTML = '';
                            counter.innerHTML = count;
                        }
                    }
                }
            }

            var xxx = Math.floor(Math.random()* (640) + 20);
            var yyy = Math.floor(Math.random()* (120) + 20);
            var ballRadius = 20;

            function ball() {
                console.log('Ball recalculating');

                balContext.beginPath();

                balContext.arc(xxx, yyy, ballRadius, 0, 2 * Math.PI, false);
                balContext.fillStyle = 'green';
                balContext.fill();
            }
        </script>
    </body>
</html>

Something like this should work. Note that ball is defined as a global variable.

var videoInput = document.getElementById('vid');
var canvasInput = document.getElementById('compare');
var canvasOverlay = document.getElementById('overlay');
var debugOverlay = document.getElementById('debug');
var overlayContext = canvasOverlay.getContext('2d');
var balOverlay = document.getElementById('Baloverlay');
var balContext = balOverlay.getContext('2d');
var counter = document.getElementById('counter'),
    count = 0,
    ball,
    statusMessages,
    supportMessages,
    htracker;

canvasOverlay.style.position = "absolute";
canvasOverlay.style.top = '0px';
canvasOverlay.style.zIndex = '100001';
canvasOverlay.style.display = 'block';
balOverlay.style.position = "absolute";
balOverlay.style.top = '0px';
balOverlay.style.zIndex = '100002';
balOverlay.style.display = 'block';
debugOverlay.style.position = "absolute";
debugOverlay.style.top = '0px';
debugOverlay.style.zIndex = '100003';
debugOverlay.style.display = 'none';

// add some custom messaging
statusMessages = {
    "whitebalance": "checking for stability of camera whitebalance",
    "detecting": "Detecting face",
    "hints": "Hmm. Detecting the face is taking a long time",
    "redetecting": "Lost track of face, redetecting",
    "lost": "Lost track of face",
    "found": "Tracking face"
};

supportMessages = {
    "no getUserMedia": "Unfortunately, <a href='http://dev.w3.org/2011/webrtc/editor/getusermedia.html'>getUserMedia</a> is not supported in your browser. Try <a href='http://www.opera.com/browser/'>downloading Opera 12</a> or <a href='http://caniuse.com/stream'>another browser that supports getUserMedia</a>. Now using fallback video for facedetection.",
    "no camera": "No camera found. Using fallback video for facedetection."
};


document.addEventListener("headtrackrStatus", function(event) {
    var messagep;
    if (event.status in supportMessages) {
        messagep = document.getElementById('gUMMessage');
        messagep.innerHTML = supportMessages[event.status];
    } else if (event.status in statusMessages) {
        messagep = document.getElementById('headtrackerMessage');
        messagep.innerHTML = statusMessages[event.status];
    }
}, true);

// the face tracking setup
htracker = new headtrackr.Tracker({
    altVideo: {
        ogv: "./media/capture5.ogv",
        mp4: "./media/capture5.mp4"
    },
    calcAngles: true,
    ui: false,
    headPosition: false,
    debug: debugOverlay
});
htracker.init(videoInput, canvasInput);
htracker.start();

// for each facetracking event received draw rectangle around tracked face on canvas
document.addEventListener("facetrackingEvent", function(event) {
    // clear canvas
    overlayContext.clearRect(0, 0, 640, 480);
    // once we have stable tracking, draw rectangle
    if (event.detection == "CS") {
        overlayContext.translate(event.x, event.y);
        //overlayContext.rotate(event.angle-(Math.PI/2));
        overlayContext.strokeStyle = "#00CC00";
        overlayContext.strokeRect((-(event.width / 2)) >> 0, (-(event.height / 2)) >> 0, event.width, event.height);
        //overlayContext.rotate((Math.PI/2)-event.angle);
        overlayContext.translate(-event.x, -event.y);
        if (!ball) { // if there is no ball then make one
            ball = new Ball();
        }
        lookForBallInbound(event.x, event.y, event.width, event.height);
    }
});

// turn off or on the canvas showing probability

function showProbabilityCanvas() {
    var debugCanvas = document.getElementById('debug');
    if (debugCanvas.style.display == 'none') {
        debugCanvas.style.display = 'block';
    } else {
        debugCanvas.style.display = 'none';
    }
}

/*==============================================
            //////////  KIJK OF BAL BINNEN VAK VALT ////////
            ==============================================*/

function lookForBallInbound(boxX, boxY, boxWidth, boxHeight) {
    var leftX = boxX - boxWidth / 2, rightX = leftX + boxWidth,
        topY = boxY - boxHeight / 2, bottomY = topY + boxHeight;
    if (!ball) return;
    if (leftX <= ball.x && rightX >= ball.x &&
        topY <= ball.y && bottomY >= ball.y) {
        ball = new Ball();
        // ^  replace the existing ball with a randomly positioned new one
        count++;
        counter.innerHTML = count;
    }
}

function Ball() {
    console.log('making new ball');
    this.x = Math.floor(Math.random() * 640 + 20);
    this.y = Math.floor(Math.random() * 120 + 20);
    this.radius = 20;
    this.draw = function() {
        balContext.clearRect(0, 0, 640, 480);
        balContext.beginPath();

        balContext.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
        balContext.fillStyle = 'green';
        balContext.fill();
    }
    this.draw();
}​

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM