Doodle jump онлайн на HTML5

Doodle jump онлайн на HTML5

02012-08-2857845Денис Абдуллин

Открытый исходный код, копируйте, и на вашем сайте будет Doodle jump онлайн на HTML5. Если HTML5 не поддерживается, то будет выведено сообщение. Игра очень популярная, в нее играют не только на переменах в школе, можно играть и на компьютере, онлайн. Автор данного кода Kushagra Agarwal, перевод и звуки добавил Denis Abdullin.

Я добавил звуки, а то без них скучновато. Т.е. автор сделал изначально без звуков, пришлось покопаться в игре и коде, чтобы добавить этот «пук-пук» и звук пружинки, и хотя бы звук падения.

Код HTML



Code
<div class="container">
  <canvas id="canvas">
  Ой, ваш браузер не поддерживает HTML5!
  </canvas>

  <div id="mainMenu">
  <h1>doodle jump</h1>
  <h3>на HTML5,</h3>
  <h3>...от <a href="http://twitter.com/solitarydesigns/" target="_blank">Kushagra Agarwal</a></h3>

  <p class="info">
  Используйте
  <span class="key left"><</span>
  <span class="key right">></span>
  и space, чтобы начать заново
  </p>
  <a class="button" href="javascript:init()">Play</a>
  </div>
   
  <div id="gameOverMenu">
  <h1>Вы проиграли!</h1>
  <h3 id="go_score">Ваш результат 0 очков</h3>

  <a class="button" href="javascript:reset()">Заново</a>

  </div>
   
   
  <!-- Preloading image <img rel="usm" src="http://yraaa.ru/smiles/wink.gif" border="0" align="absmiddle" alt=";)" /> -->
  <img id="sprite" src="images/2WEhF.png"/>

  <div id="scoreBoard">
  <p id="score">0</p>
  </div>

  </div>

<div id="audio"></div>

Код JavaScript



Code
<script type="text/javascript">
// RequestAnimFrame: a browser API for getting smooth animations
window.requestAnimFrame = (function() {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
  function(callback) {
  window.setTimeout(callback, 1000 / 60);
  };
})();

var canvas = document.getElementById('canvas'),
  ctx = canvas.getContext('2d');

var width = 422,
  height = 552;

canvas.width = width;
canvas.height = height;

//Variables for game
var platforms = [],
  image = document.getElementById("sprite"),
  player, platformCount = 10,
  position = 0,
  gravity = 0.2,
  animloop,
  flag = 0,
  menuloop, broken = 0,
  dir, score = 0, firstRun = true;

//Base object
var Base = function() {
  this.height = 5;
  this.width = width;

  //Sprite clipping
  this.cx = 0;
  this.cy = 614;
  this.cwidth = 100;
  this.cheight = 5;

  this.moved = 0;

  this.x = 0;
  this.y = height - this.height;

  this.draw = function() {
  try {
  ctx.drawImage(image, this.cx, this.cy, this.cwidth, this.cheight, this.x, this.y, this.width, this.height);
  } catch (e) {}
  };
};

var base = new Base();

//Player object
var Player = function() {
  this.vy = 11;
  this.vx = 0;

  this.isMovingLeft = false;
  this.isMovingRight = false;
  this.isDead = false;

  this.width = 55;
  this.height = 40;

  //Sprite clipping
  this.cx = 0;
  this.cy = 0;
  this.cwidth = 110;
  this.cheight = 80;

  this.dir = "left";

  this.x = width / 2 - this.width / 2;
  this.y = height;

  //Function to draw it
  this.draw = function() {
  try {
  if (this.dir == "right") this.cy = 121;
  else if (this.dir == "left") this.cy = 201;
  else if (this.dir == "right_land") this.cy = 289;
  else if (this.dir == "left_land") this.cy = 371;

  ctx.drawImage(image, this.cx, this.cy, this.cwidth, this.cheight, this.x, this.y, this.width, this.height);
  } catch (e) {}
  };

  this.jump = function() {
  this.vy = -8;
  document.getElementById('audio').innerHTML='<audio src="sounds/pup.mp3" preload="auto" autoplay autobuffer></audio>'
  };

  this.jumpHigh = function() {
  this.vy = -16;
  document.getElementById('audio').innerHTML='<audio src="sounds/high.mp3" preload="auto" autoplay autobuffer></audio>'
  };

};

