User prompt
The player's arrow should draw a trail behind itself which remains permanently.
Code edit (1 edits merged)
Please save this source code
User prompt
Stonks Go Up
Initial prompt
This game is called "Stonks Go Up" and it's based on the stonks meme where anything good that happens is called "stonks" and anything bad that happens is called "not stonks". The player controls an arrow going in the direction it's facing. The arrow should face northeast (towards the upper-right corner of the screen when) when the player is not holding on the screen, and the arrow should face southeast (towards the lower-left corner of the screen) when the player is holding on the screen. The further up the player goes, the more points they score. The score is called the "stonk market cap". As the game progresses, more and more obstacles and bonuses will fly in from the right side of the screen towards the left. If the player collides with a bonus, the game will show a "stonks" score bubble graphic and increase the score further. If the player collides with an obstacle, the game will show a "not stonks" score bubble graphic and the game will end. When the game ends, the game will zoom out and display the entire history of that play session drawn out by the player's arrow and offer the player a button to play again or to share their score online.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Arrow = Container.expand(function () {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = "northeast"; // Starting direction
self.speed = 8; // Movement speed
self.path = []; // Track arrow's path
self.update = function () {
// Move based on current direction
if (self.direction === "northeast") {
self.x += self.speed;
self.y -= self.speed;
arrowGraphics.rotation = -Math.PI / 4; // 45 degrees up
} else {
self.x += self.speed;
self.y += self.speed;
arrowGraphics.rotation = Math.PI / 4; // 45 degrees down
}
// Create trail point every few frames
if (game.ticks % 5 === 0) {
var trailPoint = new TrailPoint();
trailPoint.x = self.x;
trailPoint.y = self.y;
trailPoint.rotation = arrowGraphics.rotation;
game.addChild(trailPoint);
// Add trail point behind the arrow and other game elements
game.swapChildren(trailPoint, self);
}
// Keep in bounds
if (self.y < 100) {
self.y = 100;
self.direction = "southeast";
arrowGraphics.rotation = Math.PI / 4;
}
if (self.y > 2732 - 100) {
self.y = 2732 - 100;
self.direction = "northeast";
arrowGraphics.rotation = -Math.PI / 4;
}
// Record path for replay at game end
if (game.ticks % 5 === 0) {
self.path.push({
x: self.x,
y: self.y
});
}
};
self.changeDirection = function () {
if (self.direction === "northeast") {
self.direction = "southeast";
arrowGraphics.rotation = Math.PI / 4;
} else {
self.direction = "northeast";
arrowGraphics.rotation = -Math.PI / 4;
}
};
return self;
});
var Bonus = Container.expand(function () {
var self = Container.call(this);
var bonusGraphics = self.attachAsset('bonus', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.collected = false;
self.update = function () {
self.x += self.speed;
// Make bonus rotate
bonusGraphics.rotation += 0.05;
};
self.collect = function () {
self.collected = true;
tween(bonusGraphics, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut
});
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -10;
self.update = function () {
self.x += self.speed;
};
return self;
});
var StonksText = Container.expand(function (message, color) {
var self = Container.call(this);
var text = new Text2(message || "STONKS!", {
size: 100,
fill: color || "#00FF00"
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
self.animate = function () {
self.alpha = 1;
tween(self, {
alpha: 0,
y: self.y - 200
}, {
duration: 1500,
easing: tween.easeOut
});
tween(self.scale, {
x: 2,
y: 2
}, {
duration: 1500,
easing: tween.easeOut
});
};
return self;
});
var TrailPoint = Container.expand(function () {
var self = Container.call(this);
var trailGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var arrow;
var obstacles = [];
var bonuses = [];
var stonksTexts = [];
var trailPoints = [];
var lastObstacleTime = 0;
var lastBonusTime = 0;
var marketCap = 0;
var distance = 0;
var gameActive = true;
// Create background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Create GUI elements
var marketCapText = new Text2("Market Cap: 0", {
size: 60,
fill: 0xFFFFFF
});
marketCapText.anchor.set(0.5, 0);
LK.gui.top.addChild(marketCapText);
var distanceText = new Text2("Distance: 0", {
size: 60,
fill: 0xFFFFFF
});
distanceText.anchor.set(0.5, 0);
distanceText.y = 80;
LK.gui.top.addChild(distanceText);
// Create arrow
arrow = new Arrow();
arrow.x = 300;
arrow.y = 2732 / 2;
game.addChild(arrow);
// Play background music
LK.playMusic('bgMusic');
// Handle taps
game.down = function (x, y, obj) {
if (gameActive) {
arrow.changeDirection();
}
};
// Generate obstacles
function createObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2148; // Just off screen to the right
obstacle.y = 200 + Math.random() * (2732 - 400);
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Generate bonuses
function createBonus() {
var bonus = new Bonus();
bonus.x = 2148; // Just off screen to the right
bonus.y = 200 + Math.random() * (2732 - 400);
bonuses.push(bonus);
game.addChild(bonus);
}
// Create stonks text popup
function createStonksText(isPositive, x, y) {
var message = isPositive ? "STONKS!" : "NOT STONKS!";
var color = isPositive ? "#00FF00" : "#FF0000";
var stonksText = new StonksText(message, color);
stonksText.x = x;
stonksText.y = y;
stonksText.animate();
stonksTexts.push(stonksText);
game.addChild(stonksText);
}
// Game update loop
game.update = function () {
if (!gameActive) {
return;
}
// Create obstacles at regular intervals
if (game.ticks - lastObstacleTime > 60) {
createObstacle();
lastObstacleTime = game.ticks;
}
// Create bonuses less frequently
if (game.ticks - lastBonusTime > 180) {
createBonus();
lastBonusTime = game.ticks;
}
// Update marketCap and distance
marketCap += 1;
distance += 1;
marketCapText.setText("Market Cap: " + marketCap);
distanceText.setText("Distance: " + distance);
// Check for obstacles that are off-screen
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].x < -150) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Check for bonuses that are off-screen
for (var i = bonuses.length - 1; i >= 0; i--) {
if (bonuses[i].x < -150 || bonuses[i].collected) {
bonuses[i].destroy();
bonuses.splice(i, 1);
}
}
// Remove faded stonks texts
for (var i = stonksTexts.length - 1; i >= 0; i--) {
if (stonksTexts[i].alpha <= 0) {
stonksTexts[i].destroy();
stonksTexts.splice(i, 1);
}
}
// Check for collisions with obstacles
for (var i = 0; i < obstacles.length; i++) {
if (arrow.intersects(obstacles[i])) {
// Game over
gameActive = false;
createStonksText(false, arrow.x, arrow.y);
LK.getSound('crash').play();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 1000);
// Show game over
LK.setTimeout(function () {
LK.setScore(marketCap);
LK.showGameOver();
}, 1500);
break;
}
}
// Check for collisions with bonuses
for (var i = bonuses.length - 1; i >= 0; i--) {
if (!bonuses[i].collected && arrow.intersects(bonuses[i])) {
// Collect bonus
bonuses[i].collect();
LK.getSound('collect').play();
// Add bonus score
var bonusValue = Math.floor(Math.random() * 500) + 500;
marketCap += bonusValue;
// Show stonks text
createStonksText(true, arrow.x, arrow.y);
// Flash screen green
LK.effects.flashScreen(0x00FF00, 300);
}
}
// Increase difficulty over time
if (game.ticks % 600 === 0) {
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed -= 0.5;
}
for (var i = 0; i < bonuses.length; i++) {
bonuses[i].speed -= 0.3;
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -26,8 +26,18 @@
self.x += self.speed;
self.y += self.speed;
arrowGraphics.rotation = Math.PI / 4; // 45 degrees down
}
+ // Create trail point every few frames
+ if (game.ticks % 5 === 0) {
+ var trailPoint = new TrailPoint();
+ trailPoint.x = self.x;
+ trailPoint.y = self.y;
+ trailPoint.rotation = arrowGraphics.rotation;
+ game.addChild(trailPoint);
+ // Add trail point behind the arrow and other game elements
+ game.swapChildren(trailPoint, self);
+ }
// Keep in bounds
if (self.y < 100) {
self.y = 100;
self.direction = "southeast";
@@ -121,8 +131,19 @@
});
};
return self;
});
+var TrailPoint = Container.expand(function () {
+ var self = Container.call(this);
+ var trailGraphics = self.attachAsset('arrow', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.3,
+ scaleY: 0.3,
+ alpha: 0.5
+ });
+ return self;
+});
/****
* Initialize Game
****/
@@ -137,8 +158,9 @@
var arrow;
var obstacles = [];
var bonuses = [];
var stonksTexts = [];
+var trailPoints = [];
var lastObstacleTime = 0;
var lastBonusTime = 0;
var marketCap = 0;
var distance = 0;
arrow pointing to the right like on a stock market ticker. No shadows
cartoonish dollar bill. In-Game asset. 2d. High contrast. No shadows
green stock market chart candle. In-Game asset. 2d. High contrast. No shadows
red stock market chart candle. In-Game asset. 2d. High contrast. No shadows
screen-wrappable repeating blue grid on dark background. In-Game asset. 2d. High contrast. No shadows
white full moon. In-Game asset. 2d. High contrast. No shadows