Игра: Цветной понг на CSS3 и Сanvas

Очень простая игра в понг со случайным изменением цвета. Слабо выбить больше 50-и?;)

HTML:

<div id="g"></div>
<div id="shine"></div>
<canvas id="c"></canvas>

<audio preload="true" id="snd">
	<source src="http://www.mcalister.ch/lab/colorpong/c.wav"/>
</audio>

<div id="link"><a href="http://www.lemu.ch">www.lemu.ch</a></div>

CSS:

html, body {
  width:  100%;
  height: 100%;
  margin: 0px;
  padding: 0px;
  text-align: center;
}

#g{
  position:absolute;
	width:100%;
	height:100%;

	background: -moz-linear-gradient(top,  rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 100%);
	background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,rgba(255,255,255,0)), color-stop(100%,rgba(255,255,255,0.25)));
	background: -webkit-linear-gradient(top,  rgba(255,255,255,0) 50%,rgba(255,255,255,0.25) 100%);
	background: -o-linear-gradient(top,  rgba(255,255,255,0) 50%,rgba(255,255,255,0.25) 100%);
	background: -ms-linear-gradient(top,  rgba(255,255,255,0) 50%,rgba(255,255,255,0.25) 100%);
	background: linear-gradient(to bottom,  rgba(255,255,255,0) 50%,rgba(255,255,255,0.25) 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#40ffffff',GradientType=0 );
}  

#c{
  margin:-150px 0 0 -200px;
  position:absolute;
  top:50%;
	left:50%;
  -moz-box-shadow: 0 0 3px 0px rgba(0,0,0,0.4);
  -webkit-box-shadow: 0 0 3px 0px rgba(0,0,0,0.4);
  -o-box-shadow: 0 0 3px 0px rgba(0,0,0,0.4);
  box-shadow: 0 0 3px 0px rgba(0,0,0,0.4);
  border:5px solid #262626;
  -webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(70%, transparent), to(rgba(255,255,255,0.15)));
}

#shine{
    width:400px;
    height:300px;
    position:absolute;
    top:50%;
    left:50%;
    margin-left:-195px;
    margin-top:-145px;
	z-index:9999;
	background-image:url(http://css-live.ru/Primer/tricks/bg.png);
	opacity:0.4;
}

#link{
	position:absolute;
	right:10px;
	bottom:10px;
}

#link a{
	color:#262626;
	text-shadow:0 1px 1px rgba(255,255,255,0.3);
	text-decoration:none;
	font-size:10px;
	font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
	transition:font-size 0.2s ease-in-out;
}

#link a:hover{
	font-size:14px;
}

JavaScript:

/////////////////////////////
//     Color Pong v0.1     //
//   by Brian Mc Alister   //
//                         //
//    work in progress     //
/////////////////////////////

// init canvas
var canvas = document.getElementById("c");
var ctx= canvas.getContext("2d");
canvas.width = 400;
canvas.height = 300;

// set global vars
var score = 0;
var highscore = 0;
var collision = false;
var fl = 0;
var fr = 0;
var logo = new Image();   // Create new img element
logo.src = "http://css-live.ru/Primer/tricks/lemu.png";
snd =  document.getElementById("snd");

// function for random color
function randcol(){

  // random 70 through 255 (so its never too dark)
  var start = 70;
  return start + Math.round(Math.random() * (255-start));
}

// initialize objects
var bar = {
  height: 5,
  width: 70,
  x: 0,
  y: canvas.height-this.height,
  r: 255,
  g: 255,
  b: 255
}

var ball = {
  y: 0,
  x: 0,
  width: 5,
  height: 5,
  speedx: 200,
  speedy: -200
}

var ball2 = {
  width: ball.width,
  height: ball.height,
  x: ball.width*2*(-1),
  y: ball.height*2*(-1),
  r: 255,
  g: 255,
  b: 255,
  a: 1
}

var reset = function () {

  //initialize bar on left
  bar.x=0;
  bar.y=canvas.height-bar.height;

  //set speed so ball goes up first
  ball.speedy = -200;
  ball.speedx = 200;

  // reset score
  score = 0;

  // Place ball on screen randomly (halfway on y axis)
  ball.x = (Math.random() * (canvas.width - 5));
  ball.y = (canvas.width/2)-(ball.height/2);
};

function resetball2(){
  // hide ball2
  ball2.x=ball2.width*(-1);
  ball2.y=ball2.height*(-1);

  //set same size as ball
  ball2.width=ball.width;
  ball2.height=ball.height;

  // get random color
  ball2.r = randcol();
  ball2.g = randcol();
  ball2.b = randcol();

  // set alpha = 1
  ball2.a = 1;
}

// function for updating bar X position
function follow(e)
{
  v = e.pageX - canvas.offsetLeft -bar.width/2;
  if (v < 0){v = 0;}
  if (v > canvas.width-bar.width){v = canvas.width-bar.width;}

  bar.x = v;
}

// update bar x position
window.addEventListener("mousemove",follow,false);

var update = function (modifier) {

//update ball position
ball.x = ball.x+(ball.speedx*modifier);
ball.y= ball.y+(ball.speedy*modifier);

// collision ball
if (collision == true){
if (ball2.a > 0){ball2.width = ball2.width+1000*modifier;
ball2.height=ball2.height+1000*modifier;
ball2.x = ball.x;
ball2.y = ball.y;
ball2.a = ball2.a - 2*modifier;

}else{
collision = false;
resetball2();
}
}

// Is ball touching top?
if (ball.y <= (0) && ball.speedy < 0) {

  //change direction
  ball.speedy = ball.speedy * -1;

}

// Is ball touching left
if (ball.x <= (0) && ball.speedx < (0)){
  ball.speedx = ball.speedx * -1;
}

// Is ball touching right
if (ball.x >= (canvas.width-ball.width) && ball.speedx > (0)){
  ball.speedx = ball.speedx * -1;
}

// Is ball touching bar?
if (
  ball.x+ball.width >= (bar.x)
  && ball.x <= (bar.x+bar.width)
  && ball.y+ball.height >= (bar.y)
  && ball.speedy > 0
) {
  // reset sound and play
  snd.currentTime = 0;
  snd.play();

  // update score
  ++score;
  if (score > highscore){highscore = score;}

  // increase speed
  // boost X if ball hits corner of bar
  if(ball.x+ball.width <= (bar.x+ball.width*2)){

    // define flick size
    fl = 10+(ball.width*2-((ball.x+ball.width)-bar.x))*5;

    // always flick ball left
    if(ball.speedx < 0){ball.speedx = ball.speedx-fl;}
  	if(ball.speedx > 0){ball.speedx = ball.speedx*(-1)-fl;}
  }else if(ball.x >= (bar.x+bar.width-ball.width*2)){

  	// define flick size
    fr = 10+(ball.width*2-((ball.x+ball.width)-(bar.x+bar.width)))*5;

    // always flick ball right
    if(ball.speedx < 0){ball.speedx = ball.speedx*(-1)+fr;}
  	if(ball.speedx > 0){ball.speedx = ball.speedx+fr;}
  }else{
    // Randomize x speed on central hit ((-20) to 20)
    ball.speedx = ball.speedx + ((Math.random()*40)-20);
  }

  // update Y speed
  ball.speedy = ball.speedy +20;

  //change y direction of ball
  ball.speedy = ball.speedy * -1;

  //set collision true
  collision=true;

  //reset / initialize ball2
  resetball2();
  //set color
  bar.r = ball2.r;
  bar.g = ball2.g;
  bar.b = ball2.b;

  // set background color
  document.body.style.background = "rgb("+bar.r+","+bar.g+","+bar.b+")";
}

// Is ball touching bottom?
if (ball.y >= (canvas.height-ball.height) && ball.speedy > 0) {
  reset();
}

};

// Draw everything
var render = function () {

// set dark grey bg
ctx.fillStyle   = '#262626';
ctx.fillRect(0,0,canvas.width,canvas.height);

// set logo
ctx.drawImage(logo,canvas.width/2-logo.width/2,canvas.height/2-logo.height/2);

// draw ball2 (collision effect)
ctx.beginPath();
ctx.fillStyle   = "rgba("+ball2.r+","+ball2.g+","+ball2.b+","+ball2.a+")";
//ctx.fillRect(ball2.x,ball2.y,ball2.width,ball2.height);
ctx.arc(ball2.x+ball.width,bar.y,ball2.width,ball2.height, Math.PI*2, true);
ctx.fill();
ctx.closePath();

// draw ball
ctx.fillStyle   = "rgb("+bar.r+","+bar.g+","+bar.b+")";
ctx.fillRect(ball.x,ball.y,ball.width,ball.height);

// draw bar
ctx.fillStyle   = "rgb("+bar.r+","+bar.g+","+bar.b+")";
ctx.fillRect(bar.x,bar.y,bar.width,bar.height);

// Score
ctx.fillStyle = "rgb(250, 250, 250)";
ctx.font = "12px Helvetica";
ctx.textAlign = "right";
ctx.textBaseline = "top";
ctx.fillText("score: " + score, canvas.width-10, 23);

// HighScore
ctx.fillStyle = "rgb(250, 250, 250)";
ctx.font = "bold 12px Helvetica";
ctx.textAlign = "right";
ctx.textBaseline = "top";
ctx.fillText("best: " + highscore, canvas.width-10, 10);

};

