User prompt
The gun should automatically fire in sync with the speed of the falling notes. The player, using head movements, only needs to aim the crosshair at the notes — no manual shooting is required. ↪💡 Consider importing and using the following plugins: @upit/facekit.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Nota Avcısı: Yüzle Nişan Al!
Initial prompt
*Game Concept:* Notes fall from the top of the screen in multiple columns. A fixed gun is placed at the bottom-left corner. The player controls the aim by moving their head (FaceKit integration), and the crosshair moves accordingly on the screen. When the player taps a note while aiming at it, the note is shot and triggers a musical sound. *Features:* - Multiple falling note columns, each representing different piano notes - Fixed gun in bottom-left corner - Crosshair follows player’s head movement (FaceKit) - Tap a note while aiming to shoot and play the corresponding sound - Notes fall in sync with different music tracks (randomly chosen each round) - Difficulty increases every 10 points by speeding up the notes - Game title includes buttons to select speed: Slow, Normal, Fast - Gameplay hint: “Move your head to aim and tap notes to shoot” displayed on screen Türkçe yap
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ // Ball class: the fixed shooter at bottom left var Ball = Container.expand(function () { var self = Container.call(this); var ballAsset = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, width: BALL_SIZE, height: BALL_SIZE, color: 0xffffff, shape: 'ellipse' }); return self; }); // Bullet class: fired from ball towards crosshair var Bullet = Container.expand(function () { var self = Container.call(this); var bulletAsset = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, width: BULLET_SIZE, height: BULLET_SIZE, color: 0x00e6e6, shape: 'ellipse' }); self.vx = 0; self.vy = 0; self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Crosshair class: follows facekit position var Crosshair = Container.expand(function () { var self = Container.call(this); var crossAsset = self.attachAsset('crosshair', { anchorX: 0.5, anchorY: 0.5, width: CROSS_SIZE, height: CROSS_SIZE, color: 0xff0000, shape: 'ellipse' }); return self; }); // Note class: falling note var Note = Container.expand(function () { var self = Container.call(this); // Randomly pick a color for the note var color = NOTE_COLORS[Math.floor(Math.random() * NOTE_COLORS.length)]; var noteAsset = self.attachAsset('note', { anchorX: 0.5, anchorY: 0.5, width: NOTE_WIDTH, height: NOTE_HEIGHT, color: color, shape: 'ellipse' }); self.column = 0; // which column this note is in self.speed = noteFallSpeed; // will be set on spawn self.hit = false; // has this note been hit self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181a20 }); /**** * Game Code ****/ // Note: All note assets will be ellipses with different colors for variety // --- Constants --- var NOTE_COLORS = [0xffe066, 0x66b3ff, 0xff66a3, 0x7cff66, 0xff8c66]; var GAME_W = 2048; var GAME_H = 2732; var BALL_SIZE = 120; var NOTE_WIDTH = 160; var NOTE_HEIGHT = 90; var CROSS_SIZE = 90; var BULLET_SIZE = 60; var NOTE_COLS = 5; var NOTE_MARGIN = 60; var NOTE_AREA_W = GAME_W - 2 * NOTE_MARGIN; var NOTE_COL_W = NOTE_AREA_W / NOTE_COLS; var NOTE_START_Y = -NOTE_HEIGHT; var BALL_X = 180; var BALL_Y = GAME_H - 220; var CROSS_MIN_X = 200; var CROSS_MAX_X = GAME_W - 200; var CROSS_MIN_Y = 200; var CROSS_MAX_Y = GAME_H - 400; var BULLET_SPEED = 48; // px per frame // --- Game State --- var notes = []; var bullets = []; var crosshair = null; var ball = null; var scoreTxt = null; var tipTxt = null; var lastNoteSpawnTick = 0; var noteFallSpeed = 12; // will be set by difficulty var noteSpawnInterval = 60; // ticks between notes, will be set by difficulty var difficulty = null; // 'slow', 'normal', 'fast' var gameStarted = false; var canShoot = true; var lastScore = 0; var musicTracks = [{ id: 'music1', name: 'Parça 1' }, { id: 'music2', name: 'Parça 2' }, { id: 'music3', name: 'Parça 3' }]; var currentMusic = null; // --- Difficulty Presets --- var DIFFICULTY_PRESETS = { 'slow': { noteFallSpeed: 10, noteSpawnInterval: 80 }, 'normal': { noteFallSpeed: 14, noteSpawnInterval: 60 }, 'fast': { noteFallSpeed: 20, noteSpawnInterval: 40 } }; // --- UI: Difficulty Selection --- var diffBtns = []; function showDifficultyMenu() { var btnLabels = [{ key: 'slow', label: 'Yavaş' }, { key: 'normal', label: 'Normal' }, { key: 'fast', label: 'Hızlı' }]; var btnW = 500, btnH = 180, btnGap = 60; var startY = GAME_H / 2 - (btnLabels.length * btnH + (btnLabels.length - 1) * btnGap) / 2; for (var i = 0; i < btnLabels.length; i++) { var btn = new Container(); var bg = btn.attachAsset('btnbg', { anchorX: 0.5, anchorY: 0.5, width: btnW, height: btnH, color: 0x222a38, shape: 'box' }); var txt = new Text2(btnLabels[i].label, { size: 90, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; btn.addChild(txt); btn.x = GAME_W / 2; btn.y = startY + i * (btnH + btnGap); btn.difficulty = btnLabels[i].key; btn.down = function (x, y, obj) { startGame(this.difficulty); }; game.addChild(btn); diffBtns.push(btn); } // Show tip if (!tipTxt) { tipTxt = new Text2("Başını hareket ettir, notalara dokun ve ateş et!", { size: 70, fill: 0xFFE066 }); tipTxt.anchor.set(0.5, 0); } tipTxt.x = GAME_W / 2; tipTxt.y = 180; game.addChild(tipTxt); } // Remove difficulty menu function hideDifficultyMenu() { for (var i = 0; i < diffBtns.length; i++) { diffBtns[i].destroy(); } diffBtns = []; if (tipTxt) { tipTxt.destroy(); tipTxt = null; } } // --- Start Game --- function startGame(diffKey) { difficulty = diffKey; noteFallSpeed = DIFFICULTY_PRESETS[diffKey].noteFallSpeed; noteSpawnInterval = DIFFICULTY_PRESETS[diffKey].noteSpawnInterval; gameStarted = true; hideDifficultyMenu(); LK.setScore(0); lastScore = 0; notes = []; bullets = []; // Pick a random music currentMusic = musicTracks[Math.floor(Math.random() * musicTracks.length)]; LK.playMusic(currentMusic.id); // Ball ball = new Ball(); ball.x = BALL_X; ball.y = BALL_Y; game.addChild(ball); // Crosshair crosshair = new Crosshair(); crosshair.x = BALL_X + 400; crosshair.y = BALL_Y - 400; game.addChild(crosshair); // Score if (!scoreTxt) { scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); } scoreTxt.setText(0); // Show tip for a few seconds if (!tipTxt) { tipTxt = new Text2("Başını hareket ettir, notalara dokun ve ateş et!", { size: 70, fill: 0xFFE066 }); tipTxt.anchor.set(0.5, 0); } tipTxt.x = GAME_W / 2; tipTxt.y = 180; game.addChild(tipTxt); LK.setTimeout(function () { if (tipTxt) { tipTxt.destroy(); tipTxt = null; } }, 3000); } // --- End Game --- function endGame(win) { // Clean up for (var i = 0; i < notes.length; i++) notes[i].destroy(); notes = []; for (var i = 0; i < bullets.length; i++) bullets[i].destroy(); bullets = []; if (ball) { ball.destroy(); ball = null; } if (crosshair) { crosshair.destroy(); crosshair = null; } gameStarted = false; LK.stopMusic(); if (win) { LK.showYouWin(); } else { LK.showGameOver(); } } // --- Note Spawning --- function spawnNote() { var note = new Note(); // Pick a random column var col = Math.floor(Math.random() * NOTE_COLS); note.column = col; note.x = NOTE_MARGIN + NOTE_COL_W / 2 + col * NOTE_COL_W; note.y = NOTE_START_Y; note.speed = noteFallSpeed; notes.push(note); game.addChild(note); } // --- Difficulty Increase --- function maybeIncreaseDifficulty() { var score = LK.getScore(); if (score > 0 && score % 10 === 0 && score !== lastScore) { // Increase speed and spawn rate noteFallSpeed += 2; if (noteSpawnInterval > 20) noteSpawnInterval -= 6; lastScore = score; } } // --- Facekit Crosshair Update --- function updateCrosshair() { if (!crosshair) return; // Use facekit.noseTip or facekit.mouthCenter for aiming var fx = facekit.noseTip ? facekit.noseTip.x : facekit.mouthCenter ? facekit.mouthCenter.x : GAME_W / 2; var fy = facekit.noseTip ? facekit.noseTip.y : facekit.mouthCenter ? facekit.mouthCenter.y : GAME_H / 2; // Clamp to play area if (fx < CROSS_MIN_X) fx = CROSS_MIN_X; if (fx > CROSS_MAX_X) fx = CROSS_MAX_X; if (fy < CROSS_MIN_Y) fy = CROSS_MIN_Y; if (fy > CROSS_MAX_Y) fy = CROSS_MAX_Y; crosshair.x = fx; crosshair.y = fy; } // --- Fire Bullet --- function fireBullet() { if (!canShoot || !gameStarted) return; canShoot = false; // Find if crosshair is over a note var hitNote = null; for (var i = 0; i < notes.length; i++) { var n = notes[i]; if (!n.hit && crosshair && crosshair.intersects(n)) { hitNote = n; break; } } // Fire bullet towards crosshair var b = new Bullet(); b.x = ball.x; b.y = ball.y; // Direction vector var dx = crosshair.x - ball.x; var dy = crosshair.y - ball.y; var len = Math.sqrt(dx * dx + dy * dy); if (len === 0) { dx = 0; dy = -1; len = 1; } b.vx = BULLET_SPEED * dx / len; b.vy = BULLET_SPEED * dy / len; bullets.push(b); game.addChild(b); // If hitNote, mark as hit (so only one bullet per note) if (hitNote) { hitNote.hit = true; } // Play note sound (simulate: play a sound per note column) var soundId = 'note' + (hitNote ? hitNote.column : Math.floor(Math.random() * NOTE_COLS)); LK.getSound(soundId).play(); // Allow next shot after short delay LK.setTimeout(function () { canShoot = true; }, 250); } // --- Main Game Loop --- game.update = function () { if (!gameStarted) return; // Update crosshair position from facekit updateCrosshair(); // Spawn notes if (LK.ticks - lastNoteSpawnTick >= noteSpawnInterval) { spawnNote(); lastNoteSpawnTick = LK.ticks; // Automatically fire a bullet every time a note spawns fireBullet(); } // Update notes for (var i = notes.length - 1; i >= 0; i--) { var n = notes[i]; n.update(); // If note is hit and bullet will reach it, handled below // If note falls below screen, game over if (n.y > GAME_H + NOTE_HEIGHT / 2) { endGame(false); return; } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.update(); // Remove bullet if out of bounds if (b.x < -100 || b.x > GAME_W + 100 || b.y < -100 || b.y > GAME_H + 100) { b.destroy(); bullets.splice(i, 1); continue; } // Check collision with notes for (var j = notes.length - 1; j >= 0; j--) { var n = notes[j]; if (n.hit && b.intersects(n)) { // Hit! LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); // Remove note and bullet n.destroy(); notes.splice(j, 1); b.destroy(); bullets.splice(i, 1); // Difficulty up maybeIncreaseDifficulty(); // Win condition: 50 points if (LK.getScore() >= 50) { endGame(true); return; } break; } } } }; // --- Show Difficulty Menu on Start --- showDifficultyMenu(); /**** * Asset Initialization (for static analysis) ****/ // Notes (5 columns, 5 colors) for (var i = 0; i < NOTE_COLS; i++) {} // Ball // Crosshair // Bullet // Button background // Music tracks
===================================================================
--- original.js
+++ change.js
@@ -365,13 +365,8 @@
LK.setTimeout(function () {
canShoot = true;
}, 250);
}
-// --- Touch Handler: tap to fire if crosshair is over a note
-game.down = function (x, y, obj) {
- if (!gameStarted) return;
- fireBullet();
-};
// --- Main Game Loop ---
game.update = function () {
if (!gameStarted) return;
// Update crosshair position from facekit
@@ -379,8 +374,10 @@
// Spawn notes
if (LK.ticks - lastNoteSpawnTick >= noteSpawnInterval) {
spawnNote();
lastNoteSpawnTick = LK.ticks;
+ // Automatically fire a bullet every time a note spawns
+ fireBullet();
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var n = notes[i];
Make a wallpaper that features small music notes and guns. The image should look good for the game and not appear pixelated.. In-Game asset. 2d. High contrast. No shadows
A rounded rectangle frame with both the inside and the border colored — no text inside. Colors can be yellow, blue, or white.. In-Game asset. 2d. High contrast. No shadows
I want a button box with rounded corners and a colorful design using blue, yellow, and white colors. In-Game asset. There should be no text inside the button.
dörtken şekilde olan üzerinde 🎵 simgesi olan bir nota. In-Game asset. 2d. High contrast. No shadows
Market sepeti sarı renk oyuncak gibi. In-Game asset. 2d. High contrast. No shadows
mavi sarı renkte kenarlaı düz dörtken olan bir kart ve ya çercive. In-Game asset. 2d. High contrast. No shadows
Mavi arka plan üzerinde sarı müzik notası simgeleri ve market arabası simgeleri olsun. In-Game asset. 2d. High contrast. No shadows
beyaz ev simgesi. In-Game asset. 2d. High contrast. No shadows
Yuvarlak altın para ortasında 🎶 müzik notası. In-Game asset. 2d. High contrast. No shadows
sarı dörtgen kenarkarı açık mavi. In-Game asset. 2d. High contrast. No shadows
beyaz bir İ buton görseli. In-Game asset. 2d. High contrast. No shadows
küçük bir kırmızı kalp ve içinde beyaz 🎶 notası. In-Game asset. 2d. High contrast. No shadows