player = new Player();

//Platform class

function Platform() {
  this.width = 70;
  this.height = 17;

  this.x = Math.random() * (width - this.width);
  this.y = position;

  position += (height / platformCount);

  this.flag = 0;
  this.state = 0;

  //Sprite clipping
  this.cx = 0;
  this.cy = 0;
  this.cwidth = 105;
  this.cheight = 31;

  //Function to draw it
  this.draw = function() {
  try {

  if (this.type == 1) this.cy = 0;
  else if (this.type == 2) this.cy = 61;
  else if (this.type == 3 && this.flag === 0) this.cy = 31;
  else if (this.type == 3 && this.flag == 1) this.cy = 1000;
  else if (this.type == 4 && this.state === 0) this.cy = 90;
  else if (this.type == 4 && this.state == 1) this.cy = 1000;

  ctx.drawImage(image, this.cx, this.cy, this.cwidth, this.cheight, this.x, this.y, this.width, this.height);
  } catch (e) {}
  };

  //Platform types
  //1: Normal
  //2: Moving
  //3: Breakable (Go through)
  //4: Vanishable  
  //Setting the probability of which type of platforms should be shown at what score
  if (score >= 5000) this.types = [2, 3, 3, 3, 4, 4, 4, 4];
  else if (score >= 2000 && score < 5000) this.types = [2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4];
  else if (score >= 1000 && score < 2000) this.types = [2, 2, 2, 3, 3, 3, 3, 3];
  else if (score >= 500 && score < 1000) this.types = [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3];
  else if (score >= 100 && score < 500) this.types = [1, 1, 1, 1, 2, 2];
  else this.types = [1];

  this.type = this.types[Math.floor(Math.random() * this.types.length)];

  //We can't have two consecutive breakable platforms otherwise it will be impossible to reach another platform sometimes!
  if (this.type == 3 && broken < 1) {
  broken++;
  } else if (this.type == 3 && broken >= 1) {
  this.type = 1;
  broken = 0;
  }

  this.moved = 0;
  this.vx = 1;
}

for (var i = 0; i < platformCount; i++) {
  platforms.push(new Platform());
}

//Broken platform object
var Platform_broken_substitute = function() {
  this.height = 30;
  this.width = 70;

  this.x = 0;
  this.y = 0;

  //Sprite clipping
  this.cx = 0;
  this.cy = 554;
  this.cwidth = 105;
  this.cheight = 60;

  this.appearance = false;

  this.draw = function() {
  try {
  if (this.appearance === true) ctx.drawImage(image, this.cx, this.cy, this.cwidth, this.cheight, this.x, this.y, this.width, this.height);
  else return;
  } catch (e) {}
  };
};

var platform_broken_substitute = new Platform_broken_substitute();

//Spring Class
var spring = function() {
  this.x = 0;
  this.y = 0;

  this.width = 26;
  this.height = 30;

  //Sprite clipping
  this.cx = 0;
  this.cy = 0;
  this.cwidth = 45;
  this.cheight = 53;

  this.state = 0;

  this.draw = function() {
  try {
  if (this.state === 0) this.cy = 445;
  else if (this.state == 1) this.cy = 501;

  ctx.drawImage(image, this.cx, this.cy, this.cwidth, this.cheight, this.x, this.y, this.width, this.height);
  } catch (e) {}
  };
};

var Spring = new spring();

