-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython_learning_game (1).html
More file actions
187 lines (177 loc) · 6.5 KB
/
Copy pathpython_learning_game (1).html
File metadata and controls
187 lines (177 loc) · 6.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>趣味学Python</title>
<script src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"></script>
<style>
body { font-family: Arial, sans-serif; margin: 0; background: #f8f8f8; }
header { background: #4CAF50; color: white; padding: 10px; text-align: center; }
nav { display: flex; justify-content: center; background: #333; }
nav button { background: none; border: none; color: white; padding: 14px 20px; cursor: pointer; font-size: 16px; }
nav button:hover { background: #575757; }
section { padding: 20px; display: none; }
.active { display: block; }
#drawCardBtn { padding: 10px 20px; font-size: 18px; cursor: pointer; }
#cardResult { margin-top: 20px; font-size: 20px; font-weight: bold; }
#snakeCanvas { background: #000; display: block; margin: 20px auto; }
#pythonOutput { background: #222; color: #0f0; padding: 10px; min-height: 100px; white-space: pre-wrap; }
.card { border: 1px solid #ccc; padding: 10px; margin: 5px; display: inline-block; }
</style>
</head>
<body>
<header>
<h1>趣味学Python</h1>
</header>
<nav>
<button onclick="showSection('home')">首页</button>
<button onclick="showSection('study')">学习区</button>
<button onclick="showSection('draw')">抽卡区</button>
<button onclick="showSection('collection')">卡牌收集</button>
<button onclick="showSection('battle')">AI对战</button>
<button onclick="showSection('snake')">贪吃蛇</button>
</nav>
<section id="home" class="active">
<h2>欢迎来到 趣味学Python</h2>
<p>完成课程获得抽卡机会,收集卡牌,与AI对战!</p>
</section>
<section id="study">
<h2>学习区 - 在线运行Python</h2>
<textarea id="pythonCode" rows="8" style="width:100%;">print('Hello Python!')</textarea><br>
<button onclick="runPython()">运行代码</button>
<h3>输出结果:</h3>
<div id="pythonOutput"></div>
</section>
<section id="draw">
<h2>抽卡区</h2>
<button id="drawCardBtn">点击抽卡</button>
<div id="cardResult"></div>
</section>
<section id="collection">
<h2>卡牌收集册</h2>
<div id="cardCollection"></div>
</section>
<section id="battle">
<h2>AI 对战</h2>
<div id="battleLog"></div>
<button onclick="startBattle()">开始对战</button>
</section>
<section id="snake">
<h2>贪吃蛇小游戏</h2>
<canvas id="snakeCanvas" width="400" height="400"></canvas>
</section>
<script>
function showSection(id) {
document.querySelectorAll('section').forEach(s => s.classList.remove('active'));
document.getElementById(id).classList.add('active');
}
// 在线运行Python
let pyodideReadyPromise = loadPyodide();
async function runPython() {
let code = document.getElementById('pythonCode').value;
await pyodideReadyPromise;
try {
let output = await pyodide.runPythonAsync(code);
document.getElementById('pythonOutput').innerText = output ?? '';
} catch (err) {
document.getElementById('pythonOutput').innerText = err;
}
}
// 卡牌系统
let cardPool = [
{name: '变量猫', rarity: '普通', atk: 5, hp: 5, chance: 60},
{name: '循环龙', rarity: '稀有', atk: 8, hp: 8, chance: 30},
{name: '递归法师', rarity: '史诗', atk: 12, hp: 10, chance: 9},
{name: '算法之神', rarity: '传说', atk: 20, hp: 15, chance: 1}
];
let collection = JSON.parse(localStorage.getItem('cardCollection') || '[]');
function saveCollection() { localStorage.setItem('cardCollection', JSON.stringify(collection)); }
function updateCollectionDisplay() {
let div = document.getElementById('cardCollection');
div.innerHTML = '';
collection.forEach(c => {
div.innerHTML += `<div class='card'><b>${c.name}</b><br>${c.rarity} ATK:${c.atk} HP:${c.hp}</div>`;
});
}
updateCollectionDisplay();
document.getElementById('drawCardBtn').addEventListener('click', () => {
let rand = Math.random() * 100;
let sum = 0;
for (let card of cardPool) {
sum += card.chance;
if (rand <= sum) {
collection.push(card);
saveCollection();
updateCollectionDisplay();
document.getElementById('cardResult').innerText = `恭喜你抽到了 ${card.rarity}卡: ${card.name}`;
break;
}
}
});
// AI对战
function startBattle() {
if (collection.length === 0) {
alert('你还没有卡牌,先去抽卡!');
return;
}
let playerCard = collection[Math.floor(Math.random()*collection.length)];
let aiCard = cardPool[Math.floor(Math.random()*cardPool.length)];
let log = `你派出 ${playerCard.name} VS AI的 ${aiCard.name}\n`;
while (playerCard.hp > 0 && aiCard.hp > 0) {
aiCard.hp -= playerCard.atk;
if (aiCard.hp <= 0) { log += '你赢了!奖励一次抽卡机会!'; break; }
playerCard.hp -= aiCard.atk;
if (playerCard.hp <= 0) { log += '你输了!再接再厉!'; break; }
}
document.getElementById('battleLog').innerText = log;
}
// 贪吃蛇
const canvas = document.getElementById('snakeCanvas');
const ctx = canvas.getContext('2d');
let box = 20;
let snake = [{x: 9 * box, y: 9 * box}];
let direction;
let food = { x: Math.floor(Math.random()*20) * box, y: Math.floor(Math.random()*20) * box };
document.addEventListener('keydown', event => {
if (event.key === 'ArrowLeft' && direction !== 'RIGHT') direction = 'LEFT';
else if (event.key === 'ArrowUp' && direction !== 'DOWN') direction = 'UP';
else if (event.key === 'ArrowRight' && direction !== 'LEFT') direction = 'RIGHT';
else if (event.key === 'ArrowDown' && direction !== 'UP') direction = 'DOWN';
});
function drawSnakeGame() {
ctx.clearRect(0, 0, 400, 400);
for (let s of snake) {
ctx.fillStyle = 'lime';
ctx.fillRect(s.x, s.y, box, box);
}
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, box, box);
let snakeX = snake[0].x;
let snakeY = snake[0].y;
if (direction === 'LEFT') snakeX -= box;
if (direction === 'UP') snakeY -= box;
if (direction === 'RIGHT') snakeX += box;
if (direction === 'DOWN') snakeY += box;
if (snakeX === food.x && snakeY === food.y) {
food = { x: Math.floor(Math.random()*20) * box, y: Math.floor(Math.random()*20) * box };
} else {
snake.pop();
}
let newHead = {x: snakeX, y: snakeY};
if (snakeX < 0 || snakeY < 0 || snakeX >= 400 || snakeY >= 400 || collision(newHead, snake)) {
clearInterval(game);
alert('游戏结束');
}
snake.unshift(newHead);
}
function collision(head, array) {
for (let s of array) {
if (head.x === s.x && head.y === s.y) return true;
}
return false;
}
let game = setInterval(drawSnakeGame, 150);
</script>
</body>
</html>