JavaScript でシンプルなクリスマス ゲームを実装する

JavaScript でシンプルなクリスマス ゲームを実装する

序文

クリスマスが近づいており、ホットリストはクリスマスツリーでいっぱいです。どうしてこんなにトラフィックパスワードを見逃すのでしょうか?みんながクリスマスツリーを投稿しているので、私は投稿しません。みんなで遊べるクリスマスゲームをシェアするだけです。コードが長すぎるので、まずはいいねして集めてください。

成果を達成する

シンプルな2Dウェブゲームの制作プロセスには独自のルールがあり、各部分には一定のルーチンがあります。

規則的な部分をまとめてテンプレートを作成します。対応するテンプレートが記述されると、特定のオブジェクトを生成するときに使用できます。

テンプレート、ゲーム全体のプロセスの各機能、各jsファイルには明確な分担があります。記述する前に要約する必要があります。

思いついたことをそのまま書かないでください。結果は同じでも、コードが読みにくく保守しにくくなる可能性があり、アイデアもあまり

クリア。

コード

コードについては特に言うことはありません。コードを貼り付けるだけです。シンプルで直接的です。実行してプレイできる限り、友達と共有したり、楽しみのために自分でプレイしたりできます。ファイルを梱包しましたので、必要な場合は送ってください。

CSSコード

本文 { 背景:rgb(8,8,58);
  マージン:0;
}

#ラッパー{
  幅:500ピクセル;
  左マージン:自動;
  右マージン:自動;
  上マージン:20px;
}

JSコード

​var キャンバス = document.getElementById("キャンバス"),
    ctx = キャンバス.getContext("2d")、
    elfImage = document.getElementById("elf");
グリーンギフトイメージ = document.getElementById("グリーンギフト");
redGiftImage = document.getElementById("red_gift");
blueGiftImage = document.getElementById("blue_gift");
爆弾画像 = document.getElementById("爆弾");
bangImage = document.getElementById("bang");

var x = キャンバスの幅/ 2;
var y = キャンバスの高さ-30;
var dx = 2;
var dy = -2;
定数elfHeight = 70;
定数elfWidth = 55;
var elfX = (canvas.width-elfWidth)/2;
定数elfスピード = 10;
var rightPressed = false;
var leftPressed = false;
var spacePressed = false;
var 生成間隔;
var spawnTimer = 50;
var ギフト = [];
var maxGift = 0;
定数ギフト幅 = 40;
定数ギフト高さ = 40;
var タイマー = 0;
var ギフト回転 = 0;
定数TO_RADIANS = Math.PI/180; 
var スコア = 0;
var 健康 = 3;
定数爆弾確率 = 5;
var elf回転 = 0;
var bangX;
var bangTime;
var 雪の高さ = 6;
var スポーン時間変更間隔 = 3000;
var titleColours = [];

// スノーフレークのもの
var スノーフレーク = [];
定数maxSnowflakes = 80;
定数スノーフレークサイズ = 3;
定数スノーフレーク最小速度 = 1;
定数スノーフレーク最大速度 = 4;
const snowflakeColours = ["rgba(255,255,255,0.95)", "rgba(255,255,255,0.65)","rgba(255,255,255,0.4)"];

定数ゲームモード = {
  タイトル: 'タイトル',
  PLAYING: 「遊んでいる」
  ゲームオーバー: 「ゲームオーバー」
};

var gameMode = gameModes.TITLE;

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

関数keyDownHandler(e) {
  if(e.key == "右" || e.key == "右矢印") {
    右に押す = true;
  }
  そうでない場合(e.key == "左" || e.key == "矢印左") {
    左押下 = true;
  } そうでない場合(e.code == "スペース") {
    スペースが押された = true;
  }
}

関数keyUpHandler(e) {
  if(e.key == "右" || e.key == "右矢印") {
    右に押す = false;
  }
  そうでない場合(e.key == "左" || e.key == "矢印左") {
    左押下 = false;
  } そうでない場合(e.code == "スペース") {
    スペースが押された = false;
  }
}

