目錄
理解坐標計算
修改Sword 類的update 方法
完整代碼示例
總結
首頁 web前端 html教學 獲取HTML Canvas中旋轉劍的坐標

獲取HTML Canvas中旋轉劍的坐標

Aug 22, 2025 pm 11:51 PM

獲取HTML Canvas中旋轉劍的坐標

本文旨在幫助開發者理解如何在HTML Canvas中繪製一個旋轉的劍,並獲取劍的端點坐標。通過分析提供的代碼,我們將重點講解如何正確計算劍的端點坐標,使其能夠跟隨角色手臂旋轉,最終實現一個動態旋轉的劍的效果。本文將提供修改後的代碼示例,並解釋關鍵部分的邏輯。

理解坐標計算

在Canvas中繪製旋轉的物體,關鍵在於理解坐標系的變換。我們需要確定劍的起點(通常是角色手的位置)和終點。由於劍是旋轉的,終點坐標需要根據旋轉角度進行計算。

修改Sword 類的update 方法

原始代碼中,Sword 類的update 方法在計算劍的端點坐標時存在一些問題。正確的做法是,左手的位置作為劍的一個端點,右手的位置作為劍的另一個端點,然後根據劍的長度計算出另外兩個端點。 下面是修改後的update 方法:

 update() {
    this.draw();
    this.Lx = LeftHand.x;
    this.Ly = LeftHand.y;
    this.Rx = RightHand.x;
    this.Ry = RightHand.y;

    this.Lsx = LeftHand.x;
    this.Lsy = LeftHand.y;
    this.Rsx = RightHand.x Player.swordLength;
    this.Rsy = RightHand.y Player.swordLength;
  }

解釋:

  • this.Lx, this.Ly: 左手的位置,作為劍的一個端點。
  • this.Rx, this.Ry: 右手的位置,作為劍的另一個端點。
  • this.Lsx, this.Lsy: 左手位置不變,作為劍的第三個端點。
  • this.Rsx, this.Rsy: 右手位置加上劍的長度,作為劍的第四個端點。

完整代碼示例

以下是修改後的完整代碼示例,包含了player, leftHand, rightHand, 和sword 類的定義以及animate 函數。

 var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

c.width = window.innerWidth;
c.height = window.innerHeight;

var mouse = { x: c.width / 2, y: c.height / 2 };

window.addEventListener("resize", function (event) {
  c.width = window.innerWidth;
  c.height = window.innerHeight;
});

window.addEventListener("mousemove", function (event) {
  mouse.x = event.clientX;
  mouse.y = event.clientY;
});

class player {
  constructor(x, y, r, color, v) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.v = v;
    this.color = color;
    this.swordLength = 200;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    var dy = mouse.y - this.y;
    var dx = mouse.x - this.x;
    const angle = Math.atan2(dy, dx);

    var vx = Math.cos(angle) * this.v;
    var vy = Math.sin(angle) * this.v;

    if (Math.abs(vx) > Math.abs(dx)) {
      vx = dx;
    }

    if (Math.abs(vy) > Math.abs(dy)) {
      vy = dy;
    }
    this.x = vx;
    this.y = vy;
  }
}

class leftHand {
  constructor(x, y, r, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.angle = 0;
    this.r = r;
    this.Area = 40;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    this.x = Player.x this.Area * Math.cos(this.angle / 180);
    this.y = Player.y this.Area * Math.sin(this.angle / 180);
    this.angle = 30;
  }
}

class rightHand {
  constructor(x, y, r, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.angle = 90;
    this.r = r;
    this.Area = 40;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    this.x = Player.x this.Area * Math.cos(this.angle / 180);
    this.y = Player.y this.Area * Math.sin(this.angle / 180);
    this.angle = 30;
  }
}

