主頁 > 軟體設計 > 大家都在發圣誕樹,我偏偏要發一個圣誕小游戲給大家玩【內附原始碼】

大家都在發圣誕樹,我偏偏要發一個圣誕小游戲給大家玩【內附原始碼】

2021-12-21 08:32:11 軟體設計

?大家好,我是辣條,

前言

在這里插入圖片描述

圣誕節快來了,熱榜都被一堆圣誕樹攻占了,這樣的流量密碼我怎么會錯過,大家都發圣誕樹,我就不發啦,直接分享一個圣誕小游戲給大家玩,代碼太長一定要先贊和收藏,

領取福利

300+Python經典編程案例
50G+學習視頻教程
100+Python初階、中階、高階電子書籍
1000+簡歷模板和匯報PPT模板(轉正、年終等)

實作效果

一個簡單的2D網頁小游戲它的制作程序是有規律可尋的,它每個部分都有一定的套路,我們應該
把有規律的部分總結在一起,形成一個模板,把相應的模板寫好了,到要生產某個物件時就可以用
模板,還有游戲的整個流程每個函式,每個js檔案之間都是分工明確的;我們要總結好了才寫,
不要想到哪就寫哪,這樣雖然結果是相同的,但可能代碼的可讀性和維護性不是很強,思路不是很
清晰,
在這里插入圖片描述

代碼

代碼這塊沒啥好說的,直接給大家貼上代碼了,簡單直接,能運行可以玩就可以了,分享給自己的朋友或者自己摸魚玩,就圖一樂,檔案我已經打包好了,需要的話可以私我哦,
CSS代碼:

body { background:rgb(8,8,58);
  margin:0;
}

#wrapper {
  width:500px;
  margin-left:auto;
  margin-right:auto;
  margin-top:20px;
}

JS代碼:

?var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    elfImage = document.getElementById("elf");
greenGiftImage = document.getElementById("green_gift");
redGiftImage = document.getElementById("red_gift");
blueGiftImage = document.getElementById("blue_gift");
bombImage = document.getElementById("bomb");
bangImage = document.getElementById("bang");

var x = canvas.width/2;
var y = canvas.height-30;
var dx = 2;
var dy = -2;
const elfHeight = 70;
const elfWidth = 55;
var elfX = (canvas.width-elfWidth)/2;
const elfSpeed = 10;
var rightPressed = false;
var leftPressed = false;
var spacePressed = false;
var spawnInterval;
var spawnTimer = 50;
var gifts = [];
var maxGift = 0;
const giftWidth = 40;
const giftHeight = 40;
var timer = 0;
var giftRotation = 0;
const TO_RADIANS = Math.PI/180; 
var score = 0;
var health = 3;
const bombChance = 5;
var elfRotation = 0;
var bangX;
var bangTime;
var snowHeight = 6;
var spawnTimeChangeInterval = 3000;
var titleColours = [];

// snowflake stuff
var snowflakes = [];
const maxSnowflakes = 80;
const snowflakeSize = 3;
const snowflakeMinSpeed = 1;
const snowflakeMaxSpeed = 4;
const snowflakeColours = ["rgba(255,255,255,0.95)", "rgba(255,255,255,0.65)","rgba(255,255,255,0.4)"];

const gameModes = {
  TITLE: 'title',
  PLAYING: 'playing',
  GAMEOVER: 'gameover'
};

var gameMode = gameModes.TITLE;

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

function keyDownHandler(e) {
  if(e.key == "Right" || e.key == "ArrowRight") {
    rightPressed = true;
  }
  else if(e.key == "Left" || e.key == "ArrowLeft") {
    leftPressed = true;
  } else if(e.code == "Space") {
    spacePressed = true;
  }
}

function keyUpHandler(e) {
  if(e.key == "Right" || e.key == "ArrowRight") {
    rightPressed = false;
  }
  else if(e.key == "Left" || e.key == "ArrowLeft") {
    leftPressed = false;
  } else if(e.code == "Space") {
    spacePressed = false;
  }
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawSnow();

  timer++;

  switch (gameMode) {
    case gameModes.TITLE:
      titleScreen(); 
      break;
    case gameModes.GAMEOVER:
      gameOver();
      break;
    case gameModes.PLAYING:
      gameLoop();
      break;
  }
}

function titleScreen() {
  if (timer > titleColours.length) timer=0;

  ctx.font = "50px Arial";
  ctx.fillStyle = titleColours[timer]; 
  ctx.fillText(`圣誕抓禮物!`, 0, 50);
  ctx.fillStyle = "yellow"; 

  ctx.font = "30px Arial";
  ctx.fillText(`請按空格鍵開始!`, 65, 140);

  var highScore = getHighScore();
  if (highScore != -1) ctx.fillText(`High Score: ${highScore}`, 90, 220);

  drawRotatedImage(elfImage, canvas.width/2 - elfWidth/2, 330, elfRotation, 200);
  elfRotation+=2;
  if (elfRotation > 359) elfRotation = 0;

  if (spacePressed && timer > 5) {
    setGameMode(gameModes.PLAYING);
  }
}