function init() {
  //Variables for the game
  var dir = "left",
  jumpCount = 0;
   
  firstRun = false;

  //Function for clearing canvas in each consecutive frame

  function paintCanvas() {
  ctx.clearRect(0, 0, width, height);
  }

  //Player related calculations and functions

  function playerCalc() {
  if (dir == "left") {
  player.dir = "left";
  if (player.vy < -7 && player.vy > -15) player.dir = "left_land";
  } else if (dir == "right") {
  player.dir = "right";
  if (player.vy < -7 && player.vy > -15) player.dir = "right_land";
  }

  //Adding keyboard controls
  document.onkeydown = function(e) {
  var key = e.keyCode;
   
  if (key == 37) {
  dir = "left";
  player.isMovingLeft = true;
  } else if (key == 39) {
  dir = "right";
  player.isMovingRight = true;
  }
   
  if(key == 32) {
  if(firstRun === true)
  init();
  else  
  reset();
  }
  };

  document.onkeyup = function(e) {
  var key = e.keyCode;
   
  if (key == 37) {
  dir = "left";
  player.isMovingLeft = false;
  } else if (key == 39) {
  dir = "right";
  player.isMovingRight = false;
  }
  };

  //Accelerations produces when the user hold the keys
  if (player.isMovingLeft === true) {
  player.x += player.vx;
  player.vx -= 0.15;
  } else {
  player.x += player.vx;
  if (player.vx < 0) player.vx += 0.1;
  }

  if (player.isMovingRight === true) {
  player.x += player.vx;
  player.vx += 0.15;
  } else {
  player.x += player.vx;
  if (player.vx > 0) player.vx -= 0.1;
  }

  //Jump the player when it hits the base
  if ((player.y + player.height) > base.y && base.y < height) player.jump();

  //Gameover if it hits the bottom  
  if (base.y > height && (player.y + player.height) > height && player.isDead != "lol") {
player.isDead = true;
document.getElementById('audio').innerHTML='<audio src="sounds/gameover.mp3" preload="auto" autoplay autobuffer></audio>'
}

  //Make the player move through walls
  if (player.x > width) player.x = 0 - player.width;
  else if (player.x < 0 - player.width) player.x = width;

  //Movement of player affected by gravity
  if (player.y >= (height / 2) - (player.height / 2)) {
  player.y += player.vy;
  player.vy += gravity;
  }

  //When the player reaches half height, move the platforms to create the illusion of scrolling and recreate the platforms that are out of viewport...
  else {
  platforms.forEach(function(p, i) {

  if (player.vy < 0) {
  p.y -= player.vy;
  }

  if (p.y > height) {
  platforms[i] = new Platform();
  platforms[i].y = p.y - height;
  }

  });

  base.y -= player.vy;
  player.vy += gravity;

  if (player.vy >= 0) {
  player.y += player.vy;
  player.vy += gravity;
  }

  score++;
  }

  //Make the player jump when it collides with platforms
  collides();

  if (player.isDead === true) gameOver();
  }

  //Spring algorithms

  function springCalc() {
  var s = Spring;
  var p = platforms[0];

  if (p.type == 1 || p.type == 2) {
  s.x = p.x + p.width / 2 - s.width / 2;
  s.y = p.y - p.height - 10;

  if (s.y > height / 1.1) s.state = 0;

  s.draw();
  } else {
  s.x = 0 - s.width;
  s.y = 0 - s.height;
  }
  }

  //Platform's horizontal movement (and falling) algo

  function platformCalc() {
  var subs = platform_broken_substitute;

  platforms.forEach(function(p, i) {
  if (p.type == 2) {
  if (p.x < 0 || p.x + p.width > width) p.vx *= -1;

  p.x += p.vx;
  }

  if (p.flag == 1 && subs.appearance === false && jumpCount === 0) {
  subs.x = p.x;
  subs.y = p.y;
  subs.appearance = true;

  jumpCount++;
  }

  p.draw();
  });

  if (subs.appearance === true) {
  subs.draw();
  subs.y += 8;
  }

  if (subs.y > height) subs.appearance = false;
  }

  function collides() {
  //Platforms
  platforms.forEach(function(p, i) {
  if (player.vy > 0 && p.state === 0 && (player.x + 15 < p.x + p.width) && (player.x + player.width - 15 > p.x) && (player.y + player.height > p.y) && (player.y + player.height < p.y + p.height)) {

  if (p.type == 3 && p.flag === 0) {
  p.flag = 1;
  jumpCount = 0;
  return;
  } else if (p.type == 4 && p.state === 0) {
  player.jump();
  p.state = 1;
  } else if (p.flag == 1) return;
  else {
  player.jump();
  }
  }
  });

  //Springs
  var s = Spring;
  if (player.vy > 0 && (s.state === 0) && (player.x + 15 < s.x + s.width) && (player.x + player.width - 15 > s.x) && (player.y + player.height > s.y) && (player.y + player.height < s.y + s.height)) {
  s.state = 1;
  player.jumpHigh();
  }

  }

  function updateScore() {
  var scoreText = document.getElementById("score");
  scoreText.innerHTML = score;
  }

  function gameOver() {

  platforms.forEach(function(p, i) {
  p.y -= 12;
  });

  if(player.y > height/2 && flag === 0) {
  player.y -= 8;
  player.vy = 0;
  }  
  else if(player.y < height / 2) flag = 1;
  else if(player.y + player.height > height) {
  showGoMenu();
  hideScore();
  player.isDead = "lol";

  }
  }

  //Function to update everything

  function update() {
  paintCanvas();
  platformCalc();

  springCalc();

  playerCalc();
  player.draw();

  base.draw();

  updateScore();
  }

  menuLoop = function(){return;};
  animloop = function() {
  update();
  requestAnimFrame(animloop);
  };

  animloop();

  hideMenu();
  showScore();
}