class sword {
  constructor(Lx, Ly, Rx, Ry, color, Lsx, Lsy, Rsx, Rsy) {
    this.Lx = Lx;
    this.Ly = Ly;
    this.Rx = Rx;
    this.Ry = Ry;
    this.Lsx = Lsx;
    this.Lsy = Lsy;
    this.Rsx = Rsx;
    this.Rsy = Rsy;
    this.color = color;
  }

  draw() {
    ctx.beginPath();
    ctx.moveTo(this.Lx, this.Ly);
    ctx.lineTo(this.Rx, this.Ry);
    ctx.lineTo(this.Rsx, this.Rsy);
    ctx.lineTo(this.Lsx, this.Lsy);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }

  update() {
    this.draw();
    this.Lx = LeftHand.x;
    this.Ly = LeftHand.y;
    this.Rx = RightHand.x;
    this.Ry = RightHand.y;

    this.Lsx = LeftHand.x;
    this.Lsy = LeftHand.y;
    this.Rsx = RightHand.x Player.swordLength;
    this.Rsy = RightHand.y Player.swordLength;
  }
}

const Player = new player(c.width / 2, c.height / 2, 30, "blue", 10);

const LeftHand = new leftHand(
  c.width / 2 40 * Math.cos(0 / 180),
  c.height / 2 40 * Math.sin(0 / 180),
  10,
  "red"
);

const RightHand = new rightHand(
  c.width / 2 40 * Math.cos(90 / 180),
  c.height / 2 40 * Math.sin(90 / 180),
  10,
  "yellow"
);

const Sword = new sword(
  c.width / 2 40 * Math.cos(0 / 180),
  c.height / 2 40 * Math.sin(0 / 180),
  c.width / 2 40 * Math.cos(90 / 180),
  c.height / 2 40 * Math.sin(90 / 180),
  "black",
  c.width / 2 40 * Math.cos(0 / 180),
  c.height / 2 40 * Math.sin(0 / 180),
  c.width / 2 40 * Math.cos(90 / 180),
  c.height / 2 40 * Math.sin(90 / 180)
);

function animate() {
  requestAnimationFrame(animate);
  ctx.clearRect(0, 0, c.width, c.height);
  Player.update();
  LeftHand.update();
  RightHand.update();
  Sword.update();
}

animate();

HTML 代碼:

 


    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rotating Sword</title>


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

確保將JavaScript代碼保存到名為script.js 的文件中,並在HTML文件中引用它。

總結

通過修改Sword 類的update 方法,我們可以正確計算出劍的端點坐標,從而實現劍的旋轉效果。 關鍵在於理解坐標變換和如何根據角色手臂的位置和劍的長度計算出正確的端點坐標。 記住,canvas 坐標計算是實現複雜動畫的基礎。 掌握這些概念,你就可以創建更豐富的canvas動畫效果。

以上是獲取HTML Canvas中旋轉劍的坐標的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

如何在HTML中嵌入PDF文檔? 如何在HTML中嵌入PDF文檔? Aug 01, 2025 am 06:52 AM

使用標籤是最簡單且推薦的方法,語法為,適用於現代瀏覽器直接嵌入PDF;2.使用標籤可提供更好的控制和備用內容支持,語法為,並在標籤內提供下載鏈接作為不支持時的備用方案;3.可選通過GoogleDocsViewer嵌入,但因隱私和性能問題不建議廣泛使用;4.為提升用戶體驗,應設置合適的高度、使用響應式尺寸(如height:80vh)並提供PDF下載鏈接,以便用戶自行下載查看。

如何在html中的網站標題選項卡中添加圖標 如何在html中的網站標題選項卡中添加圖標 Aug 07, 2025 pm 11:30 PM

