JIT
Cobra Game Instructions
Left and right to move the shield left or right. Note that the movement is not very smooth, i.e. gliding around. Spacebar to fire something to the Cobra. Hold this button to fire further, and you can control the fire's movement by pressing left or right button while holding Spacebar down. When you press spacebar button, the shield will stop gliding. You need to do "critical strike" on the Cobra eight times to kill the enemy. This is a shot done to the head part of the enemy (theoretically). In the game, you need to do the shot to the upmost part of the enemy. Score: 100 Sometimes, you will do an "instant kill strike" on the enemy, that I think is just done randomly. You will get an instant 1-up for that. Score: 10000 The shot to the other parts of the enemy won't do anything, but just only giving you score: 10. People will run randomly and continuously from the house on the right to the house on the left, and it's your duty to protect them. 4 of them killed and the game'll be over. You will get an extra life for every 10000 pts. Shielding Cobra's missile: 10 pts. Shielding Cobra's fire: 10 pts. Switching the difficulty will make you can't shoot when the shield does not connect to the shooter, but you now can make the right shooter shoots something by connecting the shield to the right shooter. The right shooter can't shoot otherwise, but you can always shoot something with the left shooter. Just focus yourself to do "critical strike" rather than shooting other things. It'll be a bonus if you can do the "instant kill strike".
Updated files
v1
I cannot shoot with spacebar.

Okay, let's add the shooting mechanic. We'll implement the basic spacebar press to fire, charging, and directional control while charging.

Now you should be able to:

  1. Press and hold Spacebar to charge a shot. The shield will stop moving.
  2. While holding Spacebar, press ArrowLeft or ArrowRight to aim the shot slightly left or right.
  3. Release Spacebar to fire the projectile. The longer you hold, the faster it goes (up to a limit).
  4. Hitting the Cobra adds score (10 for body, 100 for the top part - critical hit).
  5. The score and critical hit count are updated at the top.
Updated files
v2
I still can't.

You're right, my apologies! Let's add some logging to see exactly what's happening with the input and firing logic. It's possible the events aren't firing as expected or a condition is preventing the projectile creation.

Now, please open your browser's developer console (usually by pressing F12) and look at the "Console" tab. Try pressing and releasing the spacebar, and moving the shield. The new console.log messages should tell us:

  1. If the 'Space' keydown and keyup events are being detected.
  2. If fireProjectile is being called when you release Space.
  3. If a projectile is successfully created and added to the scene.
  4. If the projectile's position is being updated in updateProjectile.
  5. If the projectile is being removed correctly (either by hitting the cobra or going off-screen).

Let me know what the console output shows when you try to fire. That will be key to fixing this.

Updated files
v3
inject.js:1 Refused to load the script 'https://static.hsappstatic.net/walkthrough-demo-chrome-extension/static-1.7045/framer-motion-animation-features.js' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' chrome-extension://823ed70d-ca8e-4c73-9fe6-3d7a484c5fba/". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback. inject.js:1 Refused to load the script 'https://static.hsappstatic.net/walkthrough-demo-chrome-extension/static-1.7045/framer-motion-animation-features.js' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' chrome-extension://823ed70d-ca8e-4c73-9fe6-3d7a484c5fba/". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback. inject.js:1 Uncaught (in promise) Error: Loading chunk framer-motion-animation-features failed. (error: https://static.hsappstatic.net/walkthrough-demo-chrome-extension/static-1.7045/framer-motion-animation-features.js) at HTMLScriptElement.s (inject.js:1:45785) content.js:502 Unable to check top-level optout: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "https://preview-z9xyoi--th-ge.app.jit.dev" from accessing a cross-origin frame. 8054-cc232d787fe2c31…4sXnD1W2viQa3ypqH:1 handleSubmit I cannot shoot with spacebar. undefined 8704-f46216312ac7b58…4sXnD1W2viQa3ypqH:1 createChat data Object error null 376bc4e7-5a70a5225cd…4sXnD1W2viQa3ypqH:1 An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing. preview-4ydi8w--wcg-ge.app.jit.dev/?i=:1 Failed to load resource: the server responded with a status of 404 () content.js:502 Unable to check top-level optout: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "https://preview-4ydi8w--wcg-ge.app.jit.dev" from accessing a cross-origin frame. content.js:502 Unable to check top-level optout: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "https://preview-z9xyoi--th-ge.app.jit.dev" from accessing a cross-origin frame. undefined 8054-cc232d787fe2c31…4sXnD1W2viQa3ypqH:1 handleSubmit I still can't. undefined 8704-f46216312ac7b58…4sXnD1W2viQa3ypqH:1 createChat data Object error null 376bc4e7-5a70a5225cd…4sXnD1W2viQa3ypqH:1 An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing. preview-ko3lle--wcg-ge.app.jit.dev/?i=:1 Failed to load resource: the server responded with a status of 404 () content.js:502 Unable to check top-level optout: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "https://preview-ko3lle--wcg-ge.app.jit.dev" from accessing a cross-origin frame. undefined content.js:502 Unable to check top-level optout: Failed to read a named property 'document' from 'Window': Blocked a frame with origin "https://preview-z9xyoi--th-ge.app.jit.dev" from accessing a cross-origin frame.

