Code edit (4 edits merged)
Please save this source code
User prompt
with current code, timerGraphics.tint is going from black to green; change it from Green to Red
User prompt
invert the timerGraphics.tint animation to go from green to red
Code edit (17 edits merged)
Please save this source code
User prompt
update the color of the TimerLine from green to red depending on its size
Code edit (1 edits merged)
Please save this source code
Code edit (16 edits merged)
Please save this source code
User prompt
Fix Bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'set')' in this line: 'this.timerLine.anchor.set(0, 0);' Line Number: 600
Code edit (1 edits merged)
Please save this source code
Code edit (12 edits merged)
Please save this source code
User prompt
update the line var elapsedTime = 10 * levelDurationInSeconds / 60; self.timerLine.update(elapsedTime); to use Date time
Code edit (10 edits merged)
Please save this source code
User prompt
Bug : when levelDurationInSeconds is 10, the TimerLine width reduces in 10 sec , but when levelDurationInSeconds is 15, the TimerLine width reduces in 22 sec instead of 15sec
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Fix Bug: 'Uncaught ReferenceError: level is not defined' in this line: 'var levelDurationInSeconds = levels[level].time;' Line Number: 169
User prompt
update the timer so that it lasts the number of seconds indicated in levels array for each level
Code edit (8 edits merged)
Please save this source code
User prompt
clean the code without doing any change in the way it behave
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Fix Bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in this line: 'var dx = newPos.x - card.x;' Line Number: 398
Code edit (5 edits merged)
Please save this source code
User prompt
update the line `var newPos = positions[index];` to retreive the newPos int the position array using the uid property
Code edit (1 edits merged)
Please save this source code
var Line = Container.expand(function (startX, startY, endX, endY) {
var self = Container.call(this);
var lineGraphics = self.createAsset('line', 'Line Graphics', 0, 0);
lineGraphics.width = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
lineGraphics.rotation = Math.atan2(endY - startY, endX - startX);
lineGraphics.x = startX;
lineGraphics.y = startY;
self.addChild(lineGraphics);
return self;
});
var Picture = Container.expand(function (index) {
var self = Container.call(this);
self.index = index;
var pictureGraphics = self.createAsset('picture' + self.index, 'Picture Graphics', .5, .5);
return self;
});
var Card = Container.expand(function (context, uid, index) {
var self = Container.call(this);
self.row = 0;
self.col = 0;
self.uid = uid;
self.id = index;
if (!index) {
self.isMatched = true;
return self;
}
self.isMatched = false;
nbCardsLeft++;
self.shakeAnimation = function (card) {
if (!card) return;
var shakeCount = 0;
var shakeTimes = 9;
var shakeStrength = 70;
var originalX = card.x;
var originalY = card.y;
function shake() {
if (shakeCount < shakeTimes) {
card.x = originalX + (Math.random() - 0.5) * shakeStrength;
shakeCount++;
LK.setTimeout(shake, 50);
} else {
card.x = originalX;
card.y = originalY;
card.scale.x = 1;
card.scale.y = 1;
if (card === selectedCard1) selectedCard1 = null;
if (card === selectedCard2) selectedCard2 = null;
isAnimating = false;
}
}
shake();
};
self.id = index;
self.on('down', function (obj) {
if (!self.isMatched && !isAnimating) {
if (!selectedCard1 || selectedCard1 && selectedCard2) {
if (selectedCard1) {
selectedCard1.scale.x = 1;
selectedCard1.scale.y = 1;
if (selectedCard1 === self) {
selectedCard1 = null;
return;
}
}
selectedCard1 = self;
selectedCard2 = null;
self.scale.x = 1.2;
self.scale.y = 1.2;
} else if (selectedCard1 && !selectedCard2 && selectedCard1 === self) {
selectedCard1.scale.x = 1;
selectedCard1.scale.y = 1;
selectedCard1 = null;
} else if (selectedCard1 && !selectedCard2 && selectedCard1 !== self) {
selectedCard2 = self;
var canLink = canBeLinked(selectedCard1, selectedCard2);
self.scale.x = 1.2;
self.scale.y = 1.2;
if (canLink) {
lastMatched = true;
selectedCard1.match(selectedCard2);
selectedCard2.match(selectedCard1);
selectedCard1 = null;
selectedCard2 = null;
} else {
lastMatched = false;
isAnimating = true;
LK.setTimeout(function () {
self.shakeAnimation(selectedCard1);
self.shakeAnimation(selectedCard2);
}, 300);
}
}
}
});
var cardGraphics = self.createAsset('card', 'Card Graphics', .5, .5);
self.match = function (otherCard) {
if (checkGameEndTimeout) {
LK.clearTimeout(checkGameEndTimeout);
}
var line = new Line(self.x, self.y, otherCard.x, otherCard.y);
LK.stage.addChild(line);
var tadaAnimationSteps = 10;
var tadaAnimationCount = 0;
var scaleDelta = 0.2;
var tadaDelay = 0;
var tadaDelayMax = 60;
self.tadaAnimation = function () {
if (tadaAnimationCount < tadaAnimationSteps) {
self.scale.x += tadaAnimationCount % 2 === 0 ? scaleDelta : -scaleDelta;
self.scale.y += tadaAnimationCount % 2 === 0 ? scaleDelta : -scaleDelta;
tadaAnimationCount++;
} else {
LK.off('tick', self.tadaAnimation);
}
};
self.shrinkAnimation = function () {
if (self.scale.x > 0.1) {
self.scale.x -= 0.01;
self.scale.y -= 0.01;
self.rotation += 0.1;
} else {
self.visible = false;
LK.off('tick', self.tadaAnimation);
LK.off('tick', self.shrinkAnimation);
currentSolvedPairs[self.id] = true;
currentNbSolved = Object.keys(currentSolvedPairs).length;
console.log("currentNbSolved: " + currentNbSolved + " / lastNbPossible: " + lastNbPossible);
if (checkGameEndTimeout) {
LK.clearTimeout(checkGameEndTimeout);
}
checkGameEndTimeout = LK.setTimeout(function () {
if (currentNbSolved >= lastNbPossible) {
console.log("call check by #" + self.id + " (uid " + self.uid + ")");
checkGameEnd(context, self.id);
}
console.log('TEMP DEBUG !!!');
tryRemixCards();
}, 1000);
}
};
LK.on('tick', self.tadaAnimation);
console.log("Setting is Matched for #" + self.id + ": " + self.row + "," + self.col + " <-> " + otherCard.row + "," + otherCard.col);
self.isMatched = true;
LK.setTimeout(function () {
LK.on('tick', self.shrinkAnimation);
}, tadaAnimationSteps * 50);
LK.setTimeout(function () {
line.destroy();
}, 1000);
};
var picture = self.addChild(new Picture(index));
picture.x = 0;
picture.y = 0;
return self;
});
var TimerLine = Container.expand(function (width, height) {
var self = Container.call(this);
var timerGraphics = self.createAsset('timerLine', 'Timer Line Graphics', 0, 0);
timerGraphics.width = width;
timerGraphics.height = height;
timerGraphics.tint = 0x00FF00;
self.addChild(timerGraphics);
self.update = function (deltaWidth) {
timerGraphics.width = Math.max(0, timerGraphics.width - deltaWidth);
};
return self;
});
console.log("Principle : A pair matching game is a type of puzzle game where the player has to find and connect two identical images on a board. The player can only connect the images with a straight line or a line that bends at most twice. The line cannot cross any other images on the board. ");
var level = 4;
var levels = [{
'rows': 2,
'cols': 2
}, {
'rows': 4,
'cols': 4
}, {
'rows': 6,
'cols': 6
}, {
'rows': 8,
'cols': 8
}, {
'rows': 10,
'cols': 10
}, {
'rows': 11,
'cols': 10
}, {
'rows': 12,
'cols': 10
}];
var MAX_INIT_TRIES = 1000;
var debug = true;
var lastMatched = false;
var cardPairs = [];
var cards = [];
var selectedCard1 = null;
var selectedCard2 = null;
var isInitializing = false;
var isAnimating = false;
var isRemixing = false;
var nbRows = 2 + 2;
var nbCols = 1 + 2;
var nbCards = nbRows * nbCols;
var nbPairs = (nbCards - nbRows * 2 - (nbCols - 2) * 2) / 2;
var nbCardsLeft = 0;
var lastNbPossible = 0;
var currentSolvedPairs = [];
var currentNbSolved = 0;
var cardWidth = 200;
var cardHeight = 200;
var horizontalOffset = (2048 - (nbCols - 1) * cardWidth) / 2;
var verticalOffset = (2732 - (nbRows - 1) * cardHeight) / 2;
var shuffleDifficulty = 4;
var lastCheckCaller = 0;
var isGameEndChecking = false;
var checkGameEndTimeout = null;
if (nbCards % 2) {
console.error('Invalid number of cards ! Should be even.', nbCards);
LK.showGameOver();
nbCols++;
}
function prepareConfig(level) {
console.log('Prepare for level #' + level);
cardPairs = [];
cards.forEach(function (row) {
row.forEach(function (card) {
if (card) card.destroy();
});
});
cards = [];
nbRows = levels[level].rows + 2;
nbCols = levels[level].cols + 2;
nbCards = nbRows * nbCols;
if (nbCards % 2) {
console.error('Invalid number of cards ! Should be even.', nbCards);
LK.showGameOver();
nbCols++;
}
nbPairs = (nbCards - nbRows * 2 - (nbCols - 2) * 2) / 2;
horizontalOffset = (2048 - (nbCols - 1) * cardWidth) / 2;
verticalOffset = (2732 - (nbRows - 1) * cardHeight) / 2;
nbCardsLeft = 0;
lastNbPossible = 0;
currentSolvedPairs = [];
currentNbSolved = 0;
lastCheckCaller = 0;
checkGameEndTimeout = null;
selectedCard1 = null;
selectedCard2 = null;
isAnimating = false;
isRemixing = false;
}
function timeBasedRandom() {
var currentTime = Date.now();
var timeSeed = currentTime % 1000;
var randomValue = Math.random() * timeSeed;
return randomValue - Math.floor(randomValue);
}
function shuffleArray(array, onlyNonEmpty) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(timeBasedRandom() * (i + 1));
if (onlyNonEmpty && (!array[i] || !array[j])) {
continue;
}
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function shuffleWithDifficulty(array, difficulty, onlyNonEmpty) {
difficulty = Math.max(0, Math.min(10, difficulty));
var maxSwapDistance = Math.ceil(array.length * (difficulty / 10));
var numberOfSwaps = Math.ceil(array.length * (difficulty / 10));
for (var i = 0; i < numberOfSwaps; i++) {
var firstIndex = Math.floor(timeBasedRandom() * array.length);
var swapDistance = Math.floor(timeBasedRandom() * maxSwapDistance);
var secondIndex = (firstIndex + swapDistance) % array.length;
if (onlyNonEmpty && (!array[firstIndex] || !array[secondIndex])) {
continue;
}
var temp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = temp;
}
ensureAdjacentIndexes(array, difficulty);
return array;
}
function ensureAdjacentIndexes(array, difficulty) {
var adjacentIndexes = Math.floor(array.length * 0.1 * (1 / difficulty));
console.log("Making adjacentIndexes : difficulty=" + difficulty + " => " + adjacentIndexes + " / " + array.length);
console.log("Before adjacent : ", array.slice(0, 30).join(", "));
var pairsToSwap = [];
for (var i = 0; i < array.length - 1; i++) {
for (var j = i + 1; j < array.length; j++) {
if (array[i] && array[j] && array[i] === array[j] && !pairsToSwap.includes(array[i])) {
pairsToSwap.push(array[i]);
}
}
}
var numberOfPairsToSwap = Math.ceil(pairsToSwap.length * (difficulty / 10));
numberOfPairsToSwap = adjacentIndexes;
console.log("numberOfPairsToSwap=" + numberOfPairsToSwap);
shuffleArray(pairsToSwap, false);
pairsToSwap = pairsToSwap.slice(0, numberOfPairsToSwap);
for (var i = 0; i < array.length - 1; i++) {
for (var j = i + 1; j < array.length; j++) {
if (array[i] && array[j] && array[i] === array[j] && pairsToSwap.includes(array[i]) && array[i + 1]) {
var temp = array[i + 1];
array[i + 1] = array[j];
array[j] = temp;
pairsToSwap.splice(pairsToSwap.indexOf(array[i]), 1);
break;
}
}
}
console.log("After adjacent : ", array.slice(0, 30).join(", "));
}
function canBeLinked(card1, card2) {
if (card1 === card2 || !card1 || !card2 || card1.id !== card2.id) {
return false;
}
var visited = Array.from({
length: nbRows
}, () => Array(nbCols).fill(false));
function dfs(card, bends, direction) {
if (!card || visited[card.row][card.col] || bends > 2) {
return false;
}
if (card === card2) {
return true;
}
visited[card.row][card.col] = true;
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
for (let [di, dj] of directions) {
var ni = card.row + di, nj = card.col + dj;
if (ni >= 0 && ni < nbRows && nj >= 0 && nj < nbCols) {
var nextCard = cards[ni][nj];
if (!nextCard || !nextCard.id || nextCard.isMatched || nextCard === card2) {
if (di !== 0) {
if (dfs(nextCard, bends + (direction === -1), 1)) return true;
} else if (dj !== 0) {
if (dfs(nextCard, bends + (direction === 1), -1)) return true;
}
}
}
}
visited[card.row][card.col] = false;
return false;
}
return dfs(card1, 0);
}
function remixCards(currentDifficulty, callback) {
console.log('Remixing cards start.');
if (isRemixing) {
console.log('already remixing.');
return false;
}
isRemixing = true;
var unmatchedCards = cards.flat().filter(function (card) {
return !card.isMatched;
});
var positions = unmatchedCards.map(function (card) {
return {
uid: card.uid,
id: card.id,
x: card.x,
y: card.y
};
});
var indexes = unmatchedCards.map(function (card) {
return card.id;
});
console.log('indexes before:', indexes);
indexes = shuffleWithDifficulty(indexes, currentDifficulty);
console.log('indexes after:', indexes);
var reorderedPosition = [];
var treatedUids = [];
for (var i = 0; i < indexes.length; i++) {
var tempIndex = indexes[i];
for (var j = 0; j < positions.length; j++) {
if (positions[j].id == tempIndex && !treatedUids[positions[j].uid]) {
reorderedPosition.push(positions[j]);
treatedUids[positions[j].uid] = true;
break;
}
}
}
positions = reorderedPosition;
unmatchedCards.forEach(function (card, index) {
var newPos = positions[index];
var moveCard = function () {
var dx = newPos.x - card.x;
var dy = newPos.y - card.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 1) {
card.x = newPos.x;
card.y = newPos.y;
var newCol = Math.floor((card.x - horizontalOffset) / cardWidth);
var newRow = Math.floor((card.y - verticalOffset) / cardHeight);
if (cards[card.row] && cards[card.row][card.col] === card) {
cards[card.row][card.col] = undefined;
}
card.col = newCol;
card.row = newRow;
cards[newRow][newCol] = card;
LK.off('tick', moveCard);
if (index === unmatchedCards.length - 1) {
console.log('isRemixing : end of last mov');
}
} else {
card.x += dx * 0.05;
card.y += dy * 0.05;
}
};
LK.on('tick', moveCard);
});
LK.setTimeout(function () {
isRemixing = false;
console.log('isRemixing timeout :' + (callback ? 'callback....' : 'NO callback'));
if (callback) {
callback();
}
console.log('Remixing cards end.');
}, 4000);
}
function checkGameEnd(context, callerId) {
console.log('checkGameEnd...by #' + callerId + " previous = " + lastCheckCaller);
if (isGameEndChecking) {
console.log('already checking...');
return;
}
if (lastCheckCaller === callerId) {
console.log('already checked...');
return;
}
isGameEndChecking = true;
lastCheckCaller = callerId;
nbCardsLeft = cards.flat().filter(function (card) {
return !card.isMatched;
}).length;
console.log("Card left : ", nbCardsLeft);
if (!nbCardsLeft) {
LK.setTimeout(function () {
if (level + 1 >= levels.length) {
LK.showGameOver();
} else {
level++;
isGameEndChecking = false;
tryInitGame(context);
}
}, 1000);
return;
}
console.log('check still possible ?..');
if (currentNbSolved >= lastNbPossible) {
var isPossible = checkBoardPossible();
console.log('Recheck Game isPossible :' + isPossible);
console.log(" New currentNbSolved: " + currentNbSolved + " / lastNbPossible: " + lastNbPossible + " / nbPairs:" + nbPairs);
var canContinue = currentNbSolved < lastNbPossible;
console.log("=> " + (canContinue ? "Ok. Can continue" : "KO. Blocked !!"));
if (!canContinue) {
tryRemixCards();
}
}
isGameEndChecking = false;
console.log('end checking.');
}
function checkBoardPossible() {
console.log("Checking if all pairs can be linked...");
var nbPossible = 0;
var nbImpossible = 0;
var indexesChecked = [];
for (var i = 0; i < cardPairs.length; i++) {
var index = cardPairs[i];
if (!index || indexesChecked[index]) {
continue;
}
var card1 = cards.flat().find(function (card) {
return card.id === index;
});
var card2 = cards.flat().find(function (card) {
return card.id === index && card !== card1;
});
if (canBeLinked(card1, card2)) {
indexesChecked[index] = true;
nbPossible++;
} else {
nbImpossible++;
}
}
console.log('nbPossible = ' + nbPossible + ' / nbImpossible = ' + nbImpossible + ' / currentNbSolved ' + currentNbSolved);
lastNbPossible = nbPossible;
return Math.max(currentNbSolved, nbPossible) >= (nbImpossible + nbPossible) * 0.1;
}
function initGame(self, currentDifficulty) {
console.log('Init game...level ' + level);
if (isInitializing) {
console.log('already Initializing...');
return;
}
isInitializing = true;
prepareConfig(level);
console.log("nbPairs : " + nbPairs);
var nextPairIndex = 1;
for (var i = 0; i < nbCards; i++) {
var row = Math.floor(i / nbCols);
var col = i % nbCols;
if (row === 0 || row === nbRows - 1 || col === 0 || col === nbCols - 1) {
cardPairs.push(0);
} else {
cardPairs.push(nextPairIndex);
nextPairIndex = nextPairIndex % nbPairs + 1;
}
}
cardPairs = shuffleWithDifficulty(cardPairs, currentDifficulty, true);
for (var i = 0; i < nbCards; i++) {
var row = Math.floor(i / nbCols);
var col = i % nbCols;
var card = self.addChild(new Card(self, i, cardPairs[i]));
card.col = col;
card.row = row;
card.x = horizontalOffset + card.col * cardWidth;
card.y = verticalOffset + card.row * cardHeight;
if (!cards[card.row]) {
cards[card.row] = [];
}
cards[card.row][card.col] = card;
}
console.log('Init game ok level' + level);
isInitializing = false;
}
function tryInitGame(context) {
console.log('tryInitGame...');
var isPossible = false;
var nbTries = 0;
var currentDifficulty = shuffleDifficulty;
while (!isPossible) {
initGame(context, currentDifficulty);
isPossible = checkBoardPossible();
console.log('Game isPossible :' + isPossible);
nbTries++;
currentDifficulty--;
if (nbTries > MAX_INIT_TRIES) {
isPossible = true;
console.warn('Unable to init game after ' + nbTries + ' tries');
LK.showGameOver();
}
}
}
function tryRemixCards(nbTries, currentDifficulty) {
nbTries = nbTries || 0;
currentDifficulty = currentDifficulty || shuffleDifficulty;
console.log('tryRemixCards...try NΒ°' + nbTries + " / difficulty=" + currentDifficulty);
remixCards(currentDifficulty, function () {
var isPossible = checkBoardPossible();
console.log('Game isPossible :' + isPossible);
nbTries++;
currentDifficulty--;
if (nbTries > MAX_INIT_TRIES) {
isPossible = true;
console.warn('Unable to remix game after ' + nbTries + ' tries');
LK.showGameOver();
} else {
tryRemixCards(nbTries, currentDifficulty);
}
});
}
var Game = Container.expand(function () {
var self = Container.call(this);
this.timerLine = new TimerLine(2048, 20);
this.timerLine.x = 0;
this.timerLine.y = 0;
LK.gui.topLeft.addChild(this.timerLine);
tryInitGame(self);
if (debug) {
var matchDebugText = new Text2('Match:', {
size: 50,
fill: '#ffffff'
});
matchDebugText.anchor.set(0, 0);
LK.gui.topLeft.addChild(matchDebugText);
LK.on('tick', function () {
if (!isGameOver) {
self.timerLine.update(1);
}
matchDebugText.setText('Level: ' + (level + 1) + ' Solved: ' + currentNbSolved + '/' + lastNbPossible);
});
}
});
a photo realistic top view of empty flat beige plastic square. Single Game Texture. In-Game asset. 2d. No background. High contrast. No shadows.
a christmas tree. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas gift. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas ball. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a golden christmas tree star. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas hat. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas leaf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas holly leaf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas snow flake. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas snow man. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas reindeer. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas candy cane. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas green ball . plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas gingerbrean man. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas pine cone. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas present green. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas boe tie. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas socks. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas penguin. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas decorated blue present. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas scarf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas gloves. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas blue decorated ball. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas candle. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas snow globe. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
an christmas elongated cuboid present. plastic style. No shadow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a round christmas gift.plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a round christmas gift.plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
one cute christmas elf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
one cute christmas elf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
one cute christmas reindeer head. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
one cute christmas reindeer head with a red nose. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
one christmas bell. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a couple of christmas bells. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas gifts bag. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas candle. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a cute santa clauss. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Santa's sleigh. Side view. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Reimagine the cute teddy bear sitting without background. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Christmas Rocking Horse. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
One Christmas Matryoshka Doll. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A christmas Miniature Train. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A christmas Toy Soldier. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A christmas Music Box . Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a cute polar bear cub. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a sled plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas gingerbread girl. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas gingerbread house. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a cute christmas jack in the box. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a cute christmas cookie. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas log cacke. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a christmas donut. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a cute christmas owl. Plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a feeric christmas landscape at night with decorated trees Background image
a feeric christmas landscape at night with snow men and snow flakes Background image
a feeric christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, Background image
a feeric christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, Santa's reindeers, green, red and blue presents Background image
a feeric christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, cute penguin, Santa's reindeers, green, red and blue presents and a lot of toys, a sled, gingerbread boy and girl, snow globes, a cute polar bear cub. a gingerbread house Background image
A Magical feeric starry christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, cute penguin, Santa's reindeers, green, red and blue presents and a lot of toys, a sled, gingerbread boy and girl, snow globes, cute polar bears cub and a gingerbread house. Realistic. Plastic style. Background image