敵キャラゴーストをグレードアップしました。
色分けと、パワーボールを取った時の困ったチャン表示です。
ソースコード
ghost.html
<link rel='stylesheet' href='multi_ghost.css' />
<script src='multi_ghost.js'></script>
<style>body{background-color:black}</style>
<div class='ghost' data-color='1' data-status='weak'>
<div class='head'></div>
<div class='face'>
<div class='eye-left'></div>
<div class='eye-right'></div>
<svg class='mouse' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 10">
<path
fill='none'
stroke='white'
stroke-width='4'
d="M 15,7 Q 15,7 17.5,3 T 25,5 35,5 45,5 55,5 65,5 75,5 85,7">
<animate
attributeName='d'
dur='800ms'
repeatCount='indefinite'
calcMode="linear"
values='M 15,7 Q 15,7 17.5,3 T 25,5 35,5 45,5 55,5 65,5 75,5 85,7;
M 15,3 Q 15,3 17.5,7 T 25,5 35,5 45,5 55,5 65,5 75,5 85,3;
M 15,7 Q 15,7 17.5,3 T 25,5 35,5 45,5 55,5 65,5 75,5 85,7;' />
</path>
</svg>
</div>
<div class='under'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 30">
<path d="M 0,0 Q 0,15 5,20 T 20,15 40,15 60,15 80,15 100,15 L 100,0">
<animate
attributeName='d'
dur='500ms'
repeatCount='indefinite'
calcMode="linear"
values='M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 25,15 45,15 65,15 85,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;' />
</path>
</svg>
</div>
</div>
<div class='ghost' data-color='1'>
<div class='head'></div>
<div class='face'>
<div class='eye-left'></div>
<div class='eye-right'></div>
</div>
<div class='under'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 30">
<path fill='red' d="M 0,0 Q 0,15 5,20 T 20,15 40,15 60,15 80,15 100,15 L 100,0" fill='red'>
<animate
attributeName='d'
dur='500ms'
repeatCount='indefinite'
calcMode="linear"
values='M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 25,15 45,15 65,15 85,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;' />
</path>
</svg>
</div>
</div>
<div class='ghost' data-color='2'>
<div class='head'></div>
<div class='face'>
<div class='eye-left'></div>
<div class='eye-right'></div>
</div>
<div class='under'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 30">
<path d="M 0,0 Q 0,15 5,20 T 20,15 40,15 60,15 80,15 100,15 L 100,0">
<animate
attributeName='d'
dur='500ms'
repeatCount='indefinite'
calcMode="linear"
values='M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 25,15 45,15 65,15 85,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;' />
</path>
</svg>
</div>
</div>
<div class='ghost' data-color='3'>
<div class='head'></div>
<div class='face'>
<div class='eye-left'></div>
<div class='eye-right'></div>
</div>
<div class='under'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 30">
<path d="M 0,0 Q 0,15 5,20 T 20,15 40,15 60,15 80,15 100,15 L 100,0">
<animate
attributeName='d'
dur='500ms'
repeatCount='indefinite'
calcMode="linear"
values='M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 25,15 45,15 65,15 85,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;' />
</path>
</svg>
</div>
</div>
<div class='ghost' data-color='4'>
<div class='head'></div>
<div class='face'>
<div class='eye-left'></div>
<div class='eye-right'></div>
</div>
<div class='under'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 30">
<path d="M 0,0 Q 0,15 5,20 T 20,15 40,15 60,15 80,15 100,15 L 100,0">
<animate
attributeName='d'
dur='500ms'
repeatCount='indefinite'
calcMode="linear"
values='M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 25,15 45,15 65,15 85,15 100,15 L 100,0;
M 0,0 Q 0,15 5,20 T 15,15 35,15 55,15 75,15 100,15 L 100,0;' />
</path>
</svg>
</div>
</div>
multi_ghost.css
.ghost{
--size-chara : 80px;
--size-width : calc(var(--size-chara) * 1.0);
--size-eye : calc(var(--size-width) * 0.3);
--size-under : calc(var(--size-width) * 0.2);
--color-body : red;
margin:50px;
width:var(--size-chara);
height:var(--size-chara);
}
.ghost[data-color='1']{--color-body : red;}
.ghost[data-color='2']{--color-body : orange;}
.ghost[data-color='3']{--color-body : lightblue;}
.ghost[data-color='4']{--color-body : pink;}
.ghost[data-status='weak']{--color-body : blue;}
.ghost > *{
margin : 0 auto;
width : var(--size-width);
}
.ghost > .head{
height : calc(var(--size-width) / 2);
background-color : var(--color-body);
border-radius : var(--size-chara) var(--size-chara) 0 0;
}
.ghost > .face{
height : 30%;
background-color : var(--color-body);
position:relative;
}
.ghost > .face > .eye-left,
.ghost > .face > .eye-right{
position:absolute;
top:-15px;
background-color:white;
width : var(--size-eye);
height : var(--size-eye);
background-color:white;
border-radius:50%;
}
.ghost > .face .eye-left{
left:13%;
}
.ghost > .face .eye-right{
right:13%;
}
.ghost:not([data-status='weak']) > .face > *::before{
content:'';
display:block;
background-color:black;
width : 50%;
height : 50%;
margin : 25%;
border-radius:50%;
transition-property : margin;
transition-duration : 0.3s;
}
.ghost:not([data-status='weak']) > .face[data-direction='right'] > *::before{
margin-left : 50%;
margin-right : 0;
}
.ghost:not([data-status='weak']) > .face[data-direction='left'] > *::before{
margin-left : 0;
margin-right : 50%;
}
.ghost:not([data-status='weak']) > .face[data-direction='top'] > *::before{
margin-top : 0;
margin-bottom : 50%;
}
.ghost:not([data-status='weak']) > .face[data-direction='bottom'] > *::before{
margin-top : 50%;
margin-bottom : 0;
}
.ghost[data-status='weak'] > .face > .eye-left,
.ghost[data-status='weak'] > .face > .eye-right{
width : calc(var(--size-eye) / 2);
height : calc(var(--size-eye) / 2);
background-color:white;
border-radius:50%;
}
.ghost[data-status='weak'] > .face > .eye-left{
left:25%;
}
.ghost[data-status='weak'] > .face > .eye-right{
right:25%;
}
.ghost[data-status='weak'] > .face > .mouse{
margin-top:10px;
}
.ghost > .under{
height : var(--size-under);
}
.ghost > .under path{
fill:var(--color-body);
}
multi_ghost.js
function change_eye(){
this.directions = ['right','left','top','bottom']
this.direction = this.directions[0]
this.change()
}
change_eye.prototype.change = function(){
const elms = document.querySelectorAll('.ghost .eye')
for(const elm of elms){
const num = Math.floor(Math.random() * this.directions.length)
elm.setAttribute('data-direction' , this.directions[num])
}
setTimeout(this.change.bind(this) , 2000)
}
switch(document.readyState){
case 'complete':
case 'interactice':
new change_eye()
break
default:
window.addEventListener('load' , (()=>{
new change_eye()
}))
}
デモ
解説
javascriptもcssも前回の設定から若干変更を加えています。
色分けするため、svgに直接付けていた色(赤色)をcssでタイプ別にセット出来るようにしています。
javascriptも、複数の敵キャラが同時に目がキョロキョロするように対応しました。
パワーボールじを食べた時の敵キャラ(青色)は、口を加えていますが、これらはすべて同じhtml構造にするので、今回のcssには記載してませんが、本番ではdata-status='week'の状態以外では非表示になるようにします。
口の波アニメが体の裾部分と同じくあまり気に入った動きをしていないんですが、このへんはこだわって時間を掛けるよりも、今回は進行優先で進めたいと思います。
キャラタイプによって、アニメーションのタイミングなどを切り替えると、もっと動きにフラクラル感が出ていいかもしれませんね。
作り終わるとこうした気づきもあるので、一旦作って自己評価するというのも重要という事がよく分かります。
知財
パックマンは、バンダイナムコ社の登録商標です。
PAC-MAN™ & ©1980 BANDAI NAMCO Entertainment Inc.
0 件のコメント:
コメントを投稿