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 はそれぞれブリージング ライト効果を実現します (サンプル コード)

推薦する

TypeScript ジェネリックパラメータのデフォルト型と新しい厳密なコンパイルオプション

目次概要コンポーネントクラスの型定義を作成するジェネリック型を使用してPropsとStateを定義す...

Windows で MySQL 5.7.17 圧縮バージョンをインストールするときに遭遇する落とし穴

まず、Windows 64 ビット用の最新の MySQL 5.7.17 コミュニティ圧縮バージョンを...

MySQLのユーザーアカウント管理と権限管理の詳細な説明

序文MySQL の権限テーブルは、データベースの起動時にメモリにロードされます。ユーザーが ID 認...

Docker Compose のインストールと使用手順

目次1. Docker Compose とは何ですか? 2. Docker Composeのインスト...

WeChatアプレットコンポーネントライフサイクルの落とし穴の記録

通常、コンポーネントのライフサイクルは、ビジネス ロジックが始まる場所です。ビジネスシナリオが複雑で...

MySQL でシンプルな検索エンジンを実装するためのサンプルコード

目次序文導入ngram全文パーサー全文インデックスを作成する検索方法1. 自然言語検索(自然言語モー...

Webフロントエンド開発コース Webフロントエンド開発ツールとは

インターネット技術の発展に伴い、ユーザーはますます Web ページに依存するようになり、Web フロ...

JDBC が MySQL に接続して中国語を処理するときに文字化けする問題の解決方法の詳細説明

JDBC が MySQL に接続して中国語を処理するときに文字化けする問題の解決方法の詳細説明最近、...

MySQL パフォーマンス最適化のヒント

MySQL パフォーマンスの最適化MySQL はインターネット企業で広く使用されており、MySQL ...

Firefox で英語の文字が折り返されない問題の解決方法

テキストのレイアウトには、言語に応じていくつかの書式設定要件があります。たとえば、簡体字中国語では、...

MySQL8.0.18 複数マスターと 1 スレーブの構成

目次1. 現実的な背景2. 合意3. マスターを構成する3.1. 起動パラメータの設定3.2. パラ...

VueはTodoListの例をカプセル化し、ブラウザのローカルキャッシュのアプリケーションを実装します。

この記事では主に、Vue で TodoList をカプセル化するケースと、ブラウザのローカル キャッ...

Vueは2つのルーティング許可制御メソッドを実装しています

目次方法 1: ルーティング メタ情報 (meta)方法 2: ルーティング テーブルを動的に生成す...

MySQLでorder byを使用せずにランキングを実装する3つの方法のまとめ

ビジネスを想定: 2位の従業員の給与情報を見るデータベースを作成する emps が存在する場合はデー...

vite2.0 設定学習の詳しい説明(typescript 版)

導入悠宇希の原文です。 vite は Vue CLI に似ています。vite も、基本的なプロジェク...