Hoạt hình Sprite. Hoạt hình sprite thích ứng với ImageMagick và GreenSock

Thuật ngữ "sprite" xuất hiện khi máy tính học cách kết hợp hình ảnh chuyển động với nền tĩnh. Điều này xảy ra vào giữa những năm bảy mươi của thế kỷ trước. Phần cứng đầu tiên có thể hiển thị hình ảnh với các họa tiết trên màn hình là con chip này của Texas Instruments, được sử dụng rộng rãi trong các máy tính gia đình và máy tính cá nhân. trình điều khiển game vào đầu những năm tám mươi.

Nếu một sprite là một bức ảnh tĩnh thì một loạt các bức ảnh này nhanh chóng thay thế nhau tạo thành một hình ảnh động được gọi là sprite. Loại này hoạt hình khác ở chỗ không phải toàn bộ khung hình (frame) thay đổi trên màn hình mà chỉ một phần nhỏ trong đó xuất hiện các hình họa tiết. Hoạt hình Sprite đôi khi còn được gọi là hoạt hình phần mềm.

Khi máy tính còn lớn, các họa tiết rất nhỏ, có kích thước 8 x 8 pixel và có thể tô màu 4-8 màu. Người anh hùng nổi tiếng nhất của trò chơi sprite đầu tiên là Mario được mọi người yêu thích. Do kích thước nhỏ bé của sprite nên không thể vẽ miệng cho nhân vật này: đây là cách bộ ria mép đặc trưng của Mario xuất hiện và người anh hùng trở nên dễ nhận biết.

Khi sức mạnh máy tính tăng lên, các họa tiết ngày càng lớn hơn, có đủ màu sắc, ngày càng giống các nhân vật hoạt hình có thật. Đỉnh cao của sự lan rộng của hoạt hình sprite xảy ra vào những năm 1990: cả trên máy tính và máy chơi game, thể loại “game đối kháng” phát triển mạnh mẽ, nơi mọi người đều có thể cảm thấy giống như Bruce Lee. Thể loại “hành động” phổ biến lúc bấy giờ trong điện ảnh đã góp phần tạo nên điều này. Ai trong chúng ta chưa chơi Mortal Kombat, dựa trên đó một bộ phim thậm chí còn được làm! Những "trò chơi chiến đấu" này hoàn toàn dựa trên sprite.

Các họa tiết mẫu từ trò chơi Street Fighter

Tuy nhiên, thể loại “nền tảng arcade” thậm chí còn trở nên phổ biến hơn, nơi hoạt hình sprite thực sự thống trị. Vào đầu những năm 90, một kỷ nguyên phục hưng bắt đầu tại xưởng phim Disney: những kiệt tác mới ra đời năm này qua năm khác. Trò chơi dựa trên phim hoạt hình nổi tiếng của studio đang có nhu cầu chưa từng có. Khả năng của hoạt hình sprite đã tăng lên rất nhiều đến mức trong một trò chơi điện tử, bạn có thể đắm mình trong bầu không khí của phim hoạt hình theo đúng nghĩa đen. Các trò chơi thực sự là những kiệt tác - phù hợp với các tính năng hoạt hình nguyên bản! "Aladdin", "The Lion King", "Hercules", "The Jungle Book" và nhiều trò chơi khác có logo Disney mãi mãi được đưa vào bộ sưu tập trò chơi điện tử vàng. Đây thực sự là thời hoàng kim của hoạt hình sprite.

Arcade Vua sư tử (1994)

Tất cả các họa tiết tạo nên hoạt ảnh đều được lưu trữ trong tập tin đặc biệt dưới dạng một bản đồ raster lớn (bitmap). Hình ảnh này được gọi là "bản đồ" vì chương trình trò chơi liên tục tìm kiếm sprite mong muốn theo tọa độ. Giả sử vùng hoạt ảnh là 16 x 32 pixel và điểm bắt đầu trên bitmap tại thời điểm cần thiết là pixel thứ 84 theo chiều ngang và pixel thứ 460 theo chiều dọc. Dữ liệu này được lập trình viên nhập vào mã trò chơi. Do đó, bitmap là một loại “bảng phân cảnh” của hoạt hình sprite, được “gắn cứng” vào mã chương trình và ẩn khỏi người xem bên ngoài. Ví dụ: đây là “bảng phân cảnh” của trò chơi “The Lion King”, nhân vật là Simba bé nhỏ:

