User prompt
Boss haraket etmesin
User prompt
Boss gelince mermi de geliyo sadece bossun mermisi olsun
User prompt
Boss mermi takip mesafesi %60 azalt 5 snde 1 mermi atsın
User prompt
Boss mermi atış hızını yavaşlat %25
User prompt
Boss geldiğinde adam gelmesin
User prompt
Zorda çok kasıyo
User prompt
Zorda bu kadar adam gelmesin az gelsin ama çok az da değil
User prompt
Adamlarınki takip etmesin sadece bossun atışları takip etsin oda tek tek sıksın 1 sn aralıklarka sıksun
User prompt
Zor seçilirse 100 score sonra boşş gelsin ve öldürmek zor olsun 49 mermide ölsün ve oda sıksın bize mermiler bizi takip etsin
User prompt
Kolay orta zor diye her oyun başlangıcı sorsun ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
İstediğim kadar mermi atım
User prompt
Mermiyi kısıtlama
User prompt
Kolay arta zır diye sormuyo sorsun ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Oyunu kastırma mermisi kısıtlama
User prompt
Kaybedince tekrar sorsun ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var globalPos = game.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 217
User prompt
Oyuna başlayınca kolay orta zor diye sorusun kolayda kolay oynansın ortada biraz zorlasın zorda adamlar 3 mermide ölsün ve bize sıksunlar biz yeşil daire alınca 2 lı sonra 3 lı sıkalım ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
Initial prompt
Karakter istediğim yere oynasın
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var EnemyShip = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.type = 'speed'; // speed, fireRate, or coins
self.update = function () {
self.y += self.speed;
self.rotation += 0.1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000011
});
/****
* Game Code
****/
var player = game.addChild(new PlayerShip());
player.x = 1024;
player.y = 2000;
tween(player, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
var playerBullets = [];
var enemies = [];
var bulletTimer = 0;
var enemySpawnTimer = 0;
var enemySpawnRate = 120;
var dragNode = null;
var upgradeLevel = storage.upgradeLevel || 1;
var coins = storage.coins || 0;
var powerUpTimer = 0;
var powerUps = [];
var difficulty = storage.difficulty || null;
var gameStarted = false;
var playerFireMode = 1; // 1 = single, 2 = double, 3 = triple
var enemyHealth = {}; // Track enemy health by difficulty
var maxBullets = 10; // Maximum bullets on screen
var currentBulletCount = 0; // Current bullet count
var isReloading = false; // Reload state
var reloadTimer = 0; // Reload timer
var reloadTime = 120; // 2 seconds at 60fps
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
// Difficulty selection UI
var difficultyTitle = new Text2('Select Difficulty', {
size: 100,
fill: 0xFFFFFF
});
difficultyTitle.anchor.set(0.5, 0.5);
difficultyTitle.x = 1024;
difficultyTitle.y = 800;
var easyBtn = new Text2('EASY', {
size: 80,
fill: 0x00FF00
});
easyBtn.anchor.set(0.5, 0.5);
easyBtn.x = 1024;
easyBtn.y = 1100;
var mediumBtn = new Text2('MEDIUM', {
size: 80,
fill: 0xFFFF00
});
mediumBtn.anchor.set(0.5, 0.5);
mediumBtn.x = 1024;
mediumBtn.y = 1300;
var hardBtn = new Text2('HARD', {
size: 80,
fill: 0xFF0000
});
hardBtn.anchor.set(0.5, 0.5);
hardBtn.x = 1024;
hardBtn.y = 1500;
// Add difficulty buttons to game if no difficulty selected
if (!difficulty) {
game.addChild(difficultyTitle);
game.addChild(easyBtn);
game.addChild(mediumBtn);
game.addChild(hardBtn);
} else {
gameStarted = true;
}
function startGame(selectedDifficulty) {
difficulty = selectedDifficulty;
storage.difficulty = difficulty;
gameStarted = true;
// Remove difficulty UI
if (difficultyTitle.parent) difficultyTitle.destroy();
if (easyBtn.parent) easyBtn.destroy();
if (mediumBtn.parent) mediumBtn.destroy();
if (hardBtn.parent) hardBtn.destroy();
// Set difficulty parameters
if (difficulty === 'easy') {
enemySpawnRate = 150;
} else if (difficulty === 'medium') {
enemySpawnRate = 100;
} else if (difficulty === 'hard') {
enemySpawnRate = 60;
}
}
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('High: ' + highScore, {
size: 80,
fill: 0xFFFF00
});
highScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -20;
highScoreTxt.y = 50;
var bulletCountTxt = new Text2('Bullets: ' + maxBullets, {
size: 60,
fill: 0x00FFFF
});
bulletCountTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(bulletCountTxt);
bulletCountTxt.x = 120;
bulletCountTxt.y = 50;
var reloadTxt = new Text2('', {
size: 50,
fill: 0xFF0000
});
reloadTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(reloadTxt);
reloadTxt.x = 120;
reloadTxt.y = 120;
function handleMove(x, y, obj) {
if (dragNode) {
// Allow free movement within screen bounds
var targetX = x;
var targetY = y;
if (targetX < 60) targetX = 60;
if (targetX > 1988) targetX = 1988;
if (targetY < 100) targetY = 100;
if (targetY > 2600) targetY = 2600;
// Direct movement without tweening for immediate response
dragNode.x = targetX;
dragNode.y = targetY;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameStarted) {
// Check difficulty button clicks using direct x,y coordinates
if (x > 824 && x < 1224) {
if (y > 1050 && y < 1150) {
startGame('easy');
return;
} else if (y > 1250 && y < 1350) {
startGame('medium');
return;
} else if (y > 1450 && y < 1550) {
startGame('hard');
return;
}
}
} else {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
bulletTimer++;
enemySpawnTimer++;
powerUpTimer++;
// Handle reloading
if (isReloading) {
reloadTimer++;
var remainingTime = Math.ceil((reloadTime - reloadTimer) / 60);
reloadTxt.setText('Reloading... ' + remainingTime + 's');
if (reloadTimer >= reloadTime) {
isReloading = false;
reloadTimer = 0;
currentBulletCount = 0;
reloadTxt.setText('');
bulletCountTxt.setText('Bullets: ' + maxBullets);
bulletCountTxt.tint = 0x00FFFF;
}
}
// Spawn player bullets with upgrade-based fire rate (only if game started)
if (gameStarted && !isReloading) {
var fireRate = Math.max(8, 15 - upgradeLevel * 2);
if (bulletTimer >= fireRate) {
var bulletsToSpawn = playerFireMode;
// Check if we have enough bullets remaining
if (currentBulletCount + bulletsToSpawn <= maxBullets) {
if (playerFireMode === 1) {
// Single bullet
var newBullet = new PlayerBullet();
newBullet.x = player.x;
newBullet.y = player.y - 40;
newBullet.lastY = newBullet.y;
playerBullets.push(newBullet);
game.addChild(newBullet);
currentBulletCount++;
} else if (playerFireMode === 2) {
// Double bullets
for (var bi = 0; bi < 2; bi++) {
var newBullet = new PlayerBullet();
newBullet.x = player.x + (bi === 0 ? -30 : 30);
newBullet.y = player.y - 40;
newBullet.lastY = newBullet.y;
playerBullets.push(newBullet);
game.addChild(newBullet);
currentBulletCount++;
}
} else if (playerFireMode === 3) {
// Triple bullets
for (var bi = 0; bi < 3; bi++) {
var newBullet = new PlayerBullet();
newBullet.x = player.x + (bi === 0 ? -40 : bi === 1 ? 0 : 40);
newBullet.y = player.y - 40;
newBullet.lastY = newBullet.y;
playerBullets.push(newBullet);
game.addChild(newBullet);
currentBulletCount++;
}
}
// Update bullet count display
var remainingBullets = maxBullets - currentBulletCount;
bulletCountTxt.setText('Bullets: ' + remainingBullets);
// Change color based on remaining bullets
if (remainingBullets <= 2) {
bulletCountTxt.tint = 0xFF0000; // Red when low
} else if (remainingBullets <= 5) {
bulletCountTxt.tint = 0xFFFF00; // Yellow when medium
}
LK.getSound('shoot').play();
bulletTimer = 0;
// Start reloading if no bullets left
if (currentBulletCount >= maxBullets) {
isReloading = true;
reloadTimer = 0;
}
}
}
}
// Spawn power-ups occasionally
if (powerUpTimer >= 600) {
var newPowerUp = new PowerUp();
newPowerUp.x = Math.random() * 1800 + 124;
newPowerUp.y = -30;
newPowerUp.lastY = newPowerUp.y;
var powerUpTypes = ['speed', 'fireRate', 'coins'];
newPowerUp.type = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
if (newPowerUp.type === 'coins') {
tween(newPowerUp, {
tint: 0xffd700
}, {
duration: 0
});
} else if (newPowerUp.type === 'fireRate') {
tween(newPowerUp, {
tint: 0xff6600
}, {
duration: 0
});
}
powerUps.push(newPowerUp);
game.addChild(newPowerUp);
powerUpTimer = 0;
}
// Spawn enemies (only if game started)
if (gameStarted && enemySpawnTimer >= enemySpawnRate) {
var newEnemy = new EnemyShip();
newEnemy.x = Math.random() * 1800 + 124;
newEnemy.y = -30;
newEnemy.lastY = newEnemy.y;
newEnemy.lastIntersectingPlayer = false;
newEnemy.scaleX = 0.5;
newEnemy.scaleY = 0.5;
newEnemy.alpha = 0.7;
// Set enemy health and speed based on difficulty
if (difficulty === 'easy') {
newEnemy.health = 1;
newEnemy.speed = 2;
} else if (difficulty === 'medium') {
newEnemy.health = 2;
newEnemy.speed = 3;
} else if (difficulty === 'hard') {
newEnemy.health = 3;
newEnemy.speed = 4;
newEnemy.canShoot = true;
newEnemy.shootTimer = Math.random() * 60;
}
enemyHealth[newEnemy.id || enemies.length] = newEnemy.health;
newEnemy.enemyId = newEnemy.id || enemies.length;
tween(newEnemy, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
enemies.push(newEnemy);
game.addChild(newEnemy);
enemySpawnTimer = 0;
if (enemySpawnRate > 30) {
enemySpawnRate -= 1;
}
}
// Update and check power-ups
for (var p = powerUps.length - 1; p >= 0; p--) {
var powerUp = powerUps[p];
if (powerUp.lastY === undefined) powerUp.lastY = powerUp.y;
// Remove power-ups that go off screen
if (powerUp.lastY <= 2800 && powerUp.y > 2800) {
powerUp.destroy();
powerUps.splice(p, 1);
continue;
}
// Check power-up collection
if (powerUp.intersects(player)) {
LK.getSound('powerup').play();
if (powerUp.type === 'coins') {
coins += 5;
storage.coins = coins;
} else if (powerUp.type === 'fireRate' && upgradeLevel < 5) {
upgradeLevel++;
storage.upgradeLevel = upgradeLevel;
} else if (powerUp.type === 'speed') {
// Green circle - upgrade fire mode
if (playerFireMode < 3) {
playerFireMode++;
}
tween(player, {
tint: 0x00ff00
}, {
duration: 200,
onFinish: function onFinish() {
tween(player, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
tween(powerUp, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
powerUp.destroy();
}
});
powerUps.splice(p, 1);
continue;
}
powerUp.lastY = powerUp.y;
}
// Update and check player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that go off screen
if (bullet.lastY >= -10 && bullet.y < -10) {
bullet.destroy();
playerBullets.splice(i, 1);
if (!isReloading) {
currentBulletCount = Math.max(0, currentBulletCount - 1);
var remainingBullets = maxBullets - currentBulletCount;
bulletCountTxt.setText('Bullets: ' + remainingBullets);
if (remainingBullets > 5) {
bulletCountTxt.tint = 0x00FFFF;
}
}
continue;
}
// Check bullet-enemy collisions
var hitEnemy = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
var enemyId = enemy.enemyId;
if (enemyHealth[enemyId] === undefined) {
enemyHealth[enemyId] = enemy.health || 1;
}
// Reduce enemy health
enemyHealth[enemyId]--;
// Flash enemy when hit
LK.effects.flashObject(enemy, 0xff0000, 100);
if (enemyHealth[enemyId] <= 0) {
// Enemy destroyed
var points = 10 + upgradeLevel * 5;
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore());
// Update high score
if (LK.getScore() > highScore) {
highScore = LK.getScore();
storage.highScore = highScore;
highScoreTxt.setText('High: ' + highScore);
tween(highScoreTxt, {
tint: 0x00ff00
}, {
duration: 300,
onFinish: function onFinish() {
tween(highScoreTxt, {
tint: 0xffff00
}, {
duration: 300
});
}
});
}
LK.getSound('explosion').play();
tween(enemy, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
enemy.destroy();
}
});
enemies.splice(j, 1);
delete enemyHealth[enemyId];
}
bullet.destroy();
playerBullets.splice(i, 1);
if (!isReloading) {
currentBulletCount = Math.max(0, currentBulletCount - 1);
var remainingBullets = maxBullets - currentBulletCount;
bulletCountTxt.setText('Bullets: ' + remainingBullets);
if (remainingBullets > 5) {
bulletCountTxt.tint = 0x00FFFF;
}
}
hitEnemy = true;
break;
}
}
if (hitEnemy) continue;
bullet.lastY = bullet.y;
}
// Update and check enemies
for (var k = enemies.length - 1; k >= 0; k--) {
var enemy = enemies[k];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
if (enemy.lastIntersectingPlayer === undefined) enemy.lastIntersectingPlayer = false;
// Remove enemies that go off screen
if (enemy.lastY <= 2800 && enemy.y > 2800) {
enemy.destroy();
enemies.splice(k, 1);
continue;
}
// Check enemy-player collision
var currentIntersecting = enemy.intersects(player);
if (!enemy.lastIntersectingPlayer && currentIntersecting) {
LK.effects.flashScreen(0xff0000, 1000);
// Clear difficulty selection to force player to choose again
storage.difficulty = null;
difficulty = null;
gameStarted = false;
LK.showGameOver();
return;
}
enemy.lastY = enemy.y;
enemy.lastIntersectingPlayer = currentIntersecting;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -96,8 +96,13 @@
var difficulty = storage.difficulty || null;
var gameStarted = false;
var playerFireMode = 1; // 1 = single, 2 = double, 3 = triple
var enemyHealth = {}; // Track enemy health by difficulty
+var maxBullets = 10; // Maximum bullets on screen
+var currentBulletCount = 0; // Current bullet count
+var isReloading = false; // Reload state
+var reloadTimer = 0; // Reload timer
+var reloadTime = 120; // 2 seconds at 60fps
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
@@ -168,8 +173,24 @@
highScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -20;
highScoreTxt.y = 50;
+var bulletCountTxt = new Text2('Bullets: ' + maxBullets, {
+ size: 60,
+ fill: 0x00FFFF
+});
+bulletCountTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(bulletCountTxt);
+bulletCountTxt.x = 120;
+bulletCountTxt.y = 50;
+var reloadTxt = new Text2('', {
+ size: 50,
+ fill: 0xFF0000
+});
+reloadTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(reloadTxt);
+reloadTxt.x = 120;
+reloadTxt.y = 120;
function handleMove(x, y, obj) {
if (dragNode) {
// Allow free movement within screen bounds
var targetX = x;
@@ -210,43 +231,78 @@
game.update = function () {
bulletTimer++;
enemySpawnTimer++;
powerUpTimer++;
+ // Handle reloading
+ if (isReloading) {
+ reloadTimer++;
+ var remainingTime = Math.ceil((reloadTime - reloadTimer) / 60);
+ reloadTxt.setText('Reloading... ' + remainingTime + 's');
+ if (reloadTimer >= reloadTime) {
+ isReloading = false;
+ reloadTimer = 0;
+ currentBulletCount = 0;
+ reloadTxt.setText('');
+ bulletCountTxt.setText('Bullets: ' + maxBullets);
+ bulletCountTxt.tint = 0x00FFFF;
+ }
+ }
// Spawn player bullets with upgrade-based fire rate (only if game started)
- if (gameStarted) {
+ if (gameStarted && !isReloading) {
var fireRate = Math.max(8, 15 - upgradeLevel * 2);
if (bulletTimer >= fireRate) {
- if (playerFireMode === 1) {
- // Single bullet
- var newBullet = new PlayerBullet();
- newBullet.x = player.x;
- newBullet.y = player.y - 40;
- newBullet.lastY = newBullet.y;
- playerBullets.push(newBullet);
- game.addChild(newBullet);
- } else if (playerFireMode === 2) {
- // Double bullets
- for (var bi = 0; bi < 2; bi++) {
+ var bulletsToSpawn = playerFireMode;
+ // Check if we have enough bullets remaining
+ if (currentBulletCount + bulletsToSpawn <= maxBullets) {
+ if (playerFireMode === 1) {
+ // Single bullet
var newBullet = new PlayerBullet();
- newBullet.x = player.x + (bi === 0 ? -30 : 30);
+ newBullet.x = player.x;
newBullet.y = player.y - 40;
newBullet.lastY = newBullet.y;
playerBullets.push(newBullet);
game.addChild(newBullet);
+ currentBulletCount++;
+ } else if (playerFireMode === 2) {
+ // Double bullets
+ for (var bi = 0; bi < 2; bi++) {
+ var newBullet = new PlayerBullet();
+ newBullet.x = player.x + (bi === 0 ? -30 : 30);
+ newBullet.y = player.y - 40;
+ newBullet.lastY = newBullet.y;
+ playerBullets.push(newBullet);
+ game.addChild(newBullet);
+ currentBulletCount++;
+ }
+ } else if (playerFireMode === 3) {
+ // Triple bullets
+ for (var bi = 0; bi < 3; bi++) {
+ var newBullet = new PlayerBullet();
+ newBullet.x = player.x + (bi === 0 ? -40 : bi === 1 ? 0 : 40);
+ newBullet.y = player.y - 40;
+ newBullet.lastY = newBullet.y;
+ playerBullets.push(newBullet);
+ game.addChild(newBullet);
+ currentBulletCount++;
+ }
}
- } else if (playerFireMode === 3) {
- // Triple bullets
- for (var bi = 0; bi < 3; bi++) {
- var newBullet = new PlayerBullet();
- newBullet.x = player.x + (bi === 0 ? -40 : bi === 1 ? 0 : 40);
- newBullet.y = player.y - 40;
- newBullet.lastY = newBullet.y;
- playerBullets.push(newBullet);
- game.addChild(newBullet);
+ // Update bullet count display
+ var remainingBullets = maxBullets - currentBulletCount;
+ bulletCountTxt.setText('Bullets: ' + remainingBullets);
+ // Change color based on remaining bullets
+ if (remainingBullets <= 2) {
+ bulletCountTxt.tint = 0xFF0000; // Red when low
+ } else if (remainingBullets <= 5) {
+ bulletCountTxt.tint = 0xFFFF00; // Yellow when medium
}
+ LK.getSound('shoot').play();
+ bulletTimer = 0;
+ // Start reloading if no bullets left
+ if (currentBulletCount >= maxBullets) {
+ isReloading = true;
+ reloadTimer = 0;
+ }
}
- LK.getSound('shoot').play();
- bulletTimer = 0;
}
}
// Spawn power-ups occasionally
if (powerUpTimer >= 600) {
@@ -373,8 +429,16 @@
// Remove bullets that go off screen
if (bullet.lastY >= -10 && bullet.y < -10) {
bullet.destroy();
playerBullets.splice(i, 1);
+ if (!isReloading) {
+ currentBulletCount = Math.max(0, currentBulletCount - 1);
+ var remainingBullets = maxBullets - currentBulletCount;
+ bulletCountTxt.setText('Bullets: ' + remainingBullets);
+ if (remainingBullets > 5) {
+ bulletCountTxt.tint = 0x00FFFF;
+ }
+ }
continue;
}
// Check bullet-enemy collisions
var hitEnemy = false;
@@ -428,8 +492,16 @@
delete enemyHealth[enemyId];
}
bullet.destroy();
playerBullets.splice(i, 1);
+ if (!isReloading) {
+ currentBulletCount = Math.max(0, currentBulletCount - 1);
+ var remainingBullets = maxBullets - currentBulletCount;
+ bulletCountTxt.setText('Bullets: ' + remainingBullets);
+ if (remainingBullets > 5) {
+ bulletCountTxt.tint = 0x00FFFF;
+ }
+ }
hitEnemy = true;
break;
}
}
Modern App Store icon, high definition, square with rounded corners, for a game titled "Galaxy Defender: Space Shooter" and with the description "Classic space shooter where you defend against enemy waves by moving your ship and firing bullets upward.". No text on icon!
Uzay gemisi. In-Game asset. 2d. High contrast. No shadows
Daha gerçekçi bir güç olsun. In-Game asset. 2d. High contrast. No shadows