반응형
[웹 게임 개발] 스틱 히어로 - 게임 인트로 만들기(1)
히어로 몸통 만들기
game.js 파일에 전역 변수로 히어로 크기 변수 지정합니다.
// 히어로 크기
let heroWidth = 80;
let heroHeight = 90;
game.js 파일에 createHero함수를 만들어 아래 코드를 작성합니다
function createHero(ctx, x, y, width, height, cornerRadius) {
ctx.beginPath();
ctx.moveTo(x + cornerRadius, y);
ctx.lineTo(x + width - cornerRadius, y);
ctx.arcTo(x + width, y, x + width, y + cornerRadius, cornerRadius);
ctx.lineTo(x + width, y + height - cornerRadius);
ctx.arcTo(x + width, y + height, x + width - cornerRadius, y + height, cornerRadius);
ctx.lineTo(x + cornerRadius, y + height);
ctx.arcTo(x, y + height, x, y + height - cornerRadius, cornerRadius);
ctx.lineTo(x, y + cornerRadius);
ctx.arcTo(x, y, x + cornerRadius, y, cornerRadius);
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
}
둥근 모서리 가진 사각형을 그리는 역할을 합니다.
- ctx : 캔버스에 그리기 위한 2D컨텍스트입니다
- x: 사각형의 시작점 x 좌표
- y: 사각형의 시작하는 y 좌표
- width : 사각형의 너비 입니다.
- height : 사각형의 높이 입니다.
- cornerRadius : 사각형의 모서리의 둥근 반지름 입니다.
다음은 함수 내부 동작 원리 입니다.
- beginPath() : 새로운 경로를 시작합니다.
- moveTo(x + cornerRadius, y) : 사각형의 왼쪽 상단 모서리에서 cornerRadius만큼 오른쪽으로 이동하여 그리기 시작점을 설정합니다.
- lineTo(x + width - cornerRadius, y) : 사각형의 상단 가장다리를 따라 오른쪽으로 그립니다. 모서리 반경을 뺀 거리입니다.
- arcTo(x + width, y, x + width, y + cornerRadius, cornerRadius) : 곡선의 시작점과 끝점을 지점 하여 라운딩 처리을 합니다.
이런 작업을 반복해 closePath로 경로 닫아주고 색상과 사각형을 채우면 됩니다.
gameIntro함수에 creatreHero함수를 호출 합니다.
function gameIntro(){
//게임 제목 생성
//시작버튼
//히어로생성
createHero(ctx, gameWidth / 2 - heroWidth / 2, gameHeight / 2 - heroHeight / 2 + 80, heroWidth, heroHeight, 15)
}
인자를 15값을 넣어 라운된 사각형을 호출합니다.
히어로 다리 만들기
createHero 함수에 매개변수 legRadius 추가하고, 다리부분 코딩을 합니다
function createHero(ctx, x, y, width, height, cornerRadius,legRadius) {
// 히어로 몸통만들기
// 히어로 다리 만들기
// 왼쪽 다리
ctx.beginPath();
ctx.arc(x + width * 0.25, y + height, legRadius, 0, Math.PI * 2);
ctx.fill();
// 오른쪽 다리
ctx.beginPath();
ctx.arc(x + width * 0.75, y + height, legRadius, 0, Math.PI * 2);
ctx.fill();
}
다리만들는 역활중
- 왼쪽 다리 첫번째 인자(x + width *0.25)는 원의 중심 x 좌표입니다. 이는 케릭터 전체 너비 25% 위치에 해당합니다
- 오른쪽 다리 첫번째 인자 (x + width * 0.75) 75% 위치입니다.
이 수치를 조절하여 다리 위치를 선택합니다
gameIntro함수에 legRadius 10을 추가합니다.
function gameIntro(){
//게임 제목 생성
//시작버튼
//히어로생성
createHero(ctx, gameWidth / 2 - heroWidth / 2, gameHeight / 2 - heroHeight / 2 + 80,
heroWidth, heroHeight,15, 10) )
}
히어로 눈 만들기
createHero에 eteRadius 매개변수 추가하고, 눈 만드는 코딩을 합니다.
function createHero(ctx, x, y, width, height, cornerRadius, legRadius, eyeRadius) {
// 히어로 몸통만들기
// 히어로 다리 만들기
// 히어로 눈 만들기
ctx.fillStyle = "white";
ctx.beginPath();
// 캐릭터의 오른쪽 상단 부분에 눈 그리기
// x 좌표는 캐릭터의 너비에 일정 비율(예: 70%)을 더한 값
// y 좌표는 캐릭터의 높이에 일정 비율(예: 30%)을 더한 값
ctx.arc(x + width * 0.7, y + height * 0.3, eyeRadius, 0, Math.PI * 2);
ctx.fill();
}
게임 인트로 함수에 인자 8를 추가하여 생성합니다.
function gameIntro(){
//게임 제목 생성
//시작버튼
//히어로생성
createHero(ctx, gameWidth / 2 - heroWidth / 2, gameHeight / 2 - heroHeight / 2 + 80,
heroWidth, heroHeight,15, 10, 8) )
}
히어로 두건 만들기
매개변수 bandanaHeight 추가하고 두건 코딩을합니다.
function createHero(ctx, x, y, width, height, cornerRadius,legRadius,eyeRadius,bandanaHeight) {
// 두건 그리기
ctx.fillStyle = "red"; // 두건의 색깔을 빨간색으로 설정
ctx.beginPath();
ctx.moveTo(x-2, y + height * 0.15); // 두건의 시작점
ctx.lineTo(x + width+2, y + height * 0.15); // 두건의 윗부분
ctx.lineTo(x + width+2, y + height * 0.2 + bandanaHeight); // 두건의 오른쪽 아래
ctx.lineTo(x-2, y + height * 0.2 + bandanaHeight); // 두건의 왼쪽 아래
ctx.closePath();
ctx.fill();
}
호출에 매개변수 10 추가하여 호출합니다.
function gameIntro(){
//게임 제목 생성
//시작버튼
//히어로생성
createHero(ctx, gameWidth / 2 - heroWidth / 2, gameHeight / 2 - heroHeight / 2 + 80,
heroWidth, heroHeight,15, 10, 8, 10) )
}
game.js
더보기
// 캔버스 요소와 그래픽 컨텍스트를 가져옵니다.
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 캔버스 크기 설정
let gameWidth = canvas.width = 400;
let gameHeight = canvas.height = 550;
// 히어로 크기
let heroWidth = 80;
let heroHeight = 90;
// 게임 인트로
function gameIntro(){
//게임 제목 생성
const text = "Stick Hero"
ctx.fillStyle = 'black'
ctx.textAlign = 'center'; // 가로 중앙 정렬
ctx.font = "bold 34px Arial "
ctx.fillText(text, gameWidth / 2, 70)
//게임 시작 버튼과 글생성
const btnPositionX = gameWidth / 2
const btnPositionY = gameHeight / 2 - 100
const radius = 50
ctx.fillStyle = "red"
ctx.beginPath();
ctx.arc(btnPositionX,btnPositionY, radius, 0, 2 * Math.PI, false);
ctx.fill();
const btnText = "Start"
ctx.font = "bold 30px Arial"
ctx.textBaseline ="middle"
ctx.fillStyle = "white"
ctx.fillText(btnText, btnPositionX, btnPositionY)
// 배경음악 설정
// const backgroundMusic = new Audio('assets/sounds/intro.mp3')
// backgroundMusic.loop = true;
// try{
// backgroundMusic.play()
// }catch (error){
// console.log("음악을 재생할 수 없습니다.", error)
// }
//히어로 생성
createHero(ctx, gameWidth / 2 - heroWidth / 2, gameHeight / 2 - heroHeight / 2 + 80, heroWidth, heroHeight, 15, 10, 8, 10);
}
function createHero(ctx, x, y, width, height, cornerRadius,legRadius,eyeRadius,bandanaHeight) {
//몸통
ctx.beginPath();
ctx.moveTo(x + cornerRadius, y);
ctx.lineTo(x + width - cornerRadius, y);
ctx.arcTo(x + width , y, x + width, y + cornerRadius, cornerRadius);
ctx.lineTo(x + width, y + height - cornerRadius);
ctx.arcTo(x + width, y + height, x + width - cornerRadius, y + height, cornerRadius);
ctx.lineTo(x + cornerRadius, y + height);
ctx.arcTo(x, y + height, x, y + height - cornerRadius, cornerRadius);
ctx.lineTo(x, y + cornerRadius);
ctx.arcTo(x, y, x + cornerRadius, y, cornerRadius);
ctx.closePath();
ctx.fillStyle = "black";
ctx.fill();
// 왼쪽 다리
ctx.beginPath();
ctx.arc(x + width * 0.25, y + height, legRadius, 0, Math.PI * 2);
ctx.fill();
// 오른쪽 다리
ctx.beginPath();
ctx.arc(x + width * 0.75, y + height, legRadius, 0, Math.PI * 2);
ctx.fill();
// 오른쪽 눈 그리기
ctx.fillStyle = "white"; // 눈의 색깔을 흰색으로 설정
ctx.beginPath();
// 캐릭터의 오른쪽 상단 부분에 눈 그리기
// x 좌표는 캐릭터의 너비에 일정 비율(예: 70%)을 더한 값
// y 좌표는 캐릭터의 높이에 일정 비율(예: 30%)을 더한 값
ctx.arc(x + width * 0.7, y + height * 0.3, eyeRadius, 0, Math.PI * 2);
ctx.fill();
// 두건 그리기
ctx.fillStyle = "red"; // 두건의 색깔을 빨간색으로 설정
ctx.beginPath();
ctx.moveTo(x-2, y + height * 0.15); // 두건의 시작점
ctx.lineTo(x + width+2, y + height * 0.15); // 두건의 윗부분
ctx.lineTo(x + width+2, y + height * 0.2 + bandanaHeight); // 두건의 오른쪽 아래
ctx.lineTo(x-2, y + height * 0.2 + bandanaHeight); // 두건의 왼쪽 아래
ctx.closePath();
ctx.fill();
}
window.onload = gameIntro
반응형