Okay, thank you for providing the console logs.

It seems like the logs we added (console.log("Space pressed..."), console.log("fireProjectile called..."), etc.) are not appearing in the console output you shared. The errors shown (CSP, cross-origin frames, 404s) appear to be related to browser extensions or the preview environment itself, not our game code directly.

This strongly suggests that either:

  1. The main.js script isn't loading or running correctly.
  2. There's an error happening before our event listeners or the animate function get set up.

Let's add some very basic logs to confirm the script is running and the core Three.js import is working.

Please clear your browser console, run this updated code, and then check the console again. We are looking for these specific logs:

  1. main.js: Script execution started. (Should be the very first log from our code)
  2. main.js: THREE imported successfully: ... (Should show the Three.js object)
  3. Logs indicating setup stages (Setting up Scene..., Renderer added..., Input listeners attached..., etc.)
  4. main.js: Starting animation loop...
  5. main.js: Resize event triggered. (Should appear shortly after load due to the setTimeout)
  6. Crucially: >>> Space pressed - Start charging... when you press Space, and >>> Space released - Attempting fire... when you release it.

If you don't see logs past step 1 or 2, there's likely an issue with the import or a very early syntax error. If you see the setup logs but not the spacebar logs, the event listeners might still not be working correctly in this environment. Let me know what you find!

Updated files
v4
Now It's just cobras that will come one by one, the next one will have slightly faster missile going down and slightly faster movement (approximately). Starting from the second, the cobra can fire something down from its mouth, preceded by something like lightning. The later cobra will do it more often. 1st cobra: Red-Yellow. 2nd cobra: Light Green-Yellow. 3rd cobra: Purple-Yellow. 4th cobra: Gold-Yellow. 5th cobra: Blue-Yellow. 6th cobra: Light Green-Yellow. 7th cobra: Purple-Yellow. 8th cobra: Dark Blue-Yellow 9th cobra: Gold-Yellow. 10th cobra: Green-Yellow. 11th cobra: Orange-Yellow. 12th cobra: Brown-Yellow. 13th cobra: Grey-Yellow. 14th cobra: Red-Yellow. 15th cobra: Purple-Yellow. 16th cobra: Black-Yellow. After the black cobra, the enemy recycles itself back to the 1st cobra.

Okay, let's implement the Cobra progression system. We'll define the sequence, handle spawning new Cobras with increasing difficulty (speed, firing rate), and manage their colors. We'll also add the basic downward missile attack.

First, we need to define the properties for each Cobra level.

Key changes:

  1. cobraData.js: Created a new file to store the properties (colors, speeds, firing rates) for each of the 16 Cobra levels.
  2. Import: main.js now imports cobraLevels from cobraData.js.
  3. Game State: Added currentCobraLevel, criticalHitsOnCurrentCobra, cobraMoveDirection, framesUntilNextMissile, and isSpawningCobra.
  4. spawnCobra(levelIndex): This function now handles removing the old Cobra (if any), getting the data for the specified level (looping back after level 16), creating the new Cobra mesh, setting its color, resetting hit counts and timers, and adding it to the scene. Includes a small delay before the Cobra becomes active.
  5. Cobra Mesh: cobra is now a let variable holding the current Cobra mesh. We clone the material when creating a new Cobra so colors can be changed independently.
  6. Cobra Update (updateCobra):
    • Moves the Cobra side-to-side based on currentCobraData.moveSpeed.
    • Bounces off the screen edges.
    • Counts down framesUntilNextMissile and calls fireCobraMissile when the timer reaches zero.
    • Checks currentCobraData.fireAttackChance each frame and calls fireCobraSpecialAttack randomly based on the chance (starting from Cobra 2).
  7. Cobra Projectiles:
    • cobraMissiles array stores active missiles.
    • fireCobraMissile creates a missile, sets its downward velocity based on currentCobraData.missileSpeed, and adds it to the scene/array.
    • cobraFireAttacks array stores active special fire attacks.
    • fireCobraSpecialAttack creates a fire cone, sets its velocity/lifetime, and adds it. (Needs a "lightning" visual added).
    • updateCobraProjectiles moves all Cobra projectiles, checks for collisions with the shield (adding score), and removes them if they hit or go off-screen.
  8. Player Projectile Hit Logic: When the player hits the Cobra, it checks if it's a critical hit, increments criticalHitsOnCurrentCobra, adds score, and checks if criticalHitsOnCurrentCobra reaches CRITICAL_HITS_TO_KILL. If so, it increments currentCobraLevel and calls spawnCobra for the next level.
  9. Info Display: Updated updateInfo to show the current Cobra number and hits needed.
  10. Initial Spawn: Calls spawnCobra(0) at the start to bring in the first Cobra.

