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>