Around Runner Game - HTML5
Around Run Game
동그란 원에서 장애물을 피하며 살아남기 게임
전체화면으로 게임하기: https://pythonblog.co.kr/example/around_run/
기본설정
<script>
let game;
window.onload = function() {
let config = {
type: Phaser.CANVAS,
backgroundColor: 0x444444,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
parent: "theAroundGame",
width: 800,
height: 800
},
scene: playGame
}
game = new Phaser.Game(config);
window.focus();
}
class playGame extends Phaser.Scene{
preload(){}
create(){}
update(){}
}
</script>
게임옵션 정의 및 원 그리기
...
...
let gameOptions = {
bigCircleRadius: 300,
bigCircleThickness: 20,// 큰 원의 두께(픽셀)
playerRadius: 25, // 플레이어의 반지름(픽셀)
playerSpeed: 0.6, // 플레이어 속도, 프레임당 각도
worldGravity: 0.8, //중력
jumpForce: [12, 8] // 싱글, 2단뛰기 점프파워
}
create(){
// 원 그리기
this.bigCircle = this.add.graphics();
this.bigCircle.lineStyle(gameOptions.bigCircleThickness, 0xffffff);
this.bigCircle.strokeCircle(game.config.width / 2, game.config.height / 2, gameOptions.bigCircleRadius);
}
플레이어 추가
preload(){
this.load.image("player", "https://actioncall.github.io/actioncall/assets/img/around_eyes.png");
}
create(){
...
...
//플레이어 추가
this.distanceFromCenter = gameOptions.bigCircleRadius - gameOptions.playerRadius - gameOptions.bigCircleThickness / 2; //원 중앙과의 거리
this.player = this.add.sprite(game.config.width / 2, game.config.height / 2 - this.distanceFromCenter, "player");
//플레이어 셋팅
this.player.currentAngle = -90; // 플레이어 현재 각도
this.player.previousAngle = this.player.currentAngle; // 플레이어 이전 각도
this.player.jumpOffset = 0; // 점프 오프셋, 점프 중 지면과 거리
this.player.jumps = 0; //점프 횟수
this.player.jumpForce = 0; // 현재 점프포스파워
}
점프하기
create(){
...
...
//마우스 클릭 리스너
this.input.on("pointerdown", function(){
// 2회 미만 점프
if(this.player.jumps < 2){
this.player.jumps ++;
this.player.jumpForce = gameOptions.jumpForce[this.player.jumps - 1]; //jumpForce: [12, 8] 1회,2회
}
}, this);
}
update(){
if(this.player.jumps > 0){
console.log("this.player.jumpForce : "+this.player.jumpOffset);
this.player.jumpOffset += this.player.jumpForce; //점프오프셋에 점프파워 추가
this.player.jumpForce -= gameOptions.worldGravity; //중력을 통해 점프력 감소
// 점프오프셋이 다 감소하여 0보다 작으면 착지 상태
if(this.player.jumpOffset < 0){
//점프 오프셋, 점프 횟수, 점프 포스 초기화
this.player.jumpOffset = this.player.jumps = this.player.jumpForce = 0;
}
}
// 점프 오프셋으로 플레이어 위치 결정
let distanceFromCenter = this.distanceFromCenter - this.player.jumpOffset;
// 삼각법을 사용하여 플레이어 위치 지정
let radians = Phaser.Math.DegToRad(this.player.currentAngle); //라디안으로 변환
this.player.x = game.config.width / 2 + distanceFromCenter * Math.cos(radians);
this.player.y = game.config.height / 2 + distanceFromCenter * Math.sin(radians);
}
플레이어 이동 및 회전
update(){ ... ... ...
// 이전 각도를 현재 각도로 업데이트
this.player.previousAngle = this.player.currentAngle;
// 현재 각도에 플레이어 속도 추가
this.player.currentAngle = Phaser.Math.Angle.WrapDegrees(this.player.currentAngle + gameOptions.playerSpeed);
//회전 시키기
let revolutions = gameOptions.bigCircleRadius / gameOptions.playerRadius + 1;
this.player.angle = -this.player.currentAngle * revolutions;
}
플레이어 이동 자리 색 칠하기
create(){
...
...
...
// 그려진 모든 호를 저장할 배열
this.paintedArcs = [];
//지나간 원을 그릴 그래픽
this.highlightCircle = this.add.graphics();
}
update(){
...
...
...
//점프하지 않을때
if(this.player.jumpOffset == 0){
this.paintedRatio = 0;
//Phaser 각도를 더 읽기 쉬운 각도로 변환합니다. 0:위,90:오른, 180:아래, 270:왼
let currentAngle = this.getGameAngle(this.player.currentAngle);
let previousAngle = this.getGameAngle(this.player.previousAngle);
if(currentAngle >= previousAngle){
// paintedArcs 배열에 추가
this.paintedArcs.push([previousAngle, currentAngle]);
}else{
// 플레이어가 360보다 작은 값에서 360보다 큰 값, 즉 0으로 전달된 경우
this.paintedArcs.push([previousAngle, 360]);
this.paintedArcs.push([0, currentAngle]);
}
// 하이라이트 처리 준비
this.highlightCircle.clear();
this.highlightCircle.lineStyle(gameOptions.bigCircleThickness, 0xaa00aa);
// 겹치는 원을 병합
this.paintedArcs = this.mergeIntervals(this.paintedArcs);
// 배열에 저장된..
this.paintedArcs.forEach(function(i){
// 원 길이에 따라 도장 비율 값 증가
this.paintedRatio += (i[1] - i[0]);
console.log("i : "+i+" ---------"+this.paintedRatio);
// 지나간 자리의 색을 칠한다.
this.highlightCircle.beginPath();
this.highlightCircle.arc(game.config.width / 2, game.config.height / 2, gameOptions.bigCircleRadius, Phaser.Math.DegToRad(i[0] - 90), Phaser.Math.DegToRad(i[1] - 90), false);
this.highlightCircle.strokePath();
}.bind(this));
}
}
// Phaser 각도 변환
getGameAngle(angle){
let gameAngle = angle + 90;
if(gameAngle < 0){
gameAngle = 360 + gameAngle
}
return gameAngle;
}
mergeIntervals(intervals){
if(intervals.length <= 1){
return intervals;
}
let stack = [];
let top = null;
intervals = intervals.sort(function(a, b){
return a[0] - b[0]
});
stack.push(intervals[0]);
for(let i = 1; i < intervals.length; i++){
top = stack[stack.length - 1];
if(top[1] < intervals[i][0]){
stack.push(intervals[i]);
}
else{
if (top[1] < intervals[i][1]){
top[1] = intervals[i][1];
stack.pop();
stack.push(top);
}
}
}
return stack;
}
텍스트 표시 및 재시작
...
...
create(){
constructor(){
super("PlayGame");
}
...
...
...
// 플레이어 진행 상황을 표시하는 텍스트
this.levelText = this.add.text(game.config.width / 2, game.config.height / 2, "", {
fontFamily: "Arial",
fontSize: 96,
color: "#00ff00"
});
this.levelText.setOrigin(0.5);
}
update(){
...
...
//점프하지 않을때
if(this.player.jumpOffset == 0){
...
...
...
// 모든 원 길이의 합을 0 -> 100의 값으로 변환
this.paintedRatio = Math.round(this.paintedRatio * 100 / 360);
// 플레이어 진행률 텍스트 업데이트
this.levelText.setText(this.paintedRatio + "%");
// 만약 플레이어가 원 전체를 칠했다면...
if(this.paintedRatio == 100){
// 2초 후에 게임을 다시 시작합니다.
this.time.addEvent({
delay: 2000,
callbackScope: this,
callback: function(){
this.scene.start("PlayGame");
}
});
}
}
}
점프시 audio 추가
preload(){
this.load.audio("bong_001", "https://actioncall.github.io/actioncall/assets/audio/bong_001.ogg");
}
create(){
this.jumpOgg = this.sound.add('bong_001');
...
...
this.input.on("pointerdown", function(){
// 2회 미만 점프
if(this.player.jumps < 2){
this.jumpOgg.play();
...
...
}
}, this);
...
...
}
캐릭터 변경 및 애니메이션 효과
preload(){
...
...
//this.load.image("player", "https://actioncall.github.io/actioncall/assets/img/around_eyes.png");
this.load.spritesheet('player','https://actioncall.github.io/actioncall/assets/img/p_run.png', { frameWidth: 37, frameHeight: 46 });
}
create(){
...
...
this.anims.create({
key: 'run',
frames: this.anims.generateFrameNumbers('player', { start: 0, end: 5 }),
frameRate: 10,
repeat: -1
});
this.player.anims.play('run');
this.anims.create({
key: 'jump',
frames: this.anims.generateFrameNumbers('player', { start: 6, end: 8 }),
frameRate: 10,
repeat: -1
});
...
...
this.input.on("pointerdown", function(){
// 2회 미만 점프
if(this.player.jumps < 2){
this.player.anims.play('jump');
...
...
}
}, this);
...
...
//현재 각도에 맞춰 캐릭터 회전
this.player.angle = this.getGameAngle(this.player.currentAngle)-150;
//회전 시키기(삼각법)
//let revolutions = gameOptions.bigCircleRadius / gameOptions.playerRadius + 1;
//this.player.angle = -this.player.currentAngle * revolutions;
}
- 기존 플레이어의 회원시키기 기능 주석 처리
배경 변경
preload(){
...
...
this.load.image("bg1", "https://actioncall.github.io/actioncall/assets/img/bg1.png");
}
create(){
...
...
this.add.image(game.config.width / 2, game.config.height / 2,'bg1');
// 큰 원 그리기
//this.bigCircle = this.add.graphics();
//this.bigCircle.lineStyle(gameOptions.bigCircleThickness, 0xffffff);
//this.bigCircle.strokeCircle(game.config.width / 2, game.config.height / 2, gameOptions.bigCircleRadius);
}
- 기존 원 그리기 부분 주석 처리
적 추가하기
let gameOptions = {
...
...
mobSpeed:0.1,
mobRadius: 10,
}
preload(){
...
...
this.load.image("mob1", "https://actioncall.github.io/actioncall/assets/img/Rectangle.png"); |
}
create(){
...
...
...
this.distanceFromCenterMob = gameOptions.bigCircleRadius - gameOptions.mobRadius - gameOptions.bigCircleThickness / 2;
this.mob1 = this.add.image(game.config.width / 2, game.config.height / 2 + this.distanceFromCenterMob,'mob1');
this.mob1.currentAngle = -90;
}
update(){
...
...
...
//위치 지정 이동
this.mob1.currentAngle = Phaser.Math.Angle.WrapDegrees(this.mob1.currentAngle + gameOptions.mobSpeed);
let mobXY = this.getXY(this.mob1.currentAngle,this.distanceFromCenterMob);
this.mob1.y = mobXY.x;
this.mob1.x = mobXY.y;
//radians = this.getRadians(this.mob1.currentAngle); //라디안으로 변환
//this.mob1.y = game.config.width / 2 + mobDist * Math.cos(radians);
//this.mob1.x = game.config.height / 2 + mobDist * Math.sin(radians);
}
getXY(currentAngle,dist){
let radians = this.getRadians(currentAngle); //라디안으로 변환
return {x: game.config.width / 2 + dist * Math.cos(radians),y:game.config.height / 2 + dist * Math.sin(radians)}
}
...
...
...
- 기존 이동 기능 getXY 함수로 변경
적과 충돌 감지
let gameState = {
state:'run'
}
class playGame extends Phaser.Scene{
create(){
...
...
//this.player = this.add.sprite(game.config.width / 2, game.config.height / 2 - this.distanceFromCenter, "player");
this.player = this.physics.add.sprite(game.config.width / 2, game.config.height / 2 - this.distanceFromCenter, "player");
...
...
//this.mob1 = this.add.image(game.config.width / 2, game.config.height / 2 + this.distanceFromCenterMob,'mob1');
this.mob1 = this.physics.add.image(game.config.width / 2, game.config.height / 2 + this.distanceFromCenterMob,'mob1');
this.physics.add.overlap(this.player, this.mob1, this.playerOverlap, null, this);
...
...
}
playerOverlap(player, mob){
if(gameState.state != 'death'){
this.deathOgg.play({volume:0.3});
}
gameState.state = 'death';
}
}
시작버튼 추가하기
...
...
let orignalGameOptions = gameOptions;
class playGame extends Phaser.Scene{
constructor(){
super("PlayGame");
}
preload(){
...
...
this.load.image("startBtn", "https://actioncall.github.io/actioncall/assets/img/start_btn.png");
}
create(){
this.startBtn = this.add.sprite(100, 100, 'startBtn').setInteractive();
this.startBtn.on('pointerdown', function () { this.startGame(); },this ); // Start game on click
...
...
}
startGame(){
stage=1;
gameOptions = orignalGameOptions;
this.scene.start("PlayGame")
}
전체 소스
let game;
let stage = 1;
let score = 0;
let mob_cnt = 0;
let GAMESTATE = { state:'run'}
let BUFF = {speed:1,speedTime:0, jumpPower:1,jumpPowerTime:0,recovery:0,recoveryTime:0}
let gameOptions = {
gameVolume: 0.3,
bigCircleRadius: 300, //원의 반지름
bigCircleThickness: 20,//원의 두께(픽셀)
playerRadius: 18, // 플레이어의 반지름(픽셀)
playerSpeed: 120, // 플레이어 속도, 프레임당 각도
playerHp:100,
playerRecovery:0,
worldGravity: 0.8, //중력
jumpForce: [12, 7], // 싱글, 2단뛰기 점프파워
mob:{atk:10,speed:60,radius:20},
mobSpeed:50,
mobRadius: 20,
}
window.onload = function() {
let config = {
type: Phaser.CANVAS,
backgroundColor: 0x000000,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
parent: "theGame",
width: 800,
height: 800
},
physics: {default: 'arcade',
arcade: {gravity: { y: 0 },
debug: false}
},
scene: playGame
}
game = new Phaser.Game(config);
window.focus();
}
class playGame extends Phaser.Scene{
constructor(){
super("PlayGame");
}
preload(){
//this.load.image("player", "https://actioncall.github.io/actioncall/assets/img/around_eyes.png");
this.load.audio("bong_001", "https://actioncall.github.io/actioncall/assets/audio/bong_001.ogg");
this.load.audio('death', 'https://actioncall.github.io/actioncall/assets/audio/death.ogg');
this.load.audio('gameOverAudio', 'https://actioncall.github.io/actioncall/assets/audio/GameOver.mp3');
this.load.audio('forest', 'https://actioncall.github.io/actioncall/assets/audio/forest.mp3');
this.load.audio('powerUp1', 'https://actioncall.github.io/actioncall/assets/audio/powerUp11.ogg');
this.load.spritesheet('player','https://actioncall.github.io/actioncall/assets/img/player_run.png', { frameWidth: 37, frameHeight: 46 });
//this.load.image("particle1", "https://actioncall.github.io/actioncall/assets/img/blue.png");
this.load.image("bg1", "https://actioncall.github.io/actioncall/assets/img/bg1.png");
this.load.image("mob1", "https://actioncall.github.io/actioncall/assets/img/Rectangle.png");
this.load.image("mob2", "https://actioncall.github.io/actioncall/assets/img/Triangle.png");
this.load.image("startBtn", "https://actioncall.github.io/actioncall/assets/img/start_btn.png");
//item
this.load.image("potionRoundIndigo", "https://actioncall.github.io/actioncall/assets/img/PotionRoundIndigo.png");
this.load.image("potionRoundPink", "https://actioncall.github.io/actioncall/assets/img/PotionRoundPink.png");
this.load.image("potionRoundPurple", "https://actioncall.github.io/actioncall/assets/img/PotionRoundPurple.png");
this.load.image("potionRoundRed", "https://actioncall.github.io/actioncall/assets/img/PotionRoundRed.png");
this.potionNames = ['potionRoundIndigo','potionRoundPink','potionRoundPurple','potionRoundRed'];
}
startGame(){
stage = 1;
score = 0;
mob_cnt = 0;
gameOptions.playerSpeed = 120;
gameOptions.jumpForce[0]= 12;
gameOptions.playerRecovery=0;
//this.player.hp=0;
this.scene.start("PlayGame")
}
create(){
GAMESTATE.state="run";
// 그려진 모든 원를 저장할 배열
this.paintedArcs = [];
this.mobs = [];
this.potion = [];
this.init_audio();
this.init_btn();
this.add.image(game.config.width / 2, game.config.height / 2,'bg1');
//플레이어 추가
this.distanceFromCenter = gameOptions.bigCircleRadius - gameOptions.playerRadius - gameOptions.bigCircleThickness / 2; //원 중앙과의 거리
this.player = this.physics.add.sprite(game.config.width / 2, game.config.height / 2 - this.distanceFromCenter, "player");
this.anims.create({
key: 'run',
frames: this.anims.generateFrameNumbers('player', { start: 0, end: 5 }),
frameRate: 10,
repeat: -1
});
this.player.anims.play('run');
this.anims.create({
key: 'jump',
frames: this.anims.generateFrameNumbers('player', { start: 6, end: 8 }),
frameRate: 10,
repeat: -1
});
//플레이어 셋팅
this.init_player();
this.input.on("pointerdown", function(){this.jumping();}, this);
this.input.keyboard.on('keydown-' + 'UP', function () { this.jumping();}, this);
this.init_display();
//포션 생성
this.createPotion();
if(stage == 1 || stage % 2 == 0){mob_cnt+=1;}
for(var i=0;i<mob_cnt;i++){
let mob = this.createMob(this.getMinus_or_Plus()==-1?'mob1':'mob2');
mob.currentAngle = (this.player.previousAngle*-1)-this.getRandom(1,180);
mob.speed = this.getRandom(5, gameOptions.mob.speed);
mob.atk = this.getRandom(5, gameOptions.mob.atk);
mob.radius = this.getRandom(5, gameOptions.mob.radius);
this.mobs.push(mob);
this.physics.add.overlap(this.player, mob, this.playerOverlap, null, this);
}
//지나간 원을 샐칠할 객체
this.highlightCircle = this.add.graphics();
if(stage > 1){
this.playerStatUp();
}
}
createPotion(){
for(var i=0;i<this.potionNames.length;i++){
let potion = this.physics.add.sprite(game.config.width / 2, game.config.height / 2 - this.distanceFromCenter, this.potionNames[i]);
potion.currentAngle = this.getRandom(Math.abs(this.player.currentAngle),360);
if(this.getRandom(1,100) > 22){
potion.disableBody(true, true);
}
potion.setScale(0.1).refreshBody();
let potionXy = this.getXY(potion.currentAngle, this.distanceFromCenter)
potion.x = potionXy.x;
potion.y = potionXy.y;
potion.angle = this.getGameAngle(potion.currentAngle)-180;
potion.name = this.potionNames[i]
this.physics.add.overlap(this.player, potion, this.potionProcess, null, this);
}
}
potionProcess(player, potion){
let potionName = potion.name;
let objText;
let colorText;
potion.disableBody(true, true);
if("potionRoundIndigo" == potionName){
BUFF.jumpPower = 1.2;
BUFF.jumpPowerTime = 500;
objText = "JumpPower X "+BUFF.jumpPower;
colorText ="#6610f2";
}else if("potionRoundPink" == potionName){
BUFF.speed = 2;
BUFF.speedTime = 300;
objText = "SpeedUP X "+BUFF.speed;
colorText ="#e83e8c";
}else if("potionRoundPurple" == potionName){
BUFF.recovery = 2;
BUFF.recoveryTime = 1000;
objText = "recovery X "+BUFF.recovery;
colorText ="#6610f2";
}else if("potionRoundRed" == potionName){
player.hp+=200;
objText = "HP +500";
colorText ="#e71a11";
}
this.noticeTween(objText, game.config.width / 2, game.config.height / 2+50, {fontFamily: "Arial",fontSize: 30,color:colorText })
this.setDisplay();
if(player.hp <= 0){
GAMESTATE.state = 'death'
this.gameOver();
}
}
createMob(obj_name){
this.distanceFromCenterMob = gameOptions.bigCircleRadius - gameOptions.mobRadius - gameOptions.bigCircleThickness / 2;
return this.physics.add.image(game.config.width / 2, game.config.height / 2 + this.distanceFromCenterMob,obj_name);
}
update(){
if(GAMESTATE.state != 'death'){
if(this.player.jumps > 0) GAMESTATE.state = 'jump';
if(GAMESTATE.state == 'jump') this.jump();
if(GAMESTATE.state == 'run') this.run();
this.move();
this.player.hp= this.player.hp+1+gameOptions.playerRecovery+BUFF.recovery;
score+=1;
this.player.timer+=1;
this.setDisplay();
}
if(BUFF.speedTime > 0){
BUFF.speedTime -= 1;
}else{
BUFF.speed = 1;
}
if(BUFF.jumpPowerTime > 0){
BUFF.jumpPowerTime -= 1;
}else{
BUFF.jumpPower = 1;
}
if(BUFF.recoveryTime > 0){
BUFF.recoveryTime -= 1;
}else{
BUFF.recovery = 0;
}
//if(BUFF.speedTime
}
jump(){
this.player.jumpOffset += this.player.jumpForce; //점프오프셋에 점프파워 추가
this.player.jumpForce -= gameOptions.worldGravity; //중력을 통해 점프력 감소
// 점프오프셋이 다 감소하여 0보다 작으면 착지 상태
if(this.player.jumpOffset < 0){
//점프 오프셋, 점프 횟수, 점프 포스 초기화
this.player.jumpOffset = this.player.jumps = this.player.jumpForce = 0;
this.player.anims.play('run');
GAMESTATE.state = 'run';
}
}
run(){
this.paintedRatio = 0;
//Phaser 각도를 더 읽기 쉬운 각도로 변환합니다. 0:위,90:오른, 180:아래, 270:왼
let currentAngle = this.getGameAngle(this.player.currentAngle);
let previousAngle = this.getGameAngle(this.player.previousAngle);
if(currentAngle >= previousAngle){
// paintedArcs 배열에 추가
this.paintedArcs.push([previousAngle, currentAngle]);
}else{
// 플레이어가 360보다 작은 값에서 360보다 큰 값, 즉 0으로 전달된 경우
this.paintedArcs.push([previousAngle, 360]);
this.paintedArcs.push([0, currentAngle]);
}
// 색칠할 준비
this.highlightCircle.clear();
this.highlightCircle.lineStyle(gameOptions.bigCircleThickness, 0xffffff);
// 겹치는 원을 병합
this.paintedArcs = this.mergeIntervals(this.paintedArcs);
// 배열에 저장된..
this.paintedArcs.forEach(function(i){
// 원 길이에 따라 도장 비율 값 증가
this.paintedRatio += (i[1] - i[0]);
// 지나간 자리의 색을 칠한다.
this.highlightCircle.beginPath();
this.highlightCircle.arc(game.config.width / 2, game.config.height / 2, gameOptions.bigCircleRadius, Phaser.Math.DegToRad(i[0] - 90), Phaser.Math.DegToRad(i[1] - 90), false);
this.highlightCircle.strokePath();
}.bind(this));
// 모든 원 길이의 합을 0 -> 100 값으로 변환
this.paintedRatio = Math.round(this.paintedRatio * 100 / 360);
// 플레이어 진행률 텍스트 업데이트
//this.levelText.setText(this.paintedRatio + "%");
// 만약 플레이어가 원 전체를 칠함.
if(this.paintedRatio == 100){
this.success();
}
}
move(){
// 이전 각도를 현재 각도로 업데이트
this.player.previousAngle = this.player.currentAngle;
// 현재 각도에 플레이어 속도 추가
this.player.currentAngle = Phaser.Math.Angle.WrapDegrees(this.player.currentAngle + ((this.player.speed*BUFF.speed)*0.01));
// 점프 오프셋으로 플레이어 위치 결정
let distanceFromCenter = this.distanceFromCenter - this.player.jumpOffset;
// 삼각법을 사용하여 플레이어 위치 지정
let playerXY = this.getXY(this.player.currentAngle, distanceFromCenter)
this.player.x = playerXY.x;
this.player.y = playerXY.y;
//현재 각도에 맞춰 캐릭터 회전
this.player.angle = this.getGameAngle(this.player.currentAngle)-150;
this.moveMob();
}
moveMob(){
this.mobs.forEach(function(mob){
mob.currentAngle = Phaser.Math.Angle.WrapDegrees(mob.currentAngle + (mob.speed*0.01));
let mobXY = this.getXY(mob.currentAngle, this.distanceFromCenterMob);
mob.y = mobXY.x;
mob.x = mobXY.y;
mob.angle= mob.currentAngle * (gameOptions.bigCircleRadius / mob.radius + 1)*mob.speed*0.01;
},this);
}
success(){
stage +=1;
if(this.player.timer < 600){
score =score+(this.player.timer*3);
}
this.scene.start("PlayGame");
//this.time.addEvent({delay: 300,callbackScope: this,callback: function(){this.playerStatUp();}});
}
gameOver(){
// this.musicAudio.stop();
this.gameOverAudio.play({volume:gameOptions.gameVolume});
GAMESTATE.state = 'death';
this.player.anims.stop();
var gameOverText = this.add.text(game.config.width / 2, game.config.height / 2,"GAME OVER",{fontFamily: "Arial",fontSize: 60,color: "#3a3b45"});
gameOverText.setOrigin(0.5);
this.tweens.add({targets: gameOverText,duration: 300,y:game.config.height / 2-200}, this);
this.time.addEvent({
delay: 5000,
callbackScope: this,
callback: function(){
this.startGame();
}
});
}
setDisplay(){
this.stageText.setText("STAGE "+stage);
// 플레이어 진행률 텍스트 업데이트
this.levelText.setText(this.paintedRatio + "%");
this.jumpPowerText.setText("JumpPower:"+gameOptions.jumpForce[0]+(BUFF.jumpPowerTime > 0?" X"+BUFF.jumpPower:""));
this.speedText.setText("Speed:"+this.player.speed+(BUFF.speedTime > 0?" X"+BUFF.speed:""));
this.hpText.setText("Hp:"+Math.round(this.player.hp));
//this.pointTitle.setText('Point:'+player_point);
this.scoreText.setText('Score:'+score)
// this.gameInfoText.setText("JumpPower:"+gameOptions.jumpForce[0]+
// "\nSpeed:"+this.player.speed+
// "\nHp:"+this.player.hp
// )
}
playerOverlap(player, mob){
if(GAMESTATE.state != 'death'){
player.hp = player.hp - mob.atk;
this.hpText.setColor("#ff0000");
this.time.addEvent({delay: 500,callbackScope: this,callback: function(){this.hpText.setColor("#ffffff");}});
if(GAMESTATE.state != 'death' && player.hp <= 0 ){
this.gameOver();
}
}
}
jumping(){
// 2회 미만 점프
if(this.player.jumps < 2){
this.player.anims.play('jump');
this.jumpAudio.play({volume:gameOptions.gameVolume});
this.player.jumps ++;
this.player.jumpForce = gameOptions.jumpForce[this.player.jumps - 1] * BUFF.jumpPower; //jumpForce: [12, 8] 1회,2회
this.player.hp-=20;
}
}
getXY(currentAngle, dist){
let radians = this.getRadians(currentAngle); //라디안으로 변환
return {x: game.config.width / 2 + dist * Math.cos(radians),y:game.config.height / 2 + dist * Math.sin(radians)}
}
getRadians(currentAngle){
return Phaser.Math.DegToRad(currentAngle);
}
// 페이저 각도를 보다 읽기 쉬운 각도로 변환하는 방법
getGameAngle(angle){
let gameAngle = angle + 90;
if(gameAngle < 0){
gameAngle = 360 + gameAngle
}
return gameAngle;
}
mergeIntervals(intervals){
if(intervals.length <= 1){
return intervals;
}
let stack = [];
let top = null;
intervals = intervals.sort(function(a, b){
return a[0] - b[0]
});
stack.push(intervals[0]);
for(let i = 1; i < intervals.length; i++){
top = stack[stack.length - 1];
if(top[1] < intervals[i][0]){
stack.push(intervals[i]);
}
else{
if (top[1] < intervals[i][1]){
top[1] = intervals[i][1];
stack.pop();
stack.push(top);
}
}
}
return stack;
}
init_btn(){
let sc_width = game.config.width / 2+300
let sc_height = (game.config.height / 2);
this.startBtn = this.add.sprite(sc_width, 50, 'startBtn').setInteractive();
this.startBtn.on('pointerdown', function () { this.startGame(); },this ); // Start game on click
}
playerStatUp(){
let num = this.getRandom(1,3)
let numText;
let numUp;
if(num == 1){
numUp=10;
this.player.speed+=numUp;
gameOptions.playerSpeed+=numUp;
numText = "Speed +"+numUp
}else if(num == 2 ){
numUp=0.5;
gameOptions.jumpForce[0]= gameOptions.jumpForce[0]+0.5;
numText = "Jump Power +"+numUp
}else if(num == 3 ){
numUp=0.1;
gameOptions.playerRecovery+=0.3;
numText = "HP Recovery +"+numUp
}
let sc_width = game.config.width / 2;
let sc_height = (game.config.height / 2);
this.powerUp1Audio.play({volume:gameOptions.gameVolume});
this.noticeTween(numText+' UP',sc_width, sc_height,{fontFamily: "Arial",fontSize: 33,color: "#1cc88a"});
}
noticeTween(message, sc_width, sc_height, config){
var noticeObj = this.add.text(sc_width, sc_height+160,message,config);
noticeObj.setOrigin(0.5);
var timeline = this.tweens.timeline({
tweens: [{
targets: noticeObj,
y:sc_height-200,
duration: 100,
ease: 'Cubic.easeInOut'
},
{
targets: noticeObj,
y:-100,
duration: 300,
delay: 1000
}]
});
}
init_audio(){
// this.musicAudio = this.sound.add('forest');
// this.musicAudio.play({volume:volume:gameOptions.gameVolume});
// this.musicAD.setLoop(true);
this.jumpAudio = this.sound.add('bong_001');
this.deathAudio = this.sound.add('death');
this.gameOverAudio = this.sound.add('gameOverAudio');
this.powerUp1Audio = this.sound.add('powerUp1');
}
init_display(){
let sc_width = game.config.width / 2;
let sc_height = (game.config.height / 2);
let fontConfig = {fontFamily: "Arial",fontSize: 50,color: "#ffffff"}
// 플레이어 진행 상황을 표시하는 텍스트
this.stageText = this.add.text(sc_width, 50, "STAGE "+stage, fontConfig);
fontConfig.fontSize = 20;
this.scoreText = this.add.text(50, 25,'Score:'+score,fontConfig);
fontConfig.fontSize = 69;
this.levelText = this.add.text(sc_width, sc_height-75, "", fontConfig);
fontConfig.fontSize = 25;
//this.gameInfoText = this.add.text(sc_width, sc_height,'',fontConfig);
this.jumpPowerText = this.add.text(sc_width, sc_height,'',fontConfig);
this.speedText = this.add.text(sc_width, sc_height+30,'',fontConfig);
this.hpText = this.add.text(sc_width, sc_height+60,'',fontConfig);
this.stageText.setOrigin(0.5);
this.levelText.setOrigin(0.5);
//this.gameInfoText.setOrigin(0.5);
this.jumpPowerText.setOrigin(0.5);
this.speedText.setOrigin(0.5);
this.hpText.setOrigin(0.5);
}
init_player(){
this.player.currentAngle = this.getRandom(1,90) * this.getMinus_or_Plus(); // 플레이어 현재 각도
this.player.previousAngle = this.player.currentAngle; // 플레이어 이전 각도
this.player.jumpOffset = 0; // 점프 오프셋, 점프 중 지면과 거리
this.player.jumps = 0; //점프 횟수
this.player.jumpForce = 0; // 현재 점프포스파워
this.player.speed = gameOptions.playerSpeed;
this.player.hp = gameOptions.playerHp;
this.player.timer = 0;
}
getRandom(idx1, idx2){
return (Math.floor(Math.random() *idx2)+idx1)
}
getMinus_or_Plus(){
return (Math.floor(Math.random() * 2)==0?-1:1)
}
//회전
mobAngle(currentAngle){
return currentAngle* (gameOptions.bigCircleRadius / gameOptions.mobRadius + 1)*0.1;
}
}
현재글 : Around Runner Game - HTML5
Comments
Login: