JavaScript網頁設計高級案例:構建交互式圖片畫廊

JavaScript網頁設計高級案例:構建交互式圖片畫廊

在現代Web開發中,交互式元素已成為提升用戶體驗的關鍵因素。本文將通過一個高級案例 - 構建交互式圖片畫廊,展示如何結合HTML和JavaScript創建引人入勝的網頁應用。這個案例不僅涵蓋了基礎的Web開發技術,還融入了性能優化和現代設計模式。

項目概述

我們將構建的交互式圖片畫廊具有以下功能:

  • 響應式布局,適應不同設備尺寸
  • 圖片類別篩選功能
  • 點擊圖片展示大圖和詳細信息的模態框
  • 平滑的動畫和過渡效果
  • 懶加載技術提升性能
  • 本地存儲保存用戶的設置偏好

HTML結構

首先,我們需要建立一個清晰的HTML結構作為應用的骨架:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>交互式圖片畫廊</title><link rel="stylesheet" href="styles.css">
</head>
<body><header class="gallery-header"><h1>精美圖片畫廊</h1><div class="filter-container"><button class="filter-btn active" data-category="all">全部</button><button class="filter-btn" data-category="nature">自然風光</button><button class="filter-btn" data-category="architecture">建筑設計</button><button class="filter-btn" data-category="people">人物肖像</button></div></header><main class="gallery-container"><!-- 圖片項將通過JavaScript動態加載 --></main><!-- 模態框 --><div class="modal" id="imageModal"><span class="close-modal">&times;</span><div class="modal-content"><img class="modal-img" id="modalImage"><div class="image-info"><h3 id="imageTitle"></h3><p id="imageDescription"></p><p id="imageAuthor"></p></div></div></div><footer><p>? 2025 交互式圖片畫廊 | 設計與開發</p></footer><script src="gallery.js"></script>
</body>
</html>

JavaScript實現

現在,讓我們深入JavaScript部分,實現交互式功能:

