经典街机游戏“街头霸王”对于80后的童鞋们来说一定不陌生。Ken和隆的华丽冲击波、将军的半月斩、春丽的倒挂旋风腿不禁让许多人都回到了童年的美好时光。今天,我们就用jQuery和CSS3技术来还原“街头霸王”的风采。在这个教程中,将制作Ken的移动、跳跃、出拳、出腿、回旋踢、升龙霸和冲击波的动画,你可以通过界面上的按钮或键盘来控制这些动作。还等上面,让我们开始吧!
创建CSS动画
我们将从人物出拳动画开始制作。看下边边的人物Ken的sprite图,我们将使用第三排的人物图片。我们可以用 Photoshop 来制作这张sprite图,确保所有人物图片的尺寸一样大。在这个demo中人物图片都是70像素宽和80像素高。
然后我们需要使用一个<div>来放置游戏人物,这样才能使它动起来:
<div class="ken"></div>
.ken {
width:70px; height:80px; /* exactly the size of an image in our sprite */
background-image:url('../images/sprite.png');
}
注意这里书写的代码中都没有使用浏览器厂商的前缀。现在来写人物出拳的CSS代码:
.punch {
animation: punch steps(4) 0.15s infinite;
}
@keyframes punch {
from { background-position:0px -160px; }
to { background-position:-280px -160px; }
}
我们要做的是使用一个名字为.punch的class来应用人物出拳的动画效果,该动画将图片的background-position在X轴上从0px移动到-280px。这个动画过程被分割为4个部分,steps(4)对应于4副图片,每隔0.15秒显示一幅图片,然后无限循环下去。
最后我们需要一个方法来在其它键被按下时从div.punch中添加和移除class .punch。
$(document).on('keydown', function(e) {
if (e.keyCode === 68) { // 68 is the letter D on the keyboard
$('.ken').addClass('punch');
setTimeout(function() { $ken.removeClass('punch'); }, 150);
}
});
上面的代码是如果按下了“D”键(升龙霸),人物将先使用 jQuery 来 addClass('punch'),然后在延时150毫秒后移除该class(记住我们在CSS动画中有一个0.15秒的延时)。以上就是创建一个人物动作的所有要求。
通过SASS来创建动画
如果你仔细观察的CSS代码,会发现有许多值是不变的。(例如sprite图片的宽度和高度)。在你创建其它动画的时候,会发现有大量的重复代码,非常不变于阅读和管理。SASS能够很好的帮助我们解决这个问题。
首先,我们需要一些基本的@mixins如:animation()和keyframes()。
@mixin animation($params) {
-webkit-animation:$params;
-moz-animation:$params;
-ms-animation:$params;
animation:$params;
}
@mixin keyframes($name) {
@-webkit-keyframes $name { @content }
@-moz-keyframes $name { @content }
@-ms-keyframes $name { @content }
@keyframes $name { @content }
}
我们需要使用变量来存储图片的宽度和高度:
$spriteWidth:70px;
$spriteHeight:80px;
最后我们可以将这些变量进行组合创建一个新的mixin,它将为我们解析和执行背景图片的动画。
@mixin anim($animName, $steps, $animNbr, $animParams){
.#{$animName} {
@content;
@include animation($animName steps($steps) $animParams);
}
@include keyframes($animName) {
from { background-position:0px (-$spriteHeight * ($animNbr - 1)); }
to { background-position:-($spriteWidth * $steps) (-$spriteHeight * ($animNbr - 1)); }
}
}
现在你可以只使用一行代码就可以创建一个人物动作了。
$spriteWidth:70px;
$spriteHeight:80px;
/* punch */
@include anim($animName:punch, $steps:3, $animNbr:3, $animParams:.15s infinite);
/* kick */
@include anim($animName:kick, $steps:5, $animNbr:7, $animParams:.5s infinite);
/* hadoken */
@include anim($animName:hadoken, $steps:4, $animNbr:1, $animParams:.5s infinite);
...
$animNbr是一个非常重要的变量:所有的计算都基于该变量进行。实际上它只是sprite图上该动作所排的位置。我们的第一个例子是出拳,它在sprite图上排在第3行,出腿排在第7行,等等。
为冲击波添加碰撞检测
我们需要一个非常快的循环来做碰撞检测。它没50毫秒检测一次冲击波的位置,然后和某些物体的位置作比较(这里是和屏幕耳的最右边作比较)。如果冲击波的位置比屏幕的宽度大,说明冲击波碰撞了屏幕的边部,我们要立即为它添加一个 .explode class。
var $fireball = $('', { class:'fireball' });
$fireball.appendTo($ken);
var isFireballColision = function(){
return $fireballPos.left + 75 > $(window).width();
};
var explodeIfColision = setInterval(function(){
$fireballPos = $fireball.offset();
if (isFireballColision()) {
$fireball.addClass('explode');
clearInterval(explodeIfColision);
setTimeout(function() { $fireball.remove(); }, 500);
}
}, 50);
小结
基本的制作过程就这么多,我们还可以为它添加一些背景音乐,创建另外一些角色等等。制作一个小游戏就这么简单,你应该发挥自己的无限想象力,相信你一定可以做的更好。