User prompt
otomatik sağa gitmeyi kaldır
User prompt
oyun ekranın sağ bakan ok ve sola bakan ok ekle ve bunlara tıklandığında o yöne gitdin
Code edit (1 edits merged)
Please save this source code
User prompt
Shadow Run
Initial prompt
🎮 OYUN ADI: Shadow Run 🎯 OYUNUN AMACI Oyuncu, reflekslerini ve zamanlamasını kullanarak, engellerle dolu bir 2D parkurdan en kısa sürede geçmeye çalışır. Amaç, seviye sonuna ulaşmak veya en yüksek puanı elde etmektir. 🧩 OYUNUN YAPISI 🗺️ Dünya Yapısı 2D sidescroller (yan kaydırmalı) Toplam 5 dünya, her biri 10 bölümden oluşur (toplam 50 seviye) Her dünyanın kendine özgü teması vardır: Şehir Harabeleri Fabrika Bölgesi Dağ Geçitleri Neon Gece (Cyberpunk) Antik Tapınak 🧱 Bölüm Yapısı Her bölümün başı ve sonu var (başlangıç bayrağı ve bitiş portalı) Checkpoint sistemi (büyük bölümlerde) Zaman/puan tabanlı derecelendirme: ★☆☆ → ★★★ 🕹️ KONTROLLER Tuşlar Aksiyon ← / → Hareket SPACE Zıplama ↓ Eğilme / Kayma SHIFT Koşma / Sprint R Yeniden başlat Mobil için: Sanal joystick + butonlar ⚙️ OYUN MEKANİKLERİ Ana Mekanikler Zıplama: Duvara çarptığında kayar. Çift Zıplama: Havada bir kez daha zıplama. Duvar Atlama: Duvarlar arasında sekerek çıkma. Koşu Modu: SHIFT ile hız artar ama durmak zorlaşır. Kayma: Engellerin altından geçme (↓ tuşu ile) Fizik Yerçekimi: Orta seviye Momentum korunur: hızlı koşarken zıplama menzili artar Tehlikeler Çivili tuzaklar Dönen testere bıçakları Düşen platformlar Hareketli düşmanlar (bekleyen robotlar, nöbetçiler) 🎨 GRAFİK VE STİL Grafik Türü 2D pixel art (retro stil) 60 FPS akıcılık Karakter Siluet şeklinde ninja/sokak koşucusu Farklı kostümler açılabilir Ortamlar Parallax arka plan Canlı renkler, animasyonlu objeler (hareket eden bulutlar, ışıklar vs.) 🔊 SES VE MÜZİK Dinamik müzik sistemi (bölüm ilerledikçe tempolu hale gelir) Zıplama, düşme, ölüm, başarı gibi durumlar için ses efektleri Dünyaya özel temalar (örn. Cyberpunk dünyasında elektronik müzik) 🛒 MAĞAZA / GELİŞTİRME SİSTEMİ Oyun içi para: Bölümde toplanan yıldızlar ile kazanılır Mağaza: Kostümler Yeni parkur ayakkabısı (daha yükseğe zıplama) Gölge efekti (estetik amaçlı) Yetenekler: 2x Zıplama süresi Yavaş zaman (1-2 saniye için) 🧠 YAPAY ZEKA Düşmanlar: Basit ileri-geri gezen robotlar Oyuncuya koşan mini dronelar Hareket algılayıcı lazer sistemleri 🏁 BÖLÜM TASARIMI Her seviye şu bölümlerden oluşur: Giriş (öğretici varsa) Ana parkur alanı Tehlike/engeller dizisi Kısa dinlenme noktası Final bölümü + çıkış portalı 🧭 MENÜ SİSTEMİ Ana Menü Oyna Seviye Seç Ayarlar (ses, kontrol, grafik) Mağaza Hakkında Pause Menüsü Devam et Yeniden Başla Ana Menü 💾 KAYIT / İLERLEME Otomatik kayıt (checkpoints + bölüm sonu) Bulut kaydetme (isteğe bağlı) Her bölümde maksimum puan takip sistemi (leaderboard)
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
level: 1,
stars: 0
});
/****
* Classes
****/
// Exit (level goal) class
var Exit = Container.expand(function () {
var self = Container.call(this);
var exit = self.attachAsset('exit', {
anchorX: 0.5,
anchorY: 1
});
return self;
});
// Parallax background layer class
var ParallaxLayer = Container.expand(function () {
var self = Container.call(this);
self.speed = 0;
self.sprite = null;
self.setLayer = function (id, speed) {
self.sprite = self.attachAsset(id, {
anchorX: 0,
anchorY: 0
});
self.speed = speed;
};
self.update = function (dx) {
if (self.sprite) {
self.x -= dx * self.speed;
if (self.x < -2048) self.x += 2048;
if (self.x > 2048) self.x -= 2048;
}
};
return self;
});
// Platform class
var Platform = Container.expand(function () {
var self = Container.call(this);
var plat = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Runner (player) class
var Runner = Container.expand(function () {
var self = Container.call(this);
var runnerSprite = self.attachAsset('runner', {
anchorX: 0.5,
anchorY: 1
});
// Physics
self.vx = 0;
self.vy = 0;
self.onGround = false;
self.doubleJumped = false;
self.wallJumped = false;
self.facing = 1; // 1: right, -1: left
self.isSliding = false;
self.slideTimer = 0;
self.jumpBuffer = 0;
self.dead = false;
// Movement constants
self.speed = 16;
self.jumpPower = 48;
self.gravity = 4;
self.maxFall = 48;
self.slideDuration = 18;
self.slideSpeed = 24;
self.wallJumpPower = 44;
self.wallJumpH = 18;
// For wall jump detection
self.touchingWall = 0; // -1: left, 1: right, 0: none
// Update per frame
self.update = function () {
if (self.dead) return;
// Horizontal movement (manual, only if arrow pressed)
if (leftPressed && !rightPressed) {
self.vx = self.isSliding ? self.slideSpeed * -1 : self.speed * -1;
} else if (rightPressed && !leftPressed) {
self.vx = self.isSliding ? self.slideSpeed * 1 : self.speed * 1;
} else {
self.vx = 0;
}
// Gravity
self.vy += self.gravity;
if (self.vy > self.maxFall) self.vy = self.maxFall;
// Slide timer
if (self.isSliding) {
self.slideTimer--;
if (self.slideTimer <= 0) {
self.isSliding = false;
runnerSprite.height = 180;
runnerSprite.y = 0;
}
}
// Apply movement
self.x += self.vx;
self.y += self.vy;
// Clamp to world bounds
if (self.x < 60) self.x = 60;
if (self.x > 2048 - 60) self.x = 2048 - 60;
if (self.y > 2732 - 60) {
self.y = 2732 - 60;
self.vy = 0;
self.onGround = true;
self.doubleJumped = false;
self.wallJumped = false;
}
};
// Jump
self.jump = function () {
if (self.dead) return;
if (self.onGround) {
self.vy = -self.jumpPower;
self.onGround = false;
self.doubleJumped = false;
LK.getSound('jump').play();
} else if (!self.doubleJumped) {
self.vy = -self.jumpPower * 0.9;
self.doubleJumped = true;
LK.getSound('jump').play();
} else if (self.touchingWall !== 0 && !self.wallJumped) {
self.vy = -self.wallJumpPower;
self.vx = self.wallJumpH * -self.touchingWall;
self.wallJumped = true;
self.facing = -self.touchingWall;
LK.getSound('jump').play();
}
};
// Slide
self.slide = function () {
if (self.dead) return;
if (self.onGround && !self.isSliding) {
self.isSliding = true;
self.slideTimer = self.slideDuration;
runnerSprite.height = 90;
runnerSprite.y = 90;
}
};
// Die
self.die = function () {
if (self.dead) return;
self.dead = true;
LK.getSound('death').play();
tween(self, {
alpha: 0
}, {
duration: 400,
easing: tween.linear,
onFinish: function onFinish() {
LK.effects.flashScreen(0xff0000, 600);
LK.showGameOver();
}
});
};
return self;
});
// Spike (obstacle) class
var Spike = Container.expand(function () {
var self = Container.call(this);
var spike = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1
});
return self;
});
// Star collectible class
var Star = Container.expand(function () {
var self = Container.call(this);
var star = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222a38
});
/****
* Game Code
****/
// Music
// Sound effects
// Parallax background layers
// Level exit
// Star collectible
// Obstacle (spike)
// Ground platform
// Silhouette runner (player)
// --- Level Data (MVP: 1 level, can expand later) ---
var levelData = {
platforms: [{
x: 1024,
y: 2600,
w: 1200
},
// ground
{
x: 600,
y: 2200,
w: 400
}, {
x: 1400,
y: 2000,
w: 400
}, {
x: 900,
y: 1700,
w: 300
}, {
x: 400,
y: 1400,
w: 300
}, {
x: 1200,
y: 1200,
w: 400
}, {
x: 1800,
y: 900,
w: 300
}],
spikes: [{
x: 800,
y: 2540
}, {
x: 1300,
y: 2540
}, {
x: 1400,
y: 1940
}, {
x: 1200,
y: 1140
}],
stars: [{
x: 600,
y: 2100
}, {
x: 900,
y: 1600
}, {
x: 1800,
y: 800
}],
exit: {
x: 1800,
y: 740
}
};
// --- Parallax Background ---
var bg_far = new ParallaxLayer();
bg_far.setLayer('bg_far', 0.1);
game.addChild(bg_far);
var bg_mid = new ParallaxLayer();
bg_mid.setLayer('bg_mid', 0.2);
game.addChild(bg_mid);
var bg_near = new ParallaxLayer();
bg_near.setLayer('bg_near', 0.3);
game.addChild(bg_near);
// --- Platforms ---
var platforms = [];
for (var i = 0; i < levelData.platforms.length; i++) {
var p = new Platform();
p.x = levelData.platforms[i].x;
p.y = levelData.platforms[i].y;
p.width = levelData.platforms[i].w;
p.children[0].width = levelData.platforms[i].w;
platforms.push(p);
game.addChild(p);
}
// --- Spikes ---
var spikes = [];
for (var i = 0; i < levelData.spikes.length; i++) {
var s = new Spike();
s.x = levelData.spikes[i].x;
s.y = levelData.spikes[i].y;
spikes.push(s);
game.addChild(s);
}
// --- Stars ---
var stars = [];
for (var i = 0; i < levelData.stars.length; i++) {
var st = new Star();
st.x = levelData.stars[i].x;
st.y = levelData.stars[i].y;
stars.push(st);
game.addChild(st);
}
// --- Exit ---
var exit = new Exit();
exit.x = levelData.exit.x;
exit.y = levelData.exit.y;
game.addChild(exit);
// --- Runner (Player) ---
var runner = new Runner();
runner.x = 200;
runner.y = 2500;
game.addChild(runner);
// --- Camera ---
var cameraY = 0;
// --- Score/Stars UI ---
var starTxt = new Text2('0', {
size: 100,
fill: 0xFFE066
});
starTxt.anchor.set(0, 0);
LK.gui.top.addChild(starTxt);
starTxt.x = 120;
starTxt.y = 10;
// --- Level UI ---
var levelTxt = new Text2('Level 1', {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.x = 1024;
levelTxt.y = 10;
// --- Touch Controls (Jump/Slide/Left/Right) ---
// Left Arrow Button
var leftBtn = new Text2('←', {
size: 120,
fill: 0xFFFFFF
});
leftBtn.anchor.set(0.5, 1);
LK.gui.bottomLeft.addChild(leftBtn);
leftBtn.x = 80;
leftBtn.y = -40;
// Right Arrow Button
var rightBtn = new Text2('→', {
size: 120,
fill: 0xFFFFFF
});
rightBtn.anchor.set(0.5, 1);
LK.gui.bottomLeft.addChild(rightBtn);
rightBtn.x = 320;
rightBtn.y = -40;
// Jump Button
var jumpBtn = new Text2('JUMP', {
size: 80,
fill: 0xFFFFFF
});
jumpBtn.anchor.set(0.5, 1);
LK.gui.bottomLeft.addChild(jumpBtn);
jumpBtn.x = 560;
jumpBtn.y = -40;
// Slide Button
var slideBtn = new Text2('SLIDE', {
size: 80,
fill: 0xFFFFFF
});
slideBtn.anchor.set(0.5, 1);
LK.gui.bottomRight.addChild(slideBtn);
slideBtn.x = -200;
slideBtn.y = -40;
// --- Touch Controls State for Arrows ---
var leftPressed = false;
var rightPressed = false;
// --- Arrow Button Events ---
leftBtn.down = function () {
leftPressed = true;
rightPressed = false;
runner.facing = -1;
};
leftBtn.up = function () {
leftPressed = false;
};
rightBtn.down = function () {
rightPressed = true;
leftPressed = false;
runner.facing = 1;
};
rightBtn.up = function () {
rightPressed = false;
};
// --- State ---
var collectedStars = 0;
var levelComplete = false;
// --- Helper: AABB collision ---
function aabb(a, b) {
return a.x - a.width / 2 < b.x + b.width / 2 && a.x + a.width / 2 > b.x - b.width / 2 && a.y - a.height < b.y && a.y > b.y - b.height;
}
// --- Game Update ---
game.update = function () {
// Camera follows runner
var targetY = runner.y - 1800;
cameraY += (targetY - cameraY) * 0.15;
game.y = -cameraY;
// Parallax backgrounds
bg_far.update(runner.vx * 0.5);
bg_mid.update(runner.vx * 0.7);
bg_near.update(runner.vx);
// Runner physics
runner.onGround = false;
runner.touchingWall = 0;
// --- Arrow Button Direction Control ---
if (leftPressed && !rightPressed) {
runner.facing = -1;
} else if (rightPressed && !leftPressed) {
runner.facing = 1;
}
// Platform collision
for (var i = 0; i < platforms.length; i++) {
var p = platforms[i];
// Only check if close
if (Math.abs(runner.x - p.x) < p.width / 2 + 80 && Math.abs(runner.y - p.y) < 200) {
// Vertical collision (landing)
if (runner.y + runner.vy >= p.y - 30 && runner.y < p.y && runner.x > p.x - p.width / 2 + 30 && runner.x < p.x + p.width / 2 - 30 && runner.vy >= 0) {
runner.y = p.y - 30;
runner.vy = 0;
runner.onGround = true;
runner.doubleJumped = false;
runner.wallJumped = false;
}
// Wall collision (left)
if (runner.x + runner.vx > p.x - p.width / 2 - 60 && runner.x < p.x - p.width / 2 && runner.y > p.y - 120 && runner.y < p.y + 30) {
runner.x = p.x - p.width / 2 - 60;
runner.vx = 0;
runner.touchingWall = -1;
}
// Wall collision (right)
if (runner.x + runner.vx < p.x + p.width / 2 + 60 && runner.x > p.x + p.width / 2 && runner.y > p.y - 120 && runner.y < p.y + 30) {
runner.x = p.x + p.width / 2 + 60;
runner.vx = 0;
runner.touchingWall = 1;
}
}
}
// Spikes collision
for (var i = 0; i < spikes.length; i++) {
var s = spikes[i];
if (!runner.dead && Math.abs(runner.x - s.x) < 60 && Math.abs(runner.y - s.y) < 60) {
runner.die();
}
}
// Star collection
for (var i = 0; i < stars.length; i++) {
var st = stars[i];
if (!st.collected && Math.abs(runner.x - st.x) < 60 && Math.abs(runner.y - st.y) < 80) {
st.collected = true;
tween(st, {
alpha: 0,
y: st.y - 80
}, {
duration: 400,
onFinish: function onFinish() {
st.destroy();
}
});
collectedStars++;
LK.getSound('star').play();
starTxt.setText(collectedStars);
}
}
// Exit collision
if (!levelComplete && Math.abs(runner.x - exit.x) < 80 && Math.abs(runner.y - exit.y) < 160) {
levelComplete = true;
LK.getSound('exit').play();
tween(runner, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
// Save progress
storage.level = Math.max(storage.level, 2);
storage.stars = (storage.stars || 0) + collectedStars;
LK.setScore(collectedStars);
LK.showYouWin();
}
});
}
};
// --- Touch Controls ---
jumpBtn.down = function () {
runner.jump();
};
slideBtn.down = function () {
runner.slide();
};
// --- Swipe Controls (for mobile) ---
var swipeStartY = null;
game.down = function (x, y, obj) {
swipeStartY = y;
};
game.up = function (x, y, obj) {
if (swipeStartY !== null) {
var dy = y - swipeStartY;
if (dy < -80) {
runner.jump();
} else if (dy > 80) {
runner.slide();
}
}
swipeStartY = null;
};
// --- Music ---
LK.playMusic('bgm1');
// --- Init UI ---
starTxt.setText(collectedStars);
levelTxt.setText('Level 1'); ===================================================================
--- original.js
+++ change.js
@@ -80,10 +80,16 @@
self.touchingWall = 0; // -1: left, 1: right, 0: none
// Update per frame
self.update = function () {
if (self.dead) return;
- // Horizontal movement (auto-run)
- self.vx = self.isSliding ? self.slideSpeed * self.facing : self.speed * self.facing;
+ // Horizontal movement (manual, only if arrow pressed)
+ if (leftPressed && !rightPressed) {
+ self.vx = self.isSliding ? self.slideSpeed * -1 : self.speed * -1;
+ } else if (rightPressed && !leftPressed) {
+ self.vx = self.isSliding ? self.slideSpeed * 1 : self.speed * 1;
+ } else {
+ self.vx = 0;
+ }
// Gravity
self.vy += self.gravity;
if (self.vy > self.maxFall) self.vy = self.maxFall;
// Slide timer