Moving Ball
42324 ワード
Moving Ball
本明細書では、ソースを参照する.
インタラクティブ開発者のモバイル画面のボール作成について学習する.CSSやHTMLはあまり見どころがなく、主にJS部分を理解して真似しています.
HTML
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-COmpatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title></title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>
CSS
* {
user-select: none;
-ms-user-select: none;
outline: 0;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
html {
width : 100%;
height : 100%;
}
body{
width: 100%;
height: 100%;
overflow: hidden;
background-color: #161e38;
}
canvas{
width: 100%;
height: 100%;
}
JS
block.jsexport class Block{
// 생성자
constructor(width, height, x, y){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.maxX = width + x;
this.maxY = height + y;
}
draw(ctx){
const xGap = 80;
const yGap = 60;
// 블럭 그림
ctx.fillStyle = '#ff384e';
ctx.beginPath();
ctx.rect(this.x, this.y, this.width, this.height);
ctx.fill();
// 블럭 옆면 부분
ctx.fillStyle = '#190f3a';
ctx.beginPath();
ctx.moveTo(this.maxX, this.maxY);
ctx.lineTo(this.maxX - xGap, this.maxY + yGap);
ctx.lineTo(this.x - xGap, this.maxY + yGap);
ctx.lineTo(this.x, this.maxY);
ctx.fill();
ctx.fillStyle = '#9d0919';
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x, this.maxY);
ctx.lineTo(this.x - xGap, this.maxY + yGap);
ctx.lineTo(this.x - xGap, this.maxY + yGap - this.height);
ctx.fill();
}
}
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-COmpatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title></title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>
* {
user-select: none;
-ms-user-select: none;
outline: 0;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
html {
width : 100%;
height : 100%;
}
body{
width: 100%;
height: 100%;
overflow: hidden;
background-color: #161e38;
}
canvas{
width: 100%;
height: 100%;
}
export class Block{
// 생성자
constructor(width, height, x, y){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.maxX = width + x;
this.maxY = height + y;
}
draw(ctx){
const xGap = 80;
const yGap = 60;
// 블럭 그림
ctx.fillStyle = '#ff384e';
ctx.beginPath();
ctx.rect(this.x, this.y, this.width, this.height);
ctx.fill();
// 블럭 옆면 부분
ctx.fillStyle = '#190f3a';
ctx.beginPath();
ctx.moveTo(this.maxX, this.maxY);
ctx.lineTo(this.maxX - xGap, this.maxY + yGap);
ctx.lineTo(this.x - xGap, this.maxY + yGap);
ctx.lineTo(this.x, this.maxY);
ctx.fill();
ctx.fillStyle = '#9d0919';
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x, this.maxY);
ctx.lineTo(this.x - xGap, this.maxY + yGap);
ctx.lineTo(this.x - xGap, this.maxY + yGap - this.height);
ctx.fill();
}
}
export class Ball{
constructor(stageWidth, stageHeight, radius, speed){
this.radius = radius;
this.vx = speed;
this.vy = speed;
const diameter = this.radius*2;
this.x = diameter + (Math.random() * stageWidth - diameter);
this.y = diameter + (Math.random() * stageHeight - diameter);
}
draw(ctx, stageWidth, stageHeight, block){
this.x += this.vx;
this.y += this.vy;
// 윈도우에 튕기는걸 판별하는 함수
this.bounceWindow(stageWidth, stageHeight);
// 블록에 튕기는걸 판별하는 함수
this.bounceBlock(block);
ctx.fillStyle = '#fdd700';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
ctx.fill();
}
bounceWindow(stageWidth, stageHeight){
const minX = this.radius;
const maxX = stageWidth - this.radius;
const minY = this.radius;
const maxY = stageHeight - this.radius;
if (this.x <= minX || this.x >= maxX){
this.vx *= -1;
this.x += this.vx;
}else if (this.y <= minY || this.y >= maxY){
this.vy *= -1;
this.y += this.vy;
}
}
bounceBlock(block){
const minX = block.x - this.radius;
const maxX = block.maxX + this.radius;
const minY = block.y - this.radius
const maxY = block.maxY + this.radius;
if (this.x > minX && this.x < maxX && this.y > minY && this.y < maxY){
const x1 = Math.abs(minX - this.x);
const x2 = Math.abs(this.x - maxX);
const y1 = Math.abs(minY - this.y);
const y2 = Math.abs(this.y - maxY);
const min1 = Math.min(x1, x2);
const min2 = Math.min(y1, y2);
const min = Math.min(min1, min2);
if (min == min1){
this.vx *= -1;
this.x += this.vx;
}else if (min == min2){
this.vy *= -1;
this.y += this.vy;
}
}
}
}
app.js
import {
Ball
} from './ball.js';
import {
Block
} from './block.js';
class App{
constructor(){
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d')
document.body.appendChild(this.canvas);
window.addEventListener('resize', this.resize.bind(this), false);
this.resize();
this.ball = new Ball(this.stageWidth, this.stageHeight, 60, 15);
this.block = new Block(700, 30, 300, 450);
window.requestAnimationFrame(this.animate.bind(this));
}
resize(){
this.stageWidth = document.body.clientWidth;
this.stageHeight = document.body.clientHeight;
this.canvas.width = this.stageWidth * 2;
this.canvas.height = this.stageHeight * 2;
this.ctx.scale(2, 2);
}
animate(t){
window.requestAnimationFrame(this.animate.bind(this));
this.ctx.clearRect(0, 0, this.stageWidth, this.stageHeight);
this.block.draw(this.ctx);
this.ball.draw(this.ctx, this.stageWidth, this.stageHeight, this.block);
}
}
window.onload = () => {
new App();
}
Reference
この問題について(Moving Ball), 我々は、より多くの情報をここで見つけました https://velog.io/@kgh396/Moving-Ballテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol