카테고리 없음

공튀기기

psys 2020. 7. 9. 10:27
728x90

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #wrapper {
            position: relative;
            margin: 0px auto;
            width: 400px;
            height: 500px;
            background-color: rgba(31, 143, 187, 0.562);
            ;
        }

        #id_bar {
            position: absolute;
            bottom: 40px;
            width: 80px;
            height: 20px;
            background-color: wheat;
        }

        #id_ball {
            background-image: url("./images/wow.png");
            background-size: 50px 50px;
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: wheat;
            border-radius: 50%;
        }

        #id_marker {
            position: absolute;
            width: 10px;
            height: 10px;
            background-color: chartreuse;
        }
    </style>
</head>

<body><input type=button value="자동모드" onclick="f_auto()">
    <input type=button value="자동모드취소" onclick="f_autoCan()">
    <div id="wrapper" tabindex="0" autofocus onkeydown=f_lrMove()>
        <div id="id_marker"></div>
        <div id="id_ball"></div>
        <div id="id_bar"></div>
    </div>
    <script>
        var v_bar = document.getElementById("id_bar");
        var v_ball = document.getElementById("id_ball");
        var v_marker = document.getElementById("id_marker");
        var v_parWidth = 400;
        var v_mvWidth = 10;
        function f_auto() {
            v_autoMode = true;
        }
        function f_autoCan(){
            v_autoMode = false;
        }
        function f_lrMove() {
            // 좌우 화살표 눌렀을 때 막대 움직이기
            if (event.keyCode == 37) {   // 왼쪽 화살표
                //왼쪽으로 가는 건 left값이 0보다 클때만 
                if (parseInt(v_bar.style.left) > 0) {
                    v_bar.style.left = parseInt(v_bar.style.left) - v_mvWidth + "px";
                }
            }
            if (event.keyCode == 39) {  // 오른쪽 화살표
                //오른쪽으로 가는 건 left값 + 막대width가 wrapper넓이보다 작을때 
                if ((parseInt(v_bar.style.left) + 80) < 400) {
                    v_bar.style.left = parseInt(v_bar.style.left) + v_mvWidth + "px";
                }
            }
        }
        // 초기세팅이 필요한 일들은 window.onload 이벤트에 모아서
        window.onload = function () {
            if (!v_bar.style.left) {  // 초기값 없을때 초기값 강제 세팅
                v_bar.style.left = "30px";
                v_bar.style.top = "460px";
                v_ball.style.left = Math.floor(Math.random() * 35) * 10 + "px";
                v_ball.style.top = "10px";
            }
            f_moveBall(); // 공 움직이는 함수 콜
        }
        var v_mvW = 10; // 좌우 이동 폭
        var v_mvH = 10; // 상하 이동 폭
        var v_gak = 0;  // 각도
        var v_autoMode = false;
        function f_moveBall() {
            v_gak = (v_gak + 10) % 360;
            v_ball.style.left = parseInt(v_ball.style.left) + v_mvW + "px";
            v_ball.style.top = parseInt(v_ball.style.top) + v_mvH + "px";
            v_ball.style.transform = "rotate(" + v_gak + "deg)";

            var v_ballLeft = parseInt(v_ball.style.left);
            var v_ballRight = v_ballLeft + 50;
            var v_ballTop = parseInt(v_ball.style.top);
            var v_ballBottom = v_ballTop + 50;
            var v_barLeft = parseInt(v_bar.style.left);
            var v_barRight = v_barLeft + 80;
            var v_barTop = parseInt(v_bar.style.top);

            /* 자동으로 막대 움직이기  공의 x중심과 막대의 x중심이 일치하도록 */
            // v_barLeft + 40 = v_ballLeft + 25;//공/2
            // v_barLeft=v_ballLeft+25-40;
            // v_barLeft = v_ballLeft - 15;
            // v_bar.style.left = (v_ballLeft - 15) + "px";
            if (v_autoMode) {
                v_bar.style.left = (v_ballLeft - 15) + "px";
            }

            // 회전시 좌표축도 회전하는지 체크를 위한 마커
            v_marker.style.left = v_ballLeft + "px";
            v_marker.style.top = v_ballTop + "px";

            // 좌우벽 충돌 체크 
            if (v_ballLeft <= 0 || v_ballRight >= 400) {
                v_mvW = -v_mvW;    // 이동방향전환 오른쪽->왼쪽, 왼쪽 -> 오른쪽 
            }

            // 상하벽 충돌 체크 
            if (v_ballTop <= 0 || v_ballBottom >= 500) {
                v_mvH = -v_mvH;    // 이동방향전환 오른쪽->왼쪽, 왼쪽 -> 오른쪽 
            }

            //막대충돌 체크
            var v_bottomCheck = (v_ballBottom >= v_barTop);
            var v_lrCheck = (v_ballRight >= v_barLeft) && (v_ballLeft <= v_barRight);
            if (v_bottomCheck && v_lrCheck) {
                if (v_mvW > 0) {
                    // v_ball.style.transform = "skewX(-45deg)"; // skew 뒤틀리다
                    v_ball.style.transform = "skewX(-45deg) rotate(" + v_gak + "deg)";
                } else {
                    // v_ball.style.transform = "skewX(45deg)";           
                    v_ball.style.transform = "skewX(45deg) rotate(" + v_gak + "deg)";
                }
                //아래의 코드 들어가면 뒤틀림 없음!
                //왜? 뒤틀릴 시간이 없고 회전을 했기 때문
                // v_ball.style.transform = "rotate("+v_gak+"deg)";               
                v_mvH = -v_mvH;  // 위아래 방향만 전환
            }

            setTimeout(f_moveBall, 200);

        }
    // 여기서 문제  막대가 좌우로 움직이는데
    // 부모(wrapper)를 벗어나지 않게 해 주세용
    </script>