// 圖片數據 - 使用公共鏈接
const galleryData = [{id: 1,src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e",thumbnail: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=400&h=300&auto=format&fit=crop",title: "森林小徑",description: "陽光透過樹葉,灑在蜿蜒的森林小徑上",category: "nature",author: "張明"},{id: 2,src: "https://images.unsplash.com/photo-1486325212027-8081e485255e",thumbnail: "https://images.unsplash.com/photo-1486325212027-8081e485255e?w=400&h=300&auto=format&fit=crop",title: "現代建筑",description: "城市中心的現代玻璃建筑,反射著周圍的景色",category: "architecture",author: "李華"},{id: 3,src: "https://images.unsplash.com/photo-1533738363-b7f9aef128ce",thumbnail: "https://images.unsplash.com/photo-1533738363-b7f9aef128ce?w=400&h=300&auto=format&fit=crop",title: "街頭藝術家",description: "專注于表演的街頭藝術家,吸引了眾多觀眾",category: "people",author: "王芳"},{id: 4,src: "https://images.unsplash.com/photo-1472214103451-9374bd1c798e",thumbnail: "https://images.unsplash.com/photo-1472214103451-9374bd1c798e?w=400&h=300&auto=format&fit=crop",title: "山間湖泊",description: "清澈的湖水倒映著周圍的群山和藍天",category: "nature",author: "陳曉"},{id: 5,src: "https://images.unsplash.com/photo-1511818966892-d7d671e672a2",thumbnail: "https://images.unsplash.com/photo-1511818966892-d7d671e672a2?w=400&h=300&auto=format&fit=crop",title: "歷史建筑",description: "古典風格的歷史建筑,展示著精美的建筑細節",category: "architecture",author: "趙建"},{id: 6,src: "https://images.unsplash.com/photo-1504439904031-93ded9f93e4e",thumbnail: "https://images.unsplash.com/photo-1504439904031-93ded9f93e4e?w=400&h=300&auto=format&fit=crop",title: "都市人像",description: "忙碌的都市生活中,一位沉思的年輕人",category: "people",author: "林美"}
];// DOM 元素
const galleryContainer = document.querySelector('.gallery-container');
const filterButtons = document.querySelectorAll('.filter-btn');
const modal = document.getElementById('imageModal');
const modalImage = document.getElementById('modalImage');
const modalClose = document.querySelector('.close-modal');
const imageTitle = document.getElementById('imageTitle');
const imageDescription = document.getElementById('imageDescription');
const imageAuthor = document.getElementById('imageAuthor');// 當前選中的類別
let currentCategory = 'all';// 初始化函數
function initGallery() {// 加載用戶上次選擇的類別(如果有)const savedCategory = localStorage.getItem('preferredCategory');if (savedCategory) {currentCategory = savedCategory;// 更新按鈕狀態filterButtons.forEach(btn => {btn.classList.toggle('active', btn.getAttribute('data-category') === currentCategory);});} else {// 確保"全部"按鈕處于激活狀態filterButtons.forEach(btn => {btn.classList.toggle('active', btn.getAttribute('data-category') === 'all');});}// 加載圖片renderGallery();// 添加延遲加載后的動畫效果setTimeout(() => {animateGalleryItems();}, 100);// 添加事件監聽器setupEventListeners();
}// 渲染畫廊
function renderGallery() {// 清空畫廊容器galleryContainer.innerHTML = '';// 篩選圖片const filteredImages = currentCategory === 'all' ? galleryData : galleryData.filter(image => image.category === currentCategory);// 創建圖片元素filteredImages.forEach((image, index) => {const galleryItem = document.createElement('div');galleryItem.className = 'gallery-item';galleryItem.setAttribute('data-id', image.id);// 所有圖片都直接加載,不再使用懶加載// 這樣可以確保無論是初始加載還是切換類別,圖片都能顯示galleryItem.innerHTML = `<img class="gallery-img" src="${image.thumbnail}" alt="${image.title}"><div class="image-overlay"><h3>${image.title}</h3></div>`;galleryContainer.appendChild(galleryItem);});// 初始加載后立即添加動畫效果setTimeout(() => {animateGalleryItems();}, 50);
}// 實現懶加載implementLazyLoading();
}// 懶加載實現
function implementLazyLoading() {const lazyImages = document.querySelectorAll('img[data-src]');if ('IntersectionObserver' in window) {const imageObserver = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.target;img.src = img.getAttribute('data-src');img.removeAttribute('data-src');// 添加加載完成的類img.classList.add('loaded');observer.unobserve(img);}});}, {// 修改閾值,使圖片在進入視口前就開始加載rootMargin: '50px',threshold: 0.1});lazyImages.forEach(img => {imageObserver.observe(img);});} else {// 降級處理:立即加載所有圖片lazyImages.forEach(img => {img.src = img.getAttribute('data-src');img.removeAttribute('data-src');img.classList.add('loaded');});}// 如果沒有圖片加載,可能是首次加載出現問題,強制加載第一屏圖片if (lazyImages.length === 0 || document.querySelectorAll('.gallery-item').length === 0) {console.log('強制重新渲染畫廊');setTimeout(() => renderGallery(), 100);}
}// 設置事件監聽器
function setupEventListeners() {// 篩選按鈕點擊事件filterButtons.forEach(button => {button.addEventListener('click', function() {const category = this.getAttribute('data-category');// 更新按鈕樣式filterButtons.forEach(btn => btn.classList.remove('active'));this.classList.add('active');// 更新當前類別并保存到本地存儲currentCategory = category;localStorage.setItem('preferredCategory', category);// 為畫廊添加轉場動畫類galleryContainer.classList.add('category-transition');// 短暫延遲后重新渲染畫廊,創造平滑過渡效果setTimeout(() => {// 重新渲染畫廊renderGallery();// 移除轉場類setTimeout(() => {galleryContainer.classList.remove('category-transition');}, 50);}, 300);});});// 圖片點擊事件(使用事件委托)galleryContainer.addEventListener('click', function(e) {const galleryItem = e.target.closest('.gallery-item');if (galleryItem) {const imageId = parseInt(galleryItem.getAttribute('data-id'));openModal(imageId);}});// 關閉模態框事件modalClose.addEventListener('click', closeModal);window.addEventListener('click', function(e) {if (e.target === modal) {closeModal();}});// 鍵盤事件處理window.addEventListener('keydown', function(e) {if (e.key === 'Escape' && modal.style.display === 'flex') {closeModal();}});
}// 打開模態框
function openModal(imageId) {const image = galleryData.find(img => img.id === imageId);if (image) {// 設置模態框內容modalImage.src = image.src;imageTitle.textContent = image.title;imageDescription.textContent = image.description;imageAuthor.textContent = `攝影師: ${image.author}`;// 顯示模態框并添加動畫效果modal.style.display = 'flex';setTimeout(() => {modal.classList.add('show');}, 10);// 防止滾動document.body.style.overflow = 'hidden';}
}// 關閉模態框
function closeModal() {modal.classList.remove('show');setTimeout(() => {modal.style.display = 'none';// 恢復滾動document.body.style.overflow = 'auto';// 清除圖片,減輕內存負擔modalImage.src = '';}, 300); // 匹配CSS過渡時間
}// 添加畫廊項目的動畫效果
function animateGalleryItems() {const items = document.querySelectorAll('.gallery-item');items.forEach((item, index) => {item.style.animationDelay = `${index * 0.05}s`;item.classList.add('animate');});
}// 添加響應式支持
function handleResponsive() {const checkWidth = () => {// 根據窗口寬度調整顯示樣式if (window.innerWidth < 768) {galleryContainer.classList.add('mobile-view');} else {galleryContainer.classList.remove('mobile-view');}};// 初始檢查checkWidth();// 窗口調整時檢查window.addEventListener('resize', checkWidth);
}// 性能優化:去抖動函數
function debounce(func, wait) {let timeout;return function() {const context = this;const args = arguments;clearTimeout(timeout);timeout = setTimeout(() => func.apply(context, args), wait);};
}// 優化后的窗口調整處理
window.addEventListener('resize', debounce(function() {// 調整畫廊布局const galleryItems = document.querySelectorAll('.gallery-item');// 根據視窗大小調整項目大小和布局if (window.innerWidth < 768) {galleryItems.forEach(item => {item.style.width = '100%';});} else if (window.innerWidth < 1024) {galleryItems.forEach(item => {item.style.width = 'calc(50% - 20px)';});} else {galleryItems.forEach(item => {item.style.width = 'calc(33.333% - 20px)';});}
}, 250));// 初始化畫廊
document.addEventListener('DOMContentLoaded', function() {// 立即初始化畫廊initGallery();handleResponsive();// 如果初次加載沒有顯示圖片,在短暫延遲后重試一次setTimeout(() => {if (document.querySelectorAll('.gallery-item').length === 0) {console.log('初始化重試');renderGallery();animateGalleryItems();}}, 500);
});

CSS樣式(核心部分)

雖然本文重點是JavaScript,但為了完整性,這里提供核心CSS樣式:

/* 基礎樣式 */
* {margin: 0;padding: 0;box-sizing: border-box;
}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;line-height: 1.6;color: #333;background-color: #f9f9f9;
}/* 畫廊容器樣式 */
.gallery-container {display: flex;flex-wrap: wrap;justify-content: space-between;max-width: 1200px;margin: 2rem auto;padding: 0 20px;
}/* 畫廊項目樣式 */
.gallery-item {position: relative;width: calc(33.333% - 20px);margin-bottom: 30px;border-radius: 5px;overflow: hidden;box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);cursor: pointer;transition: transform 0.3s ease, box-shadow 0.3s ease;opacity: 0;transform: translateY(20px);
}.gallery-item.animate {animation: fadeIn 0.5s forwards;
}.gallery-item:hover {transform: translateY(-10px);box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
}/* 圖片樣式 */
.gallery-img {width: 100%;height: 250px;object-fit: cover;transition: transform 0.5s ease;
}.gallery-item:hover .gallery-img {transform: scale(1.1);
}/* 圖片疊加層 */
.image-overlay {position: absolute;bottom: 0;left: 0;right: 0;background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));padding: 15px;color: white;opacity: 0;transition: opacity 0.3s ease;
}.gallery-item:hover .image-overlay {opacity: 1;
}/* 篩選按鈕 */
.filter-container {text-align: center;margin: 2rem 0;
}.filter-btn {background: none;border: 2px solid #3498db;color: #3498db;padding: 8px 20px;margin: 0 5px;border-radius: 30px;cursor: pointer;font-weight: bold;transition: all 0.3s ease;
}.filter-btn.active, .filter-btn:hover {background-color: #3498db;color: white;
}/* 模態框樣式 */
.modal {display: none;position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.8);z-index: 1000;justify-content: center;align-items: center;opacity: 0;transition: opacity 0.3s ease;
}.modal.show {opacity: 1;
}.modal-content {display: flex;flex-direction: column;max-width: 900px;width: 90%;background-color: white;border-radius: 5px;overflow: hidden;box-shadow: 0 5px 30px rgba(0, 0, 0, 0.3);transform: scale(0.9);transition: transform 0.3s ease;
}.modal.show .modal-content {transform: scale(1);
}.modal-img {width: 100%;max-height: 70vh;object-fit: contain;
}.image-info {padding: 20px;
}.close-modal {position: absolute;top: 15px;right: 20px;color: white;font-size: 30px;cursor: pointer;z-index: 1001;
}/* 動畫 */
@keyframes fadeIn {to {opacity: 1;transform: translateY(0);}
}/* 類別切換過渡效果 */
.category-transition {opacity: 0.6;transition: opacity 0.3s ease;
}/* 響應式設計 */
@media (max-width: 1024px) {.gallery-item {width: calc(50% - 15px);}
}@media (max-width: 768px) {.gallery-item {width: 100%;}.modal-content {flex-direction: column;}.filter-container {display: flex;flex-wrap: wrap;justify-content: center;}.filter-btn {margin-bottom: 10px;}
}

代碼解析與最佳實踐

1. 模塊化與組織結構

我們的代碼采用了功能模塊化的組織方式:

  • 數據層:使用galleryData數組存儲圖片信息
  • 視圖層:通過renderGallery()函數負責DOM渲染
  • 控制層:事件處理函數管理用戶交互

這種分離關注點的方式使代碼更易于維護和擴展。

2. 性能優化策略

本案例中實現了多種性能優化策略:

  • 懶加載:使用IntersectionObserver API實現圖片懶加載,減少初始加載時間
  • 去抖動:通過debounce函數優化窗口調整事件,減少不必要的計算
  • 事件委托:為畫廊容器而非每個圖片項添加點擊事件,提高性能
  • 清理資源:關閉模態框時清除圖片源,減輕內存負擔

3. 增強用戶體驗

  • 平滑動畫:使用CSS過渡和動畫創建流暢的視覺效果
  • 本地存儲:通過localStorage保存用戶的類別偏好
  • 鍵盤支持:添加鍵盤事件處理(Esc關閉模態框)
  • 響應式設計:根據設備尺寸調整布局

4. 無障礙性考慮

雖然未在代碼中詳細展示,但實際項目應考慮以下無障礙性改進:

  • 為所有圖片添加有意義的alt屬性
  • 確保可通過鍵盤導航操作所有功能
  • 添加適當的ARIA屬性以支持屏幕閱讀器
  • 維持足夠的色彩對比度

效果

構建交互式圖片畫廊

進一步擴展

這個交互式圖片畫廊還可以進一步擴展:

  1. 搜索功能:添加關鍵詞搜索能力
  2. 無限滾動:實現無限滾動或分頁加載更多圖片
  3. 分享功能:允許用戶分享特定圖片到社交媒體
  4. 主題切換:添加暗/亮模式切換
  5. 后端集成:連接到真實API獲取圖片數據
  6. 圖片上傳:允許用戶上傳自己的圖片

總結

本文通過構建交互式圖片畫廊的案例,展示了如何結合HTML和JavaScript創建一個功能豐富的Web應用。我們不僅實現了基本的圖片展示和篩選功能,還融入了現代Web開發的最佳實踐,包括懶加載、事件優化、本地存儲和響應式設計。

這個案例可作為中高級JavaScript開發者的學習參考,也可以作為實際項目的起點進行擴展和定制。通過理解和應用這些技術,開發者可以創建既美觀又高效的Web應用,提供出色的用戶體驗。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74906.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74906.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74906.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux命令大全:從入門到高效運維

適合人群&#xff1a;Linux新手 | 運維工程師 | 開發者 目錄 一、Linux常用命令&#xff08;每天必用&#xff09; 1. 文件與目錄操作 2. 文件內容查看與編輯 二、次常用命令&#xff08;按需使用&#xff09; 1. 系統管理與監控 2. 網絡與通信 3. 權限與用戶管理 三、…