関数draw() {
  ctx.clearRect(0, 0, キャンバス.幅, キャンバス.高さ);
  雪を描画します。

  タイマー++;

  スイッチ(ゲームモード){
    ケース gameModes.TITLE:
      タイトル画面(); 
      壊す;
    gameModes.GAMEOVERの場合:
      ゲームオーバー();
      壊す;
    gameModes.PLAYINGの場合:
      ゲームループ();
      壊す;
  }
}

関数タイトルスクリーン() {
  タイマーが titleColours.length より大きい場合、タイマーは 0 になります。

  ctx.font = "50px Arial";
  ctx.fillStyle = titleColours[タイマー]; 
  ctx.fillText(`クリスマスプレゼントゲット!`, 0, 50);
  ctx.fillStyle = "黄色"; 

  ctx.font = "30px Arial";
  ctx.fillText(`スペースバーを押して開始してください!`, 65, 140);

  var highScore = getHighScore();
  if (highScore != -1) ctx.fillText(`ハイスコア: ${highScore}`, 90, 220);

  回転画像を描画します(elfImage、canvas.width/2 - elfWidth/2、330、elfRotation、200);
  elf回転+=2;
  elfRotation > 359 の場合、elfRotation = 0;

  if (スペースが押された && タイマー > 5) {
    ゲームモードを設定します(gameModes.PLAYING);
  }
}

関数ゲームループ(){
  スノーパーソンを描画します。
  ギフトを生成します。
  ギフトを処理します();
  床を描画します。
  HUD を描画します。
  エルフを描画します。
  強打を描画します。

  if(右押下) {
    elfX += elf速度;
    elfX + elfWidth > canvas.width の場合{
      elfX = キャンバスの幅 - (elfWidth + 5);
    }
  }
  そうでない場合(左押された場合) {
    elfX -= elf速度;
    (elfX < -15)の場合{
      エルフX = -15;
    }
  }
}

関数gameOver() {
  ctx.font = "50px Arial";
  ctx.fillStyle = "黄色";
  ctx.fillText(`ゲームオーバー!`, 80, 200);
  ctx.font = "30px Arial";
  ctx.fillText(`最終スコア: ${score}`,130, 240);
  ctx.fillText('続行するにはスペースキーを押してください',80, 280);

  if (スペースが押された && タイマー > 5) {
    ゲームを初期化します。
    ゲームモードを設定します(gameModes.TITLE);
  }
}

関数 processGifts() {
  ギフト.forEach((g) => {
    g && g.alive の場合 { 
      // ギフトを抽選する
      ギフトを描画します。
      キャンバスの高さがgyより大きい場合
        g.alive = false;
        if (!g.bomb) スコア --;
      }

      //ギフトを移動する
      g.y+=g速度;

      // ギフトを回転する
      g.rotation+=5;
      g.rotation > 359 の場合、g.rotation = 0 ;

      // 衝突をチェックする
      ((gy + (giftHeight/2)) >= ((canvas.height - elfHeight - snowHeight) + 20) の場合
          && (gy<canvas.height-snowHeight+20)) {
        ((elfX + 25) <= (gx + (giftWidth/2)) && ((elfX+20) + (elfWidth)) >= gx ) の場合
        {
          g.alive = false;
          もし(!g.爆弾) { 
            スコア+=5;
          } それ以外 {
            爆弾衝突を実行します。
          }
        }
      }
    }
  });
}

関数drawGift(g) {
  スイッチ(g.colour){
    ケース1:
      緑色のギフト画像を描画します。
      壊す;
    ケース2:
      g を描画します。
      壊す;
    ケース3:
      g を描画します。
      壊す;
    ケース4:
      回転画像を描画します(bombImage, gx, gy, 180, 45);
      壊す;
  }
}

関数drawColouredGift(colourImage, g) {
  回転画像を描画します(colourImage、gx、gy、g.rotation、35);
}