</body>

</html>

 

자동모드시

막대 벗어남 해결

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #wrapper {
            position: relative;
            margin: 0px auto;
            width: 400px;
            height: 500px;
            background-color: rgba(31, 143, 187, 0.562);
            ;
        }

        #id_bar {
            position: absolute;
            bottom: 40px;
            width: 80px;
            height: 20px;
            background-color: wheat;
        }

        #id_ball {
            background-image: url("./images/wow.png");
            background-size: 50px 50px;
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: wheat;
            border-radius: 50%;
        }

        #id_marker {
            position: absolute;
            width: 10px;
            height: 10px;
            background-color: chartreuse;
        }
    </style>
</head>

<body><input type=button value="자동모드" onclick="f_auto()">
    <input type=button value="자동모드취소" onclick="f_autoCan()">
    <div id="wrapper" tabindex="0" autofocus onkeydown=f_lrMove()>
        <div id="id_marker"></div>
        <div id="id_ball"></div>
        <div id="id_bar"></div>
    </div>
    <script>
        var v_bar = document.getElementById("id_bar");
        var v_ball = document.getElementById("id_ball");
        var v_marker = document.getElementById("id_marker");
        var v_parWidth = 400;
        var v_mvWidth = 10;
        function f_auto() {
            v_autoMode = true;
        }
        function f_autoCan() {
            v_autoMode = false;
        }
        function f_lrMove() {
            // 좌우 화살표 눌렀을 때 막대 움직이기
            if (event.keyCode == 37) {   // 왼쪽 화살표
                //왼쪽으로 가는 건 left값이 0보다 클때만 
                if (parseInt(v_bar.style.left) > 0) {
                    v_bar.style.left = parseInt(v_bar.style.left) - v_mvWidth + "px";
                }
            }
            if (event.keyCode == 39) {  // 오른쪽 화살표
                //오른쪽으로 가는 건 left값 + 막대width가 wrapper넓이보다 작을때 
                if ((parseInt(v_bar.style.left) + 80) < 400) {
                    v_bar.style.left = parseInt(v_bar.style.left) + v_mvWidth + "px";
                }
            }
        }
        // 초기세팅이 필요한 일들은 window.onload 이벤트에 모아서
        window.onload = function () {
            if (!v_bar.style.left) {  // 초기값 없을때 초기값 강제 세팅
                v_bar.style.left = "30px";
                v_bar.style.top = "460px";
                v_ball.style.left = Math.floor(Math.random() * 35) * 10 + "px";
                v_ball.style.top = "10px";
            }
            f_moveBall(); // 공 움직이는 함수 콜
        }
        var v_mvW = 10; // 좌우 이동 폭
        var v_mvH = 10; // 상하 이동 폭
        var v_gak = 0;  // 각도
        var v_autoMode = false;
        function f_moveBall() {
            v_gak = (v_gak + 10) % 360;
            v_ball.style.left = parseInt(v_ball.style.left) + v_mvW + "px";
            v_ball.style.top = parseInt(v_ball.style.top) + v_mvH + "px";
            v_ball.style.transform = "rotate(" + v_gak + "deg)";

            var v_ballLeft = parseInt(v_ball.style.left);
            var v_ballRight = v_ballLeft + 50;
            var v_ballTop = parseInt(v_ball.style.top);
            var v_ballBottom = v_ballTop + 50;
            var v_barLeft = parseInt(v_bar.style.left);
            var v_barRight = v_barLeft + 80;
            var v_barTop = parseInt(v_bar.style.top);

            /* 자동으로 막대 움직이기  공의 x중심과 막대의 x중심이 일치하도록 */
            // v_barLeft + 40 = v_ballLeft + 25;//공/2
            // v_barLeft=v_ballLeft+25-40;
            // v_barLeft = v_ballLeft - 15;
            // v_bar.style.left = (v_ballLeft - 15) + "px";
            if (v_autoMode) {
                if (v_ballLeft <= 15) {
                    // alert("넘어감");
                    v_bar.style.left = "0px";
                } else if (v_ballRight >= 385) {
                    // alert("넘어감");
                    v_bar.style.right = (v_ballLeft-10) + "px";
                } else {
                    v_bar.style.left = (v_ballLeft - 10) + "px";
                }
            }

            // 회전시 좌표축도 회전하는지 체크를 위한 마커
            v_marker.style.left = v_ballLeft + "px";
            v_marker.style.top = v_ballTop + "px";

            // 좌우벽 충돌 체크 
            if (v_ballLeft <= 0 || v_ballRight >= 400) {
                v_mvW = -v_mvW;    // 이동방향전환 오른쪽->왼쪽, 왼쪽 -> 오른쪽 
            }

            // 상하벽 충돌 체크 
            if (v_ballTop <= 0 || v_ballBottom >= 500) {
                v_mvH = -v_mvH;    // 이동방향전환 오른쪽->왼쪽, 왼쪽 -> 오른쪽 
            }

            //막대충돌 체크
            var v_bottomCheck = (v_ballBottom >= v_barTop);
            var v_lrCheck = (v_ballRight >= v_barLeft) && (v_ballLeft <= v_barRight);
            if (v_bottomCheck && v_lrCheck) {
                if (v_mvW > 0) {
                    // v_ball.style.transform = "skewX(-45deg)"; // skew 뒤틀리다
                    v_ball.style.transform = "skewX(-45deg) rotate(" + v_gak + "deg)";
                } else {
                    // v_ball.style.transform = "skewX(45deg)";           
                    v_ball.style.transform = "skewX(45deg) rotate(" + v_gak + "deg)";
                }
                //아래의 코드 들어가면 뒤틀림 없음!
                //왜? 뒤틀릴 시간이 없고 회전을 했기 때문
                // v_ball.style.transform = "rotate("+v_gak+"deg)";               
                v_mvH = -v_mvH;  // 위아래 방향만 전환
            }

            setTimeout(f_moveBall, 100);

        }
    // 여기서 문제  막대가 좌우로 움직이는데
    // 부모(wrapper)를 벗어나지 않게 해 주세용
    </script>