要為網站標題欄添加圖標,需在HTML的部分鏈接一個favicon文件,具體步驟如下:1.準備一個16x16或32x32像素的圖標文件,推薦使用favicon.ico命名並放置於網站根目錄,或使用PNG、SVG等現代格式;2.在HTML的中添加鏈接標籤,如,若使用PNG或SVG格式則相應調整type屬性;3.可選地為移動設備添加高分辨率圖標,如AppleTouchIcon,並通過sizes屬性指定不同尺寸;4.遵循最佳實踐,將圖標置於根目錄以確保自動檢測,更新後清除瀏覽器緩存,檢查文件路徑正確性,

使用HTML'輸入類型”作為用戶數據 使用HTML'輸入類型”作為用戶數據 Aug 03, 2025 am 11:07 AM

選擇合適的HTMLinput類型能提升數據準確性、增強用戶體驗並提高可用性。 1.根據數據類型選用對應input類型,如text、email、tel、number和date,可實現自動校驗和適配鍵盤;2.利用HTML5新增類型如url、color、range和search,可提供更直觀的交互方式;3.配合使用placeholder和required屬性,可提升表單填寫效率和正確率,但需注意placeholder不能替代label。

如何以HTML表單創建搜索輸入字段 如何以HTML表單創建搜索輸入字段 Aug 02, 2025 pm 04:44 PM

Usetheelementwithinatagtocreateasemanticsearchfield.2.Includeaforaccessibility,settheform'sactionandmethod="get"attributestosenddatatoasearchendpointwithashareableURL.3.Addname="q"todefinethequeryparameter,useplaceholdertoguideuse

為什麼我的HTML圖像未顯示? 為什麼我的HTML圖像未顯示? Aug 16, 2025 am 10:08 AM

首先檢查src屬性路徑是否正確,確保相對路徑或絕對路徑與HTML文件位置匹配;2.核實文件名和擴展名是否拼寫正確且區分大小寫;3.確認圖像文件實際存在於指定目錄中;4.使用合適的alt屬性並確保圖像格式為瀏覽器廣泛支持的.jpg、.png、.gif或.webp;5.排除瀏覽器緩存問題,嘗試強制刷新或直接訪問圖像URL;6.檢查服務器權限設置,確保文件可被讀取且未被屏蔽;7.驗證img標籤語法正確,包含正確的引號和屬性順序,最終通過瀏覽器開發者工具排查404錯誤或語法問題以確保圖像正常顯示。

如何使用HTML ABBR標籤進行縮寫 如何使用HTML ABBR標籤進行縮寫 Aug 05, 2025 pm 12:54 PM

使用HTML的標籤能提升內容的可訪問性和清晰度;1.用縮寫標記縮寫或首字母縮略詞;2.為不常見的縮寫添加title屬性以提供完整解釋;3.在文檔首次出現時使用,避免重複標註;4.可通過CSS自定義樣式,默認瀏覽器通常顯示帶點下劃線;5.有助於屏幕閱讀器用戶理解術語,增強用戶體驗。

如何將圖標添加到HTML中的按鈕 如何將圖標添加到HTML中的按鈕 Aug 07, 2025 pm 11:09 PM

使用FontAwesome可通過引入CDN並在按鈕中添加圖標類來快速添加圖標,如Like;2.使用標籤可在按鈕中嵌入自定義圖標,需指定正確的路徑和尺寸;3.直接嵌入SVG代碼可實現高分辨率圖標並保持與文本顏色一致;4.應通過CSS添加間距並為圖標按鈕添加aria-label以提升可訪問性;綜上,FontAwesome最適合標準圖標,圖片適用於自定義設計,而SVG提供最佳縮放和控制,應根據項目需求選擇方法,通常推薦FontAwesome。

如何創建一個在HTML中發送表單數據的提交按鈕 如何創建一個在HTML中發送表單數據的提交按鈕 Aug 02, 2025 pm 04:46 PM

使用元素並設置action和method屬性指定數據提交地址和方式;2.添加帶name屬性的輸入字段以確保數據可被服務器識別;3.使用或創建提交按鈕,點擊後瀏覽器會將表單數據發送至指定URL,由後端處理,完成數據提交。

See all articles