Luis-Filipe commited on
Commit
b5a1fc7
·
verified ·
1 Parent(s): 6398ffa

Upload 5 files

Browse files
README-TRANSPARENT.md ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Space Invaders - Transparent Sprites Edition
2
+
3
+ ## 🎨 What's New: Transparent Backgrounds!
4
+ Your sprites now have **transparent backgrounds** instead of white ones, making them look much more professional and natural in the game!
5
+
6
+ ## ✅ Background Removal Results:
7
+ - **Ship**: Removed 866 white pixels → Transparent background
8
+ - **Invader**: Removed 777 white pixels → Transparent background
9
+ - **Bullet**: Removed 21 white pixels → Transparent background
10
+
11
+ ## 🚀 Quick Start
12
+ 1. Open `space-invaders.html` in your web browser
13
+ 2. Click "START GAME"
14
+ 3. Use **Arrow Keys** or **A/D** to move your ship
15
+ 4. Press **SPACEBAR** to shoot
16
+ 5. Enjoy the clean, professional look!
17
+
18
+ ## 🎮 What You'll See
19
+ - **Your ship** with transparent background (no white box around it)
20
+ - **Your invader** with clean edges and no white background
21
+ - **Your bullet** seamlessly integrated into the game
22
+ - **Professional appearance** - sprites blend naturally with the black space background
23
+
24
+ ## 📁 File Structure
25
+ ```
26
+ your-game/
27
+ ├── space-invaders.html # Main game file
28
+ └── assets/
29
+ ├── ship-transparent.png # Your ship (transparent background, 40×30px)
30
+ ├── invader-transparent.png # Your invader (transparent background, 35×25px)
31
+ └── bullet-transparent.png # Your bullet (transparent background, 4×10px)
32
+ ```
33
+
34
+ ## 🎯 Technical Improvements
35
+ - **Alpha channel support** - Sprites use RGBA for transparency
36
+ - **Clean edges** - No more white squares around your artwork
37
+ - **Better blending** - Sprites integrate seamlessly with game background
38
+ - **Professional quality** - Industry-standard sprite handling
39
+
40
+ ## 🎨 Visual Benefits
41
+ - **No white boxes** around your sprites
42
+ - **Clean, crisp edges**
43
+ - **Natural look** on black space background
44
+ - **Professional game appearance**
45
+ - **Better visual impact**
46
+
47
+ ---
48
+ **Created by MiniMax Agent** | *November 2025*
assets/bullet-transparent.png ADDED
assets/invader-transparent.png ADDED
assets/ship-transparent.png ADDED
space-invaders.html ADDED
@@ -0,0 +1,499 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Space Invaders - Transparent Sprites</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ padding: 20px;
11
+ background: #000;
12
+ font-family: 'Courier New', monospace;
13
+ color: #00ff00;
14
+ display: flex;
15
+ flex-direction: column;
16
+ align-items: center;
17
+ user-select: none;
18
+ }
19
+
20
+ .title {
21
+ margin-bottom: 20px;
22
+ text-shadow: 0 0 10px #00ff00;
23
+ }
24
+
25
+ #gameCanvas {
26
+ border: 3px solid #00ff00;
27
+ box-shadow: 0 0 20px rgba(0, 255, 0, 0.3);
28
+ background: #000;
29
+ }
30
+
31
+ .hud {
32
+ margin: 15px 0;
33
+ font-size: 20px;
34
+ font-weight: bold;
35
+ text-shadow: 0 0 5px #00ff00;
36
+ }
37
+
38
+ .controls {
39
+ margin: 10px 0;
40
+ color: #00cc00;
41
+ font-size: 14px;
42
+ }
43
+
44
+ .game-btn {
45
+ margin: 15px 0;
46
+ padding: 12px 24px;
47
+ background: transparent;
48
+ border: 2px solid #00ff00;
49
+ color: #00ff00;
50
+ font-family: 'Courier New', monospace;
51
+ cursor: pointer;
52
+ font-size: 16px;
53
+ transition: all 0.3s;
54
+ }
55
+
56
+ .game-btn:hover {
57
+ background: #00ff00;
58
+ color: #000;
59
+ box-shadow: 0 0 15px #00ff00;
60
+ }
61
+
62
+ .status {
63
+ margin: 10px 0;
64
+ font-size: 14px;
65
+ color: #008800;
66
+ }
67
+
68
+ .hidden {
69
+ display: none;
70
+ }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <h1 class="title">🚀 SPACE INVADERS - TRANSPARENT SPRITES 🚀</h1>
75
+
76
+ <div class="hud">
77
+ SCORE: <span id="score">000000</span> |
78
+ LIVES: <span id="lives">3</span> |
79
+ LEVEL: <span id="level">1</span>
80
+ </div>
81
+
82
+ <canvas id="gameCanvas" width="800" height="600"></canvas>
83
+
84
+ <div class="controls">
85
+ 🎮 MOVE: Arrow Keys or A/D | 🚀 SHOOT: SPACEBAR
86
+ </div>
87
+
88
+ <button class="game-btn" id="startBtn" onclick="startGame()">START GAME</button>
89
+ <button class="game-btn hidden" id="restartBtn" onclick="restartGame()">RESTART</button>
90
+
91
+ <div class="status" id="status">Loading transparent sprites...</div>
92
+
93
+ <script>
94
+ const canvas = document.getElementById('gameCanvas');
95
+ const ctx = canvas.getContext('2d');
96
+
97
+ let gameState = 'menu';
98
+ let score = 0;
99
+ let lives = 3;
100
+ let level = 1;
101
+
102
+ // Game objects
103
+ let player = {
104
+ x: 380,
105
+ y: 550,
106
+ width: 40,
107
+ height: 30,
108
+ speed: 6,
109
+ lastShot: 0,
110
+ shootDelay: 250
111
+ };
112
+
113
+ let invaders = [];
114
+ let bullets = [];
115
+
116
+ // Your transparent sprites
117
+ let sprites = {
118
+ loaded: false,
119
+ ship: null,
120
+ invader: null,
121
+ bullet: null
122
+ };
123
+
124
+ // Game settings
125
+ const INVADER_ROWS = 5;
126
+ const INVADER_COLS = 11;
127
+ const INVADER_WIDTH = 35;
128
+ const INVADER_HEIGHT = 25;
129
+
130
+ // Movement
131
+ let invaderDirection = 1;
132
+ let invaderSpeed = 1;
133
+ let invaderDropDistance = 20;
134
+
135
+ // Input
136
+ const keys = {};
137
+
138
+ // Setup
139
+ function init() {
140
+ updateStatus('Loading transparent sprites...');
141
+ loadTransparentSprites();
142
+ createInvaders();
143
+ drawInitialScreen();
144
+
145
+ // Keyboard events
146
+ document.addEventListener('keydown', (e) => {
147
+ keys[e.code] = true;
148
+ if (e.code === 'Space') {
149
+ e.preventDefault();
150
+ if (gameState === 'playing') {
151
+ shoot();
152
+ }
153
+ }
154
+ });
155
+
156
+ document.addEventListener('keyup', (e) => {
157
+ keys[e.code] = false;
158
+ });
159
+ }
160
+
161
+ function loadTransparentSprites() {
162
+ console.log('Loading your transparent sprites...');
163
+
164
+ // Use your transparent sprites
165
+ const spriteFiles = {
166
+ ship: 'assets/ship-transparent.png',
167
+ invader: 'assets/invader-transparent.png',
168
+ bullet: 'assets/bullet-transparent.png'
169
+ };
170
+
171
+ let loadedCount = 0;
172
+ const totalSprites = Object.keys(spriteFiles).length;
173
+
174
+ Object.keys(spriteFiles).forEach(key => {
175
+ const img = new Image();
176
+
177
+ img.onload = () => {
178
+ console.log(`✓ Loaded transparent ${key} sprite: ${img.width}x${img.height}px`);
179
+ sprites[key] = img;
180
+ loadedCount++;
181
+
182
+ if (loadedCount === totalSprites) {
183
+ sprites.loaded = true;
184
+ updateStatus('✓ All transparent sprites loaded! Game ready!');
185
+ console.log('All transparent sprites loaded successfully!');
186
+ }
187
+ };
188
+
189
+ img.onerror = () => {
190
+ console.error(`✗ Failed to load transparent ${key} sprite`);
191
+ updateStatus(`✗ Failed to load ${key} sprite - using fallback shapes`);
192
+ };
193
+
194
+ img.src = spriteFiles[key];
195
+ });
196
+ }
197
+
198
+ function drawInitialScreen() {
199
+ // Clear
200
+ ctx.fillStyle = '#000';
201
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
202
+
203
+ // Draw stars
204
+ ctx.fillStyle = '#003300';
205
+ for (let i = 0; i < 50; i++) {
206
+ const x = (i * 137) % canvas.width;
207
+ const y = (i * 173) % canvas.height;
208
+ ctx.fillRect(x, y, 2, 2);
209
+ }
210
+
211
+ // Draw title text
212
+ ctx.fillStyle = '#00ff00';
213
+ ctx.font = '32px Courier New';
214
+ ctx.textAlign = 'center';
215
+ ctx.fillText('SPACE INVADERS - TRANSPARENT SPRITES', canvas.width/2, canvas.height/2 - 50);
216
+
217
+ ctx.font = '20px Courier New';
218
+ ctx.fillText('Click START GAME to begin!', canvas.width/2, canvas.height/2 + 20);
219
+ ctx.fillText('Use ARROW KEYS + SPACEBAR', canvas.width/2, canvas.height/2 + 50);
220
+
221
+ // Test sprite display
222
+ if (sprites.loaded) {
223
+ ctx.drawImage(sprites.ship, canvas.width/2 - 20, canvas.height/2 + 80, 40, 30);
224
+ ctx.drawImage(sprites.invader, canvas.width/2 - 17, canvas.height/2 + 120, 35, 25);
225
+ }
226
+ }
227
+
228
+ function createInvaders() {
229
+ invaders = [];
230
+ const startX = 50;
231
+ const startY = 80;
232
+ const spacingX = 60;
233
+ const spacingY = 40;
234
+
235
+ for (let row = 0; row < INVADER_ROWS; row++) {
236
+ for (let col = 0; col < INVADER_COLS; col++) {
237
+ invaders.push({
238
+ x: startX + col * spacingX,
239
+ y: startY + row * spacingY,
240
+ width: INVADER_WIDTH,
241
+ height: INVADER_HEIGHT,
242
+ alive: true,
243
+ row: row,
244
+ col: col
245
+ });
246
+ }
247
+ }
248
+ }
249
+
250
+ function startGame() {
251
+ gameState = 'playing';
252
+ score = 0;
253
+ lives = 3;
254
+ level = 1;
255
+ player.x = 380;
256
+ createInvaders();
257
+ bullets = [];
258
+ invaderDirection = 1;
259
+ invaderSpeed = 1;
260
+
261
+ document.getElementById('startBtn').classList.add('hidden');
262
+ document.getElementById('restartBtn').classList.add('hidden');
263
+
264
+ updateStatus('Game started! Destroy all invaders!');
265
+ gameLoop();
266
+ }
267
+
268
+ function restartGame() {
269
+ gameState = 'menu';
270
+ document.getElementById('startBtn').classList.remove('hidden');
271
+ document.getElementById('restartBtn').classList.add('hidden');
272
+ drawInitialScreen();
273
+ updateStatus('Game ready! Click START GAME');
274
+ }
275
+
276
+ function shoot() {
277
+ const now = Date.now();
278
+ if (now - player.lastShot < player.shootDelay) return;
279
+
280
+ player.lastShot = now;
281
+ bullets.push({
282
+ x: player.x + player.width/2 - 2,
283
+ y: player.y,
284
+ width: 4,
285
+ height: 10
286
+ });
287
+ }
288
+
289
+ function update() {
290
+ if (gameState !== 'playing') return;
291
+
292
+ // Player movement
293
+ if (keys['ArrowLeft'] || keys['KeyA']) {
294
+ player.x = Math.max(0, player.x - player.speed);
295
+ }
296
+ if (keys['ArrowRight'] || keys['KeyD']) {
297
+ player.x = Math.min(canvas.width - player.width, player.x + player.speed);
298
+ }
299
+
300
+ // Update bullets
301
+ bullets = bullets.filter(bullet => {
302
+ bullet.y -= 8;
303
+ return bullet.y > -20;
304
+ });
305
+
306
+ // Update invaders
307
+ updateInvaders();
308
+
309
+ // Check collisions
310
+ checkCollisions();
311
+
312
+ // Check win/lose conditions
313
+ checkGameConditions();
314
+ }
315
+
316
+ function updateInvaders() {
317
+ const aliveInvaders = invaders.filter(inv => inv.alive);
318
+
319
+ if (aliveInvaders.length === 0) return;
320
+
321
+ const rightmost = Math.max(...aliveInvaders.map(inv => inv.x + inv.width));
322
+ const leftmost = Math.min(...aliveInvaders.map(inv => inv.x));
323
+
324
+ let shouldDrop = false;
325
+
326
+ if ((rightmost >= canvas.width - 50 && invaderDirection > 0) ||
327
+ (leftmost <= 50 && invaderDirection < 0)) {
328
+ shouldDrop = true;
329
+ }
330
+
331
+ if (shouldDrop) {
332
+ invaderDirection *= -1;
333
+ aliveInvaders.forEach(invader => {
334
+ invader.y += invaderDropDistance;
335
+ });
336
+ invaderSpeed += 0.1;
337
+ } else {
338
+ aliveInvaders.forEach(invader => {
339
+ invader.x += invaderSpeed * invaderDirection;
340
+ });
341
+ }
342
+ }
343
+
344
+ function checkCollisions() {
345
+ bullets.forEach((bullet, bulletIndex) => {
346
+ invaders.forEach(invader => {
347
+ if (invader.alive &&
348
+ bullet.x < invader.x + invader.width &&
349
+ bullet.x + bullet.width > invader.x &&
350
+ bullet.y < invader.y + invader.height &&
351
+ bullet.y + bullet.height > invader.y) {
352
+
353
+ invader.alive = false;
354
+ bullets.splice(bulletIndex, 1);
355
+ score += 10 * level;
356
+ updateHUD();
357
+
358
+ createExplosion(invader.x + invader.width/2, invader.y + invader.height/2);
359
+ }
360
+ });
361
+ });
362
+ }
363
+
364
+ function createExplosion(x, y) {
365
+ ctx.save();
366
+ ctx.fillStyle = '#ff6600';
367
+ ctx.beginPath();
368
+ ctx.arc(x, y, 15, 0, Math.PI * 2);
369
+ ctx.fill();
370
+
371
+ ctx.fillStyle = '#ffff00';
372
+ ctx.beginPath();
373
+ ctx.arc(x, y, 8, 0, Math.PI * 2);
374
+ ctx.fill();
375
+ ctx.restore();
376
+ }
377
+
378
+ function checkGameConditions() {
379
+ const aliveInvaders = invaders.filter(inv => inv.alive);
380
+
381
+ if (aliveInvaders.length === 0) {
382
+ levelComplete();
383
+ return;
384
+ }
385
+
386
+ const bottomInvader = Math.max(...aliveInvaders.map(inv => inv.y));
387
+ if (bottomInvader >= canvas.height - 100) {
388
+ gameOver();
389
+ return;
390
+ }
391
+ }
392
+
393
+ function levelComplete() {
394
+ updateStatus(`Level ${level} complete!`);
395
+ level++;
396
+ createInvaders();
397
+ updateHUD();
398
+ }
399
+
400
+ function gameOver() {
401
+ gameState = 'gameover';
402
+ updateStatus(`GAME OVER! Final Score: ${score}`);
403
+ document.getElementById('restartBtn').classList.remove('hidden');
404
+ }
405
+
406
+ function draw() {
407
+ ctx.fillStyle = '#000';
408
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
409
+
410
+ drawStars();
411
+
412
+ if (gameState === 'playing') {
413
+ drawPlayer();
414
+ drawInvaders();
415
+ drawBullets();
416
+ }
417
+ }
418
+
419
+ function drawStars() {
420
+ ctx.fillStyle = '#003300';
421
+ for (let i = 0; i < 30; i++) {
422
+ const x = (i * 47) % canvas.width;
423
+ const y = (i * 83) % canvas.height;
424
+ ctx.fillRect(x, y, 1, 1);
425
+ }
426
+ }
427
+
428
+ function drawPlayer() {
429
+ if (sprites.loaded && sprites.ship) {
430
+ ctx.drawImage(sprites.ship, player.x, player.y, player.width, player.height);
431
+ } else {
432
+ // Fallback to red triangle
433
+ ctx.fillStyle = '#ff0000';
434
+ ctx.beginPath();
435
+ ctx.moveTo(player.x + player.width/2, player.y);
436
+ ctx.lineTo(player.x, player.y + player.height);
437
+ ctx.lineTo(player.x + player.width, player.y + player.height);
438
+ ctx.closePath();
439
+ ctx.fill();
440
+ }
441
+ }
442
+
443
+ function drawInvaders() {
444
+ invaders.forEach(invader => {
445
+ if (invader.alive) {
446
+ if (sprites.loaded && sprites.invader) {
447
+ ctx.drawImage(sprites.invader, invader.x, invader.y, invader.width, invader.height);
448
+ } else {
449
+ // Fallback to green rectangle
450
+ ctx.fillStyle = '#00ff00';
451
+ ctx.fillRect(invader.x, invader.y, invader.width, invader.height);
452
+ ctx.fillStyle = '#008800';
453
+ ctx.fillRect(invader.x + 5, invader.y + 5, invader.width - 10, invader.height - 10);
454
+ }
455
+ }
456
+ });
457
+ }
458
+
459
+ function drawBullets() {
460
+ if (sprites.loaded && sprites.bullet) {
461
+ bullets.forEach(bullet => {
462
+ ctx.drawImage(sprites.bullet, bullet.x, bullet.y, bullet.width, bullet.height);
463
+ });
464
+ } else {
465
+ // Fallback to yellow rectangles
466
+ ctx.fillStyle = '#ffff00';
467
+ bullets.forEach(bullet => {
468
+ ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
469
+ });
470
+ }
471
+ }
472
+
473
+ function updateHUD() {
474
+ document.getElementById('score').textContent = score.toString().padStart(6, '0');
475
+ document.getElementById('lives').textContent = lives;
476
+ document.getElementById('level').textContent = level;
477
+ }
478
+
479
+ function updateStatus(message) {
480
+ document.getElementById('status').textContent = message;
481
+ console.log(message);
482
+ }
483
+
484
+ function gameLoop() {
485
+ if (gameState !== 'playing') return;
486
+
487
+ update();
488
+ draw();
489
+
490
+ requestAnimationFrame(gameLoop);
491
+ }
492
+
493
+ // Initialize game
494
+ init();
495
+ updateHUD();
496
+
497
+ </script>
498
+ </body>
499
+ </html>