Windows 10/11 使用 VSCode + SSH 免密遠程連接 Ubuntu 服務器(指定端口)

摘要&#xff1a; 本文詳細介紹如何在 Windows 系統上通過 VSCode Remote-SSH 免密登錄遠程 Ubuntu 服務器&#xff08;SSH 端口 2202&#xff09;&#xff0c;避免每次輸入密碼的繁瑣操作&#xff0c;提高開發效率。 1. 環境準備 本地系統&#xff1a;Windows 10/11遠程服務…

一些需要學習的C++庫:CGAL和Eysshot

寫在前面&#xff1a; 從開始工作到現在&#xff0c;去過多家公司&#xff0c;多個行業&#xff0c; 雖然大部分時間在通信業&#xff0c;但也有其它的行業的工作沒有做完&#xff0c;但也很感興趣。每次想要研究一下時&#xff0c;總是想不起來。 這里寫一些信息&#xff0c;…

藍橋杯16天刷題計劃一一Day01

藍橋杯16天刷題計劃一一Day01&#xff08;STL練習&#xff09; 作者&#xff1a;blue 時間&#xff1a;2025.3.26 文章目錄 藍橋杯16天刷題計劃一一Day01&#xff08;STL練習&#xff09;[P1540 [NOIP 2010 提高組\] 機器翻譯 - 洛谷 (luogu.com.cn)](https://www.luogu.com.…

相對位置2d矩陣和kron運算的思考

文章目錄 1. 相對位置矩陣2d2. kron運算 1. 相對位置矩陣2d 在swin-transformer中&#xff0c;我們會計算每個patch之間的相對位置&#xff0c;那么我們看到有一連串的拉伸和相減&#xff0c;直接貼代碼&#xff1a; import torch import torch.nn as nntorch.set_printoptio…

Redis 版本演進及主要新特性

