Hướng dẫn game puzzle javascript - trò chơi giải đố javascript
Nội dung chính Show
Cải thiện kỹ năng JavaScript của bạn với một dự án thú vịNhững gì chúng tôi sẽ tạo ra!Bài đăng này xuất hiện lần đầu tiên trên blog cá nhân của tôi Này yo! Trong bài đăng này, chúng tôi sẽ tạo ra một trò chơi với các kỹ năng thiết kế web cơ bản. Tất cả những gì bạn cần là kiến thức cơ bản về HTML, CSS và JavaScript. Trò chơi chúng tôi đang thực hiện là 8 trò chơi câu đố phổ biến. Nó được làm bằng 9 viên gạch với 8 trong số chúng chứa đầy nội dung và cái cuối cùng trống rỗng. Để giải câu đố, người chơi sẽ phải sắp xếp lại các viên gạch. Mở trình chỉnh sửa văn bản yêu thích của bạn, tôi đang sử dụng VSCODE và tạo các tệp sau: Cấu trúc thư mục dự ánBây giờ chúng tôi tạo một bộ chứa Div với một danh sách không có thứ tự có 9 phần tử danh sách trong * {6: Bây giờ, hãy để thêm một số kiểu dáng. Đầu tiên, tôi đã loại bỏ phần đệm và ký quỹ mặc định bằng cách chọn mọi phần tử trên trang bằng cách sử dụng ________ 17. Tôi cũng biến phần thân máy trở thành một thùng chứa flex để chúng ta có thể sử dụng flexbox để tạo kiểu trang. DIV container được cung cấp chiều cao và chiều rộng 500px và một nền đẹp đi cùng với nền cơ thể.I also made the body a flex container so that we can use flexbox to style the page. The container div is given a height and width of 500px and a nice background that goes along with the body’s background. Dòng này * {8; Trung tâm sắp xếp các div container bằng cách cho nó một biên độ 10px ở trên cùng và dưới cùng và một lề tự động (bằng) ở bên trái và bên phải. * {9 * { Xem trước * {6 Trong trình duyệt yêu thích của bạn, bạn cũng nên có điều này: Bây giờ, hãy để phong cách các mục danh sách. Tôi cũng sẽ biến 1 thành một thùng chứa flex và không gian các mục trong danh sách đều: Lưu ý: Một số người dùng đã báo cáo rằng căn chỉnh 2 không nhất quán trên các trình duyệt Firefox và Edge, tôi khuyên bạn nên xem dự án này trong trình duyệt Google Chrome hoặc tìm bản sửa lỗi cho trình duyệt cụ thể của bạn.: Some users have reported that 2 không nhất quán trên các trình duyệt Firefox và Edge, tôi khuyên bạn nên xem dự án này trong trình duyệt Google Chrome hoặc tìm bản sửa lỗi cho trình duyệt cụ thể của bạn.: Some users have reported that 2 alignment isn’t consistent on FireFox and edge browsers, I recommend viewing this project in Google Chrome browser or find a fix for your particular browser. * {9 * { Xem trước * {6 Trong trình duyệt yêu thích của bạn, bạn cũng nên có điều này: Nice. Bây giờ, hãy để phong cách các mục danh sách. Tôi cũng sẽ biến 1 thành một thùng chứa flex và không gian các mục trong danh sách đều: Lưu ý: Một số người dùng đã báo cáo rằng căn chỉnh 8Tile: * {9 * {7 2 không nhất quán trên các trình duyệt Firefox và Edge, tôi khuyên bạn nên xem dự án này trong trình duyệt Google Chrome hoặc tìm bản sửa lỗi cho trình duyệt cụ thể của bạn.: Some users have reported that 2 alignment isn’t consistent on FireFox and edge browsers, I recommend viewing this project in Google Chrome browser or find a fix for your particular browser. * {9 * { * {8 * {6 một lần nữa, bạn nên có một cái gì đó như thế này: * {9 * {0 Trong câu đố trượt 8 gạch, gạch thứ 9 nên trống để chúng tôi sẽ tạo ra một lớp tạo kiểu cho gạch trống. Trước đó, hãy để cho cung cấp cho các nội dung mục danh sách, cập nhật * {6 để có nội dung sau (Iithve đã bao gồm liên kết cho 6Font); 7
Thêm phần sau vào bảng kiểu để tạo kiểu Xem trước một lần nữa: Thực hiện chức năng với JavaScriptHãy để thêm một tiêu đề đẹp trước container: Sau đây là các kiểu cho tiêu đề: Tôi đã bao gồm một liên kết đến draggable and some droppable, to do this we have to define drag and drop event handlers in the script file. Open up the* {73 and fill it up with the following contents: * {74 * {7 * {75 xử lý sự kiện * {76EMED khi người dùng bắt đầu kéo. Bởi vì chúng tôi sẽ chuyển dữ liệu trong khi kéo, chúng tôi lấy dữ liệu được đính kèm vào phần tử và thêm nó vào * {77Object, một đối tượng được sử dụng để giữ dữ liệu được kéo trong quá trình kéo và thả. * {71Font trong phần đầu: 7 * {3 * {78 * {2 Xem trước trang web một lần nữa, bạn nên có cái này: Boomshakala! Thiết kế của trò chơi đã hoàn tất, bây giờ, hãy để cho nó sống với JavaScript!Trong trình xử lý sự kiện * {81, chúng tôi nhận được * {82 trong * {77Object và sau đó chúng tôi chuyển nó sang phần tử mà chúng tôi đang thả cho đến: * {84 Trong * {85, chúng tôi xóa dữ liệu được lưu trữ trong * {86 khi sự kiện kéo kết thúc. Bây giờ, chúng tôi cần cập nhật tệp * {6, chúng tôi sẽ tạo ra mục danh sách trước khi gạch trống (‘h Hàn) có thể kéo và làm cho lớp trống trống có thể bỏ được. 7 * {3 Tôi đã đưa ra cả hai mục trong danh sách ID ID kể từ trong các trình xử lý sự kiện của chúng tôi, chúng tôi phải nhận nội dung của họ thông qua ID của họ (xem * {75 nơi chúng tôi có * {00). Ngói ‘H, được thực hiện * {01 và tôi cũng đặt nó các thuộc tính ____ ____52 và ____53 cho các trình xử lý sự kiện có liên quan. Gạch trống được thực hiện ____54 và hiện nó có các thuộc tính cho xử lý * {05and * {06Event.The empty tile is made * {04 and it now has attributes for * {05and * {06event handling. The empty tile is made * {04 and it now has attributes for * {05and * {06event handling. Xem trước trang web, kéo và thả gạch ‘h cho đến ô trống: Tính năng kéo và thả hoạt động, nhưng có một vấn đề. Sau khi bỏ nội dung của gạch ‘H, giờ đây chúng ta có hai gạch có‘ H, trong đó. Chúng ta sẽ cần phải làm trống gạch đầu tiên sau khi hoạt động thả. Sau đó, chúng tôi sẽ thay đổi kiểu dáng của gạch sau khi kéo và thả hoạt động. Để làm trống gạch nguồn sau khi hoạt động thả, hãy cập nhật tệp tập lệnh như sau: * {74 * {0 Chuyển tất cả chức năng sang JavaScriptCác ô hiện có nội dung được xác định trong tệp HTML, chúng tôi sẽ xóa các nội dung đó và điền chúng vào JavaScript. Cập nhật * {08File như sau: 7 * {1 Trong loại * {73 theo sau: * {31 Đầu tiên tôi có tất cả các * {32Items thành * {33 (một cái gì đó giống như một mảng) bằng cách sử dụng * {34. Mảng * {35 có danh sách các chữ cái và mục cuối cùng là chuỗi trống, đây là cho gạch trống. Trong hàm * {36, tôi đặt ID cho từng mục danh sách bằng cách gọi hàm * {37 trên mỗi mục, ID được tạo bằng cách đồng thuận tiền tố * {38 với chỉ số của vòng lặp For. Trong hàm * {36, tôi đặt ID cho từng mục danh sách bằng cách gọi hàm * {37 trên mỗi mục, ID được tạo bằng cách đồng thuận tiền tố * {38 với chỉ số của vòng lặp For. * {39, tôi lặp qua tất cả các mục * {38 trong khi theo dõi chỉ mục của chúng, * {71 và tôi điền vào mỗi * {72 với một phần tử từ mảng * {35, truy cập nó với chỉ mục * {71. Nếu bạn xem trước trang web, bạn có các ô được lấp đầy như chúng tôi đã có trước đó, nhưng bây giờ chúng tôi đang làm điều đó từ JavaScript. Tuyệt vời :) (Don Tiết lo lắng về màn hình của gạch trống chưa)Ngẫu nhiên các gạch Các gạch được lấp đầy với nội dung của các chữ cái từ A-H, với tập lệnh hiện tại, chúng ta sẽ luôn có cùng cấu hình của các ô. Những gì chúng tôi muốn là các gạch nên được xáo trộn để chúng tôi luôn có được một cấu hình ngẫu nhiên mà sau đó phải được sắp xếp lại để giải câu đố.Xáo trộn các mảng `` Letters` trước khi điền vào Làm thế nào chúng ta có thể viết một chức năng sẽ xáo trộn mảng? Thuật toán cho hàm này như sau - vòng lặp qua mảng - cho mỗi chỉ mục I trong vòng lặp, chọn một chỉ số ngẫu nhiên khác J - các phần tử hoán đổi tại Index I và J — Loop through the array — For each index i in the loop, pick another random index j — swap elements at index i and j * {31 Dừng lại!!! Cố gắng thực hiện thuật toán này trước khi xem việc thực hiện của tôi. Bạn đã nghĩ ra một cái gì đó tương tự? * {76 của mảng trong hàm xáo trộn trước khi xáo trộn nó, điều này đảm bảo rằng chúng tôi không thay đổi (a.k.a * {77) được truyền trong mảng nhưng trả lại một cái mới xáo trộn.Bây giờ, hãy cập nhật chức năng * {39 để xáo trộn mảng trước khi điền vào các ô: * {31 Bây giờ khi bạn làm mới trang, bạn sẽ nhận được một cấu hình mới của gạch mỗi lần!Đặt gạch có thể bỏ rơi và kéo theo Bây giờ, chúng tôi sẽ viết một chức năng sẽ tham gia vào danh sách các mục* {38, tìm mã có nội dung trống và làm cho nó có thể giảm được. Chúng tôi cũng sẽ viết một chức năng sẽ tạo tất cả các ô trên trang có thể kéo, chúng tôi sẽ thay đổi chức năng này sau đó để nó chỉ có các gạch trên đỉnh, dưới, trái và bên phải của gạch trống sẽ có thể kéo. Trước các chức năng này, chúng tôi sẽ tạo hàmBạn đã nghĩ ra một cái gì đó tương tự? Lưu ý rằng tôi đã tạo ra mộtNếu bạn xem trước trang, bạn sẽ nhận thấy rằng bạn có thể thả gạch xuống gạch trống nhưng khi bạn làm, gạch được lấp đầy nhưng nó vẫn được tạo kiểu như gạch trống và nó là gạch duy nhất mà bạn có thể thả gạch. Bây giờ chúng tôi sẽ cập nhật ứng dụng để, khi một ô trống được thả xuống từ một Nguồn gạch, nó sẽ trở nên lấp đầy và nó không thể bỏ rơi nữa. Hãy nhớ rằng chúng tôi đã sử dụng hàm * {28 để đặt thuộc tính, chúng tôi sẽ sử dụng cùng một hàm để xóa thuộc tính, chúng tôi sẽ đặt giá trị của thuộc tính chúng tôi muốn xóa thành một chuỗi trống. Sau đó chúng tôi sẽ làm cho Droppable Nguồn và trống: * {74 Kiểm tra ứng dụng ngay bây giờ và bạn sẽ thấy rằng mỗi khi bạn kéo và thả một viên gạch, nguồn trở thành một gạch trống và đích sẽ được lấp đầy !. Bạn cũng sẽ nhận thấy rằng bạn có thể kéo và thả gạch không liền kề với gạch trống, sau đó chúng tôi sẽ sửa chữa cái này. Nhận trạng thái trò chơi và kích thướcMỗi khi người chơi kéo và thả một viên gạch, sự sắp xếp của các viên gạch thay đổi, chúng tôi muốn theo dõi sự thay đổi này trong đối tượng * {30. Hãy để tạo ra một chức năng có trạng thái. Chúng tôi cũng sẽ tạo ra một chức năng sẽ lưu trữ biểu diễn trực quan của các gạch như một mảng mảng. Cập nhật tệp * {31 như sau: * {74 Hàm * {33 vòng lặp qua nội dung (là một mảng của các chữ cái có độ dài 9) ba lần, mỗi lần cắt ba nội dung và đặt chúng vào một mảng, điều này cho chúng ta một mảng 3 mảng. Mảng đầu tiên đại diện cho hàng đầu tiên của trò chơi, mảng thứ hai đại diện cho hàng thứ hai và mảng thứ ba đại diện cho hàng thứ ba. Điều này có nghĩa là bây giờ chúng tôi có trạng thái trò chơi được lưu trữ ở hai định dạng: * {34 lưu trữ các ô theo trình tự tuyến tính (mảng 1D); * {35 lưu trữ các ô trong một mảng 2D làm biểu diễn trực quan của nó. State.Content vs State.dimension Trong hàm * {21, tôi đã đăng xuất đầu ra của hàm * {33, bạn sẽ thấy rằng nó lưu trữ biểu diễn trực quan của trò chơi trong một mảng 2D đẹp. Lưu ý rằng tôi đã thêm một dòng mới vào hàm * {38 để lưu trữ chỉ mục của gạch trống trong trạng thái ứng dụng, * {39; Chỉ mục được lưu trữ ở đây là chỉ mục từ mảng tuyến tính 1D của các mục * {38.empty tile in the app state, * {39; The index stored here is the index from the 1D linear array of * {38 items.empty tile in the app state, * {39; The index stored here is the index from the 1D linear array of * {38 items. Nhận ô trốngChúng ta cần có được ô trống để chúng ta chỉ có thể tạo ra các ô liền kề của nó có thể kéo được. Hiện tại chúng ta có thể kéo bất kỳ gạch nào cho đến gạch trống, xem hình ảnh bên dưới. Trong mỗi hình ảnh, chỉ có gạch chấm (màu đỏ) có thể kéo được: Chúng tôi sẽ tạo chức năng * {01 sẽ trả về các vị trí 2D của ô trống từ * {35. Chúng tôi đã có chỉ số của ô trống được lưu trữ trong * {03 lưu trữ chỉ số 1D của ô trống. Cách lấy vị trí 2D từ chỉ mục 1DChúng tôi sẽ thực hiện một số toán học để tính toán vị trí 2D của ô trống từ chỉ số 1D. Đại diện 2D của trò chơi có 3 hàng và 3 cột; Nó bao gồm tổng cộng 9 gạch. ____104 chứa chỉ số tuyến tính của ô trống, vì các chỉ số của mảng bắt đầu từ 0, số ô thực tế của mảng trống sẽ là * {05. Để có được hàng trong đó rơi xuống, chúng tôi sẽ chia số ô cho 3, (số lượng ô liên tiếp). Chúng tôi lấy kết quả * {06of, đây là số hàng trong đó rơi xuống. Có được cột trong đó các ô trống rơi khá khó khăn; Chúng tôi nhân số * {07 với 3 và trừ * {08 khỏi kết quả, sau đó chúng tôi trừ tổng kết quả từ 3. Tạo hàm * {01 ngay sau chức năng * {10: * {74 Chỉ tạo các gạch liền kề thành ô trống có thể kéoBây giờ chúng ta có một cách để có được vị trí ô trống, chúng ta chỉ có thể tạo ra các ô liền kề xung quanh nó có thể kéo. Một ô trống có thể có một ô ở trên, bên dưới, ở bên trái hoặc bên phải của nó có thể kéo được. Một ô trống đôi khi có thể không có tất cả 4 mặt liền kề: Làm thế nào chúng ta có thể có được các chỉ số của các viên gạch liền kề với gạch trống? Hãy lấy một ví dụ: Trong ví dụ trên, gạch trống nằm trên hàng 1 và col 1. Các ô bên trái và bên phải của nó đều nằm trên cùng một hàng 1. Ngói bên trái nằm trên col 0 (hàng gạch trống - 1). Ngói bên phải là trên col 2 (hàng gạch trống + 1). Tương tự, các gạch trên cùng và dưới cùng trên cùng 1 với gạch trống nhưng trên hàng 0 và hàng 2 tương ứng. Hãy để cập nhật chức năng * {12:Let’s update the * {12 function: Let’s update the * {12 function: Bây giờ, chúng tôi nhận được các gạch liền kề và chỉ làm cho những viên gạch có thể kéo được. Nếu bạn đã kiểm tra trò chơi đủ, bạn sẽ nhận thấy rằng một số gạch đã được tạo ra khi một viên gạch trống liền kề với chúng vẫn còn kéo sau khi tệp trống như đã được lấp đầy.Test the game, you will notice that only the tiles adjacent to the empty tile are draggable. If you tested the game enough, you will notice that some tiles that have been made draggable when an empty tile was adjacent to them are still draggable after the empty file as been filled up. Làm thế nào chúng ta có thể khắc phục điều này? Đơn giản: Chúng tôi cần cập nhật trạng thái ứng dụng và kích thước mỗi khi chúng tôi hoàn thành lực kéo và thả. Cập nhật tệp * {131 như sau:Simple: We need to update the app state and dimension every time we complete a drag and drop. Update the * {31 file as follows: * {31Simple: We need to update the app state and dimension every time we complete a drag and drop. Update the * {31 file as follows: * {31 Vẫn còn một vấn đề tinh tế tương tự như vấn đề chúng tôi vừa giải quyết. Tất cả các gạch mà chúng tôi có thể làm được khi chúng trống vẫn có thể thả ngay cả khi chúng được lấp đầy, giờ đây chúng tôi sẽ tạo ra một chức năng (được gọi là * {15) sẽ khiến một viên gạch không thể vượt qua được khi nó được lấp đầy. Chúng tôi sẽ gọi chức năng này trong hàm * {85. Tạo hàm * {15 sau hàm * {38 và gọi nó trong hàm * {85 như sau: * {74 Cho đến các bước cuối cùngTrò chơi gần như hoàn tất, bây giờ chúng tôi phải kiểm tra xem người dùng đã sắp xếp các viên gạch theo đúng thứ tự. Trước đó, có một thuộc tính quan trọng của Ngói 8-Puzle mà chúng ta cần xem xét: nó không phải là tất cả các cấu hình có thể giải quyết được.it’s not all configurations that are solvable.it’s not all configurations that are solvable. Vì chúng tôi đang chọn ngẫu nhiên các gạch, nên có thể có được một cấu hình không thể giải quyết được. Làm thế nào để chúng tôi biết nếu một trường hợp nhất định của câu đố có thể giải quyết được không? Một trường hợp nhất định của 8 câu đố chỉ có thể giải được nếu số lượng đảo ngược là một số chẵn trong cấu hình... Những gì mà một sự đảo ngược? Một sự đảo ngược xảy ra khi một cặp gạch nằm trong * {21Order vì chúng phải ở trong cấu hình chính xác. Ví dụ: với cấu hình sau: * {3 Có hai nghịch đảo trong cấu hình (h, f) và (h, g), vì số lượng nghịch đảo là hai (một số chẵn), cấu hình này sẽ có thể giải quyết được. Để biết nếu một cấu hình nhất định là có thể giải quyết được, chúng tôi đếm số lượng đảo ngược. làm sao chúng ta làm việc đó bây giờ? Đơn giản: Chúng tôi chọn từng phần tử và so sánh nó với các phần tử khác sau nó, nếu phần tử thứ nhất là ‘lớn hơn yếu tố thứ hai, thì chúng tôi đã gặp phải sự đảo ngược. Mở tệp * {243 và tạo hàm * {23 ngay trước hàm * {39, chúng tôi cũng sẽ cập nhật hàm * {39 để chỉ điền vào các ô nếu cấu hình được tạo có thể giải quyết được:: We pick each element and compare it with other elements after it, if the first element is ‘greater’ than the second element, then we have encountered an inversion. Open up the 3 và tạo hàm * {23 ngay trước hàm * {39, chúng tôi cũng sẽ cập nhật hàm * {39 để chỉ điền vào các ô nếu cấu hình được tạo có thể giải quyết được:: We pick each element and compare it with other elements after it, if the first element is ‘greater’ than the second element, then we have encountered an inversion. Open up the * {73 file and create an * {23 function right before the * {39 function, also we we will update the * {39 function to only fill the tiles if the generated configuration is solvable: * {31 Bây giờ chúng tôi chắc chắn rằng cấu hình sẽ luôn có thể giải quyết được! Kiểm tra giải pháp chính xácBây giờ chúng tôi phải kiểm tra khi một người chơi đã giải câu đố. Chúng tôi sẽ tạo một hàm * {27 sẽ sử dụng các mảng * {34 và * {35, chuyển đổi cả hai mảng thành một chuỗi và sau đó so sánh cả hai chuỗi để kiểm tra xem chúng có bằng nhau không. Tạo chức năng sau chức năng * {30: * {31 * {4 Khi nào chúng ta kiểm tra giải pháp? Vào cuối mỗi sự kiện kéo, vì vậy chúng tôi phải cập nhật chức năng * {85: Hãy thử trò chơi, khi sắp xếp chính xác, thông báo được đăng nhập vào bảng điều khiển. Chúng tôi sẽ muốn người chơi trong trò chơi của chúng tôi kiểm tra bảng điều khiển để biết khi nào họ giải câu đố. Chúng tôi sẽ tạo ra một phương thức sẽ bật lên khi câu đố như đã được giải quyết, tôi sẽ di chuyển nhanh một chút, các mã dễ hiểu: * {406 * {5 * {34 * {31 Hãy thử trò chơi ngay bây giờ: Congratulations!!!Ồ! Đó là một chuyến đi dài, tôi hy vọng bạn đã học được một số thứ mới và vui chơi trong khi xây dựng 8 trò chơi giải đố. Mã hoàn chỉnh là trên GitHub ở đây. Chia sẻ bài đăng này nếu bạn thấy nó hữu ích và bạn có thể theo dõi tôi trên Twitter @solathecoder để biết các bài viết công nghệ tuyệt vời hơn. Cho đến khi chúng ta gặp lại nhau, mã hóa hạnh phúc! Một ghi chú từ nhóm tiếng Anh đơn giảnBạn có biết rằng chúng tôi có bốn ấn phẩm và một kênh YouTube? Bạn có thể tìm thấy tất cả những điều này từ trang chủ của chúng tôi tại PlainEnglish.io - cho thấy một số tình yêu bằng cách cung cấp cho các ấn phẩm của chúng tôi theo dõi và đăng ký kênh YouTube của chúng tôi!plainenglish.io — show some love by giving our publications a follow and subscribing to our YouTube channel!plainenglish.io — show some love by giving our publications a follow and subscribing to our YouTube channel! Bạn có thể viết một trò chơi trong HTML không?Yếu tố này là hoàn hảo để tạo ra các trò chơi trong HTML. Phần tử cung cấp tất cả các chức năng bạn cần để làm trò chơi. Sử dụng JavaScript để vẽ, viết, chèn hình ảnh, và nhiều hơn nữa, vào.. The. The Element cung cấp tất cả các chức năng bạn cần để làm trò chơi.Sử dụng JavaScript để vẽ, viết, chèn hình ảnh, và nhiều hơn nữa, vào. |