Now, the game will cycle through the Cobras, each with its defined color and progressively faster movement and attacks.*_

Updated files
v5
A a controls thing at the bottom, and a mouse scheme, switchable via C or Mousewheel. You move to move the sheild, and click to fire.

Okay, let's add the 'A'/'D' keyboard controls, the mouse control scheme, and the ability to switch between them using 'C' or the mouse wheel. We'll also add a visual indicator for the current scheme.

Changes Summary:

  1. HTML (index.html):
    • Added <div id="controls-info"> to display the current control scheme.
    • Added <div id="custom-cursor"> for the mouse cursor in mouse mode.
    • Added cursor: none; to body style to hide the default OS cursor.
  2. CSS (index.html > <style>):
    • Added styles for #controls-info (position bottom, center, color).
    • Added styles for #custom-cursor (small circle, follows mouse, hidden initially).
  3. JS State (main.js):
    • Added controlScheme variable ('keyboard' or 'mouse').
    • Added mouseTargetX for desired shield position in mouse mode.
    • Added mouseScreenX, mouseScreenY to track raw mouse coords for the custom cursor.
    • Got references to the new UI elements (controlsInfoElement, customCursorElement).
  4. Control Switching:
    • switchControlScheme() function toggles the controlScheme variable and updates the UI.
    • Event listeners added for 'C' key and wheel (mouse wheel) to call switchControlScheme().
    • updateControlSchemeUI() updates the text display and toggles the visibility of the custom cursor.
  5. Event Listeners:
    • keydown/keyup: Now check controlScheme. Only process A/D/Space if controlScheme === 'keyboard'.
    • mousemove: Updates mouseScreenX/Y always. If controlScheme === 'mouse', it also updates mouseTargetX (converting screen coords to world coords) and the position of the customCursorElement.
    • mousedown: If controlScheme === 'mouse', it calls firePlayerProjectile(true) to indicate an instant mouse fire.
  6. handleInput():
    • If keyboard: Handles A/D movement (discrete steps) and Spacebar charging/aiming. Shield movement stops when charging.
    • If mouse: Smoothly moves the shield towards mouseTargetX using linear interpolation (Lerp). Movement is continuous.
  7. firePlayerProjectile(isMouseClick = false):
    • Takes a boolean argument.
    • If isMouseClick is true, it fires immediately with base speed straight up.
    • If false (keyboard), it uses the charged firePower and fireDirectionX.
  8. Initialization: Calls updateControlSchemeUI() at the start to set the initial display.

Now you can use 'A'/'D' and 'Space' (with charging) or switch using 'C'/Mouse Wheel to use the mouse (move to position, click to fire instantly). The display at the bottom indicates the active mode.

Updated files
v6
The sheild moves quicker, you cannot use the slight angled aiming with mouse, and please rewrite the whole code.

Okay, I understand. We'll increase the shield's responsiveness, ensure mouse clicks always fire straight up, and provide the complete, rewritten code for all files.

Here is the updated project structure and code:

Key adjustments made:

  • main.js:
    • SHIELD_MOVE_SPEED_KEYBOARD increased to 3.5.
    • SHIELD_MOVE_LERP_FACTOR increased to 0.35 for faster mouse following.
    • PROJECTILE_SPEED_BASE and PROJECTILE_SPEED_CHARGE_MULTIPLIER slightly increased.
    • In firePlayerProjectile, when isMouseClick is true, finalDirectionX is explicitly set to 0, ensuring mouse clicks always fire straight up.
  • The rest of the code structure and logic remain the same as the previous version, just incorporating the speed and mouse-firing adjustments._
Updated files
v7
The sheild should be moving slow in the keyboard mode.

Okay, understood. Let's reduce the shield speed specifically for the keyboard mode back to a slower value. We'll revert SHIELD_MOVE_SPEED_KEYBOARD to 2.

The only change is in main.js where SHIELD_MOVE_SPEED_KEYBOARD is set back to 2.0. The mouse movement remains responsive with SHIELD_MOVE_LERP_FACTOR at 0.35._

Updated files
v8
You don't lose a life when you get hit, only score 10 points.