User prompt
update the advanced terrain cards in the main deck to show a band of colour along the top matching the basic terrain but in purple for now. implement a colour band at the bottom of all the creatures to denote their type and sub-type: basic herbivore is yellow, advanced herbivore is green, basic carnivore is orange and advanced carnivore is red. go!
User prompt
now we need to build the main deck so that we can implement that into the game and begin the game loop, here is the main deck card split: 20x 'Advanced' 'Terrain' cards (2 x 'fresh' 'water' cards both with no climate requirement [can be placed on any climate], 5 x 'sea' 'water' cards, 1 requires 'cold', 1 requires 'hot' and 1 requires 'temperate' climates, the 4th requires either 'temperate' or 'hot' climates and the 5th has no climate requirements. Then there are the 'land' terrain cards: 3 x 'mountain' types 1 has no climate requirements, 1 needs either temperate or cold and the last needs either temperate or hot, 5 x 'hill' type, 1 needs hot, 1 needs cold and 1 needs temperate, 1 needs either temperate or hot and the 5th needs either temperate or cold, finally, there are the 'flat land' cards - 5 of them, 1 each for cold, temperate and hot as the other types, 1 for temperate of hot, and the 5th requires either temperate or cold as before. the rest of the main deck are the creature cards split into 32 x basic herbivore cards, 12 x advanced herbivore cards, 10 x basic carnivore cards and 8 x advanced carnivore cards we will leave the parameters of the creature cards until later but perhaps for now, add some place-holder information for them with basic climate requirements. go!
User prompt
move the 'scry active' text reminder to the right under the 'cards drawn' text and make it read: 'Scry' and have a small highlight
User prompt
shift the climate zone text left a little so its fully visible and shift the cards slightly right
User prompt
good, now make the climate zone text verticle as atm it dissapears behind cards
User prompt
i have realised that during gameplay, the climate parameter for each space needs to stay visible and thus i think rather than display it as a band of colour on each card, lets put it as a background for each row and change the colour bar at the top of the basic terrain cards to white to denote 'basic' status. please implement these changes
User prompt
good, now increase the text size and make it bolder as it is hard to read atm
User prompt
perfect! UI is filled but not too full, however, during game play cards will get placed upon others in a 'stack' system which will increase the y axis of each card stack so therefore, please decrease card scale by 10% and increase the amount of space between the tops and bottoms of any such card row by enough to fit the coloured strip indicators twice
User prompt
i have zoomed my screen which is good, thank you but i also feel an increase in the card size will help since there is so mucu unused space on the UI anyway, please implement card scale increase by 50%
User prompt
yes
User prompt
brilliant! lets do the setup: there is a pool of 23 basic terrain cards split thus: 9 x water-type cards (6 x sea, 3 x fresh) 14 x land-type cards (4 x mountain, 5 x hill and 5 x flat land), they are shuffled and arranged in a planet layout: 2-4-6-4-2 formation (top to bottom). Climate zones are assigned before the shuffle: Cold (rows 1&5), Temperate (rows 2&4), Hot (row 3) Cards gain climate attributes based on their row position as mentioned before. This setup is the 'basic' setup and there will be options to vary this with things like: number of cards in each row, what each rows climate is and so on that can be chosen by the user or randomised in the pre-setup step. after the drawn basic terrains are placed and climates are assigned to them, the main deck is shuffled, the round marker is set to 0 and the 'scry' token is shown in the info panel of the UI ('scry' rule to be discussed later). No cards are in the players hand at this stage. the un-used basic terrain cards are not used during game (except for some events). implement this please
Code edit (1 edits merged)
Please save this source code
User prompt
Evolution Links: Planet Builder
Initial prompt
Game is a single player, turn based card game to be created as an app to play on mobile and desktop devices. The visuals are in simple 2D and the main screen is the 'board' which is a grid of the cards dealt in setup and added to during play. Also in the UI is the player hand and a scoring/info visual helper. The game is played in turns which are split over 5 'rounds'. A round is completed when the 'main deck' runs out and is reshuffled. A turn is split into 'phases' which will be described in detail later but essentially, a turn is: draw 3 cards from the main deck, play 1 card onto a card already in play, apply any 'on-play' effect, adjust the 'links' (to be explained later), check states and finish turn. basically the game represents the evolution of a planet and the interactions between carnivores and their herbivore prey (hence the 'links'). There are also 'events' that are added to the deck if a creature dies. There is a setup step before the game begins which lays out a number of cards in position to represent the fresh planet. Perhaps 2 player integration later on in a 'hot seat' kind of way. Is that enough info for a basic reference? We can discuss card types, setup, in depth turn structure etc etc, what shall we discuss or is there info that you feel is necessary now?
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var CreatureCard = Container.expand(function (creatureData) {
var self = Container.call(this);
self.creatureData = creatureData || {
type: 'basic',
dietType: 'herbivore',
name: 'Basic Herbivore',
health: 3,
terrainRequirement: 'land',
climateRequirement: 'any'
};
// Create creature visual
var creatureAsset;
if (self.creatureData.type === 'basic' && self.creatureData.dietType === 'herbivore') {
creatureAsset = self.attachAsset('creatureBasicHerbivore', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.creatureData.type === 'advanced' && self.creatureData.dietType === 'herbivore') {
creatureAsset = self.attachAsset('creatureAdvancedHerbivore', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.creatureData.type === 'basic' && self.creatureData.dietType === 'carnivore') {
creatureAsset = self.attachAsset('creatureBasicCarnivore', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.creatureData.type === 'advanced' && self.creatureData.dietType === 'carnivore') {
creatureAsset = self.attachAsset('creatureAdvancedCarnivore', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Add creature name
self.nameText = new Text2(self.creatureData.name, {
size: 18,
fill: 0xFFFFFF
});
self.nameText.anchor.set(0.5, 0);
self.nameText.x = 0;
self.nameText.y = -100;
self.addChild(self.nameText);
// Add health display
self.healthText = new Text2("HP: " + self.creatureData.health, {
size: 16,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0);
self.healthText.x = 0;
self.healthText.y = 80;
self.addChild(self.healthText);
self.currentHealth = self.creatureData.health;
self.isInPlay = false;
self.takeDamage = function (amount) {
self.currentHealth -= amount;
self.healthText.setText("HP: " + self.currentHealth);
if (self.currentHealth <= 0) {
self.die();
}
};
self.die = function () {
if (self.isInPlay) {
// Add event card to deck
addEventCardToDeck();
// Visual death effect
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
LK.getSound('creatureDie').play();
}
};
self.down = function (x, y, obj) {
if (!self.isInPlay && playerHand.indexOf(self) !== -1) {
selectedCard = self;
draggedCard = self;
originalCardPosition = {
x: self.x,
y: self.y
};
}
};
return self;
});
var PlanetSlot = Container.expand(function (slotX, slotY) {
var self = Container.call(this);
self.slotX = slotX;
self.slotY = slotY;
self.terrainCard = null;
self.isHighlighted = false;
self.highlight = function () {
if (!self.isHighlighted && self.terrainCard) {
self.isHighlighted = true;
self.terrainCard.alpha = 0.8;
}
};
self.unhighlight = function () {
if (self.isHighlighted && self.terrainCard) {
self.isHighlighted = false;
self.terrainCard.alpha = 1.0;
}
};
self.down = function (x, y, obj) {
if (selectedCard && self.terrainCard && canPlaceCreatureOnTerrain(selectedCard, self.terrainCard)) {
placeCreatureOnTerrain(selectedCard, self.terrainCard, self.slotX, self.slotY);
}
};
return self;
});
var TerrainCard = Container.expand(function (terrainData) {
var self = Container.call(this);
self.terrainData = terrainData || {
type: 'basic',
subtype: 'land',
landType: 'flat',
waterType: null,
climate: 'temperate'
};
// Create terrain card visual based on subtype and landType/waterType
var terrainAsset;
if (self.terrainData.subtype === 'land') {
if (self.terrainData.landType === 'flat') {
terrainAsset = self.attachAsset('terrainLandFlat', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.terrainData.landType === 'hills') {
terrainAsset = self.attachAsset('terrainLandHills', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.terrainData.landType === 'mountain') {
terrainAsset = self.attachAsset('terrainLandMountain', {
anchorX: 0.5,
anchorY: 0.5
});
}
} else if (self.terrainData.subtype === 'water') {
if (self.terrainData.waterType === 'sea') {
terrainAsset = self.attachAsset('terrainWaterSea', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.terrainData.waterType === 'fresh') {
terrainAsset = self.attachAsset('terrainWaterFresh', {
anchorX: 0.5,
anchorY: 0.5
});
}
}
// Add white basic terrain indicator strip at top
var basicStrip = self.attachAsset('basicTerrainStrip', {
anchorX: 0.5,
anchorY: 0.5
});
basicStrip.y = -147;
// Add terrain type text
var terrainTypeText = self.terrainData.subtype === 'land' ? self.terrainData.landType : self.terrainData.waterType;
self.typeText = new Text2(terrainTypeText.toUpperCase(), {
size: 24,
fill: 0xFFFFFF,
font: "'Arial Black', 'Impact', 'Tahoma', sans-serif"
});
self.typeText.anchor.set(0.5, 0.5);
self.typeText.x = 0;
self.typeText.y = -84;
self.addChild(self.typeText);
// Climate will be displayed as row background instead of on individual cards
self.gridX = -1;
self.gridY = -1;
self.creatureStack = [];
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a252f
});
/****
* Game Code
****/
// Game state variables
// Terrain card assets - Land types with green strip
// Terrain card assets - Water types with blue/grey strip
// Climate indicator strips
// Creature card assets
// Event card asset
// UI elements
var currentRound = 0;
var maxRounds = 5;
var cardsDrawnThisTurn = 0;
var maxCardsPerTurn = 3;
var planetBoard = [];
var planetSlots = [];
var playerHand = [];
var maxHandSize = 5;
var mainDeck = [];
var basicTerrainPool = [];
var selectedCard = null;
var draggedCard = null;
var originalCardPosition = null;
var scryTokenActive = true;
// Planet layout: 2-4-6-4-2 formation
var planetLayout = [2, 4, 6, 4, 2];
var planetWidth = 6; // Max cards in any row
var planetHeight = 5; // Number of rows
// UI Elements
var roundText = new Text2("Round: " + currentRound, {
size: 48,
fill: 0xFFFFFF
});
roundText.anchor.set(0.5, 0);
LK.gui.top.addChild(roundText);
roundText.y = 100;
var cardsDrawnText = new Text2("Cards Drawn: " + cardsDrawnThisTurn + "/" + maxCardsPerTurn, {
size: 36,
fill: 0xFFFFFF
});
cardsDrawnText.anchor.set(0, 0);
LK.gui.topRight.addChild(cardsDrawnText);
cardsDrawnText.x = -300;
cardsDrawnText.y = 150;
var deckCountText = new Text2("Deck: " + mainDeck.length, {
size: 36,
fill: 0xFFFFFF
});
deckCountText.anchor.set(0, 0);
LK.gui.topLeft.addChild(deckCountText);
deckCountText.x = 120;
deckCountText.y = 150;
var scryText = new Text2("Scry", {
size: 32,
fill: 0x00FF00
});
scryText.anchor.set(0, 0);
LK.gui.topRight.addChild(scryText);
scryText.x = -300;
scryText.y = 190;
// Initialize basic terrain pool (23 cards total)
function createBasicTerrainPool() {
basicTerrainPool = [];
// Add 9 water cards: 6 sea, 3 fresh
for (var i = 0; i < 6; i++) {
basicTerrainPool.push({
type: 'basic',
subtype: 'water',
waterType: 'sea',
climate: null // Will be assigned during setup
});
}
for (var i = 0; i < 3; i++) {
basicTerrainPool.push({
type: 'basic',
subtype: 'water',
waterType: 'fresh',
climate: null // Will be assigned during setup
});
}
// Add 14 land cards: 4 mountain, 5 hills, 5 flat
for (var i = 0; i < 4; i++) {
basicTerrainPool.push({
type: 'basic',
subtype: 'land',
landType: 'mountain',
climate: null // Will be assigned during setup
});
}
for (var i = 0; i < 5; i++) {
basicTerrainPool.push({
type: 'basic',
subtype: 'land',
landType: 'hills',
climate: null // Will be assigned during setup
});
}
for (var i = 0; i < 5; i++) {
basicTerrainPool.push({
type: 'basic',
subtype: 'land',
landType: 'flat',
climate: null // Will be assigned during setup
});
}
// Shuffle terrain pool
for (var i = basicTerrainPool.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = basicTerrainPool[i];
basicTerrainPool[i] = basicTerrainPool[j];
basicTerrainPool[j] = temp;
}
}
// Setup planet board with terrain cards
function setupPlanet() {
// Create 2D array for planet board
for (var y = 0; y < planetHeight; y++) {
planetBoard[y] = [];
planetSlots[y] = [];
for (var x = 0; x < planetWidth; x++) {
planetBoard[y][x] = null;
planetSlots[y][x] = null;
}
}
// Place terrain cards according to 2-4-6-4-2 layout
var terrainIndex = 0;
var startY = 400;
var cardSpacing = 320;
// Add climate row backgrounds first
for (var row = 0; row < planetLayout.length; row++) {
var climate;
if (row === 0 || row === 4) {
climate = 'cold'; // Rows 1 & 5
} else if (row === 1 || row === 3) {
climate = 'temperate'; // Rows 2 & 4
} else {
climate = 'hot'; // Row 3
}
// Create climate row background
var climateRowAsset = 'climateRow' + climate.charAt(0).toUpperCase() + climate.slice(1);
var climateRowBg = LK.getAsset(climateRowAsset, {
anchorX: 0.5,
anchorY: 0.5
});
climateRowBg.x = 1024; // Center of screen
climateRowBg.y = startY + row * 420;
climateRowBg.alpha = 0.3; // Semi-transparent background
game.addChild(climateRowBg);
// Add climate label text
var climateLabel = new Text2(climate.toUpperCase(), {
size: 32,
fill: 0x000000,
font: "'Arial Black', 'Impact', 'Tahoma', sans-serif"
});
climateLabel.anchor.set(0.5, 0.5);
climateLabel.rotation = -Math.PI / 2; // Rotate 90 degrees counter-clockwise to make vertical
climateLabel.x = 50; // Move left to make fully visible
climateLabel.y = startY + row * 420;
game.addChild(climateLabel);
}
for (var row = 0; row < planetLayout.length; row++) {
var cardsInRow = planetLayout[row];
var startX = 1024 - cardsInRow * cardSpacing / 2 + cardSpacing / 2 + 50; // Shift cards right by 50px
// Assign climate based on row
var climate;
if (row === 0 || row === 4) {
climate = 'cold'; // Rows 1 & 5
} else if (row === 1 || row === 3) {
climate = 'temperate'; // Rows 2 & 4
} else {
climate = 'hot'; // Row 3
}
for (var col = 0; col < cardsInRow && terrainIndex < basicTerrainPool.length; col++) {
// Assign climate to terrain card
var terrainData = basicTerrainPool[terrainIndex];
terrainData.climate = climate;
// Create terrain card
var terrainCard = new TerrainCard(terrainData);
terrainCard.x = startX + col * cardSpacing;
terrainCard.y = startY + row * 420;
terrainCard.gridX = col;
terrainCard.gridY = row;
game.addChild(terrainCard);
// Store in board
var boardX = Math.floor((planetWidth - cardsInRow) / 2) + col;
planetBoard[row][boardX] = terrainCard;
// Create slot for this position
var slot = new PlanetSlot(boardX, row);
slot.terrainCard = terrainCard;
planetSlots[row][boardX] = slot;
terrainIndex++;
}
}
}
// Create initial creature deck
function createInitialDeck() {
mainDeck = [];
// Add basic herbivores
for (var i = 0; i < 8; i++) {
mainDeck.push({
type: 'basic',
dietType: 'herbivore',
name: 'Basic Herbivore ' + (i + 1),
health: 2 + Math.floor(i / 3),
terrainRequirement: 'land',
climateRequirement: 'any'
});
}
// Add basic carnivores
for (var i = 0; i < 6; i++) {
mainDeck.push({
type: 'basic',
dietType: 'carnivore',
name: 'Basic Carnivore ' + (i + 1),
health: 3 + Math.floor(i / 3),
terrainRequirement: 'any',
climateRequirement: 'any'
});
}
// Add advanced herbivores
for (var i = 0; i < 4; i++) {
mainDeck.push({
type: 'advanced',
dietType: 'herbivore',
name: 'Advanced Herbivore ' + (i + 1),
health: 4 + i,
terrainRequirement: 'land',
climateRequirement: 'temperate'
});
}
// Add advanced carnivores
for (var i = 0; i < 3; i++) {
mainDeck.push({
type: 'advanced',
dietType: 'carnivore',
name: 'Advanced Carnivore ' + (i + 1),
health: 5 + i,
terrainRequirement: 'any',
climateRequirement: 'any'
});
}
// Shuffle deck
shuffleDeck();
}
function shuffleDeck() {
for (var i = mainDeck.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = mainDeck[i];
mainDeck[i] = mainDeck[j];
mainDeck[j] = temp;
}
}
function drawCard() {
if (cardsDrawnThisTurn >= maxCardsPerTurn) {
return null;
}
if (mainDeck.length === 0) {
endRound();
return null;
}
if (playerHand.length >= maxHandSize) {
return null;
}
var creatureData = mainDeck.pop();
var card = new CreatureCard(creatureData);
playerHand.push(card);
cardsDrawnThisTurn++;
// Position card in hand
updateHandPositions();
game.addChild(card);
// Update UI
cardsDrawnText.setText("Cards Drawn: " + cardsDrawnThisTurn + "/" + maxCardsPerTurn);
deckCountText.setText("Deck: " + mainDeck.length);
LK.getSound('cardDraw').play();
return card;
}
function updateHandPositions() {
var handY = 2400;
var handStartX = 1024 - playerHand.length * 200 / 2 + 100;
for (var i = 0; i < playerHand.length; i++) {
var card = playerHand[i];
if (!card.isInPlay) {
tween(card, {
x: handStartX + i * 200,
y: handY
}, {
duration: 300
});
}
}
}
function canPlaceCreatureOnTerrain(creatureCard, terrainCard) {
if (!creatureCard || !terrainCard) return false;
var creature = creatureCard.creatureData;
var terrain = terrainCard.terrainData;
// Check terrain requirements
if (creature.terrainRequirement !== 'any') {
if (creature.terrainRequirement === 'land' && terrain.subtype !== 'land') return false;
if (creature.terrainRequirement === 'water' && terrain.subtype !== 'water') return false;
}
// Check climate requirements
if (creature.climateRequirement !== 'any') {
if (creature.climateRequirement !== terrain.climate) return false;
}
// Check advanced creature placement rules
if (creature.type === 'advanced') {
// Advanced creatures require advanced terrain underneath
if (terrain.type !== 'advanced') return false;
// Advanced herbivores can only be placed on basic herbivores
if (creature.dietType === 'herbivore') {
if (terrainCard.creatureStack.length === 0) return false;
var topCreature = terrainCard.creatureStack[terrainCard.creatureStack.length - 1];
if (topCreature.creatureData.type !== 'basic' || topCreature.creatureData.dietType !== 'herbivore') return false;
}
// Advanced carnivores can be placed on basic carnivores OR advanced herbivores
else if (creature.dietType === 'carnivore') {
if (terrainCard.creatureStack.length === 0) return false;
var topCreature = terrainCard.creatureStack[terrainCard.creatureStack.length - 1];
var validTarget = topCreature.creatureData.type === 'basic' && topCreature.creatureData.dietType === 'carnivore' || topCreature.creatureData.type === 'advanced' && topCreature.creatureData.dietType === 'herbivore';
if (!validTarget) return false;
}
}
return true;
}
function placeCreatureOnTerrain(creatureCard, terrainCard, gridX, gridY) {
if (!canPlaceCreatureOnTerrain(creatureCard, terrainCard)) {
return false;
}
// Remove card from hand
var handIndex = playerHand.indexOf(creatureCard);
if (handIndex !== -1) {
playerHand.splice(handIndex, 1);
}
// Add to terrain's creature stack
terrainCard.creatureStack.push(creatureCard);
creatureCard.gridX = gridX;
creatureCard.gridY = gridY;
creatureCard.isInPlay = true;
// Position creature card on terrain
var targetX = terrainCard.x;
var targetY = terrainCard.y - terrainCard.creatureStack.length * 20; // Stack offset
tween(creatureCard, {
x: targetX,
y: targetY
}, {
duration: 300
});
// Apply creature effects
applyCreatureEffect(creatureCard);
// Update hand positions
updateHandPositions();
// Clear selection
selectedCard = null;
draggedCard = null;
// Reset turn
cardsDrawnThisTurn = 0;
cardsDrawnText.setText("Cards Drawn: " + cardsDrawnThisTurn + "/" + maxCardsPerTurn);
LK.getSound('cardPlace').play();
return true;
}
function applyCreatureEffect(creatureCard) {
var creature = creatureCard.creatureData;
if (creature.dietType === 'carnivore') {
// Hunt nearby herbivores
var neighbors = getAdjacentTerrains(creatureCard.gridX, creatureCard.gridY);
for (var i = 0; i < neighbors.length; i++) {
var terrain = neighbors[i];
if (terrain && terrain.creatureStack.length > 0) {
for (var j = 0; j < terrain.creatureStack.length; j++) {
var neighbor = terrain.creatureStack[j];
if (neighbor.creatureData.dietType === 'herbivore') {
neighbor.takeDamage(1);
}
}
}
}
} else if (creature.dietType === 'herbivore') {
// Strengthen nearby herbivores
var neighbors = getAdjacentTerrains(creatureCard.gridX, creatureCard.gridY);
for (var i = 0; i < neighbors.length; i++) {
var terrain = neighbors[i];
if (terrain && terrain.creatureStack.length > 0) {
for (var j = 0; j < terrain.creatureStack.length; j++) {
var neighbor = terrain.creatureStack[j];
if (neighbor.creatureData.dietType === 'herbivore') {
neighbor.currentHealth += 1;
neighbor.healthText.setText("HP: " + neighbor.currentHealth);
}
}
}
}
}
}
function getAdjacentTerrains(gridX, gridY) {
var neighbors = [];
var directions = [{
x: -1,
y: 0
}, {
x: 1,
y: 0
}, {
x: 0,
y: -1
}, {
x: 0,
y: 1
}];
for (var i = 0; i < directions.length; i++) {
var newX = gridX + directions[i].x;
var newY = gridY + directions[i].y;
if (newX >= 0 && newX < planetWidth && newY >= 0 && newY < planetHeight) {
neighbors.push(planetBoard[newY][newX]);
}
}
return neighbors;
}
function addEventCardToDeck() {
var eventCard = {
type: 'event',
name: 'Environmental Change',
effect: 'disaster'
};
// Insert event card randomly in deck
var insertIndex = Math.floor(Math.random() * (mainDeck.length + 1));
mainDeck.splice(insertIndex, 0, eventCard);
deckCountText.setText("Deck: " + mainDeck.length);
}
function endRound() {
currentRound++;
if (currentRound > maxRounds) {
// Game complete
LK.showYouWin();
return;
}
// Reshuffle deck
createInitialDeck();
// Reset turn counter
cardsDrawnThisTurn = 0;
// Update UI
roundText.setText("Round: " + currentRound);
cardsDrawnText.setText("Cards Drawn: " + cardsDrawnThisTurn + "/" + maxCardsPerTurn);
deckCountText.setText("Deck: " + mainDeck.length);
}
// Draw card button functionality
var drawButton = LK.getAsset('terrainLandFlat', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var drawButtonText = new Text2("DRAW", {
size: 32,
fill: 0xFFFFFF
});
drawButtonText.anchor.set(0.5, 0.5);
drawButton.addChild(drawButtonText);
drawButton.x = 1700;
drawButton.y = 2400;
game.addChild(drawButton);
drawButton.down = function () {
drawCard();
};
// Game move handler
game.move = function (x, y, obj) {
if (draggedCard) {
draggedCard.x = x;
draggedCard.y = y;
// Highlight valid terrain placement
for (var gridY = 0; gridY < planetHeight; gridY++) {
for (var gridX = 0; gridX < planetWidth; gridX++) {
var terrain = planetBoard[gridY][gridX];
if (terrain && canPlaceCreatureOnTerrain(draggedCard, terrain)) {
if (Math.abs(terrain.x - x) < 140 && Math.abs(terrain.y - y) < 168) {
planetSlots[gridY][gridX].highlight();
} else {
planetSlots[gridY][gridX].unhighlight();
}
} else if (terrain) {
planetSlots[gridY][gridX].unhighlight();
}
}
}
}
};
game.up = function (x, y, obj) {
if (draggedCard) {
var placed = false;
// Check if card was dropped on valid terrain
for (var gridY = 0; gridY < planetHeight && !placed; gridY++) {
for (var gridX = 0; gridX < planetWidth && !placed; gridX++) {
var terrain = planetBoard[gridY][gridX];
if (terrain && canPlaceCreatureOnTerrain(draggedCard, terrain)) {
if (Math.abs(terrain.x - x) < 140 && Math.abs(terrain.y - y) < 168) {
placed = placeCreatureOnTerrain(draggedCard, terrain, gridX, gridY);
}
}
}
}
// If not placed, return to original position
if (!placed && originalCardPosition) {
tween(draggedCard, originalCardPosition, {
duration: 300
});
}
// Clear all highlights
for (var gridY = 0; gridY < planetHeight; gridY++) {
for (var gridX = 0; gridX < planetWidth; gridX++) {
if (planetSlots[gridY][gridX]) {
planetSlots[gridY][gridX].unhighlight();
}
}
}
draggedCard = null;
originalCardPosition = null;
}
};
// Initialize terrain-based game
createBasicTerrainPool();
setupPlanet();
createInitialDeck();
// Round starts at 0, no initial cards drawn
currentRound = 0;
roundText.setText("Round: " + currentRound);
game.update = function () {
// Update UI elements
deckCountText.setText("Deck: " + mainDeck.length);
// Update scry token display
if (scryTokenActive) {
scryText.setText("Scry");
scryText.fill = 0x00FF00;
} else {
scryText.setText("Scry");
scryText.fill = 0xFF0000;
}
// Check round end conditions
if (mainDeck.length === 0 && playerHand.length === 0) {
endRound();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -246,15 +246,16 @@
deckCountText.anchor.set(0, 0);
LK.gui.topLeft.addChild(deckCountText);
deckCountText.x = 120;
deckCountText.y = 150;
-var scryText = new Text2("SCRY ACTIVE", {
+var scryText = new Text2("Scry", {
size: 32,
fill: 0x00FF00
});
-scryText.anchor.set(0.5, 0);
-LK.gui.top.addChild(scryText);
-scryText.y = 200;
+scryText.anchor.set(0, 0);
+LK.gui.topRight.addChild(scryText);
+scryText.x = -300;
+scryText.y = 190;
// Initialize basic terrain pool (23 cards total)
function createBasicTerrainPool() {
basicTerrainPool = [];
// Add 9 water cards: 6 sea, 3 fresh
@@ -722,12 +723,12 @@
// Update UI elements
deckCountText.setText("Deck: " + mainDeck.length);
// Update scry token display
if (scryTokenActive) {
- scryText.setText("SCRY ACTIVE");
+ scryText.setText("Scry");
scryText.fill = 0x00FF00;
} else {
- scryText.setText("SCRY USED");
+ scryText.setText("Scry");
scryText.fill = 0xFF0000;
}
// Check round end conditions
if (mainDeck.length === 0 && playerHand.length === 0) {