</body>

</html>

 

다른방법's

더보기
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #wrapper {
           /* overflow: hidden; */
            position: relative;
            margin: 0px auto;
            width:400px;
            height:500px;
            background-color: rgba(31, 143, 187, 0.562);
        }
        #id_bar {
            position: absolute;
            bottom: 40px;
            width:80px;
            height:20px;
            background-color: wheat;
        }
        #id_ball {
            background-image: url("./images/wow.png");
            background-size: 50px 50px;
            position: absolute;
            width:50px;
            height:50px;
            background-color: wheat;
            border-radius: 50%;
        }
        #id_marker {
            position: absolute;
            width:10px;
            height:10px;
            background-color:chartreuse;
        }
    </style>
</head>
<body>
    <input type=button value="자동모드" onclick="f_auto()">
    <div id="wrapper" tabindex="0" autofocus onkeydown=f_lrMove()>
        <div id="id_marker"></div>
        <div id="id_ball"></div>
        <div id="id_bar"></div>
    </div>
<script>
    function f_auto(){
        v_autoMode = true;
    }
    var v_bar = document.getElementById("id_bar");
    var v_ball = document.getElementById("id_ball");
    var v_marker = document.getElementById("id_marker");
    var v_parWidth = 400;
    var v_mvWidth = 10;
    function f_lrMove(){
        // 좌우 화살표 눌렀을 때 막대 움직이기
        if(event.keyCode == 37){   // 왼쪽 화살표
            //왼쪽으로 가는 건 left값이 0보다 클때만 
            if(parseInt(v_bar.style.left) > 0 ){
                v_bar.style.left = parseInt(v_bar.style.left) - v_mvWidth + "px";
            }
        }
        if(event.keyCode == 39){  // 오른쪽 화살표
            //오른쪽으로 가는 건 left값 + 막대width가 wrapper넓이보다 작을때 
            if((parseInt(v_bar.style.left)+80) < 400 ){
                v_bar.style.left = parseInt(v_bar.style.left) + v_mvWidth + "px";
            }
        }
    }
    // 초기세팅이 필요한 일들은 window.onload 이벤트에 모아서
    window.onload = function(){
        if(!v_bar.style.left){  // 초기값 없을때 초기값 강제 세팅
            v_bar.style.left = "30px";
            v_bar.style.top = "460px";
            v_ball.style.left = Math.floor(Math.random()*35)*10 + "px";
            v_ball.style.top = "10px";
        }
        f_moveBall(); // 공 움직이는 함수 콜
    }
    var v_mvW = 10; // 좌우 이동 폭
    var v_mvH = 10; // 상하 이동 폭
    var v_gak = 0;  // 각도
    var v_autoMode = false;
    function f_moveBall(){
        v_gak = (v_gak + 10) % 360; 
        v_ball.style.left = parseInt(v_ball.style.left) + v_mvW + "px";
        v_ball.style.top = parseInt(v_ball.style.top) + v_mvH + "px";
        v_ball.style.transform = "rotate(" + v_gak + "deg)";

        var v_ballLeft = parseInt(v_ball.style.left);
        var v_ballRight = v_ballLeft + 50;
        var v_ballTop = parseInt(v_ball.style.top);
        var v_ballBottom = v_ballTop + 50;
        var v_barLeft = parseInt(v_bar.style.left);
        var v_barRight = v_barLeft + 80;
        var v_barTop = parseInt(v_bar.style.top);

        /* 자동으로 막대 움직이기  공의 x중심과 막대의 x중심이 일치하도록 */
        /* 아래방식의 코드를 디버깅 로그 출력형식으로 많이 사용함 */
        if(v_autoMode){
            var v_checkOver = (v_ballLeft -15);
            if(v_checkOver < 0){
                v_bar.style.left ="0px";  // 0보다 작은값이 오면 0으로 고정
            }else if(v_checkOver > 320){
                v_bar.style.left ="320px";  // 320보다 큰값이 오면 320으로 고정
            }else {
                v_bar.style.left = v_checkOver + "px"; // 그외의 경우는 그냥 값을 할당
            }
        }

        // 회전시 좌표축도 회전하는지 체크를 위한 마커
        v_marker.style.left = v_ballLeft + "px";
        v_marker.style.top = v_ballTop + "px";

        // 좌우벽 충돌 체크 
        if(v_ballLeft <= 0 || v_ballRight >= 400){
            v_mvW = -v_mvW;    // 이동방향전환 오른쪽->왼쪽, 왼쪽 -> 오른쪽 
        }

        // 상하벽 충돌 체크 
        if(v_ballTop <= 0 || v_ballBottom >= 500){
            v_mvH = -v_mvH;    // 이동방향전환 오른쪽->왼쪽, 왼쪽 -> 오른쪽 
        }

        //막대충돌 체크
        var v_bottomCheck = (v_ballBottom >= v_barTop);
        var v_lrCheck = (v_ballRight >= v_barLeft) && (v_ballLeft <=v_barRight); 
        if(v_bottomCheck && v_lrCheck){
            if(v_mvW > 0){
                v_ball.style.transform = "skewX(-45deg) rotate("+ v_gak + "deg)"; // skew 뒤틀리다
            }else {
                v_ball.style.transform = "skewX(45deg) rotate("+ v_gak + "deg)"; // rendering 시간 필요              
            }
            v_mvH = -v_mvH;  // 위아래 방향만 전환
        }

        setTimeout(f_moveBall,100);

    }
    // 여기서 문제  막대가 좌우로 움직이는데
    // 부모(wrapper)를 벗어나지 않게 해 주세용
</script>    
</body>
</html>