Một thể loại trò chơi phổ biến khác sử dụng các họa tiết là nhiệm vụ hoạt hình. Điều đáng chú ý là ngày nay đây có lẽ là thể loại trò chơi duy nhất dành cho máy tính để bàn, nơi hoạt hình sprite vẫn được sử dụng rộng rãi. Nhiều người trong chúng ta đã quen thuộc với các trò chơi trong loạt trò chơi “Petka và Vasily Ivanovich”, “Anh em phi công” và các nhiệm vụ hoạt hình trong nước nổi tiếng khác. Họ cũng dựa trên sprite.

Ảnh chụp màn hình trò chơi "Anh em phi công: Theo bước chân voi sọc" (1997)

Bước sang thiên niên kỷ mới, hoạt hình truyền thống bắt đầu nhường chỗ cho hoạt hình 3D. Điều tương tự cũng xảy ra trên thế giới trò chơi máy tính- các ký tự sprite bắt đầu được thay thế bằng các ký tự đa giác. Ngay cả những trò chơi dựa trên phim hoạt hình mới của Disney, được làm bằng kỹ thuật hoạt hình cổ điển, cũng được chuyển sang không gian ba chiều. Ví dụ - "Tarzan", "Lilo and Stitch", "Brother Bear", "The Princess and the Frog".

Ảnh chụp màn hình trò chơi "Anh Gấu" (2002)

Tuy nhiên, hoạt hình sprite vẫn chưa biến mất khỏi hiện trường. Nó tiếp tục được sử dụng rộng rãi trong thiết kế (hãy nhớ đến những "người trợ giúp" trước đó Phiên bản Microsoft Office), trong các chương trình giáo dục cũng như trong trò chơi - chủ yếu dành cho thiêt bị di động. Ngoài ra, ngày nay, các họa tiết được sử dụng trong hoạt ảnh Flash và GIF, nhưng chúng không được lưu trữ dưới dạng bitmap mà ở định dạng tệp đồ họa nhiều lớp, trong đó mỗi khung hoạt ảnh được đặt trên một lớp riêng biệt. Trong Adobe After Effects, bạn có thể đặt hoạt ảnh được tạo từ một chuỗi vào một cảnh tập tin đồ họa. Nói đúng ra đây cũng là hoạt hình sprite, chỉ có điều nguồn của sprite không phải là hình ảnh nhiều lớp hay bitmap mà là thư mục riêng trên máy tính. Vì vậy, các sprite, giống như những nàng tiên ma thuật, luôn sẵn sàng đến giải cứu người làm phim hoạt hình, đặc biệt là khi tạo trò chơi! :)

Các họa tiết trong trò chơi Angry Birds (2009)


Các nhân vật trong trò chơi Dust: an Elysian Tail (2012)

Ngày 12 tháng 10 năm 2011 lúc 12:00

Hoạt hình các họa tiết bằng CSS, JS và Canvas

  • Phát triển trang web,
  • Tranh sơn dầu

Chào mọi người. Cách đây vài ngày, khá tình cờ, tôi tình cờ thấy “Space Rangers 2: Dominators” trong bộ đệm đĩa. Tôi đã không cài đặt nó, vì bây giờ tôi không có đủ thời gian để đắm mình vào nó. Tôi quyết định xem những gì trên đĩa. Tôi đã xem Fan Art và ở đó tôi thấy một chương trình khai thác tài nguyên kiểm lâm. Vì vậy, tôi quyết định xem những kẻ thống trị của chúng tôi được làm bằng gì. Sau khi nhấp chuột một lúc, tôi tìm thấy các tệp có hình ảnh động ở định dạng GAI. Tôi bắt đầu ngưỡng mộ hoạt hình đó. Tôi muốn lưu chúng dưới dạng “gif”, nhưng tại sao chương trình đó không cho phép tôi lưu ảnh động? Bạn có thể lưu khung hiện tại hoặc tất cả các tệp dưới dạng PNG. Tôi quyết định lưu tất cả các khung hình và có 150 khung hình, tất cả các hình ảnh đều ở đó, tại sao không tạo hoạt ảnh tương tự với chúng.

Ma