function reset() {
  hideGoMenu();
  showScore();
  player.isDead = false;
   
  flag = 0;
  position = 0;
  score = 0;

  base = new Base();
  player = new Player();
  Spring = new spring();
  platform_broken_substitute = new Platform_broken_substitute();

  platforms = [];
  for (var i = 0; i < platformCount; i++) {
  platforms.push(new Platform());
  }
}

//Hides the menu
function hideMenu() {
  var menu = document.getElementById("mainMenu");
  menu.style.zIndex = -1;
}

//Shows the game over menu
function showGoMenu() {
  var menu = document.getElementById("gameOverMenu");
  menu.style.zIndex = 1;
  menu.style.visibility = "visible";

  var scoreText = document.getElementById("go_score");
  scoreText.innerHTML = "Ваш результат " + score + " очков!";
}

//Hides the game over menu
function hideGoMenu() {
  var menu = document.getElementById("gameOverMenu");
  menu.style.zIndex = -1;
  menu.style.visibility = "hidden";
}

//Show ScoreBoard
function showScore() {
  var menu = document.getElementById("scoreBoard");
  menu.style.zIndex = 1;
}

//Hide ScoreBoard
function hideScore() {
  var menu = document.getElementById("scoreBoard");
  menu.style.zIndex = -1;
}

function playerJump() {
  player.y += player.vy;
  player.vy += gravity;

  if (player.vy > 0 &&  
  (player.x + 15 < 260) &&  
  (player.x + player.width - 15 > 155) &&  
  (player.y + player.height > 475) &&  
  (player.y + player.height < 500))
  player.jump();

  if (dir == "left") {
  player.dir = "left";
  if (player.vy < -7 && player.vy > -15) player.dir = "left_land";
  } else if (dir == "right") {
  player.dir = "right";
  if (player.vy < -7 && player.vy > -15) player.dir = "right_land";
  }

  //Adding keyboard controls
  document.onkeydown = function(e) {
  var key = e.keyCode;

  if (key == 37) {
  dir = "left";
  player.isMovingLeft = true;
  } else if (key == 39) {
  dir = "right";
  player.isMovingRight = true;
  }
   
  if(key == 32) {
  if(firstRun === true) {
  init();
  firstRun = false;
  }
  else  
  reset();
  }
  };

  document.onkeyup = function(e) {
  var key = e.keyCode;

  if (key == 37) {
  dir = "left";
  player.isMovingLeft = false;
  } else if (key == 39) {
  dir = "right";
  player.isMovingRight = false;
  }
  };

  //Accelerations produces when the user hold the keys
  if (player.isMovingLeft === true) {
  player.x += player.vx;
  player.vx -= 0.15;
  } else {
  player.x += player.vx;
  if (player.vx < 0) player.vx += 0.1;
  }

  if (player.isMovingRight === true) {
  player.x += player.vx;
  player.vx += 0.15;
  } else {
  player.x += player.vx;
  if (player.vx > 0) player.vx -= 0.1;
  }

  //Jump the player when it hits the base
  if ((player.y + player.height) > base.y && base.y < height) player.jump();

  //Make the player move through walls
  if (player.x > width) player.x = 0 - player.width;
  else if (player.x < 0 - player.width) player.x = width;

  player.draw();
}