関数doBombCollision() {
  健康 - ;
  バンX=エルフX;
  バンタイム = 5;
  (健康 == 0)の場合{
    高スコアを設定する();
    ゲームモードを設定します(gameModes.GAMEOVER);
  }
}

関数drawBang() {
  (バンタイム>0)の場合{
    バンタイム--;
    ctx.drawImage(bangImage, bangX, (canvas.height-75)-snowHeight, 75,75);
  }
}


関数drawElf() {
  ctx.drawImage(elfImage, elfX,(canvas.height - elfHeight) - (snowHeight - 2),80,80);
}

関数spawn() {
  var newX = 5 + (Math.random() * (canvas.width - 5));

  var色;
  var 爆弾 = false;

  (ランダムナンバー(1、爆弾チャンス)==爆弾チャンス)の場合{
    色 = 4;
    爆弾 = 真;
  } それ以外 {
    色 = ランダム数値(1,3);
  }

  var 新しいギフト = {
    x: 新しいX、
    y: 0,
    速度: ランダム数値(2,6)
    生きている:本当、
    回転: 0,
    色: 色、
    爆弾:爆弾、
  };

  ギフト[maxGift] = newGift;
  最大ギフト++;
  (最大ギフト>75)の場合{
    最大ギフト = 0;
  }
}

関数spawnGifts() {
  if (タイマー > spawnTimer) {
    スポーン();
    タイマー = 0;
  }
}

関数drawRotatedImage(画像、x、y、角度、スケール)
{ 
  ctx.save(); 
  ctx.translate(x, y);
  ctx.rotate(角度 * TO_RADIANS);
  ctx.drawImage(画像、-(image.width/2)、-(image.height/2)、スケール、スケール);
  ctx.restore(); 
}

関数drawHUD() {
  ctx.font = "20px Arial";
  ctx.fillStyle = "黄色";
  ctx.fillText(`スコア: ${score}`, 0, 25);

  var heart = '❤';
  var hearts = health > 0 ? heart.repeat(health) : " ";
  ctx.fillText("Helf:", canvas.width - 120, 25);
  ctx.fillStyle = "赤";
  ctx.fillText(`${hearts}`, キャンバス幅 - 60, 26);
}

関数initialiseGame() {
  健康 = 3;
  elfX = (canvas.width-elfWidth)/2;
  バンタイム = 0;
  スコア = 0;
  雪の高さ = 6;
  タイマー = 0;
  スポーンタイマー = 50;
  ギフト = [];
}

関数initialiseSnow() {
  (i=0; i<maxSnowflakes; i++) の場合 {
    var startY = -randomNumber(0, キャンバスの高さ);
    雪の結晶[i] = {
      x: ランダム数値(0, キャンバス幅-スノーフレークサイズ),
      y: 開始Y、
      開始Y: 開始Y、
      色: スノーフレークカラー[ランダム数値(0,3)],
      半径: (Math.random() * 3 + 1),
      速度: randomNumber(スノーフレーク最小速度、スノーフレーク最大速度)
    };
  }
}

関数drawSnow() {
  (i=0; i<maxSnowflakes; i++) の場合 {
    雪片[i].y+=雪片[i].速度;
    snowflakes[i].y>canvas.heightの場合、snowflakes[i].y = snowflakes[i].startY;
    ctx.beginPath();
    ctx.arc(スノーフレーク[i].x、スノーフレーク[i].y、スノーフレーク[i].radius、0、2 * Math.PI、false);
    ctx.fillStyle = 雪片[i].colour;
    ctx.fill();
  }
}

関数drawFloor() {
  var snowTopY = canvas.height - snowHeight;

  ctx.fillStyle = '#fff';
  ctx.beginPath();
  ctx.moveTo(0, 雪の頂点Y);
  ctx.lineTo(キャンバスの幅、snowTopY);
  ctx.lineTo(キャンバスの幅、キャンバスの高さ);
  ctx.lineTo(0, キャンバスの高さ);
  ctx.closePath();
  ctx.fill();
}