var main = function () {
var now = Date.now();
var delta = now - then;

update(delta / 1000);
render();

then = now;
};

reset();
var then = Date.now();
setInterval(main, 1);
  • Internet Explorer 9 и ниже.

А вот и пример

Перевод статьи Color Pong Game с сайта cssdeck.com, автор brian.

P.S. Это тоже может быть интересно:

25 Комментарии

  1. Cypher

    Здорово. Взаимодействие со страницей, фоном классное :)
    Игра не понг, а арканойд.

    1. psywalker (Автор записи)

      Арканоид — это немного иная штука. В арканоиде нужно сбивать кирпичи/плитки, которые находятся вверху. А понг — это другое. Это симулятор пинг-понга на компе. Так же её часто можно встретить на консолях и в игровых автоматах.

      Кстати, если я не ошибаюсь, Вадим Макеев, любитель понга)

  2. kolobok-smile

    уфф максимум 11 вибил )))

    1. psywalker (Автор записи)

      Что так мало? Тренируйся ещё! К утру должно быть не меньше 30, ок?

  3. S-senj

    я на буке пальцем 14 выбил :) если бы мышью, 20-25 легко бы делал
    спасибо ) повеселили

  4. Tatiana

    Игра опасная можно на долго зависнуть:)

    1. psywalker (Автор записи)

      Ну да:) Скока у тя рекорд?)

  5. Tatiana

    :) Покамест 10 но буду стараться.

    1. psywalker (Автор записи)

      Чё, и всё?? Тока десятку?)) Давай тренируйся, ты чё) Минимум 30 должно быть :)

  6. Tatiana

    Максим вы меня в краску загнали нужно же и поработать ;)

    1. psywalker (Автор записи)

      Может на "Ты" лучше?) Не первый же день знакомы в сети. Да и потом, это ж всё-таки инет, а не улица:)

      Конечно поработайте! А потом снова за дело :)

  7. Tatiana

    А тема то увлекла, уже хочеться самой написать такую плюшку.  CSS live вдохновил :-)

    1. psywalker (Автор записи)

      Кстати, да. У меня тоже была идея вот на днях воскресить и допилить Арканоид на канвасе, который мы когда-то делали с дружищем одним) Если время найду, займусь им :)

      А вот эту штуку, если будешь делать, то допили стрелки клавы для биты:)

  8. Tatiana

    Было бы интересно эту работу увидеть:)

    1. psywalker (Автор записи)

      Нее, выставлять на всеобщее обозрение пока не хочу) + с последними появившимимся в API канваса новыми методами, имхо, алгоритмы и код можно оптимизировать. Так что могу показать… например, на вк в лс?)

  9. Tatiana

    Да было бы интересно )

  10. Tatiana

    А счет увелился, уже 14, растем :)

  11. Павел Тринько

    Смотрю, что я здесь самый умелый — 34! :D И не со 100500 раза… ;)

    1. Catherine

      И это написал человек 20.11.2012 в 17:58, буквально через 3 дня после публикации =)  Согласна, не со 100500 раза, а чуть меньше, всего лишь несколько дней непрерывных тренировок.
      Кто больше?

      1. psywalker (Автор записи)

        Я когда второй раз фигачил изначально, набрал 31)) Больше после этого у меня набрать не удавалось)) Но я особо и не пытался :)

        Да, выходит, что Пашка ща самый крутяк из нас :)

      2. Павел Тринько

        Catherine, я писал комментарий к посту на Facebook сразу после её публикации. А сюда я просто забыл зайти ;)

  12. Tatiana

    А я не заморачивалась со второго раза набра 14 с меня хватит. А потчетный вымпел  Павлу. ;-)

    1. Павел Тринько

      Ну и правильно, что не заморачивались… А за вымпел — спасибо! :)

  13. Sergey

    Я набрал 39 со второго раза!!))

  14. int

    На 25 точка начинает двоиться.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.