User prompt
Character moving by holding and obstacles are smaller
User prompt
Add a lot of obstacle
User prompt
Add more coins and do them collectiable
User prompt
Add coins somewheres in the game
Code edit (1 edits merged)
Please save this source code
User prompt
Third Person Adventure Runner
User prompt
Make the game third person camera
Initial prompt
Make me GTA 7
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
// Character properties
self.baseY = 2400; // Ground level
self.targetX = 1024; // Center of screen
self.moveSpeed = 8;
self.update = function () {
// Smooth movement toward target X position
var deltaX = self.targetX - self.x;
if (Math.abs(deltaX) > 2) {
self.x += deltaX * 0.15;
}
// Keep character within screen bounds
self.x = Math.max(200, Math.min(1848, self.x));
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Scale coin to simulate 3D perspective
self.baseScale = 0.4;
self.scale.set(self.baseScale);
// Add floating animation
self.floatOffset = Math.random() * Math.PI * 2;
self.baseY = 0;
self.update = function () {
// Move toward camera
self.y += gameSpeed;
// Simulate 3D perspective
var distanceFromCamera = (2732 - self.y) / 2732;
var perspectiveScale = self.baseScale + (1 - self.baseScale) * (1 - distanceFromCamera);
self.scale.set(perspectiveScale);
// Floating animation
self.y = self.baseY + Math.sin(LK.ticks * 0.1 + self.floatOffset) * 10;
// Coin spinning animation for classic coin effect
coinGraphics.rotation += 0.08;
// Scale pulsing to make coin more noticeable
var pulseScale = 1 + Math.sin(LK.ticks * 0.15) * 0.1;
coinGraphics.scaleX = pulseScale;
// Adjust hit area
self.hitWidth = 80 * perspectiveScale;
self.hitHeight = 80 * perspectiveScale;
};
return self;
});
var MovingObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1.0
});
// Scale obstacle to simulate 3D perspective
self.baseScale = 0.3;
self.scale.set(self.baseScale);
self.moveDirection = Math.random() < 0.5 ? -1 : 1; // Random direction
self.moveSpeed = 1 + Math.random() * 2; // Random speed
self.update = function () {
// Move toward camera (increase Y and scale)
self.y += gameSpeed;
// Side-to-side movement
self.x += self.moveDirection * self.moveSpeed;
// Bounce off screen edges
if (self.x < 200 || self.x > 1848) {
self.moveDirection *= -1;
}
// Simulate 3D perspective by scaling based on distance
var distanceFromCamera = (2732 - self.y) / 2732;
var perspectiveScale = self.baseScale + (1 - self.baseScale) * (1 - distanceFromCamera);
self.scale.set(perspectiveScale);
// Adjust apparent width based on perspective
self.hitWidth = 150 * perspectiveScale;
self.hitHeight = 200 * perspectiveScale;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1.0
});
// Scale obstacle to simulate 3D perspective
self.baseScale = 0.3;
self.scale.set(self.baseScale);
self.update = function () {
// Move toward camera (increase Y and scale)
self.y += gameSpeed;
// Simulate 3D perspective by scaling based on distance
var distanceFromCamera = (2732 - self.y) / 2732;
var perspectiveScale = self.baseScale + (1 - self.baseScale) * (1 - distanceFromCamera);
self.scale.set(perspectiveScale);
// Adjust apparent width based on perspective
self.hitWidth = 150 * perspectiveScale;
self.hitHeight = 200 * perspectiveScale;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var character;
var obstacles = [];
var coins = [];
var gameSpeed = 6;
var spawnTimer = 0;
var coinTimer = 0;
var movingObstacleTimer = 0;
var cameraY = 0;
var gameRunning = true;
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var speedTxt = new Text2('Speed: 1.0x', {
size: 60,
fill: 0xFFFFFF
});
speedTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(speedTxt);
// Create ground strips for perspective effect
var groundStrips = [];
for (var i = 0; i < 8; i++) {
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 0.5
}));
ground.x = 1024;
ground.y = 2400 + i * 300;
ground.baseY = ground.y;
ground.alpha = 0.3;
groundStrips.push(ground);
}
// Create character
character = game.addChild(new Character());
character.x = 1024;
character.y = character.baseY;
// Touch controls
game.down = function (x, y, obj) {
if (!gameRunning) return;
if (x < 1024) {
// Left side - move left
character.targetX = Math.max(200, character.targetX - 300);
} else {
// Right side - move right
character.targetX = Math.min(1848, character.targetX + 300);
}
};
// Spawn obstacles
function spawnObstacle() {
var obstacle = new Obstacle();
// Better X distribution to avoid clustering
var lanes = [300, 600, 900, 1200, 1500, 1800]; // Defined lanes
var laneIndex = Math.floor(Math.random() * lanes.length);
obstacle.x = lanes[laneIndex] + (Math.random() - 0.5) * 100; // Add slight variation
obstacle.y = -200 - Math.random() * 300; // Vary spawn depth for natural spacing
obstacle.baseY = obstacle.y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn moving obstacles
function spawnMovingObstacle() {
var obstacle = new MovingObstacle();
var lanes = [300, 600, 900, 1200, 1500, 1800];
var laneIndex = Math.floor(Math.random() * lanes.length);
obstacle.x = lanes[laneIndex];
obstacle.y = -200 - Math.random() * 400;
obstacle.baseY = obstacle.y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn coins
function spawnCoin() {
var coin = new Coin();
// Better distribution across the screen with some spacing from edges
coin.x = 250 + Math.random() * 1548; // Wider spread
coin.y = -100 - Math.random() * 200; // Vary spawn depth for natural spacing
coin.baseY = coin.y;
coins.push(coin);
game.addChild(coin);
}
// Collision detection function
function checkCollision(obj1, obj2) {
var dx = obj1.x - obj2.x;
var dy = obj1.y - obj2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = (obj1.hitWidth || 120) / 2 + (obj2.hitWidth || 150) / 2;
return distance < minDistance;
}
// Game update loop
game.update = function () {
if (!gameRunning) return;
// Increase speed over time
gameSpeed += 0.002;
speedTxt.setText('Speed: ' + (gameSpeed / 6).toFixed(1) + 'x');
// Update ground for scrolling effect
for (var i = 0; i < groundStrips.length; i++) {
var ground = groundStrips[i];
ground.y += gameSpeed;
if (ground.y > 2932) {
ground.y = -200;
}
// Perspective scaling for ground
var distanceFromCamera = (2732 - ground.y) / 2732;
var perspectiveScale = 0.5 + 0.5 * (1 - distanceFromCamera);
ground.scaleY = perspectiveScale;
}
// Spawn obstacles
spawnTimer++;
if (spawnTimer > 30 - gameSpeed * 3) {
// Spawn multiple obstacles per wave
var obstaclesToSpawn = 1 + Math.floor(Math.random() * 3); // 1-3 obstacles per wave
for (var o = 0; o < obstaclesToSpawn; o++) {
spawnObstacle();
}
spawnTimer = 0;
}
// Spawn moving obstacles
movingObstacleTimer++;
if (movingObstacleTimer > 80 - gameSpeed * 2) {
if (Math.random() < 0.4) {
// 40% chance to spawn moving obstacle
spawnMovingObstacle();
}
movingObstacleTimer = 0;
}
// Spawn coins
coinTimer++;
var coinSpawnRate = 45 - Math.floor(LK.getScore() / 50); // Spawn faster as score increases
coinSpawnRate = Math.max(20, coinSpawnRate); // Minimum spawn rate
if (coinTimer > coinSpawnRate) {
// Spawn multiple coins in a wave
var coinsToSpawn = 2 + Math.floor(Math.random() * 3); // 2-4 coins per wave
// Bonus coins for high scores
if (LK.getScore() > 200 && Math.random() < 0.3) {
coinsToSpawn += 2; // Extra coins for high scores
}
for (var k = 0; k < coinsToSpawn; k++) {
spawnCoin();
}
coinTimer = 0;
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Remove obstacles that are off screen
if (obstacle.y > 2832) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with character
if (obstacle.y > 2000 && obstacle.y < 2600) {
if (checkCollision(character, obstacle)) {
// Game over
gameRunning = false;
LK.getSound('hit').play();
LK.effects.flashScreen(0xFF0000, 500);
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
break;
}
}
}
// Update and check coins
for (var j = coins.length - 1; j >= 0; j--) {
var coin = coins[j];
// Remove coins that are off screen
if (coin.y > 2832) {
coin.destroy();
coins.splice(j, 1);
continue;
}
// Check coin collection
if (coin.y > 2000 && coin.y < 2600) {
if (checkCollision(character, coin)) {
// Coin collected
LK.setScore(LK.getScore() + 10);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('collect').play();
// Coin collection visual effect
tween(coin, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 200,
onFinish: function onFinish() {
coin.destroy();
}
});
coins.splice(j, 1);
}
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -58,8 +58,38 @@
self.hitHeight = 80 * perspectiveScale;
};
return self;
});
+var MovingObstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var obstacleGraphics = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ // Scale obstacle to simulate 3D perspective
+ self.baseScale = 0.3;
+ self.scale.set(self.baseScale);
+ self.moveDirection = Math.random() < 0.5 ? -1 : 1; // Random direction
+ self.moveSpeed = 1 + Math.random() * 2; // Random speed
+ self.update = function () {
+ // Move toward camera (increase Y and scale)
+ self.y += gameSpeed;
+ // Side-to-side movement
+ self.x += self.moveDirection * self.moveSpeed;
+ // Bounce off screen edges
+ if (self.x < 200 || self.x > 1848) {
+ self.moveDirection *= -1;
+ }
+ // Simulate 3D perspective by scaling based on distance
+ var distanceFromCamera = (2732 - self.y) / 2732;
+ var perspectiveScale = self.baseScale + (1 - self.baseScale) * (1 - distanceFromCamera);
+ self.scale.set(perspectiveScale);
+ // Adjust apparent width based on perspective
+ self.hitWidth = 150 * perspectiveScale;
+ self.hitHeight = 200 * perspectiveScale;
+ };
+ return self;
+});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
@@ -98,8 +128,9 @@
var coins = [];
var gameSpeed = 6;
var spawnTimer = 0;
var coinTimer = 0;
+var movingObstacleTimer = 0;
var cameraY = 0;
var gameRunning = true;
// UI elements
var scoreTxt = new Text2('Score: 0', {
@@ -144,14 +175,28 @@
};
// Spawn obstacles
function spawnObstacle() {
var obstacle = new Obstacle();
- obstacle.x = 200 + Math.random() * 1648; // Random X position
- obstacle.y = -200; // Start above screen
+ // Better X distribution to avoid clustering
+ var lanes = [300, 600, 900, 1200, 1500, 1800]; // Defined lanes
+ var laneIndex = Math.floor(Math.random() * lanes.length);
+ obstacle.x = lanes[laneIndex] + (Math.random() - 0.5) * 100; // Add slight variation
+ obstacle.y = -200 - Math.random() * 300; // Vary spawn depth for natural spacing
obstacle.baseY = obstacle.y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
+// Spawn moving obstacles
+function spawnMovingObstacle() {
+ var obstacle = new MovingObstacle();
+ var lanes = [300, 600, 900, 1200, 1500, 1800];
+ var laneIndex = Math.floor(Math.random() * lanes.length);
+ obstacle.x = lanes[laneIndex];
+ obstacle.y = -200 - Math.random() * 400;
+ obstacle.baseY = obstacle.y;
+ obstacles.push(obstacle);
+ game.addChild(obstacle);
+}
// Spawn coins
function spawnCoin() {
var coin = new Coin();
// Better distribution across the screen with some spacing from edges
@@ -188,12 +233,25 @@
ground.scaleY = perspectiveScale;
}
// Spawn obstacles
spawnTimer++;
- if (spawnTimer > 60 - gameSpeed * 2) {
- spawnObstacle();
+ if (spawnTimer > 30 - gameSpeed * 3) {
+ // Spawn multiple obstacles per wave
+ var obstaclesToSpawn = 1 + Math.floor(Math.random() * 3); // 1-3 obstacles per wave
+ for (var o = 0; o < obstaclesToSpawn; o++) {
+ spawnObstacle();
+ }
spawnTimer = 0;
}
+ // Spawn moving obstacles
+ movingObstacleTimer++;
+ if (movingObstacleTimer > 80 - gameSpeed * 2) {
+ if (Math.random() < 0.4) {
+ // 40% chance to spawn moving obstacle
+ spawnMovingObstacle();
+ }
+ movingObstacleTimer = 0;
+ }
// Spawn coins
coinTimer++;
var coinSpawnRate = 45 - Math.floor(LK.getScore() / 50); // Spawn faster as score increases
coinSpawnRate = Math.max(20, coinSpawnRate); // Minimum spawn rate