function gameLoop() {
  drawSnowPerson();
  spawnGifts();
  processGifts();
  drawFloor();
  drawHUD();
  drawElf();
  drawBang();

  if(rightPressed) {
    elfX += elfSpeed;
    if (elfX + elfWidth > canvas.width){
      elfX = canvas.width - (elfWidth + 5);
    }
  }
  else if(leftPressed) {
    elfX -= elfSpeed;
    if (elfX < -15){
      elfX = -15;
    }
  }
}

function gameOver() {
  ctx.font = "50px Arial";
  ctx.fillStyle = "yellow";
  ctx.fillText(`GAME OVER!`, 80, 200);
  ctx.font = "30px Arial";
  ctx.fillText(`Final score: ${score}`,130, 240);
  ctx.fillText('Press space to continue',80, 280);

  if (spacePressed && timer > 5) {
    initialiseGame();
    setGameMode(gameModes.TITLE);
  }
}

function processGifts() {
  gifts.forEach((g) => {
    if (g && g.alive) { 
      // draw gift
      drawGift(g);
      if (g.y > canvas.height) {
        g.alive = false;
        if (!g.bomb) score--;
      }

      // move gift
      g.y+=g.speed;

      // rotate gift
      g.rotation+=5;
      if ( g.rotation > 359) g.rotation = 0;

      // check for collision
      if ((g.y + (giftHeight/2)) >= ((canvas.height - elfHeight - snowHeight) + 20)
          && (g.y<canvas.height-snowHeight+20)) {
        if ((elfX + 25) <= (g.x + (giftWidth/2)) && ((elfX+20) + (elfWidth)) >= g.x )
        {
          g.alive = false;
          if (!g.bomb) { 
            score+=5;
          } else {
            doBombCollision();
          }
        }
      }
    }
  });
}

function drawGift(g) {
  switch (g.colour) {
    case 1:
      drawColouredGift(greenGiftImage, g);
      break;
    case 2:
      drawColouredGift(redGiftImage, g);
      break;
    case 3:
      drawColouredGift(blueGiftImage, g);
      break;
    case 4:
      drawRotatedImage(bombImage, g.x, g.y, 180, 45);
      break;
  }
}

function drawColouredGift(colourImage, g) {
  drawRotatedImage(colourImage, g.x, g.y, g.rotation, 35);
}

function doBombCollision() {
  health--;
  bangX=elfX;
  bangTime = 5;
  if (health == 0) {
    setHighScore();
    setGameMode(gameModes.GAMEOVER);
  }
}

function drawBang() {
  if (bangTime > 0) {
    bangTime--;
    ctx.drawImage(bangImage, bangX, (canvas.height-75)-snowHeight, 75,75);
  }
}


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

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

  var colour;
  var bomb = false;

  if (randomNumber(1,bombChance) == bombChance) {
    colour = 4;
    bomb = true;
  } else {
    colour = randomNumber(1,3);
  }

  var newGift = {
    x: newX,
    y: 0,
    speed: randomNumber(2,6),
    alive: true,
    rotation: 0,
    colour: colour,
    bomb: bomb,
  };

  gifts[maxGift] = newGift;
  maxGift++;
  if (maxGift > 75) {
    maxGift = 0;
  }
}

function spawnGifts() {
  if (timer > spawnTimer) {
    spawn();
    timer = 0;
  }
}

function drawRotatedImage(image, x, y, angle, scale)
{ 
  ctx.save(); 
  ctx.translate(x, y);
  ctx.rotate(angle * TO_RADIANS);
  ctx.drawImage(image, -(image.width/2), -(image.height/2), scale, scale);
  ctx.restore(); 
}

function drawHUD() {
  ctx.font = "20px Arial";
  ctx.fillStyle = "yellow";
  ctx.fillText(`Score: ${score}`, 0, 25);

  var heart = '?';
  var hearts = health > 0 ? heart.repeat(health) : " ";
  ctx.fillText("Helf:", canvas.width - 120, 25);
  ctx.fillStyle = "red";
  ctx.fillText(`${hearts}`, canvas.width - 60, 26);
}

function initialiseGame() {
  health = 3;
  elfX = (canvas.width-elfWidth)/2;
  bangTime = 0;
  score = 0;
  snowHeight = 6;
  timer = 0;
  spawnTimer = 50;
  gifts = [];
}

function initialiseSnow() {
  for (i=0; i<maxSnowflakes; i++) {
    var startY = -randomNumber(0, canvas.height);
    snowflakes[i] = {
      x: randomNumber(0, canvas.width-snowflakeSize),
      y: startY,
      startY: startY,
      colour: snowflakeColours[randomNumber(0,3)],
      radius: (Math.random() * 3 + 1),
      speed: randomNumber(snowflakeMinSpeed, snowflakeMaxSpeed)
    };
  }
}