Redis 版本發布歷史 穩定版本時間線 Redis 2.6 (2012年)Redis 2.8 (2013年11月)Redis 3.0 (2015年4月) - 首次支持集群Redis 3.2 (2016年5月)Redis 4.0 (2017年7月)Redis 5.0 (2018年10月)Redis 6.0 (2020年4月)Redis 6.2 (2021年2月)Redis 7.0 (2022年4月) - 最新穩定版(截至…

HTML5 Geolocation(地理定位)學習筆記

一、HTML5 Geolocation簡介 HTML5 Geolocation&#xff08;地理定位&#xff09;API用于獲取用戶的地理位置信息。通過這個API&#xff0c;可以獲取用戶的緯度、經度、海拔等信息。由于地理定位可能涉及用戶隱私&#xff0c;因此只有在用戶同意的情況下&#xff0c;才能獲取其…

愛普生VG3225EFN壓控晶振5G基站低噪聲的解決方案

在 5G 通信網絡的高速發展中&#xff0c;系統噪聲的控制成為保障網絡可靠性與數據吞吐量的關鍵。愛普生 VG3225EFN 壓控晶振憑借其卓越的低噪聲特性&#xff0c;成為 5G 基站時鐘系統的理想選擇。通過創新的技術設計&#xff0c;這款晶振不僅為基站提供了穩定的時鐘基準&#x…

【問題解決】Linux安裝conda修改~/.bashrc配置文件后,root 用戶下顯示 -bash-4.2#

問題描述 在Linux安裝conda下的python環境時候&#xff0c;修改了~/.bashrc文件&#xff0c;修改完成后&#xff0c;再次進入服務器后&#xff0c;登錄時候顯示的不是正常的[rootlocalhost ~]#&#xff0c;而是-bash-4.2# 原因分析&#xff1a; 網上原因有&#xff1a;/root下…

機器學習knnlearn5

import numpy as np from os import listdir from sklearn.neighbors import KNeighborsClassifier as kNN# 此函數用于將一個32x32的文本文件轉換為一個1x1024的一維向量 def img2vector(filename):"""將32x32的文本文件轉換為1x1024的向量:param filename: 要…

git revert 用法實戰:撤銷一個 commit 或 merge

git revert 1 區別 ? 常規的 commit &#xff08;使用 git commit 提交的 commit&#xff09; ? merge commit 2 首先構建場景 master上的代碼 dev開發分支上&#xff0c;添加一個a標簽&#xff0c;并commit這次提交 切到master上&#xff0c;再次進行改動和提交 將de…

自然語言處理|高效法律助手:AI如何解析合同條款?

引言&#xff1a;法律 AI 的崛起 在數字化浪潮快速發展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是一個陌生的概念&#xff0c;它正以快速發展滲透到各個領域&#xff0c;法律行業也不例外。從智能合同審查到法律風險預測&#xff0c;AI 技術為法律工作帶來…

【數據分享】2000—2024年我國鄉鎮的逐年歸一化植被指數(NDVI)數據(年最大值/Shp/Excel格式)

之前我們分享過2000-2024年我國逐年的歸一化植被指數&#xff08;NDVI&#xff09;柵格數據&#xff0c;該逐年數據是取的當年月歸一化植被指數&#xff08;NDVI&#xff09;的年最大值&#xff01;另外&#xff0c;我們基于此年度柵格數據按照行政區劃取平均值&#xff0c;得到…

辦公網絡健康監控(域名健康監控)

需求 辦公室訪問一些網絡經常出現故障 現需要時時觀察監控這些網絡的健康 包含專線網等其他網絡 實施 支持 SNMP 且支持 Webhook 發送報警的開源監控系統 hertzbeat:關系型數據庫+時序數據庫; Zabbix:關系型數據庫; LibreNMS:關系型數據庫; Prometheus(包含ale…

藍橋杯 合并數列

問題描述 小明發現有很多方案可以把一個很大的正整數拆成若干個正整數的和。他采用了其中兩種方案&#xff0c;分別將它們列為兩個數組&#xff1a; {a?, a?, ..., a?}{b?, b?, ..., b?} 兩個數組的元素和相同。 定義一次合并操作為&#xff1a;將某個數組中相鄰的兩…

【行駛證識別】批量咕嘎OCR識別行駛證照片復印件圖片里的文字信息保存表格或改名字,基于QT和騰訊云api_ocr的實現方式

項目背景 在許多業務場景中,如物流管理、車輛租賃、保險理賠等,常常需要處理大量的行駛證照片復印件。手動錄入行駛證上的文字信息,像車主姓名、車輛型號、車牌號碼等,不僅效率低下,還容易出現人為錯誤。借助 OCR(光學字符識別)技術,能夠自動識別行駛證圖片中的文字信…

個人學習編程(3-29) leetcode刷題

最后一個單詞的長度&#xff1a; 思路&#xff1a;跳過末尾的空格&#xff0c;可以從后向前遍歷 然后再利用 while(i>0 && s[i] ! ) 可以得到字符串的長度&#xff0c; int lengthOfLastWord(char* s) {int length 0;int i strlen(s) - 1; //從字符串末尾開始//…

PAT甲級(Advanced Level) Practice 1028 List Sorting

原題 1028 List Sorting - PAT (Advanced Level) Practice 題目大意 輸入n個學生的id、姓名、分數&#xff0c;再輸入C表示對C列進行排序。 id&#xff1a;從小到大排 姓名&#xff1a;姓名不同時從小到大排&#xff0c;相同時id從小到大排 分數&#xff1a;不同時從小到…

UE4學習筆記 FPS游戲制作20 重寫機器人和玩家死亡 切換相機和模型

定義父類中的死亡方法 在父類中定義OnDie方法&#xff0c;不需要實現&#xff0c;由子類實現各自的死亡邏輯 新建一個Die方法&#xff0c;處理公共的死亡邏輯 Die的實現&#xff1a; 以前的分離控制現在要延遲做&#xff0c;如果分離了控制器&#xff0c;就無法再獲取到玩家的…

Linux信號的誕生與歸宿:內核如何管理信號的生成、阻塞和遞達?

個人主頁&#xff1a;敲上癮-CSDN博客 個人專欄&#xff1a;Linux學習、游戲、數據結構、c語言基礎、c學習、算法 目錄 一、認識信號 二、信號的產生 1.鍵盤輸入 2.系統調用 3.系統指令 4.硬件異常 5.軟件條件 三、信號的保存 1.block 2.pending 3.handler 四、信號…