function update() {
  ctx.clearRect(0, 0, width, height);
  playerJump();
}  

menuLoop = function() {
  update();
  requestAnimFrame(menuLoop);
};

menuLoop();
</script>

Код CSS



Code
<style type="text/css">
@import url(http://fonts.googleapis.com/css?family=Gloria+Hallelujah);

*{box-sizing: border-box;}

body {
  margin: 0; padding: 0;
  font-family: 'Gloria Hallelujah', cursive;
}

.container {
  height: 552px;
  width: 422px;
  position: relative;
  margin: 20px auto;  
  overflow: hidden;
}

canvas {
  height: 552px;
  width: 422px;
  display: block;
  background: url(images/Y0BMP.png) top left;
}

#scoreBoard {
  width: 420px;
  height: 50px;
  background: rgba(182, 200, 220, 0.7);
  position: absolute;
  top: -3px;
  left: 0;
  z-index: -1;  
  border-image: url(images/5BBsR.png) 100 5 round;
}

#scoreBoard p {
  font-size: 20px;
  padding: 0;
  line-height: 47px;
  margin: 0px 0 0 5px;
}

img {display: none}

#mainMenu, #gameOverMenu {
  height: 100%;
  width: 100%;
  text-align: center;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
}

#gameOverMenu {
  visibility: hidden;
}

h2, h3, h1 {font-weight: normal}
h1 {
  font-size: 60px;  
  color: #5a5816;  
  transform: rotate(-10deg);
  margin: 0px;
}

h3 {text-align: right; margin: -10px 20px 0 0; color: #5e96be}
h3 a {color: #5a5816}

.button {
  width: 105px;
  height: 31px;
  background: url(images/2WEhF.png) 0 0 no-repeat;
  display: block;
  color: #000;
  font-size: 12px;
  line-height: 31px;
  text-decoration: none;
  position: absolute;
  left: 50%;
  bottom: 50px;
  margin-left: -53px;
}

.info {position: absolute; right: 20px; bottom: 00px; margin: 0; color: green}

.info .key {
  width: 16px;
  height: 16px;
  background: url(images/2WEhF.png) no-repeat;
  text-indent: -9999px;
  display: inline-block;
}

.info .key.left {background-position: -92px -621px;}
.info .key.right {background-position: -92px -641px;}
</style>

Создать сайт в uKit Нужен классный сайт для бизнеса?
Воспользуйтесь сервисом uKit. Никакого кода!
Комментарии (5)
Лева Лобов 2012-08-30 в 17:19 / МатериалСпам
Прикольно)
0
Гость 2012-08-28 в 23:24 / МатериалСпам
не знаю баг или нет, но если на месте прыгать он очки все равно плюсует)
1
Гладнев Ярослав 2012-08-28 в 23:29 / МатериалСпам
Естественно баг!
0
olegseniv 2012-08-29 в 03:30 / МатериалСпам
ага
0
Влад Зубаиров 2012-08-29 в 12:34 / МатериалСпам
Есть ещё баг. На 3-4 дудлера. Смотри, в начале перед тем как нажать play, разогнись до такого состояния, чтобы дудлера было 3-4. И потом так таким и останешься. Плюс в том, что когда прыгаешь ты можешь отталкиваться сразу 3-4 дудлерами. Так на много легче :)
0
Чтобы оставить комментарий или отзыв под этой публикацией, войдите или зарегистрируйтесь.