Để làm hài lòng bản thân với hoạt hình như vậy, tôi đã nhờ CSS + JS trợ giúp. Tôi nên làm gì với 150 file hình ảnh? Trọng lượng của chúng không quan trọng, mặc dù tổng cộng chúng nặng hơn một megabyte. Những vấn đề chính với họ tải đồng thời và sự thao túng. Vì thế tôi quyết định “dán” chúng lại thành một. Chỉ tải một và sử dụng CSS + JS, bạn sẽ chỉ phải định vị chính xác.
Tất cả những gì còn lại là chọn phương pháp "dán". Tôi là một lập trình viên, và tất cả chúng tôi đều lười biếng :), vì vậy tôi ngay lập tức loại bỏ việc dán thủ công biên tập đồ họa. Trước hết, như thường lệ, tôi lao vào thư viện PHP và GD. Nhưng nó còn nhiều điều chưa được mong muốn khi làm việc với các PNG trong suốt. Sau đó tôi nghĩ, mình có thể dùng gì khác để “gắn” các bức tranh lại với nhau? Và tôi đã giải quyết được thứ hiện đang có trên môi mọi người, thứ hiện được coi là thời trang - HTML5. Anh ấy chịu trách nhiệm làm việc với đồ họa - Canvas, và tôi thực sự thích điều này. Đó là lý do tại sao tôi quyết định “dán” nó lên “bức tranh”.
Và vì vậy tôi sẽ thêm thẻ này vào HTML:

Không được hỗ trợ
Trong JS, tôi sẽ chỉ định mặt nạ cho tên của ảnh, ảnh đầu tiên và số của ảnh cuối cùng (tôi không phải đổi tên các ảnh vì chúng đều theo thứ tự). Nó sẽ trông giống như thế này:

Var đầu tiên = "000"; // phần số của tên ảnh đầu tiên var Last = 49; //số ảnh cuối cùng var num = 0; //iterator var MaskFileName = ["2HULL_PEOPLE_P_A_", ".png"];//tên hình ảnh mặt nạ var dir = "ship"; //thư mục chứa ảnh

Bây giờ bạn có thể chỉ định kích thước của sprite bạn muốn lấy và lấy bối cảnh của nó:

Var canvas = document.getElementById("sprite"); // chọn canvas canvas.width của chúng tôi = (last + 1) * 75; //đặt chiều rộng, tùy thuộc vào số lượng canvas.height = 75; chiều rộng var = 0; //biến trong đó chúng ta sẽ ghi lại shift var context = canvas.getContext("2d"); // lấy bối cảnh

Để thuận tiện cho việc chuyển đổi từ số sang chuỗi (tương tự str_pad từ PHP), tôi đã viết một hàm chuyển đổi có tên hoang dã - zerofikator():

