User prompt
A little to the right
User prompt
Take the words down a bit
User prompt
Come on
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'height')' in or related to this line: 'var beam = self.attachAsset('gallows_beam', {' Line Number: 39
Code edit (1 edits merged)
Please save this source code
User prompt
Hangman: Word Guess Challenge
Initial prompt
Make a hangman game
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Hangman drawing class
var HangmanDrawing = Container.expand(function () {
var self = Container.call(this);
// Gallows
var base = self.attachAsset('gallows_base', {
anchorX: 0.5,
anchorY: 1,
x: 0,
y: 0
});
var pole = self.attachAsset('gallows_pole', {
anchorX: 0.5,
anchorY: 1,
x: 0,
y: -base.height
});
var beam = self.attachAsset('gallows_beam', {
anchorX: 0,
anchorY: 1,
x: pole.width / 2,
y: -base.height - pole.height + beam.height / 2
});
var rope = self.attachAsset('gallows_rope', {
anchorX: 0.5,
anchorY: 0,
x: beam.x + beam.width - 40,
y: beam.y - beam.height / 2
});
// Hangman parts (hidden initially)
var head = self.attachAsset('hangman_head', {
anchorX: 0.5,
anchorY: 0,
x: rope.x,
y: rope.y + rope.height
});
var body = self.attachAsset('hangman_body', {
anchorX: 0.5,
anchorY: 0,
x: head.x,
y: head.y + head.height
});
var leftArm = self.attachAsset('hangman_arm', {
anchorX: 1,
anchorY: 0.5,
x: body.x,
y: body.y + body.height * 0.2,
rotation: -Math.PI / 4
});
var rightArm = self.attachAsset('hangman_arm', {
anchorX: 0,
anchorY: 0.5,
x: body.x,
y: body.y + body.height * 0.2,
rotation: Math.PI / 4
});
var leftLeg = self.attachAsset('hangman_leg', {
anchorX: 1,
anchorY: 0.5,
x: body.x,
y: body.y + body.height,
rotation: -Math.PI / 4
});
var rightLeg = self.attachAsset('hangman_leg', {
anchorX: 0,
anchorY: 0.5,
x: body.x,
y: body.y + body.height,
rotation: Math.PI / 4
});
// Store parts in order of appearance
self.parts = [head, body, leftArm, rightArm, leftLeg, rightLeg];
// Hide all hangman parts initially
for (var i = 0; i < self.parts.length; ++i) {
self.parts[i].visible = false;
}
// Show up to n parts
self.showParts = function (n) {
for (var i = 0; i < self.parts.length; ++i) {
self.parts[i].visible = i < n;
}
};
// Reset drawing
self.reset = function () {
self.showParts(0);
};
return self;
});
// Letter button class
var LetterButton = Container.expand(function () {
var self = Container.call(this);
// Default: not used
self.used = false;
self.letter = '';
// Button background
var btn = self.attachAsset('letter_btn', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
// Letter text
var txt = new Text2('', {
size: 64,
fill: '#ffffff'
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
self.addChild(txt);
// Set letter
self.setLetter = function (letter) {
self.letter = letter;
txt.setText(letter);
};
// Mark as used
self.setUsed = function () {
self.used = true;
btn.destroy();
// Replace with used button asset
var usedBtn = self.attachAsset('letter_btn_used', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
};
// Touch event
self.down = function (x, y, obj) {
if (self.used) return;
if (typeof self.onSelect === 'function') {
self.onSelect(self.letter, self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222244
});
/****
* Game Code
****/
// Letter button asset
// Hangman parts: head, body, left arm, right arm, left leg, right leg, gallows base, pole, beam, rope
// Word list (all uppercase, no spaces)
var WORDS = ["APPLE", "BANANA", "ORANGE", "ELEPHANT", "GUITAR", "PYTHON", "JAZZ", "ROCKET", "PLANET", "MONKEY", "UMBRELLA", "VIOLET", "ZEBRA", "KANGAROO", "BICYCLE", "CIRCUS", "DIAMOND", "FROG", "HAMBURGER", "ISLAND"];
// Game state variables
var currentWord = '';
var revealed = [];
var wrongGuesses = 0;
var maxWrong = 6; // 6 hangman parts
var guessedLetters = [];
var letterButtons = [];
var hangmanDrawing = null;
var wordDisplay = null;
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
var wordY = 400;
var hangmanX = 400;
var hangmanY = 900;
var letterGridY = 1800;
// Score display (win/loss count)
var winCount = 0;
var lossCount = 0;
var winTxt = new Text2('Wins: 0', {
size: 80,
fill: '#aaffaa'
});
winTxt.anchor.set(0, 0);
LK.gui.top.addChild(winTxt);
var lossTxt = new Text2('Losses: 0', {
size: 80,
fill: '#ffaaaa'
});
lossTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(lossTxt);
// Helper: pick a random word
function pickWord() {
var idx = Math.floor(Math.random() * WORDS.length);
return WORDS[idx];
}
// Helper: update word display
function updateWordDisplay() {
var s = '';
for (var i = 0; i < revealed.length; ++i) {
s += revealed[i] ? currentWord[i] : '_';
if (i < revealed.length - 1) s += ' ';
}
wordDisplay.setText(s);
}
// Helper: update win/loss text
function updateScoreDisplay() {
winTxt.setText('Wins: ' + winCount);
lossTxt.setText('Losses: ' + lossCount);
}
// Start a new game
function startGame() {
// Remove old letter buttons
for (var i = 0; i < letterButtons.length; ++i) {
letterButtons[i].destroy();
}
letterButtons = [];
guessedLetters = [];
wrongGuesses = 0;
// Pick word
currentWord = pickWord();
revealed = [];
for (var i = 0; i < currentWord.length; ++i) {
revealed.push(false);
}
// Update word display
updateWordDisplay();
// Reset hangman
hangmanDrawing.reset();
// Create letter buttons (A-Z, 7 per row)
var cols = 7;
var rows = Math.ceil(alphabet.length / cols);
var btnSize = 120;
var spacing = 30;
var gridWidth = cols * btnSize + (cols - 1) * spacing;
var startX = (2048 - gridWidth) / 2 + btnSize / 2;
var startY = letterGridY;
for (var i = 0; i < alphabet.length; ++i) {
var btn = new LetterButton();
btn.setLetter(alphabet[i]);
// Position in grid
var col = i % cols;
var row = Math.floor(i / cols);
btn.x = startX + col * (btnSize + spacing);
btn.y = startY + row * (btnSize + spacing);
// Letter select handler
btn.onSelect = onLetterSelected;
game.addChild(btn);
letterButtons.push(btn);
}
}
// Letter selected handler
function onLetterSelected(letter, btn) {
// Mark as used
btn.setUsed();
guessedLetters.push(letter);
// Check if letter is in word
var found = false;
for (var i = 0; i < currentWord.length; ++i) {
if (currentWord[i] === letter) {
revealed[i] = true;
found = true;
}
}
updateWordDisplay();
if (found) {
// Check win
var allRevealed = true;
for (var i = 0; i < revealed.length; ++i) {
if (!revealed[i]) {
allRevealed = false;
break;
}
}
if (allRevealed) {
winCount += 1;
updateScoreDisplay();
LK.effects.flashScreen(0x00ff00, 800);
LK.showYouWin();
}
} else {
// Wrong guess
wrongGuesses += 1;
hangmanDrawing.showParts(wrongGuesses);
if (wrongGuesses >= maxWrong) {
lossCount += 1;
updateScoreDisplay();
LK.effects.flashScreen(0xff0000, 800);
// Reveal word
for (var i = 0; i < revealed.length; ++i) {
revealed[i] = true;
}
updateWordDisplay();
LK.showGameOver();
}
}
}
// Create hangman drawing
hangmanDrawing = new HangmanDrawing();
hangmanDrawing.x = hangmanX;
hangmanDrawing.y = hangmanY;
game.addChild(hangmanDrawing);
// Create word display
wordDisplay = new Text2('', {
size: 140,
fill: '#ffffff'
});
wordDisplay.anchor.set(0.5, 0.5);
wordDisplay.x = 2048 / 2;
wordDisplay.y = wordY;
game.addChild(wordDisplay);
// Start first game
startGame();
// On game reset, start a new game
game.on('reset', function () {
startGame();
}); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,313 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Hangman drawing class
+var HangmanDrawing = Container.expand(function () {
+ var self = Container.call(this);
+ // Gallows
+ var base = self.attachAsset('gallows_base', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: 0
+ });
+ var pole = self.attachAsset('gallows_pole', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 0,
+ y: -base.height
+ });
+ var beam = self.attachAsset('gallows_beam', {
+ anchorX: 0,
+ anchorY: 1,
+ x: pole.width / 2,
+ y: -base.height - pole.height + beam.height / 2
+ });
+ var rope = self.attachAsset('gallows_rope', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: beam.x + beam.width - 40,
+ y: beam.y - beam.height / 2
+ });
+ // Hangman parts (hidden initially)
+ var head = self.attachAsset('hangman_head', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: rope.x,
+ y: rope.y + rope.height
+ });
+ var body = self.attachAsset('hangman_body', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: head.x,
+ y: head.y + head.height
+ });
+ var leftArm = self.attachAsset('hangman_arm', {
+ anchorX: 1,
+ anchorY: 0.5,
+ x: body.x,
+ y: body.y + body.height * 0.2,
+ rotation: -Math.PI / 4
+ });
+ var rightArm = self.attachAsset('hangman_arm', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: body.x,
+ y: body.y + body.height * 0.2,
+ rotation: Math.PI / 4
+ });
+ var leftLeg = self.attachAsset('hangman_leg', {
+ anchorX: 1,
+ anchorY: 0.5,
+ x: body.x,
+ y: body.y + body.height,
+ rotation: -Math.PI / 4
+ });
+ var rightLeg = self.attachAsset('hangman_leg', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: body.x,
+ y: body.y + body.height,
+ rotation: Math.PI / 4
+ });
+ // Store parts in order of appearance
+ self.parts = [head, body, leftArm, rightArm, leftLeg, rightLeg];
+ // Hide all hangman parts initially
+ for (var i = 0; i < self.parts.length; ++i) {
+ self.parts[i].visible = false;
+ }
+ // Show up to n parts
+ self.showParts = function (n) {
+ for (var i = 0; i < self.parts.length; ++i) {
+ self.parts[i].visible = i < n;
+ }
+ };
+ // Reset drawing
+ self.reset = function () {
+ self.showParts(0);
+ };
+ return self;
+});
+// Letter button class
+var LetterButton = Container.expand(function () {
+ var self = Container.call(this);
+ // Default: not used
+ self.used = false;
+ self.letter = '';
+ // Button background
+ var btn = self.attachAsset('letter_btn', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: 0
+ });
+ // Letter text
+ var txt = new Text2('', {
+ size: 64,
+ fill: '#ffffff'
+ });
+ txt.anchor.set(0.5, 0.5);
+ txt.x = 0;
+ txt.y = 0;
+ self.addChild(txt);
+ // Set letter
+ self.setLetter = function (letter) {
+ self.letter = letter;
+ txt.setText(letter);
+ };
+ // Mark as used
+ self.setUsed = function () {
+ self.used = true;
+ btn.destroy();
+ // Replace with used button asset
+ var usedBtn = self.attachAsset('letter_btn_used', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: 0
+ });
+ };
+ // Touch event
+ self.down = function (x, y, obj) {
+ if (self.used) return;
+ if (typeof self.onSelect === 'function') {
+ self.onSelect(self.letter, self);
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
+ backgroundColor: 0x222244
+});
+
+/****
+* Game Code
+****/
+// Letter button asset
+// Hangman parts: head, body, left arm, right arm, left leg, right leg, gallows base, pole, beam, rope
+// Word list (all uppercase, no spaces)
+var WORDS = ["APPLE", "BANANA", "ORANGE", "ELEPHANT", "GUITAR", "PYTHON", "JAZZ", "ROCKET", "PLANET", "MONKEY", "UMBRELLA", "VIOLET", "ZEBRA", "KANGAROO", "BICYCLE", "CIRCUS", "DIAMOND", "FROG", "HAMBURGER", "ISLAND"];
+// Game state variables
+var currentWord = '';
+var revealed = [];
+var wrongGuesses = 0;
+var maxWrong = 6; // 6 hangman parts
+var guessedLetters = [];
+var letterButtons = [];
+var hangmanDrawing = null;
+var wordDisplay = null;
+var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
+var wordY = 400;
+var hangmanX = 400;
+var hangmanY = 900;
+var letterGridY = 1800;
+// Score display (win/loss count)
+var winCount = 0;
+var lossCount = 0;
+var winTxt = new Text2('Wins: 0', {
+ size: 80,
+ fill: '#aaffaa'
+});
+winTxt.anchor.set(0, 0);
+LK.gui.top.addChild(winTxt);
+var lossTxt = new Text2('Losses: 0', {
+ size: 80,
+ fill: '#ffaaaa'
+});
+lossTxt.anchor.set(1, 0);
+LK.gui.topRight.addChild(lossTxt);
+// Helper: pick a random word
+function pickWord() {
+ var idx = Math.floor(Math.random() * WORDS.length);
+ return WORDS[idx];
+}
+// Helper: update word display
+function updateWordDisplay() {
+ var s = '';
+ for (var i = 0; i < revealed.length; ++i) {
+ s += revealed[i] ? currentWord[i] : '_';
+ if (i < revealed.length - 1) s += ' ';
+ }
+ wordDisplay.setText(s);
+}
+// Helper: update win/loss text
+function updateScoreDisplay() {
+ winTxt.setText('Wins: ' + winCount);
+ lossTxt.setText('Losses: ' + lossCount);
+}
+// Start a new game
+function startGame() {
+ // Remove old letter buttons
+ for (var i = 0; i < letterButtons.length; ++i) {
+ letterButtons[i].destroy();
+ }
+ letterButtons = [];
+ guessedLetters = [];
+ wrongGuesses = 0;
+ // Pick word
+ currentWord = pickWord();
+ revealed = [];
+ for (var i = 0; i < currentWord.length; ++i) {
+ revealed.push(false);
+ }
+ // Update word display
+ updateWordDisplay();
+ // Reset hangman
+ hangmanDrawing.reset();
+ // Create letter buttons (A-Z, 7 per row)
+ var cols = 7;
+ var rows = Math.ceil(alphabet.length / cols);
+ var btnSize = 120;
+ var spacing = 30;
+ var gridWidth = cols * btnSize + (cols - 1) * spacing;
+ var startX = (2048 - gridWidth) / 2 + btnSize / 2;
+ var startY = letterGridY;
+ for (var i = 0; i < alphabet.length; ++i) {
+ var btn = new LetterButton();
+ btn.setLetter(alphabet[i]);
+ // Position in grid
+ var col = i % cols;
+ var row = Math.floor(i / cols);
+ btn.x = startX + col * (btnSize + spacing);
+ btn.y = startY + row * (btnSize + spacing);
+ // Letter select handler
+ btn.onSelect = onLetterSelected;
+ game.addChild(btn);
+ letterButtons.push(btn);
+ }
+}
+// Letter selected handler
+function onLetterSelected(letter, btn) {
+ // Mark as used
+ btn.setUsed();
+ guessedLetters.push(letter);
+ // Check if letter is in word
+ var found = false;
+ for (var i = 0; i < currentWord.length; ++i) {
+ if (currentWord[i] === letter) {
+ revealed[i] = true;
+ found = true;
+ }
+ }
+ updateWordDisplay();
+ if (found) {
+ // Check win
+ var allRevealed = true;
+ for (var i = 0; i < revealed.length; ++i) {
+ if (!revealed[i]) {
+ allRevealed = false;
+ break;
+ }
+ }
+ if (allRevealed) {
+ winCount += 1;
+ updateScoreDisplay();
+ LK.effects.flashScreen(0x00ff00, 800);
+ LK.showYouWin();
+ }
+ } else {
+ // Wrong guess
+ wrongGuesses += 1;
+ hangmanDrawing.showParts(wrongGuesses);
+ if (wrongGuesses >= maxWrong) {
+ lossCount += 1;
+ updateScoreDisplay();
+ LK.effects.flashScreen(0xff0000, 800);
+ // Reveal word
+ for (var i = 0; i < revealed.length; ++i) {
+ revealed[i] = true;
+ }
+ updateWordDisplay();
+ LK.showGameOver();
+ }
+ }
+}
+// Create hangman drawing
+hangmanDrawing = new HangmanDrawing();
+hangmanDrawing.x = hangmanX;
+hangmanDrawing.y = hangmanY;
+game.addChild(hangmanDrawing);
+// Create word display
+wordDisplay = new Text2('', {
+ size: 140,
+ fill: '#ffffff'
+});
+wordDisplay.anchor.set(0.5, 0.5);
+wordDisplay.x = 2048 / 2;
+wordDisplay.y = wordY;
+game.addChild(wordDisplay);
+// Start first game
+startGame();
+// On game reset, start a new game
+game.on('reset', function () {
+ startGame();
});
\ No newline at end of file