関数drawSnowPerson() {
  var snowTopY = canvas.height - snowHeight;

  円を描画します("#fff", 100, snowTopY-20, 40);
  円を描画します("#fff", 100, snowTopY-70, 20);
  長方形を描画します("#835C3B", 85, snowTopY-105, 30, 20);
  長方形を描画します("#835C3B", 75, snowTopY-90, 50, 6);
  三角形を描画します("#ffa500", 100, snowTopY-64, 7);
  円を描画します("#000", 93, snowTopY-76, 3);
  円を描画します("#000", 108, snowTopY-76, 3);
  円を描画します("#000", 100, snowTopY-40, 2);
  円を描画します("#000", 100, snowTopY-30, 2);
  円を描画します("#000", 100, snowTopY-20, 2);
}

関数drawTriangle(色, x, y, 高さ) {
  ctx.strokeStyle = ctx.fillStyle = color;
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x - 高さ、y - 高さ);
  ctx.lineTo(x + 高さ、y - 高さ);
  ctx.fill();
}

関数drawCircle(色, x, y, 半径) {
  ctx.strokeStyle = ctx.fillStyle = color;
  ctx.beginPath();
  ctx.arc(x, y, 半径, 0, Math.PI * 2, true);
  ctx.closePath();
  ctx.stroke();
  ctx.fill();
}

関数drawRectangle(色, x, y, 幅, 高さ) {
  ctx.strokeStyle = ctx.fillStyle = color;
  ctx.fillRect(x, y, 幅, 高さ);
}

関数 randomNumber(low, high) {
  Math.floor(Math.random() * high) + low を返します。 
}

関数 makeColorGradient(周波数1, 周波数2, 周波数3,
                            フェーズ1、フェーズ2、フェーズ3、
                            中心、幅、長さ){
  var colors = [];

  (var i = 0; i < len; ++i) の場合
  {
    var r = Math.sin(周波数1*i + 位相1) * 幅 + 中心;
    var g = Math.sin(周波数2*i + 位相2) * 幅 + 中心;
    var b = Math.sin(周波数3*i + 位相3) * 幅 + 中心;
    colors.push(RGB2Color(r,g,b));
  }
  色を返します。
}

関数 RGB2Color(r,g,b) {
  '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b) を返します。
}

関数byte2Hex(n) {
  var nybHexString = "0123456789ABCDEF";
  String(nybHexString.substr((n >> 4) & 0x0F,1)) + nybHexString.substr(n & 0x0F,1) を返します。
}

関数setColourGradient() {
  中心 = 128;
  幅 = 127;
  ステップ = 6;
  周波数 = 2*Math.PI/ステップ;
  makeColorGradient(frequency,frequency,frequency,0,2,4,center,width,50) を返します。
}

関数initialiseSpawnInterval() {
  ゲームモード === gameModes.PLAYING && spawnTimer>2 の場合 {
    スポーンタイマー--;
    スポーン時間変更間隔 -= 50;
  }
}

関数setGameMode(モード) {
  ゲームモード = モード;
  タイマー=0;
}

関数raiseSnow() {
  gameMode === gameModes.PLAYING && snowHeight < canvas.height) の場合 {
    雪の高さ++;
  }
}

関数setHighScore() {
  var 現在の高スコア = getHighScore();
  現在のハイスコアが -1 より大きく、スコアが現在のハイスコアより大きい場合、
    localStorage.setItem("highScore", スコア);
  }
}

関数 getHighScore() {
  (!localStorage) の場合は -1 を返します。
  var highScore = localStorage.getItem("highScore");
  highScore を 0 で返します。
}

タイトルカラー = setColourGradient();
Snow() を初期化します。
描画間隔を30に設定します。
setInterval(スポーン間隔を初期化し、スポーン時間変更間隔を設定します);
setInterval(RaiseSnow, 666);

HTMLコード