function drawSnow() {
  for (i=0; i<maxSnowflakes; i++) {
    snowflakes[i].y+=snowflakes[i].speed;
    if (snowflakes[i].y>canvas.height) snowflakes[i].y = snowflakes[i].startY;
    ctx.beginPath();
    ctx.arc(snowflakes[i].x, snowflakes[i].y, snowflakes[i].radius, 0, 2 * Math.PI, false);
    ctx.fillStyle = snowflakes[i].colour;
    ctx.fill();
  }
}

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

  ctx.fillStyle = '#fff';
  ctx.beginPath();
  ctx.moveTo(0, snowTopY);
  ctx.lineTo(canvas.width, snowTopY);
  ctx.lineTo(canvas.width, canvas.height);
  ctx.lineTo(0, canvas.height);
  ctx.closePath();
  ctx.fill();
}

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

  drawCircle("#fff", 100, snowTopY-20, 40);
  drawCircle("#fff", 100, snowTopY-70, 20);
  drawRectangle("#835C3B", 85, snowTopY-105, 30, 20);
  drawRectangle("#835C3B", 75, snowTopY-90, 50, 6);
  drawTriangle("#ffa500", 100, snowTopY-64, 7);
  drawCircle("#000", 93, snowTopY-76, 3);
  drawCircle("#000", 108, snowTopY-76, 3);
  drawCircle("#000", 100, snowTopY-40, 2);
  drawCircle("#000", 100, snowTopY-30, 2);
  drawCircle("#000", 100, snowTopY-20, 2);
}

function drawTriangle(color, x, y, height) {
  ctx.strokeStyle = ctx.fillStyle = color;
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x - height, y - height);
  ctx.lineTo(x + height, y - height);
  ctx.fill();
}

function drawCircle(color, x, y, radius) {
  ctx.strokeStyle = ctx.fillStyle = color;
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2, true);
  ctx.closePath();
  ctx.stroke();
  ctx.fill();
}

function drawRectangle(color, x, y, width, height) {
  ctx.strokeStyle = ctx.fillStyle = color;
  ctx.fillRect(x, y, width, height);
}

function randomNumber(low, high) {
  return Math.floor(Math.random() * high) + low; 
}

function makeColorGradient(frequency1, frequency2, frequency3,
                            phase1, phase2, phase3,
                            center, width, len) {
  var colours = [];

  for (var i = 0; i < len; ++i)
  {
    var r = Math.sin(frequency1*i + phase1) * width + center;
    var g = Math.sin(frequency2*i + phase2) * width + center;
    var b = Math.sin(frequency3*i + phase3) * width + center;
    colours.push(RGB2Color(r,g,b));
  }
  return colours;
}

function RGB2Color(r,g,b) {
  return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
}

function byte2Hex(n) {
  var nybHexString = "0123456789ABCDEF";
  return String(nybHexString.substr((n >> 4) & 0x0F,1)) + nybHexString.substr(n & 0x0F,1);
}

function setColourGradient() {
  center = 128;
  width = 127;
  steps = 6;
  frequency = 2*Math.PI/steps;
  return makeColorGradient(frequency,frequency,frequency,0,2,4,center,width,50);
}

function initialiseSpawnInterval() {
  if (gameMode === gameModes.PLAYING && spawnTimer>2) {
    spawnTimer--;
    spawnTimeChangeInterval-=50;
  }
}

function setGameMode(mode) {
  gameMode = mode;
  timer=0;
}

function raiseSnow() {
  if (gameMode === gameModes.PLAYING && snowHeight < canvas.height) {
    snowHeight++;
  }
}

function setHighScore() {
  var currentHighScore = getHighScore();
  if (currentHighScore !=-1 && score > currentHighScore) {
    localStorage.setItem("highScore", score);
  }
}

function getHighScore() {
  if (!localStorage) return -1;
  var highScore = localStorage.getItem("highScore");
  return highScore || 0;
}

titleColours = setColourGradient();
initialiseSnow();
setInterval(draw, 30);
setInterval(initialiseSpawnInterval, spawnTimeChangeInterval);
setInterval(raiseSnow, 666);

html代碼

<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Elf Gift Catch</title>

<link rel="stylesheet" href="css/style.css">#中間省略N個代碼太長了

</head>
<body>

<div id="wrapper">

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


  
</div>

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

</body>
</html>

演示流程

打包的檔案就三個,一個css的代碼,一個JS的代碼,還有一個html的檔案,打包好之后,點擊html的檔案就能直接運行了呢,
在這里插入圖片描述

👇🏻 添加 博主 獲取更多資料👇🏻

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/387956.html

標籤:其他

上一篇:二叉搜索樹

下一篇:【JavaSE基礎】隨著jdk的更新,你確定你真的還了解介面嗎?教你深入理解和掌握介面

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more