Lryan64's picture
使用 HTML5 Canvas + JavaScript 创建一个完整的复古风格贪吃蛇游戏。
7c060f8 verified
document.addEventListener('DOMContentLoaded', () => {
// DOM Elements
const personInput = document.getElementById('personInput');
const addPersonBtn = document.getElementById('addPersonBtn');
const peopleList = document.getElementById('peopleList');
const clearListBtn = document.getElementById('clearListBtn');
const importBtn = document.getElementById('importBtn');
const exportBtn = document.getElementById('exportBtn');
const groupSize = document.getElementById('groupSize');
const shuffleMethod = document.getElementById('shuffleMethod');
const generateBtn = document.getElementById('generateBtn');
const resultsSection = document.getElementById('resultsSection');
const groupsContainer = document.getElementById('groupsContainer');
const copyResultsBtn = document.getElementById('copyResultsBtn');
// Load people from localStorage
let people = JSON.parse(localStorage.getItem('groupGeniePeople')) || [];
// Render people list
function renderPeopleList() {
peopleList.innerHTML = '';
people.forEach((person, index) => {
const li = document.createElement('li');
li.className = 'flex justify-between items-center bg-gray-50 p-2 rounded';
li.innerHTML = `
<span>${person}</span>
<button data-index="${index}" class="text-red-500 hover:text-red-700">
<i data-feather="x"></i>
</button>
`;
peopleList.appendChild(li);
});
feather.replace();
}
// Add person(s) to list
function addPerson() {
const input = personInput.value.trim();
if (input.includes(',') || input.includes(' ') || input.includes('\n')) {
addMultiplePeople(input);
} else if (input && !people.includes(input)) {
people.push(input);
localStorage.setItem('groupGeniePeople', JSON.stringify(people));
}
personInput.value = '';
renderPeopleList();
}
// Remove person from list
function removePerson(index) {
people.splice(index, 1);
localStorage.setItem('groupGeniePeople', JSON.stringify(people));
renderPeopleList();
}
// Clear all people
function clearPeople() {
if (confirm('Are you sure you want to clear all people?')) {
people = [];
localStorage.removeItem('groupGeniePeople');
renderPeopleList();
}
}
// Import people from text with multiple separators (comma, space, or newline)
function importPeople() {
const text = prompt('Enter names separated by commas, spaces, or new lines:');
if (text) {
const newPeople = text.split(/[\n,\s]+/) // Split by comma, space, or newline
.map(name => name.trim())
.filter(name => name);
people = [...new Set([...people, ...newPeople])];
localStorage.setItem('groupGeniePeople', JSON.stringify(people));
renderPeopleList();
}
}
// Add multiple people from input
function addMultiplePeople(names) {
const newPeople = names.split(/[\n,\s]+/)
.map(name => name.trim())
.filter(name => name);
newPeople.forEach(name => {
if (name && !people.includes(name)) {
people.push(name);
}
});
localStorage.setItem('groupGeniePeople', JSON.stringify(people));
renderPeopleList();
}
// Export people to clipboard
function exportPeople() {
navigator.clipboard.writeText(people.join('\n'))
.then(() => alert('People list copied to clipboard!'))
.catch(err => console.error('Failed to copy:', err));
}
// Fisher-Yates shuffle algorithm
function fisherYatesShuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
// Random sort shuffle (less reliable)
function randomSortShuffle(array) {
return array.sort(() => Math.random() - 0.5);
}
// Generate groups
function generateGroups() {
if (people.length === 0) {
alert('Please add some people first!');
return;
}
const membersPerGroup = parseInt(groupSize.value) || 3;
if (membersPerGroup < 1) {
alert('Members per group must be at least 1');
return;
}
// Shuffle based on selected method
const shuffledPeople = shuffleMethod.value === 'fisher-yates'
? fisherYatesShuffle([...people])
: randomSortShuffle([...people]);
// Create groups
const groups = [];
for (let i = 0; i < shuffledPeople.length; i += membersPerGroup) {
groups.push(shuffledPeople.slice(i, i + membersPerGroup));
}
// Display groups
displayGroups(groups);
}
// Display groups in UI
function displayGroups(groups) {
groupsContainer.innerHTML = '';
groups.forEach((group, index) => {
const groupCard = document.createElement('div');
groupCard.className = `group-card bg-group-${(index % 6) + 1} p-4 rounded-lg shadow-sm`;
groupCard.innerHTML = `
<h3 class="font-bold text-lg mb-3">Group ${index + 1}</h3>
<ul class="space-y-2">
${group.map(member => `<li class="flex items-center gap-2"><i data-feather="user" class="w-4 h-4"></i> ${member}</li>`).join('')}
</ul>
`;
groupsContainer.appendChild(groupCard);
});
resultsSection.classList.remove('hidden');
feather.replace();
}
// Copy results to clipboard
function copyResults() {
const groupElements = document.querySelectorAll('#groupsContainer > div');
let text = '';
groupElements.forEach((group, index) => {
text += `Group ${index + 1}:\n`;
const members = group.querySelectorAll('li');
members.forEach(member => {
text += `- ${member.textContent.trim()}\n`;
});
text += '\n';
});
navigator.clipboard.writeText(text.trim())
.then(() => alert('Groups copied to clipboard!'))
.catch(err => console.error('Failed to copy:', err));
}
// Event listeners
addPersonBtn.addEventListener('click', (e) => {
addPerson();
e.preventDefault(); // Prevent form submission if in a form
});
personInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
addPerson();
e.preventDefault(); // Prevent form submission if in a form
}
});
peopleList.addEventListener('click', (e) => {
if (e.target.closest('button')) {
const index = e.target.closest('button').dataset.index;
removePerson(index);
}
});
clearListBtn.addEventListener('click', clearPeople);
importBtn.addEventListener('click', importPeople);
exportBtn.addEventListener('click', exportPeople);
generateBtn.addEventListener('click', generateGroups);
copyResultsBtn.addEventListener('click', copyResults);
// Initial render
renderPeopleList();
});