I have a game where you have to guess which of the 3 pots has the gold behind it. I want it so that every time a user clicks a pot, it randomises the pots and allows the user to choose again but the gold has moved to possibly another place but possibly the same as it will be randomised.
我有一个游戏,你必须猜测3个底池中哪一个有金币。我想要它,以便每次用户点击一个底池时,它随机化底池并允许用户再次选择,但是黄金已经移动到可能的另一个地方,但可能与随机化相同。
This the HTML that I have at the moment:
这是我目前的HTML:
<div id="content">
<center>
<p>Lives: <span id="lives"></span></p>
<p>Score: <span id="score"></span></p>
<p id="game_status"></p>
<p>
<img id="pot1" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot" onclick="clickMeIDFunction('pot1')">
<img id="pot2" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot" onclick="clickMeIDFunction2('pot2')">
<img id="pot3" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot" onclick="clickMeIDFunction3('pot3')">
</p>
Javascript:
var pots = new Array("nope.gif","nope.gif","gold-bar-icon.png");
function shuffle(pots){
for(swaps=0; swaps<3; swaps++){
shuffle1=Math.floor(Math.random()*pots.length);
shuffle2=Math.floor(Math.random()*pots.length);
temp=pots[shuffle1];
pots[shuffle1]=pots[shuffle2];
pots[shuffle2]=temp;
}
}
lives=3;
score=0;
function refreshGame(){
for(var i = 1 ; i<=3 ; i++){
document.getElementById('pot'+i).src="imageedit_2_3920956067.gif";
}
}
function clickMeIDFunction(theElementID){
var theElement = document.getElementById(theElementID);
theElement.src = "nope.gif";
lives--;
setTimeout(refreshGame,1000);
update_game_info()
}
function clickMeIDFunction2(theElementID){
var theElement = document.getElementById(theElementID);
theElement.src = 'nope.gif';
lives--;
setTimeout(refreshGame,1000);
update_game_info()
}
function clickMeIDFunction3(theElementID){
var theElement = document.getElementById(theElementID);
theElement.src = "gold-bar-icon.png";
score++;
setTimeout(refreshGame,1000);
update_game_info();
}
function update_game_info(){
document.getElementById("lives").innerHTML = lives;
document.getElementById("score").innerHTML = score;
if (lives == 0){
document.getElementById("game_status").innerHTML = "Game Over!";
}
}
update_game_info();
2 个解决方案
#1
Well, I guess you could make it a bit easier to modify afterwards, and to keep it more together, as a complete game.
好吧,我想你可以让事后更容易修改,并将它保持在一起,作为一个完整的游戏。
I believe you could make it yourself lots easier by only randomizing a nr, and then checking if the random nr corresponds with the image being clicked.
我相信你可以通过随机化一个nr然后检查随机nr是否与被点击的图像相对应来让自己变得更容易。
By separating the functions that need do the different aspects of your game, a reset and start method can easily be implemented.
通过分离需要执行游戏不同方面的功能,可以轻松实现重置和启动方法。
The nr of pots that are available are dynamically created, as well as the lives and the points given per correct guess and miss, which images you wish to use, and where the elements should be placed. The game is currently run when the window gets loaded :)
可用的nr个罐子是动态创建的,以及每个正确的猜测和未命中给出的生命和点数,您希望使用哪些图像以及应该放置元素的位置。当窗口加载时,游戏当前正在运行:)
var game = (function() {
function Game(options) {
this.options = options;
this.imageSet = options.imageSet;
this.waiting = false;
// sets the current pot of Gold (0 >= nr < this.options.totalPots)
this.setPotOfGold = function() {
this.currentPot = parseInt(Math.random() * this.options.totalPots);
};
this.createPots = function() {
var el = document.getElementById(this.options.gameTargets.playfield),
i,
len,
img;
if (el) {
for (i = 0, len = this.options.totalPots; i < len; i++) {
// show the cards, with the guess card on top
img = document.createElement('img');
img.addEventListener('click', this.guessImage.bind(this, i));
img.src = this.imageSet.turn;
img.id = 'picture-' + i;
el.appendChild(img);
}
}
};
this.correctGuess = function() {
var that = this;
this.score += this.options.pointsPerHit;
this.showMessage('Correct guess, next round is coming!');
setTimeout(function() {
that.reset();
}, 2500);
return this.imageSet.correct;
};
this.wrongGuess = function() {
var that = this;
this.score += this.options.pointsPerMiss;
this.lives--;
console.log(this.lives);
if (this.lives < 0) {
this.showMessage('Game over! The game will automatically restart!');
setTimeout(function() {
that.lives = that.options.maxLives;
that.score = 0;
that.reset();
}, 2500);
}
return this.imageSet.incorrect;
};
this.showMessage = function(message) {
var el = document.getElementById('message-container');
if (!el) {
el = document.createElement('div');
el.id = 'message-container';
document.body.appendChild(el);
}
el.className = 'message';
el.innerHTML = message;
this.waiting = true;
};
this.hideMessage = function(message) {
var el = document.getElementById('message-container');
if (el) {
el.className = 'hidden';
}
this.waiting = false;
};
this.guessImage = function(index) {
var real_image, el = document.getElementById('picture-' + index);
if (this.waiting || el.src !== this.imageSet.turn) {
// already clicked that one
return;
}
if (this.currentPot === index) {
real_image = this.correctGuess();
} else {
real_image = this.wrongGuess();
}
el.src = real_image;
this.setScoreboard();
};
this.init = function() {
// reset score stuff
this.lives = this.options.maxLives;
this.score = 0;
// initialize
this.createPots();
// reset (that sets the initial pot of gold and returns the src's)
this.reset();
};
this.setScoreboard = function () {
var lblLives = document.getElementById(this.options.gameTargets.lives),
lblScore = document.getElementById(this.options.gameTargets.score);
console.log('setScoreBoard');
lblLives.innerHTML = this.lives;
lblScore.innerHTML = this.score;
};
this.reset = function() {
this.hideMessage();
this.setPotOfGold();
var el = document.getElementById(this.options.gameTargets.playfield),
i, len, img;
if (el) {
for (i = 0, len = this.options.totalPots; i < len; i++) {
img = document.getElementById('picture-' + i);
img.src = this.imageSet.turn;
}
}
this.setScoreboard();
};
}
function resetGame() {
if (typeof game.current === 'undefined') {
// first run of the game, no game defined yet...
game.current = new Game({
gameTargets: {
playfield: 'game-container',
lives: 'lblLives',
score: 'lblScore'
},
maxLives: 5,
pointsPerMiss: -5,
pointsPerHit: 10,
totalPots: 5,
imageSet: {
correct: 'http://www.moonbattery.com/archives/pot_of_gold.jpg',
incorrect: 'http://www.boosshing.co.uk/images/news/2026679582-Boossh-Noodles.jpg',
turn: 'http://blog.payonomy.com/wp-content/uploads/2013/09/Question-Mark.png'
}
});
game.current.init();
} else {
game.current.reset();
}
}
window.game = {
reset: resetGame
};
return game;
}());
window.addEventListener('load', game.reset);
.hidden {
display: none;
visibility: hidden;
}
.scoreboard {
border: solid #a0a0a0 1px;
box-shadow: red 2px 2px;
background-color: #666666;
}
.scoreboard .label {
color: #ffffff;
font-weight: bold;
}
.scoreboard .value {
background-color: #efefef;
color: #000000;
text-align: right;
}
.scoreboard td {
padding: 5px;
}
.container {
border: solid #a0a0a0 1px;
padding: 15px;
}
.message
{
position: absolute;
display: block;
width: 240px;
left: 50%;
margin-left: -120px;
background-color: #efefef;
color: #000000;
text-align: center;
padding: 5px;
top: 100px;
z-index: 10;
}
.container img
{
width: 120px; height: 120px;
}
.container img:hover
{
cursor: pointer;
}
<div id="game-scoreboard" class="scoreboard">
<table>
<tr>
<td class="label">Lives:</td>
<td class="value"><span id="lblLives">0</span>
</td>
<td class="label">Score:</td>
<td class="value"><span id="lblScore">0</span>
</td>
</tr>
</table>
</div>
<div id="game-container" class="container">
</div>
#2
It seems to be working for me. It's not a perfect shuffle algorithm, but it does rearrange the items in the pots
array. If you want an ideal shuffle algorithm, take a look at Fisher-Yates. You don't seem to be calling your function anywhere, however. Add a shuffle(pots)
call to wherever you want the randomization to happen, either refresh_game_info
or update_game_info
or both.
它似乎对我有用。它不是一个完美的shuffle算法,但它确实重新排列了pots数组中的项目。如果你想要一个理想的shuffle算法,请看看Fisher-Yates。但是,您似乎没有在任何地方调用您的函数。将shuffle(pots)调用添加到您希望随机化发生的任何位置(refresh_game_info或update_game_info或两者)。
That takes care of the array, but that's not yet connected to the images in the DOM or how they decide which pot has been selected and whether there's gold behind it or not. You could make your shuffle algorithm rearrange the pots elements, which could look fancy if you want to animate it. The simpler thing to do is to unite the onclick methods and use the ID of the clicked element.
这需要处理数组,但是还没有连接到DOM中的图像,或者它们如何决定选择哪个底池以及它背后是否有金币。你可以让你的shuffle算法重新排列pot元素,如果你想要动画它可能看起来很花哨。更简单的方法是联合onclick方法并使用被点击元素的ID。
<img id="pot1" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot"
onclick="potClicked(this)">
<img id="pot2" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot"
onclick="potClicked(this)">
<img id="pot3" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot"
onclick="potClicked(this)">
In this code, referencing this
to the onclick
handler passes the DOM element itself into the potClicked
function. Then you can get rid of the three onclick
functions you have in your code and do the logic in a single method.
在此代码中,将此引用到onclick处理程序会将DOM元素本身传递给potClicked函数。然后,您可以摆脱代码中的三个onclick函数,并在单个方法中执行逻辑。
function potClicked(theElement){
// This is error prone! Only works with elements that have an ID conforming
// to "pot#": starts with 3 letters followed by 1 digit number.
// Use smarter function if you have different or longer IDs.
var id = parseInt(theElement.id.substr(3,1));
var image = pots[id];
if(image == "nope.gif") {
// Guessed wrong
lives--;
} else {
// Guessed right
score++;
}
theElement.src = image;
lives--;
setTimeout(refreshGame,1000);
update_game_info()
}
And that should just about wrap it up.
这应该就是把它包起来。
#1
Well, I guess you could make it a bit easier to modify afterwards, and to keep it more together, as a complete game.
好吧,我想你可以让事后更容易修改,并将它保持在一起,作为一个完整的游戏。
I believe you could make it yourself lots easier by only randomizing a nr, and then checking if the random nr corresponds with the image being clicked.
我相信你可以通过随机化一个nr然后检查随机nr是否与被点击的图像相对应来让自己变得更容易。
By separating the functions that need do the different aspects of your game, a reset and start method can easily be implemented.
通过分离需要执行游戏不同方面的功能,可以轻松实现重置和启动方法。
The nr of pots that are available are dynamically created, as well as the lives and the points given per correct guess and miss, which images you wish to use, and where the elements should be placed. The game is currently run when the window gets loaded :)
可用的nr个罐子是动态创建的,以及每个正确的猜测和未命中给出的生命和点数,您希望使用哪些图像以及应该放置元素的位置。当窗口加载时,游戏当前正在运行:)
var game = (function() {
function Game(options) {
this.options = options;
this.imageSet = options.imageSet;
this.waiting = false;
// sets the current pot of Gold (0 >= nr < this.options.totalPots)
this.setPotOfGold = function() {
this.currentPot = parseInt(Math.random() * this.options.totalPots);
};
this.createPots = function() {
var el = document.getElementById(this.options.gameTargets.playfield),
i,
len,
img;
if (el) {
for (i = 0, len = this.options.totalPots; i < len; i++) {
// show the cards, with the guess card on top
img = document.createElement('img');
img.addEventListener('click', this.guessImage.bind(this, i));
img.src = this.imageSet.turn;
img.id = 'picture-' + i;
el.appendChild(img);
}
}
};
this.correctGuess = function() {
var that = this;
this.score += this.options.pointsPerHit;
this.showMessage('Correct guess, next round is coming!');
setTimeout(function() {
that.reset();
}, 2500);
return this.imageSet.correct;
};
this.wrongGuess = function() {
var that = this;
this.score += this.options.pointsPerMiss;
this.lives--;
console.log(this.lives);
if (this.lives < 0) {
this.showMessage('Game over! The game will automatically restart!');
setTimeout(function() {
that.lives = that.options.maxLives;
that.score = 0;
that.reset();
}, 2500);
}
return this.imageSet.incorrect;
};
this.showMessage = function(message) {
var el = document.getElementById('message-container');
if (!el) {
el = document.createElement('div');
el.id = 'message-container';
document.body.appendChild(el);
}
el.className = 'message';
el.innerHTML = message;
this.waiting = true;
};
this.hideMessage = function(message) {
var el = document.getElementById('message-container');
if (el) {
el.className = 'hidden';
}
this.waiting = false;
};
this.guessImage = function(index) {
var real_image, el = document.getElementById('picture-' + index);
if (this.waiting || el.src !== this.imageSet.turn) {
// already clicked that one
return;
}
if (this.currentPot === index) {
real_image = this.correctGuess();
} else {
real_image = this.wrongGuess();
}
el.src = real_image;
this.setScoreboard();
};
this.init = function() {
// reset score stuff
this.lives = this.options.maxLives;
this.score = 0;
// initialize
this.createPots();
// reset (that sets the initial pot of gold and returns the src's)
this.reset();
};
this.setScoreboard = function () {
var lblLives = document.getElementById(this.options.gameTargets.lives),
lblScore = document.getElementById(this.options.gameTargets.score);
console.log('setScoreBoard');
lblLives.innerHTML = this.lives;
lblScore.innerHTML = this.score;
};
this.reset = function() {
this.hideMessage();
this.setPotOfGold();
var el = document.getElementById(this.options.gameTargets.playfield),
i, len, img;
if (el) {
for (i = 0, len = this.options.totalPots; i < len; i++) {
img = document.getElementById('picture-' + i);
img.src = this.imageSet.turn;
}
}
this.setScoreboard();
};
}
function resetGame() {
if (typeof game.current === 'undefined') {
// first run of the game, no game defined yet...
game.current = new Game({
gameTargets: {
playfield: 'game-container',
lives: 'lblLives',
score: 'lblScore'
},
maxLives: 5,
pointsPerMiss: -5,
pointsPerHit: 10,
totalPots: 5,
imageSet: {
correct: 'http://www.moonbattery.com/archives/pot_of_gold.jpg',
incorrect: 'http://www.boosshing.co.uk/images/news/2026679582-Boossh-Noodles.jpg',
turn: 'http://blog.payonomy.com/wp-content/uploads/2013/09/Question-Mark.png'
}
});
game.current.init();
} else {
game.current.reset();
}
}
window.game = {
reset: resetGame
};
return game;
}());
window.addEventListener('load', game.reset);
.hidden {
display: none;
visibility: hidden;
}
.scoreboard {
border: solid #a0a0a0 1px;
box-shadow: red 2px 2px;
background-color: #666666;
}
.scoreboard .label {
color: #ffffff;
font-weight: bold;
}
.scoreboard .value {
background-color: #efefef;
color: #000000;
text-align: right;
}
.scoreboard td {
padding: 5px;
}
.container {
border: solid #a0a0a0 1px;
padding: 15px;
}
.message
{
position: absolute;
display: block;
width: 240px;
left: 50%;
margin-left: -120px;
background-color: #efefef;
color: #000000;
text-align: center;
padding: 5px;
top: 100px;
z-index: 10;
}
.container img
{
width: 120px; height: 120px;
}
.container img:hover
{
cursor: pointer;
}
<div id="game-scoreboard" class="scoreboard">
<table>
<tr>
<td class="label">Lives:</td>
<td class="value"><span id="lblLives">0</span>
</td>
<td class="label">Score:</td>
<td class="value"><span id="lblScore">0</span>
</td>
</tr>
</table>
</div>
<div id="game-container" class="container">
</div>
#2
It seems to be working for me. It's not a perfect shuffle algorithm, but it does rearrange the items in the pots
array. If you want an ideal shuffle algorithm, take a look at Fisher-Yates. You don't seem to be calling your function anywhere, however. Add a shuffle(pots)
call to wherever you want the randomization to happen, either refresh_game_info
or update_game_info
or both.
它似乎对我有用。它不是一个完美的shuffle算法,但它确实重新排列了pots数组中的项目。如果你想要一个理想的shuffle算法,请看看Fisher-Yates。但是,您似乎没有在任何地方调用您的函数。将shuffle(pots)调用添加到您希望随机化发生的任何位置(refresh_game_info或update_game_info或两者)。
That takes care of the array, but that's not yet connected to the images in the DOM or how they decide which pot has been selected and whether there's gold behind it or not. You could make your shuffle algorithm rearrange the pots elements, which could look fancy if you want to animate it. The simpler thing to do is to unite the onclick methods and use the ID of the clicked element.
这需要处理数组,但是还没有连接到DOM中的图像,或者它们如何决定选择哪个底池以及它背后是否有金币。你可以让你的shuffle算法重新排列pot元素,如果你想要动画它可能看起来很花哨。更简单的方法是联合onclick方法并使用被点击元素的ID。
<img id="pot1" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot"
onclick="potClicked(this)">
<img id="pot2" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot"
onclick="potClicked(this)">
<img id="pot3" src="imageedit_2_3920956067.gif" width="238" height="170" class="pot"
onclick="potClicked(this)">
In this code, referencing this
to the onclick
handler passes the DOM element itself into the potClicked
function. Then you can get rid of the three onclick
functions you have in your code and do the logic in a single method.
在此代码中,将此引用到onclick处理程序会将DOM元素本身传递给potClicked函数。然后,您可以摆脱代码中的三个onclick函数,并在单个方法中执行逻辑。
function potClicked(theElement){
// This is error prone! Only works with elements that have an ID conforming
// to "pot#": starts with 3 letters followed by 1 digit number.
// Use smarter function if you have different or longer IDs.
var id = parseInt(theElement.id.substr(3,1));
var image = pots[id];
if(image == "nope.gif") {
// Guessed wrong
lives--;
} else {
// Guessed right
score++;
}
theElement.src = image;
lives--;
setTimeout(refreshGame,1000);
update_game_info()
}
And that should just about wrap it up.
这应该就是把它包起来。