<script>
var canvas, g;
var characterPosX, characterPosY, characterImage, characterR;
var enemyPosX, enemyPosY, enemyImage, enemySpeed, enemyR;
var cloudPosX, cloudPosY, cloudImage, cloudSpeed;
var cloud2PosX, cloud2PosY, cloud2Image, cloud2Speed;
var groundPosX, groundPosY, groundImage, groundSpeed;
var speed,acceleration;
var score;
var scene;
var frameCount;
var darken; // 画面の暗さ
var damageCount;
// シーンを配列に格納
const Scenes = {GameMain: "GameMain", GameOver: "GameOver", GameOpen: "GameOpen", GameDamage: "GameDamage"};
// キャラクター画像を配列に格納
const ImgArray = {
CharaRun1: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220211/20220211130115.png"
,CharaRun2: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220213/20220213165305.png"
,CharaRun3: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220213/20220213165308.png"
,CharaJump: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220216/20220216232026.png"
,CharaWarp1: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220216/20220216000325.png"
,CharaWarp2: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220216/20220216000328.png"
,CharaWarp3: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220216/20220216000332.png"
,CharaDamage: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220216/20220216232029.png"
,Enemy1: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220211/20220211222731.png"
,Cloud1: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220217/20220217234842.png"
,Cloud2: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220217/20220217234839.png"
,imgGround: "https://cdn-ak.f.st-hatena.com/images/fotolife/y/you_key69/20220219/20220219092721.png"
};
onload = function () {
// 描画コンテキストの取得
canvas = document.getElementById("gamecanvas");
g = canvas.getContext("2d");
// 初期化
scene = "";
darken = 0;
// 入力処理の指定
document.onkeydown = keydown;
document.onmousedown = mousedown;
// ゲームループの設定(FPS)
setInterval("gameloop()", 16);
};
// 画面クリックしてスタート
function restart() {
if (scene == "" || scene == Scenes.GameOver) {
scene = Scenes.GameOpen;
open();
}
}
function open() {
// キャラクター表示位置
characterPosX = 70;
characterPosY = 0;
characterImage = new Image();
characterImage.src = ImgArray.CharaWarp1;
// 敵
enemyImage = new Image();
enemyImage.src = "";
// 雲の表示位置
cloudPosX = 300;
cloudPosY = 142;
cloudImage = new Image();
cloudImage.src = ImgArray.Cloud1; // 小
cloud2PosX = 120;
cloud2PosY = 71;
cloud2Image = new Image();
cloud2Image.src = ImgArray.Cloud2; // 大
// スコア初期化
score = 0;
frameCount = 0;
darken = 0;
damageCount = 0;
}
function init() {
// キャラクター表示位置・スピード・半径
characterPosX = 70;
characterPosY = 299;
characterR = 22;
characterImage = new Image();
characterImage.src = ImgArray.CharaRun1;
speed = 0;
acceleration = 0;
// 敵の表示位置・スピード
enemyPosX = 630;
enemyPosY = 308;
enemyR = 18;
enemyImage = new Image();
enemyImage.src = ImgArray.Enemy1;
enemySpeed = 5;
frameCount = 0;
scene = Scenes.GameMain;
}
// キー押下
function keydown(e) {
if (e.keyCode == 74) { // [J]押下時
characterJump();
}
else if (e.keyCode == 72) { // [H]押下時
restart();
}
}
// マウスクリック(タップ)
function mousedown() {
if (scene == Scenes.GameMain) {
characterJump();
}
}
function characterJump() {
if (characterPosY == 299) {
speed = -16; // Y軸の移動スピード
acceleration = 1.2; // 加速度(重力)
}
}
function gameloop() {
update(); // キャラクターの移動
draw(); // キャラクターの描画
}
function update() {
frameCount++;
if (scene == Scenes.GameOpen) {
// 着地するまで下移動
if (characterPosY <= 280) {
characterPosY = characterPosY + 10;
frameCount = 0;
}
else {
//着地モーション
if (frameCount <= 5 ) {
characterImage.src = ImgArray.CharaWarp2;
}
else if (frameCount <= 10 ) {
characterImage.src = ImgArray.CharaWarp1;
}
else if (frameCount <= 15 ) {
characterImage.src = ImgArray.CharaWarp3;
}
else {
characterImage.src = ImgArray.CharaRun1;
// ランニングスタート!
init();
}
}
}
else if (scene == Scenes.GameMain) {
speed = speed + acceleration;
characterPosY = characterPosY + speed;
if (characterPosY > 299) {
characterPosY = 299; // 着地
speed = 0;
acceleration = 0;
}
// 敵が左端まで行ったら戻る
enemyPosX -= enemySpeed;
if (enemyPosX < -100) {
enemyPosX = 240 + Math.floor(Math.random() * 180); // ランダムに出現
score += 100; // 避けたら100pt加算
enemySpeed = 5 + Math.floor(score / 1000); // 1000点毎にスピードアップ
darken = Math.floor(score / 1000) * -20; // 1000点毎に背景色暗くする
}
// 雲の動き(敵の動きと同期)
cloudPosX -= enemySpeed; // 小
if (cloudPosX < -50) {
cloudPosX = 420 + Math.floor(Math.random() * 110); // ランダムに出現
}
cloud2PosX -= enemySpeed; // 大
if (cloud2PosX < -50) {
cloud2PosX = 420 + Math.floor(Math.random() * 80); // ランダムに出現
}
groundPosX -= enemySpeed; // 地面
if (groundPosX < 513) {
groundPosX = 1026; // 左端までいったら戻る
}
// 走る動作
if (characterPosY == 299) {
if (frameCount <= 10 ) {
characterImage.src = ImgArray.CharaRun1;
}
else if (frameCount <= 20 ) {
characterImage.src = ImgArray.CharaRun2;
}
else if (frameCount <= 30 ) {
characterImage.src = ImgArray.CharaRun3;
}
else {
characterImage.src = ImgArray.CharaRun2;
}
}
// ジャンプ動作
else {
characterImage.src = ImgArray.CharaJump;
}
// 当たり判定
var diffX = characterPosX - enemyPosX;
var diffY = characterPosY - enemyPosY;
var distance = Math.sqrt(diffX * diffX + diffY * diffY);
if (distance < characterR + enemyR) {
enemySpeed = 0;
scene = Scenes.GameDamage;
}
else {
// フレームカウントリセット
if (frameCount == 40) {
frameCount = 0;
}
}
}
// ダメージシーン(かつ超過タップによるリセット防止)
else if (scene == Scenes.GameDamage) {
// 後方へ戻す
characterPosX = characterPosX - 1;
// 点滅させる
damageCount ++;
if (damageCount <= 5 || (damageCount > 10 && damageCount <= 15) || (damageCount > 20 && damageCount <= 25)) {
characterImage.src = ImgArray.CharaDamage;
}
else {
characterImage.src = "";
}
// ゲームオーバーシーンへ
if (characterPosX == 0) {
scene = Scenes.GameOver;
}
}
}
function draw() {
// 背景描画
var red = 102 + darken;
var green = 187 + darken;
var blue = 221 + darken;
var rgb = "rgb(" + red + "," + green + "," + blue + ")";
g.fillStyle = rgb;
g.fillRect(0, 0, 420, 326);
/*
g.fillStyle = "rgb(188,153,51)";
g.lineWidth = 3;
g.strokeStyle = 'black';
g.strokeRect(0, 326, 420, 34);
g.fillRect(0, 326, 420, 34);
*/
// 初期画面は文言の表示のみ
if (scene == "") {
g.fillStyle = "rgb(255,255,255)";
g.font = "12pt Arial";
var overLabel = "Click Here or Press [H] to Start";
var overLabelWidth = g.measureText(overLabel).width;
g.fillText(overLabel, 210 - overLabelWidth / 2, 220); // 表示文言,位置指定(x,y)
// 地面
groundPosX = 1026;
groundPosY = 360;
groundImage = new Image();
groundImage.src = ImgArray.imgGround;
g.drawImage(
groundImage,
groundPosX - groundImage.width,
groundPosY - groundImage.height
);
}
else {
// 背景描画(地面・雲)
g.drawImage(
groundImage,
groundPosX - groundImage.width,
groundPosY - groundImage.height
);
g.drawImage(
cloudImage,
cloudPosX - cloudImage.width / 2,
cloudPosY - cloudImage.height / 2
);
g.drawImage(
cloud2Image,
cloud2PosX - cloud2Image.width / 2,
cloud2PosY - cloud2Image.height / 2
);
// キャラクタ描画
g.drawImage(
characterImage,
characterPosX - characterImage.width / 2,
characterPosY - characterImage.height / 2
);
// 敵描画
g.drawImage(
enemyImage,
enemyPosX - enemyImage.width / 2,
enemyPosY - enemyImage.height / 2
);
// スコア描画
g.fillStyle = "rgb(255,255,255)";
g.font = "16pt Arial";
var scoreLabel = "SCORE : " + score;
var scoreLabelWidth = g.measureText(scoreLabel).width;
g.fillText(scoreLabel, 390 - scoreLabelWidth, 40); // 表示文言,位置指定(x,y)
if (scene == Scenes.GameOver) {
// ゲームオーバー表示
g.fillStyle = "rgb(255,255,255)";
g.font = "24pt Arial";
var overLabel = "GAME OVER";
var overLabelWidth = g.measureText(overLabel).width;
g.fillText(overLabel, 210 - overLabelWidth / 2, 180); // 表示文言,位置指定(x,y)
g.fillStyle = "rgb(255,255,255)";
g.font = "12pt Arial";
var overLabel = "Click Here or Press [H] to Restart";
var overLabelWidth = g.measureText(overLabel).width;
g.fillText(overLabel, 210 - overLabelWidth / 2, 220); // 表示文言,位置指定(x,y)
}
}
}
</script>
<canvas id="gamecanvas" width="420" height="360" onclick="restart()"></canvas>