Get coordinates of a rotating rectangular sword in HTML Canvas
This article aims to solve the problem of drawing a rotating rectangular sword in HTML Canvas and getting its endpoint coordinates. By analyzing the existing code, the endpoint calculation method of the sword is clarified, and the modified sword.update() function is provided to ensure that the sword rotates with the character's arm. At the same time, it provides a complete runnable code example, which is convenient for developers to apply directly to their projects.
Drawing a rotating rectangle in HTML Canvas, especially weapons like swords, involves coordinate calculations and angle rotations. Here are the steps to get the coordinates of a rotating rectangular sword in Canvas and draw it correctly:
Understand the coordinate system
The coordinate system origin (0, 0) of Canvas is located in the upper left corner. The positive direction of the X-axis is to the right, and the positive direction of the Y-axis is to the down. All coordinate calculations are based on this origin.
Key code analysis and correction
There is a problem with the sword.update() function in the original code to calculate the endpoint coordinates of the sword, which leads to the incorrect drawing of the sword. The correct logic is:
- The position of the left hand is an end point of the sword.
- The right hand position is the other endpoint of the sword.
- The other two endpoints of the sword can be determined by adding Player.swordLength to the right-hand position.
Therefore, it is necessary to modify the sword.update() function as follows:
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; }
The key to this code is to correctly set the values of Lsx, Lsy, Rsx and Rsy to ensure that the shape and rotation of the sword are consistent with the movement of the arm.
Complete code example
The following is a revised complete code example that can be copied and run directly:
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 file:
<meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Canvas Sword</title> <style> body { margin: 0; overflow: hidden; /* Prevent scrollbars */ } canvas { display: block; /* Remove extra space below canvas */ } </style> <canvas id="canvas"></canvas> <script> // JavaScript code from previous response goes here 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(); </script>
Notes:
- Make sure that the HTML file is introduced.
- The width and height properties of the Canvas element should be set to the size of the window to make full use of screen space.
- Using requestAnimationFrame() in the animate() function can achieve smoother animation effects.
Summarize
By understanding the Canvas coordinate system and correctly calculating and updating the endpoint coordinates of the sword, the drawing of the rotating rectangular sword can be achieved. The key lies in the correction of the sword.update() function and ensuring that all coordinate calculations are based on the Canvas origin. In addition, the code example uses object-oriented programming ideas, defining characters, arms, and swords as classes, making the code structure clearer and easier to understand.
The above is the detailed content of Get coordinates of a rotating rectangular sword in HTML Canvas. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

To create an HTML unordered list, you need to use a tag to define a list container. Each list item is wrapped with a tag, and the browser will automatically add bullets; 1. Create a list with a tag; 2. Each list item is defined with a tag; 3. The browser automatically generates default dot symbols; 4. Sublists can be implemented through nesting; 5. Use the list-style-type attribute of CSS to modify the symbol style, such as disc, circle, square, or none; use these tags correctly to generate a standard unordered list.

Using tags is the easiest and recommended method. The syntax is suitable for modern browsers to embed PDF directly; 2. Using tags can provide better control and backup content support, syntax is, and provides download links in tags as backup solutions when they are not supported; 3. It can be embedded through Google DocsViewer, but it is not recommended to use widely due to privacy and performance issues; 4. In order to improve the user experience, appropriate heights should be set, responsive sizes (such as height: 80vh) and PDF download links should be provided so that users can download and view them themselves.

ThecontenteditableattributemakesanyHTMLelementeditablebyaddingcontenteditable="true",allowinguserstodirectlymodifycontentinthebrowser.2.Itiscommonlyusedinrichtexteditors,note-takingapps,andin-placeeditinginterfaces,supportingelementslikediv

To add an icon to the website title bar, you need to link a favicon file in part of the HTML. The specific steps are as follows: 1. Prepare a 16x16 or 32x32 pixel icon file. It is recommended to use favicon.ico to name it and place it in the website root directory, or use modern formats such as PNG and SVG; 2. Add link tags to HTML, such as PNG or SVG formats, adjust the type attribute accordingly; 3. Optionally add high-resolution icons for mobile devices, such as AppleTouchIcon, and specify different sizes through the sizes attribute; 4. Follow best practices, place the icon in the root directory to ensure automatic detection, clear the browser cache after update, and check the correctness of the file path.

Choosing the right HTMLinput type can improve data accuracy, enhance user experience, and improve usability. 1. Select the corresponding input types according to the data type, such as text, email, tel, number and date, which can automatically checksum and adapt to the keyboard; 2. Use HTML5 to add new types such as url, color, range and search, which can provide a more intuitive interaction method; 3. Use placeholder and required attributes to improve the efficiency and accuracy of form filling, but it should be noted that placeholder cannot replace label.

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

First, check whether the src attribute path is correct, and ensure that the relative or absolute path matches the HTML file location; 2. Verify whether the file name and extension are spelled correctly and case-sensitive; 3. Confirm that the image file actually exists in the specified directory; 4. Use appropriate alt attributes and ensure that the image format is .jpg, .png, .gif or .webp widely supported by the browser; 5. Troubleshoot browser cache issues, try to force refresh or directly access the image URL; 6. Check server permission settings to ensure that the file can be read and not blocked; 7. Verify that the img tag syntax is correct, including the correct quotes and attribute order, and finally troubleshoot 404 errors or syntax problems through the browser developer tool to ensure that the image is displayed normally.

The novalidate attribute is used to disable the browser's default form verification; 1. After adding novalidate, the browser will not perform the default verification even if the input field contains constraints such as required, pattern, min, max, etc.; 2. The form will ignore whether the input is valid and submitted directly, which is suitable for custom verification using JavaScript, multi-step forms or temporary bypass verification in the development testing stage; 3. It is a Boolean property that does not require assignment, and acts on the entire form; 4. Remove novalidate to restore the normal verification behavior of the browser; therefore, novalidate enables developers to independently control the timing and method of form verification.