<!DOCTYPE html>
<html lang="ja" >
<ヘッド>
<メタ文字セット="UTF-8">
<title>エルフギフトキャッチ</title>

<link rel="stylesheet" href="css/style.css" rel="external nofollow" >#N 文字を省略するとコードが長くなりすぎます</head>
<本文>

<div id="ラッパー">

	<canvas id="canvas" width="450" ​​height="540"></canvas>
	
</div>


  
</div>

<script src="js/script.js"></script>

</本文>
</html>

デモンストレーションのプロセス

パッケージ化されたファイルは、CSS コード、JS コード、HTML ファイルの 3 つです。パッケージ化後は、HTML ファイルをクリックして直接実行できます。

上記は、JavaScript を使用して簡単なクリスマス ゲームを実装する方法の詳細です。JavaScript クリスマス ゲームの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JS を使用して HTML で回転するクリスマスツリーを実装する
  • JavaScript によるダイナミッククリスマスツリーの詳細な説明
  • JavaScript フラッシュクリスマスツリー実装コード
  • JS 実用的なオブジェクト指向スネークゲームの例
  • HTML+CSS+JavaScript でシンプルな三目並べゲームを作成する
  • JavaScript でのモグラ叩きゲームの実装

<<:  3つの簡単な例を使ってハイパーリンクの下線を削除する方法

>>:  Pure CSS と Flutter はそれぞれブリージング ライト効果を実現します (サンプル コード)

推薦する

最新の仮想マシン VMware 14 インストール チュートリアル

まず、VMware 14のアクティベーションコードをお渡ししますFF31K-AHZD1-H8ETZ-...

MySQL 8.0 の新機能: ハッシュ結合

MySQL 開発チームは、2019 年 10 月 14 日に MySQL 8.0.18 GA バージ...

CSS で波の効果を作成するためのアイデア

以前、純粋な CSS を使用して波の効果を実現する方法をいくつか紹介しました。それらについては、次の...

Vuex データの永続性を実装するためのアイデアとコード

vuexとはvuex: vue.js専用に開発された状態管理ツールで、すべてのコンポーネントの状態を...

Vue.jsはアイコンをクリックしてズームインし、

前回の記事では、Vue で画像の切り抜きや拡大・縮小、回転を実現する方法を紹介しました。今回は、アイ...

MySQL は information_schema オブジェクトの付与をバイパスし、ERROR 1044 (4200) エラーを報告します

この質問は、MySQL の権限に関する WeChat グループのネットユーザー間の議論です。次のよう...

CentOS7 で ethereum/Ethereum を最初からインストールする

目次序文sudo書き込み権限を追加するgit 2.9.0をインストールopenssl 1.1.1l ...

JavaScript で Priority Queue を実装する

目次1. 優先キューの紹介2. 優先キューのカプセル化1. 優先キューの紹介通常のキューに要素が挿入...

Sublime Text - ブラウザのショートカットキーを設定するための推奨方法

コード効果を異なるブラウザで表示することはよくあることなので、異なるショートカットキーを使用して対応...

MySQL の日付関数と日付変換およびフォーマット関数

MySQL は、膨大なユーザーベースを持つ無料のリレーショナル データベースです。この記事では、My...

純粋な CSS ドロップダウン メニュー

成果を達成する実装コードhtml <div id="コンテナ"> &...

HTML でフレームセット タグを使用するチュートリアル

フレームセット ページは通常の Web ページとは多少異なります。依然として <HTML>...

Vueはタブルーティング切り替えコンポーネントのメソッド例を実装します

序文この記事では、vue に付属している vue-router.js ルーティングを使用してページン...

Docker Swarm サービス オーケストレーション コマンドの詳細な説明

1. はじめにDocker には、タスクを構成する複数の Docker コンテナをオーケストレーショ...

Nginx レイヤー 4 負荷分散構成ガイド

1. レイヤー4負荷分散の概要レイヤー 4 ロード バランシングとは何ですか?いわゆる 4 層負荷分...