Hàm zerofikator(int, length) ( // khi nhập vào, chúng ta lấy số và độ dài của chuỗi var prefix = ""; for (var i = num.toString().length; i< length; i++) { prefix += "0"; } return prefix + num; }

Hàm draw() ( var img = document.createElement("img"); /* mỗi lần gọi hàm này, chúng ta tạo một đối tượng hình ảnh mới */ img.onload = function () ( // khi hình ảnh được tải, chúng ta vẽ với nó trên canvas context.drawImage(img, width, 0); width += 75; // mỗi lần chúng ta dịch chuyển nó theo chiều rộng của hình ảnh để vẽ sang bên phải của hình ảnh trước đó chứ không phải trên đó if (zerofikator(num, first.length) != zerofikator(last, first.length)) ( //kiểm tra xem chúng ta đã đến bản vẽ cuối cùng chưa num++; //tăng iterator draw(); //và chạy lại hàm ) ) img.src = dir + "/" + mặt nạFileName + zerofikator( num, first.length) + mặt nạTên tệp; //thu thập tên của tệp hình ảnh để tải) draw(); //gọi hàm lần đầu tiên

Sau khi khởi chạy một trang như vậy, chúng ta sẽ thấy một hình ảnh rộng từng khung hình, nếu lưu nó, chúng ta có thể gọi nó là một hình ảnh. Nhân tiện, sprite đã lưu nặng 615 KB và 150 bức ảnh nặng 1.189 KB, hmm, đó là một điểm cộng nữa :).

Tôi quyết định thêm trực tiếp phép chuyển đổi vào tệp bằng cách nhấp vào khung vẽ (giải quyết vấn đề lưu đối với một số trình duyệt):

Canvas.onclick = function () ( window.location = context.canvas.toDataURL("image/png"); );

Hoạt hình

Chà, bây giờ chúng ta có thể bắt đầu hoạt hình.
Chúng tôi thêm một vài “cô gái” vào HTML mà chúng tôi sẽ làm việc tiếp theo:

Kiểu Var = (); styles.cursor = "con trỏ"; // để làm rõ rằng đây là phần tử của chúng ta, hãy thay đổi con trỏ styles.width = "75px"; // kích thước phần tử styles.height = "75px"; var elementId = "súng"; // id của phần tử chứa hoạt ảnh sẽ là var imgName = "canvas.png"; // tên file sprite

Hàm spriteAnimation(elementId, imgName, styles) ( var img = document.createElement("img"); var offset = 0; img.onload = function () ( //ngay khi sprite được tải var element = document.getElementById (elementId); element.style.cursor = style.cursor; element.style.width = styles.width; element.style.height = styles.height; element.style.background = "url("" + imgName + "" ) " + offset + "px 50%"; //thay đổi kiểu cho phần tử của chúng ta var i = 0; element.onmouseover = function() ( //đính kèm trình xử lý di chuột interval = setInterval(function() ( //chạy khoảng nếu (bù< img.width) { //для смены позиции изображения i++; // если дошли до конца спрайта } else { i = 0; // то возвращаемся к началу } offset = 75 * i; //сдвиг по слайду element.style.background = "url("" + imgName + "") " + offset + "px 50%"; //меняем позиционирование спрайта } , 1000/24) //24 кадра в секунду } element.onmouseout = function(){ //вешаем обработчик на убирание курсора мыши clearInterval(interval) //удаляем интервал (прекращаем анимацию) } } img.src = imgName; //даем имя нашего спрайта }

Ồ vâng, bạn cũng cần gọi hàm này:

SpriteAnimation(elementId, imgName, styles); spriteAnimation("ship", "ship.png", styles);

Và để làm cho nó trông phù hợp, bạn có thể thêm ảnh có nền và định vị chính xác:

Hoạt hình Sprite là một trong những thứ mà mặc dù còn nguyên thủy nhưng vẫn hoạt động thành công và được sử dụng trong đô họa may tinh và trò chơi trong hơn một phần tư thế kỷ. Ngay cả các trò chơi 3D cũng có các họa tiết - ví dụ như bảng quảng cáo vụ nổ. Nhiều trình duyệt và trò chơi flash sử dụng hoạt ảnh sprite vì nó rất đơn giản và không yêu cầu hiệu suất cao- chỉ cần chuyển khung hình và thế là xong!

Nếu một sprite là một bức ảnh tĩnh thì một loạt các bức ảnh này nhanh chóng thay thế nhau tạo thành một hình ảnh động được gọi là sprite. Loại hoạt hình này khác ở chỗ nó không phải là toàn bộ khung hình (frame) thay đổi trên màn hình mà chỉ là một phần nhỏ trong đó xuất hiện các họa tiết. Hoạt hình Sprite đôi khi còn được gọi là hoạt hình phần mềm.

Khi máy tính còn lớn, các họa tiết rất nhỏ, có kích thước 8 x 8 pixel và có thể tô màu 4-8 màu. Người anh hùng nổi tiếng nhất của trò chơi sprite đầu tiên là Mario được mọi người yêu thích. Do kích thước nhỏ bé của sprite nên không thể vẽ miệng cho nhân vật này: đây là cách bộ ria mép đặc trưng của Mario xuất hiện và người anh hùng trở nên dễ nhận biết.

Khi sức mạnh máy tính tăng lên, các họa tiết ngày càng lớn hơn, có đủ màu sắc, ngày càng giống các nhân vật hoạt hình có thật. Đỉnh cao của sự lan rộng của hoạt hình sprite xảy ra vào những năm 1990: cả trên máy tính và máy chơi game, thể loại “game đối kháng” phát triển mạnh mẽ, nơi mọi người đều có thể cảm thấy giống như Bruce Lee. Thể loại “hành động” phổ biến lúc bấy giờ trong điện ảnh đã góp phần tạo nên điều này. Ai trong chúng ta chưa chơi Mortal Kombat, dựa trên đó một bộ phim thậm chí còn được làm! Những "trò chơi chiến đấu" này hoàn toàn dựa trên sprite.

Bước sang thiên niên kỷ mới, hoạt hình truyền thống bắt đầu nhường chỗ cho hoạt hình 3D. Điều tương tự cũng xảy ra trong thế giới trò chơi máy tính - các nhân vật sprite bắt đầu được thay thế bằng các nhân vật đa giác. Tuy nhiên, hoạt hình sprite vẫn chưa biến mất khỏi hiện trường. Nó tiếp tục được sử dụng rộng rãi trong thiết kế (hãy nhớ đến những “người trợ giúp” từ nhiều nơi khác). phiên bản trước Office), trong các chương trình giáo dục cũng như trong trò chơi - chủ yếu dành cho thiết bị di động. Ngoài ra, ngày nay các họa tiết được sử dụng trong hoạt hình Flash và GIF, nhưng chúng không được lưu trữ dưới dạng bitmap mà ở định dạng tệp đồ họa nhiều lớp, trong đó mỗi khung hình hoạt hình được đặt trên một lớp riêng biệt. Trong Adobe After Effects, bạn có thể đặt hoạt ảnh được tạo từ một chuỗi tệp đồ họa vào một cảnh. Nói đúng ra thì đây cũng là hoạt hình sprite, chỉ có điều nguồn gốc của sprite không phải là hình ảnh nhiều lớp hay bitmap mà là một thư mục riêng trên máy tính. Vì vậy, các sprite, giống như những nàng tiên ma thuật, luôn sẵn sàng đến giải cứu người làm phim hoạt hình, đặc biệt là khi tạo trò chơi!

Chào mọi người. Cách đây vài ngày, khá tình cờ, tôi tình cờ thấy “Space Rangers 2: Dominators” trong bộ đệm đĩa. Tôi đã không cài đặt nó, vì bây giờ tôi không có đủ thời gian để đắm mình vào nó. Tôi quyết định xem những gì trên đĩa. Tôi đã xem Fan Art và ở đó tôi thấy một chương trình khai thác tài nguyên kiểm lâm. Vì vậy, tôi quyết định xem những kẻ thống trị của chúng tôi được làm bằng gì. Sau khi nhấp chuột một lúc, tôi tìm thấy các tệp có hình ảnh động ở định dạng GAI. Tôi bắt đầu ngưỡng mộ hoạt hình đó. Tôi muốn lưu chúng dưới dạng “gif”, nhưng tại sao chương trình đó không cho phép tôi lưu ảnh động? Bạn có thể lưu khung hiện tại hoặc tất cả các tệp dưới dạng PNG. Tôi quyết định lưu tất cả các khung hình và có 150 khung hình, tất cả các hình ảnh đều ở đó, tại sao không tạo hoạt ảnh tương tự với chúng.

Ma

Để làm hài lòng bản thân với hoạt hình như vậy, tôi đã nhờ CSS + JS trợ giúp. Tôi nên làm gì với 150 file hình ảnh? Trọng lượng của chúng không quan trọng, mặc dù tổng cộng chúng nặng hơn một megabyte. Các vấn đề chính là việc tải và thao tác đồng thời của chúng. Vì thế tôi quyết định “dán” chúng lại thành một. Chỉ tải một và sử dụng CSS + JS, bạn sẽ chỉ phải định vị chính xác.
Tất cả những gì còn lại là chọn phương pháp "dán". Tôi là một lập trình viên, và tất cả chúng tôi đều lười biếng :), vì vậy tôi ngay lập tức loại bỏ việc dán thủ công vào trình chỉnh sửa đồ họa. Trước hết, như thường lệ, tôi lao vào thư viện PHP và GD. Nhưng nó còn nhiều điều chưa được mong muốn khi làm việc với các PNG trong suốt. Sau đó tôi nghĩ, mình có thể dùng gì khác để “gắn” các bức tranh lại với nhau? Và tôi đã giải quyết được thứ hiện đang có trên môi mọi người, thứ hiện được coi là thời trang - HTML5. Anh ấy chịu trách nhiệm làm việc với đồ họa - Canvas, và tôi thực sự thích điều này. Đó là lý do tại sao tôi quyết định “dán” nó lên “bức tranh”.
Và vì vậy tôi sẽ thêm thẻ này vào HTML:

Không được hỗ trợ
Trong JS, tôi sẽ chỉ định mặt nạ cho tên của ảnh, ảnh đầu tiên và số của ảnh cuối cùng (tôi không phải đổi tên các ảnh vì chúng đều theo thứ tự). Nó sẽ trông giống như thế này:

Var đầu tiên = "000"; // phần số của tên ảnh đầu tiên var Last = 49; //số ảnh cuối cùng var num = 0; //iterator var MaskFileName = ["2HULL_PEOPLE_P_A_", ".png"];//tên hình ảnh mặt nạ var dir = "ship"; //thư mục chứa ảnh

Bây giờ bạn có thể chỉ định kích thước của sprite bạn muốn lấy và lấy bối cảnh của nó:

Var canvas = document.getElementById("sprite"); // chọn canvas canvas.width của chúng tôi = (last + 1) * 75; //đặt chiều rộng, tùy thuộc vào số lượng canvas.height = 75; chiều rộng var = 0; //biến trong đó chúng ta sẽ ghi lại shift var context = canvas.getContext("2d"); // lấy bối cảnh

Để thuận tiện cho việc chuyển đổi từ số sang chuỗi (tương tự str_pad từ PHP), tôi đã viết một hàm chuyển đổi có tên hoang dã - zerofikator():

Hàm zerofikator(int, length) ( // khi nhập vào, chúng ta lấy số và độ dài của chuỗi var prefix = ""; for (var i = num.toString().length; i< length; i++) { prefix += "0"; } return prefix + num; }

Hàm draw() ( var img = document.createElement("img"); /* mỗi lần gọi hàm này, chúng ta tạo một đối tượng hình ảnh mới */ img.onload = function () ( // khi hình ảnh được tải, chúng ta vẽ với nó trên canvas context.drawImage(img, width, 0); width += 75; // mỗi lần chúng ta dịch chuyển nó theo chiều rộng của hình ảnh để vẽ sang bên phải của hình ảnh trước đó chứ không phải trên đó if (zerofikator(num, first.length) != zerofikator(last, first.length)) ( //kiểm tra xem chúng ta đã đến bản vẽ cuối cùng chưa num++; //tăng iterator draw(); //và chạy lại hàm ) ) img.src = dir + "/" + mặt nạFileName + zerofikator( num, first.length) + mặt nạTên tệp; //thu thập tên của tệp hình ảnh để tải) draw(); //gọi hàm lần đầu tiên

Sau khi khởi chạy một trang như vậy, chúng ta sẽ thấy một hình ảnh rộng từng khung hình, nếu lưu nó, chúng ta có thể gọi nó là một hình ảnh. Nhân tiện, sprite đã lưu nặng 615 KB và 150 bức ảnh nặng 1.189 KB, hmm, đó là một điểm cộng nữa :).

Tôi quyết định thêm trực tiếp phép chuyển đổi vào tệp bằng cách nhấp vào khung vẽ (giải quyết vấn đề lưu đối với một số trình duyệt):

Canvas.onclick = function () ( window.location = context.canvas.toDataURL("image/png"); );

Hoạt hình

Chà, bây giờ chúng ta có thể bắt đầu hoạt hình.
Chúng tôi thêm một vài “cô gái” vào HTML mà chúng tôi sẽ làm việc tiếp theo:

Kiểu Var = (); styles.cursor = "con trỏ"; // để làm rõ rằng đây là phần tử của chúng ta, hãy thay đổi con trỏ styles.width = "75px"; // kích thước phần tử styles.height = "75px"; var elementId = "súng"; // id của phần tử chứa hoạt ảnh sẽ là var imgName = "canvas.png"; // tên file sprite

Hàm spriteAnimation(elementId, imgName, styles) ( var img = document.createElement("img"); var offset = 0; img.onload = function () ( //ngay khi sprite được tải var element = document.getElementById (elementId); element.style.cursor = style.cursor; element.style.width = styles.width; element.style.height = styles.height; element.style.background = "url("" + imgName + "" ) " + offset + "px 50%"; //thay đổi kiểu cho phần tử của chúng ta var i = 0; element.onmouseover = function() ( //đính kèm trình xử lý di chuột interval = setInterval(function() ( //chạy khoảng nếu (bù< img.width) { //для смены позиции изображения i++; // если дошли до конца спрайта } else { i = 0; // то возвращаемся к началу } offset = 75 * i; //сдвиг по слайду element.style.background = "url("" + imgName + "") " + offset + "px 50%"; //меняем позиционирование спрайта } , 1000/24) //24 кадра в секунду } element.onmouseout = function(){ //вешаем обработчик на убирание курсора мыши clearInterval(interval) //удаляем интервал (прекращаем анимацию) } } img.src = imgName; //даем имя нашего спрайта }

Ồ vâng, bạn cũng cần gọi hàm này:

SpriteAnimation(elementId, imgName, styles); spriteAnimation("ship", "ship.png", styles);

Và để làm cho nó trông phù hợp, bạn có thể thêm ảnh có nền và định vị chính xác:

biến xoay, thiết lập góc quay của sprite.

Nhấn nút A sẽ làm cho màu sprite thay đổi - màu mớiđã được chọn ngẫu nhiên. Nhấn nút S dẫn đến giảm tham số tỷ lệ, điều này chịu trách nhiệm cho kích thước của sprite hiển thị trên màn hình, nhấn nút W sẽ dẫn đến tăng tham số tỷ lệ và theo đó, làm giảm kích thước của tinh linh.

Tham số gốc chỉ định gốc tọa độ cho sprite. Theo mặc định, tọa độ vị trí của sprite tương ứng với góc trên bên trái của nó. Tương đối với trái góc trên cùng, trong trường hợp này, sprite cũng được xoay. Để phép quay xảy ra xung quanh tâm của sprite, chúng ta ghi vào biến Origin kết quả của việc chia chiều dài và chiều rộng của sprite cho 2. Kết quả là, sprite trước tiên được hiển thị trên màn hình có tính đến tính toán nguồn gốc tọa độ mới cho nó và thứ hai, trong quá trình xoay sprite, nó được thực hiện xung quanh tâm của sprite chứ không phải xung quanh góc trên cùng bên trái của nó. Chúng ta hãy xem xét kỹ hơn lệnh Draw mà chúng ta đã sử dụng để hiển thị sprite trên màn hình. Trong bảng 10.1. mỗi thông số của nó được mô tả.

Bảng 10.1. Mô tả các tham số của lệnh Draw
Yếu tố Sự miêu tả
MySprite kết cấu ma
chức vụ vị trí sprite
spRec Một hình chữ nhật bao quanh một sprite trong một kết cấu có thể được sử dụng để hiển thị các vùng khác nhau của kết cấu
màu sắc Sprite màu sắc
Vòng xoay Góc quay sprite
nguồn gốc Gốc tọa độ của sprite, tương ứng với sprite được quay và hiển thị trên màn hình
tỉ lệ Kích thước sprite.
SpriteEffects.None Hiệu ứng đầu ra của Sprite - cho phép bạn xoay sprite 180 độ hoặc, nếu tham số được đặt thành Không - không ảnh hưởng đến vị trí của sprite theo bất kỳ cách nào
(thả nổi) 0 Độ sâu của Sprite. Có thể thay đổi từ 0 đến 1

Trong bộ lễ phục. 10.1. bạn có thể xem màn hình trò chơi của dự án P6_1.

Bây giờ chúng ta hãy xem hoạt hình sprite.

Hoạt hình ma

Để tạo ra một sprite hoạt hình, bạn cần chuẩn bị nguồn nguyên liệu phù hợp. Thường xuyên, tập tin nguồnđối với các họa tiết hoạt hình, hãy bao gồm một số hình ảnh liên tiếp. Mỗi hình ảnh này đại diện cho một khung hình động riêng biệt. Thách thức của việc tạo ra các họa tiết hoạt hình là phát triển một cơ chế cho phép hình ảnh thay đổi ở một tốc độ nhất định.

Hãy tạo một sprite mà chúng ta sẽ tạo hoạt ảnh. Chúng tôi đã sử dụng một sprite để tạo hoạt ảnh, bao gồm hai hình ảnh (Hình 10.2.). Khi nó hoạt hình, hiệu ứng nhấp nháy sẽ được tạo ra - màu đen sẽ được thay thế bằng màu xanh lá cây.

Hãy tạo một dự án trò chơi tiêu chuẩn, hãy gọi nó là P6_2. Trong Liệt kê 10.2. Mã cho lớp Game1 được hiển thị. Trong dự án này, chúng tôi đã thực hiện mà không tạo thêm các thành phần trò chơi mà triển khai tất cả các chức năng cần thiết trong lớp trò chơi chính.

Sử dụng hệ thống; sử dụng System.Collections.Generic; sử dụng Microsoft.Xna.Framework; sử dụng Microsoft.Xna.Framework.Audio; sử dụng Microsoft.Xna.Framework.Content; sử dụng Microsoft.Xna.Framework.GamerServices; sử dụng Microsoft.Xna.Framework.Graphics; sử dụng Microsoft.Xna.Framework.Input; sử dụng Microsoft.Xna.Framework.Net; sử dụng Microsoft.Xna.Framework.Storage; không gian tên P6_2 ( ///

/// Đây là loại chính cho bạn trò chơi /// lớp công khai Game1: Microsoft.Xna.Framework.Game ( Đồ họa GraphicsDeviceManager; SpriteBatch spriteBatch; Kết cấu Text2D; // Số khung hình trong hình ảnh const int Frames = 2; // Tần số hoạt ảnh - số khung hình trên giây const int FramesPerSec = 10; / / Khung hiện tại để hiển thị int numberOfFrame=0; //Thời gian trong đó một khung được hiển thị float timePerFrame; //Thời gian đã trôi qua kể từ khi bắt đầu hiển thị float của khung hiện tại TotalElapsed; //Vị trí của vị trí Vector2 đầu ra sprite; // Hình chữ nhật để thiết lập vị trí khung trong ảnh Hình chữ nhật sprRec; // Độ rộng khung int widthFrame = 64; public Game1() ( Graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; ) protected ghi đè void Khởi tạo() ( vị trí = new Vector2( 100, 100); // Thời gian cho một khung hình được tính bằng kết quả của việc chia 1 giây // cho số khung hình được chỉ định trên mỗi giây timePerFrame = (float)1 / framePerSec; sprRec = new Rectangle (0, 0, 64, 64); base.Initialize(); ) protected ghi đè void LoadContent() ( // Tạo một SpriteBatch mới, có thể được sử dụng để vẽ họa tiết. spriteBatch = new SpriteBatch(GraphicsDevice); text = Content.Load ("hoạt hình"); // TODO: sử dụng this.Content để tải nội dung trò chơi của bạn tại đây ) protected ghi đè void UnloadContent() ( // TODO: Dỡ bỏ mọi nội dung không phải ContentManager tại đây ) // Thủ tục này được sử dụng để tạo hiệu ứng cho sprite // Cần số lượng số giây đã trôi qua kể từ lệnh gọi trước đó // của thủ tục cập nhật void ChangeFrame(float elpT) ( //Tăng tổng thời gian hiển thị của sprite lên // thời gian đã trôi qua kể từ đó cuộc gọi cuối tổng số thủ tục đã qua += elpT; //nếu tổng thời gian hiển thị của một sprite lớn hơn thời gian // được phân bổ cho một sprite if (totalElapsed > timePerFrame) ( //Nếu số khung bằng số khung-1 if (numberOfFrame == khung- 1) ( //đặt số khung thành 0 numberOfFrame = 0; ) //nếu không, tăng số khung lên 1 khác numberOfFrame++; //tạo một hình chữ nhật mới // Tọa độ X của nó tương ứng với tọa độ của góc trên bên trái / /của khung, Y là 0, chiều dài và chiều rộng luôn bằng 64 sprRec = new Rectangle( (int)widthFrame * numberOfFrame, 0, 64, 64); //đặt lại TotalElapsed thành 0 TotalElapsed = 0; ) ) ghi đè được bảo vệ void Update(GameTime gameTime) ( //Gọi thủ tục hoạt hình sprite //chuyển thời gian đã trôi qua làm tham số sau // lệnh gọi cuối cùng Update ChangeFrame((float)gameTime.ElapsedGameTime.TotalSeconds); base.Update(gameTime); ) ghi đè được bảo vệ void Draw(GameTime gameTime) ( Graphics.GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin( ); spriteBatch.Draw(kết cấu, vị trí, sprRec, Color.White); spriteBatch.End(); base.Draw(gameTime); ) ) ) Liệt kê 10.2. Mã lớp Game1

Nếu chúng tôi mô tả ngắn gọn trình tự công việc của dự án này, chúng tôi sẽ nhận được như sau: trong chu trình Update(), chúng tôi gọi thủ tục ChangeFrame(), mà chúng tôi chuyển thời gian đã trôi qua kể từ lệnh gọi cuối cùng tới Update(). Trong quy trình này, chúng tôi kiểm tra xem thời gian hiện tại có đủ không