I'm trying to recreate my own version of FlappyBird. You can see my game here: http://ps11.pstcc.edu/~c2375a22/lab6/lab6.html
The only problem that I've encountered is that none of my "blocks" are showing up. If you have never played FlappyBird, the blocks are objects that you must avoid in order to keep progressing throughout the game. If you touch a block, you lose.
My player controls are working and the collision system seems to be fine as well. Any ideas?
This is my code:
$(function () {
alert("Welcome to Space Dodge!"
+ "\n\nNavigate your vessel through the unknown for as long as you can!"
+ "\n\nUse 'Spacebar' to control the ship."
+ "\n\nIf the ship hits a block, the top, or the bottom, you lose!")
//Game variables
var game_area = $('#game_area');
var ship = $('#ship');
var block = $('.block');
var block1 = $('#block1');
var block2 = $('#block2');
var score = $('#score');
var restart_button = $('#restart_button');
//Set up variables
var game_width = parseInt(game_area.width());
var game_height = parseInt(game_area.height());
var block_initial_position = parseInt(block.css('right'));
var block_initial_height = parseInt(block.css('height'));
var ship_left = parseInt(ship.css('left'));
var ship_height = parseInt(ship.height());
//Starting speed - this will increase by +1 every time the player goes through a checkpoint
var speed = 10;
var go_up = false;
var update_score = false;
var game_over = false;
var the_game = setInterval(function () {
if (collision(ship, block1) || collision(ship, block2) || parseInt(ship.css('top')) <= 0 || parseInt(ship.css('top')) > game_height - ship_height) {
end_game();
alert("Game Over! \n\nClick 'Restart' to play again. ")
} else {
var block_current_position = parseInt(block.css('right'));
//Update the score when the poles have passed the bird successfully
if (block_current_position > game_width - ship_left) {
if (score_updated === false) {
score.text(parseInt(score.text()) + 1);
score_updated = true;
}
}
//Check whether the poles went out of the container
if (block_current_position > game_width) {
var new_height = parseInt(Math.random() * 100);
//Change the pole's height
block1.css('height', block_initial_height + new_height);
block2.css('height', block_initial_height - new_height);
//Increase speed,
speed = speed + 1;
score_updated = false;
pole_current_position = pole_initial_position;
}
//Move blocks
block.css('right', block_current_position + speed);
if (go_up === false) {
go_down();
}
}
}, 40);
//Determine collison domains
function collision($div1, $div2) {
//First set of axis
var x1 = $div1.offset().left;
var y1 = $div1.offset().top;
var h1 = $div1.outerHeight(true);
var w1 = $div1.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
//Second set of axis
var x2 = $div2.offset().left;
var y2 = $div2.offset().top;
var h2 = $div2.outerHeight(true);
var w2 = $div2.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// If the ship meets this condition, collision is false
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
return true;
}
function go_down() {
ship.css('top', parseInt(ship.css('top')) + 5);
}
function up() {
ship.css('top', parseInt(ship.css('top')) - 10);
}
function end_game() {
clearInterval(the_game);
game_over = true;
}
$(document).on('keydown', function (e) {
var key = e.keyCode;
if (key === 32 && go_up === false && game_over === false) {
go_up = setInterval(up, 50);
}
});
$(document).on('keyup', function (e) {
var key = e.keyCode;
if (key === 32) {
clearInterval(go_up);
go_up = false;
}
});
//Reload the page and reset the game
restart_button.click(function () {
location.reload();
});
});
body {
height: 100%;
width: 100%;
margin: 0;
background-color: black;
}
#game_area {
position: relative;
height: 400px;
width: 90%;
border: 2px solid chartreuse;
background-color: black;
margin-top: 4%;
margin-bottom: 4%;
margin-left: 4%;
overflow: hidden;
}
#ship {
position: absolute;
background: url('ship.png');
height: 42px;
width: 65px;
background-size: contain;
background-repeat: no-repeat;
top: 20%;
left: 15%;
}
.block {
position: absolute;
height: 130px;
width: 50px;
background-color: chartreuse;
right: -50px;
}
#block1 {
top: 0;
}
#block2 {
bottom: 0;
}
#score_area {
text-align: center;
font-size: 40px;
color: chartreuse;
}
<body>
<!-- Game area on the page -->
<div class="container" id="game_area">
<div id="ship"></div>
<div id="block1"></div>
<div id="block2"></div>
</div>
<!-- Score section -->
<div class="container" id="score_area">
<P>Score: <span id="score">0</span></P>
</div>
<!-- Restart button -->
<div class="container" id="restart_area">
<center><button type="button" class="btn btn-primary"
id="restart_button">Restart</button></center>
</div>
<!-- Game script -->
<script src="lab6_game.js"></script>
</body>
</html>
Add the class block to... blocks :p
<div id="block1" class="block"></div>
<div id="block2" class="block"></div>
Instead of
<div id="block1" ></div>
<div id="block2" ></div>
Related
I am currently constructing a roulette system programme ( this is more to keep me from betting than to bet! ) and am just doing the basic framework but already hit a problem with the main window '#results' not scrolling when it is filled with the results. The scroll needs to follow the latest line of content so the latest returned from the input in the modal box is always showing at the bottom. I have spent hours on lots of possible solutions to no avail.
Here is the code: ( i apologise for the length of the full script )
<!DOCTYPE html>
<html>
<body>
<div id="results">
</div>
<div id="modal">
<div id="modal-content">
<p>Select a number between 0 and 36:</p>
<div id="numberButtons"></div>
<button id="close-button" onclick="closeModal()">Close</button>
</div>
</div>
</div>
<style>
/* The modal background */
#modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
}
/* The modal content */
#modal-content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #fefefe;
padding: 20px;
width: 18%;
border: 3px solid black;
}
/* The close button */
#close-button {
display: block;
margin: 0 auto;
}
#numberButtons button {
color: white;
width: 50px;
height: 50px;
font-size:30px;
font-weight:600;
}
#modal.inactive{
opacity: 0.2;
}
</style>
<script>
var bankRoll = parseFloat(prompt("Please enter your starting bankroll:"));
if(isNaN(bankRoll)){
bankRoll = parseFloat(prompt("Invalid input. Please enter a valid number for your starting bankroll:"));
}
bankRoll = bankRoll.toFixed(2);
var spinNumber=0;
var backline="";
var isDragging = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;
const modalContent = document.querySelector("#modal-content");
modalContent.addEventListener("mousedown", dragStart);
modalContent.addEventListener("mouseup", dragEnd);
modalContent.addEventListener("mousemove", drag);
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
if (e.target === modalContent) {
isDragging = true;
}
}
let inactivityTimeout;
function dragEnd(e) {
initialX = currentX;
initialY = currentY;
isDragging = false;
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(() => {
modal.classList.add("inactive")
}, 15000)
}
function drag(e) {
if (e.buttons === 1) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, modalContent);
clearTimeout(inactivityTimeout);
modal.classList.remove("inactive")
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
function getNumberType(number) {
if (number === 0) {
return "green";
} else if (number % 2 === 0) {
return "even";
} else {
return "odd";
}
}
function roulette(number) {
// Determine the color of the number
var color;
if (number === 0) {
color = "Green";
} else if (number === 1 || number === 3 || number === 5 || number === 7 || number === 9 || number === 12 || number === 14 || number === 16 || number === 18 || number === 19 || number === 21 || number === 23 || number === 25 || number === 27 || number === 30 || number === 32 || number === 34 || number === 36) {
color = "Red";
} else {
color = "Black";
}
// Map the color names to CSS color values
if (color === "Green") {
return "rgb(0, 128, 0)";
} else if (color === "Red") {
return "rgb(255, 0, 0)";
} else {
return "rgb(0, 0, 0)";
}
}
function backgroundline() {
if (spinNumber % 2 === 0) {
backline="#D3D3D3"
} else {
backline="#E5E4E2";
}
}
function spin(number) {
// Determine the color of the number
var color = roulette(number);
spinNumber= spinNumber+1;
bankRoll=bankRoll-10;
backgroundline();
// Display the result
var resultsDiv = document.getElementById("results");
var resultHTML = `${number}`;
resultHTML = `<div style="padding:10px 0; background: ${backline};vertical-align:middle;margin-bottom:- 20px;">
<div style="padding:5px; display: inline-block; background: yellow; color:black;vertical-align:middle; width:30px; text-align:right;">${spinNumber}</div>
<div style="margin: 0 10px; display:inline-block; width: 70px; text-align:center;vertical-align:middle">£ ${bankRoll}</div>
<div style="color: white; padding: 5px; display: inline-block; width:30px; padding-top:15px;vertical-align:middle; font-size: 25px; font-weight:600; height:30px; text-align:center; background-color: ${color}; ">${resultHTML}</div>
</div>
<br style="height:0px;"/>`;
resultsDiv.innerHTML += resultHTML;
}
// Set up the buttons
for (let i = 0; i <= 36; i++) {
let button = document.createElement("button");
button.innerHTML = i;
button.style.backgroundColor = roulette(i);
button.addEventListener("click", function() {
spin(i);
});
document.getElementById("numberButtons").appendChild(button);
}
function closeModal() {
// Get the modal element
var modal = document.getElementById("modal");
// Remove the modal element from the DOM
modal.remove();
}
</script>
</body>
</html>
I have tried lots of solutions on Stack Overflow and across the Internet further field that I thought might work but it just doesn't seem to want to do it.
after adding element in Results div you have to call this function.
add this function
window.scrollTo(0, document.body.scrollHeight)
after this line
resultsDiv.innerHTML += resultHTML;
I have this little block that I move around using javascript code. It works all good except if I keep moving it, it can easily get out of the box where it is supposed to be.
Can I prevent this somehow? So no matter how far I want to move it, it will stay stuck inside of the container/box ?
Here's my snippet code:
/// store key codes and currently pressed ones
var keys = {};
keys.UP = 38;
keys.LEFT = 37;
keys.RIGHT = 39;
keys.DOWN = 40;
/// store reference to character's position and element
var character = {
x: 100,
y: 100,
speedMultiplier: 2,
element: document.getElementById("character")
};
var is_colliding = function(div1, div2) {
var d1_height = div1.offsetHeight;
var d1_width = div1.offsetWidth;
var d1_distance_from_top = div1.offsetTop + d1_height;
var d1_distance_from_left = div1.offsetLeft + d1_width;
var d2_height = div2.offsetHeight;
var d2_width = div2.offsetWidth;
var d2_distance_from_top = div2.offsetTop + d2_height;
var d2_distance_from_left = div2.offsetLeft + d2_width;
var not_colliding =
d1_distance_from_top <= div2.offsetTop ||
div1.offsetTop >= d2_distance_from_top ||
d1_distance_from_left <= div2.offsetTop ||
div1.offsetLeft >= d2_distance_from_left;
return !not_colliding;
};
/// key detection (better to use addEventListener, but this will do)
document.body.onkeyup =
document.body.onkeydown = function(e){
if (e.preventDefault) {
e.preventDefault();
}
else {
e.returnValue = false;
}
var kc = e.keyCode || e.which;
keys[kc] = e.type == 'keydown';
};
/// character movement update
var moveCharacter = function(dx, dy){
character.x += (dx||0) * character.speedMultiplier;
character.y += (dy||0) * character.speedMultiplier;
character.element.style.left = character.x + 'px';
character.element.style.top = character.y + 'px';
};
/// character control
var detectCharacterMovement = function(){
if ( keys[keys.LEFT] ) {
moveCharacter(-5, 0);
}
if ( keys[keys.RIGHT] ) {
moveCharacter(5, 0);
}
if ( keys[keys.UP] ) {
moveCharacter(0, -5);
}
if ( keys[keys.DOWN] ) {
moveCharacter(0, 5);
}
};
/// update current position on screen
moveCharacter();
/// game loop
setInterval(function(){
detectCharacterMovement();
}, 1000/24);
body{
display: flex;
justify-content: center;
align-items: center;
}
#character {
position: absolute;
width: 42px;
height: 42px;
background: red;
z-index:99;
}
#container{
width: 400px;
height: 400px;
background: transparent;
border:5px solid rgb(0, 0, 0);
position: relative;
overflow: hidden;
}
<div id="container">
<div id="character"></div>
</div>
PS: You can move the box using keyboard arrows.
Get the container width and height into variable and set a condition on your move
var moveCharacter = function(dx, dy){
let div_width = document.getElementById('container').clientWidth;
let div_height = document.getElementById('container').clientHeight;
if((div_width - character.x) < 50 ){ // 50 = width of character and padding
character.x = div_width - 50;
}
if(character.x < 10){ // Padding
character.x = 11;
}
if((div_height - character.y) < 50 ){
character.y = div_height - 50;
}
if(character.y < 10){
character.y = 11;
}
When the right arrow key is pressed I would like to increment the left position of a div by 10px using the style property. Here is my script and what I've tried so far:
document.onkeydown = KeyPressed;
function KeyPressed(k) {
var LeftBtn = 37;
var RightBtn = 39;
var UpBtn = 38;
var DownBtn = 40;
if (k.keyCode == RightBtn) {
document.getElementById("test").style.left = document.getElementById("test").style.left + 10px;
}
}
#test {
position: relative;
left: 0px;
width: 25px;
height: 80px;
background-color: black;
}
<div id="test"></div>
The style property of a DOM element is essentially a dictionary with string key-value pairs. It expects a CSS key, and a proper string value.
Your current code comes out as left: 10px10px and that doesn't make much sense for CSS.
In order for this to work, you'd have to regard the px.
document.onkeydown = KeyPressed;
function KeyPressed(k) {
var LeftBtn = 37;
var RightBtn = 39;
var UpBtn = 38;
var DownBtn = 40;
if (k.keyCode == RightBtn) {
var moveEl = document.getElementById("test"),
currLeft = parseInt(moveEl.style.left || 0);
moveEl.style.left = (currLeft + 10) + 'px';
}
}
#test {
position: relative;
left: 0px;
width: 25px;
height: 80px;
background-color: black;
}
<div id="test"></div>
Further reading and examples - HTMLElement.style
Remove px from 10.
if (k.keyCode == RightBtn) {
document.getElementById("test").style.left = document.getElementById("test").style.left + 10;
}
Try following way:
document.onkeydown = KeyPressed;
function KeyPressed(k) {
var LeftBtn = 37;
var RightBtn = 39;
var UpBtn = 38;
var DownBtn = 40;
if(k.keyCode == RightBtn) {
document.getElementById("test").style.left = parseInt(document.getElementById("test").style.left || 0) + 10 + 'px';
}
}
I've created a snake game, and when the snake hit the wall or itself, it still wont stop moving. I figured out if I used the clearTimeout(), it would help. but it didn't.
Is there a way to stop the loop? or it is another issue?
jQuery(document).ready(function($) {
init();
});
var move;
function init() {
board.initBoard();
drawSnake();
food.createFood();
}
function play() {
$('.newGame').css('visibility', 'hidden');
$('.playgame').css('visibility', 'hidden');
moveSnake();
getSnakeDir();
}
function gameover() {
clearTimeout(move);
$('.newGame').css('visibility', 'visible');
}
function playGame() {
$('#gameboard').empty();
$('.newGame').hide();
init();
play();
}
var board = {
DIM: 20,
initBoard: function() {
for (var i = 0; i < board.DIM; i++) {
var row = $('<div class="row-' + i + '"></div>');
for (var j = 0; j < board.DIM; j++) {
var col = ('<div class="col-' + j + '-' + i + '"></div>');
$(row).append(col);
}
$("#gameboard").append(row);
}
}
}
var snake = {
position: ['10-10', '10-11', '10-12'],
direction: 'r',
speed: 200,
};
function drawSnake() {
$('.col-10-10').addClass('snake');
$('.col-11-10').addClass('snake');
}
function getSnakeDir() {
$(document).keydown(function(event) {
//event.preventDefault();
if (event.which == 38) {
snake.direction = 'u';
} else if (event.which == 39) {
snake.direction = 'r';
} else if (event.which == 40) {
snake.direction = 'd';
} else if (event.which == 37) {
snake.direction = 'l';
}
});
}
function moveSnake() {
var tail = snake.position.pop();
$('.col-' + tail).removeClass('snake');
var coords = snake.position[0].split('-');
var x = parseInt(coords[0]);
var y = parseInt(coords[1]);
if (snake.direction == 'r') {
x = x + 1;
} else if (snake.direction == 'd') {
y = y + 1;
} else if (snake.direction == 'l') {
x = x - 1;
} else if (snake.direction == 'u') {
y = y - 1;
}
var currentcoords = x + '-' + y;
snake.position.unshift(currentcoords);
$('.col-' + currentcoords).addClass('snake');
//when snake eats food
if (currentcoords == food.coords) {
console.log('true');
$('.col-' + food.coords).removeClass('food');
snake.position.push(tail);
food.createFood();
}
//game over
if (x < 0 || y < 0 || x > board.DIM || y > board.DIM) {
gameover();
}
//if snake touch itself
if (hitItself(snake.position) == true) {
gameover();
}
move=setTimeout(moveSnake, 200);
}
var food = {
coords: "",
createFood: function() {
var x = Math.floor(Math.random() * (board.DIM-1)) + 1;
var y = Math.floor(Math.random() * (board.DIM-1)) + 1;
var fruitCoords = x + '-' + y;
$('.col-' + fruitCoords).addClass('food');
food.coords = fruitCoords;
},
}
function hitItself(array) {
var valuesSoFar = Object.create(null);
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in valuesSoFar) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}
.buttonnewgame {
position: relative;
}
.newGame {
position: absolute;
top: 45%;
left: 25%;
padding: 15px;
font-size: 1em;
font-family: arial;
visibility: hidden;
}
.gameContainer{
width: 100%;
}
#gameboard {
background-color:#eee;
padding:3px;
}
.playgame {
position: absolute;
top: 45%;
left: 20%;
padding: 15px;
font-size: 1em;
font-family: arial;
}
/* styling the board */
div[class^='row'] {
height: 15px;
text-align: center;
}
div[class*='col']{
display: inline-block;
border: 1px solid grey;
width: 15px;
height: 15px;
}
/*display the snake*/
.snake {
background-color: blue;
z-index: 99;
}
.food {
background: red;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game">
<div class="buttonnewgame">
<input type="button" name="new game" value="new game" class="newGame" onclick="playGame()" />
<button class="playgame" onclick="play()">Play Game</button>
<div class="gameContainer">
<div id="gameboard">
<!-- snake game in here -->
</div>
</div>
</div>
</div>
There were a few problems, but here is the 'working version' (there are more bugs).
1) I renamed drawSnake to createSnake. You weren't fully reinitializing the snake when you called init(). The snakes position was not being reset in the previous drawSnake method, so it would seem like the game was not playable.
After that there were 2 more bugs.
2) You have to return after you call gameOver or the game never really ends does it? Once you clear the timeout in gameover, you immediately set another Timeout for on the last line of moveSnake() because you didn't return once the game was over. That lead to weird results that made it seem like the game was unresponsive.
3) You were using a combination of visibility none or visible and $.hide(). $.hide() uses display: none, so when you tried to show it again with the visibility style change, its still display: none so the new game button would stop appearing.
My advice to any game coder is to learn how to separate the code that handles how the game works (logic of the game, how the clock ticks, initialization of game state, etc) , and how it is displayed (the html and css). Modeling the game logic after a cleanly written system is easy to read and debug. The code becomes harder to understand and modify when the display code is mixed in with game logic. In theory, our game should work perfectly without any kind of rendering. Then we could write a renderer that produces an HTML canvas, html DOM, text in the command line, or OpenGL.
Heres an old project I never finished that should illustrate a separation between model and view.
http://tando.us/ganix/ganix.htm
jQuery(document).ready(function($) {
init();
});
var move;
function init() {
board.initBoard();
createSnake();
food.createFood();
}
function play() {
$('.newGame').hide();
$('.playgame').hide();
moveSnake();
getSnakeDir();
}
function gameover() {
clearTimeout(move);
$('.newGame').show();
}
function playGame() {
$('#gameboard').empty();
$('.newGame').hide();
init();
play();
}
var board = {
DIM: 20,
initBoard: function() {
for (var i = 0; i < board.DIM; i++) {
var row = $('<div class="row-' + i + '"></div>');
for (var j = 0; j < board.DIM; j++) {
var col = ('<div class="col-' + j + '-' + i + '"></div>');
$(row).append(col);
}
$("#gameboard").append(row);
}
}
}
var snake = {
position: ['10-10', '10-11', '10-12'],
direction: 'r',
speed: 200,
};
function createSnake() {
$('.col-10-10').addClass('snake');
$('.col-11-10').addClass('snake');
snake.position = ['10-10', '10-11', '10-12'];
}
function getSnakeDir() {
$(document).keydown(function(event) {
//event.preventDefault();
if (event.which == 38) {
snake.direction = 'u';
} else if (event.which == 39) {
snake.direction = 'r';
} else if (event.which == 40) {
snake.direction = 'd';
} else if (event.which == 37) {
snake.direction = 'l';
}
});
}
function moveSnake() {
var tail = snake.position.pop();
$('.col-' + tail).removeClass('snake');
var coords = snake.position[0].split('-');
var x = parseInt(coords[0]);
var y = parseInt(coords[1]);
if (snake.direction == 'r') {
x = x + 1;
} else if (snake.direction == 'd') {
y = y + 1;
} else if (snake.direction == 'l') {
x = x - 1;
} else if (snake.direction == 'u') {
y = y - 1;
}
var currentcoords = x + '-' + y;
snake.position.unshift(currentcoords);
$('.col-' + currentcoords).addClass('snake');
//when snake eats food
if (currentcoords == food.coords) {
console.log('true');
$('.col-' + food.coords).removeClass('food');
snake.position.push(tail);
food.createFood();
}
//game over
if (x < 0 || y < 0 || x > board.DIM || y > board.DIM) {
gameover();
return;
}
//if snake touch itself
if (hitItself(snake.position) == true) {
gameover();
return;
}
move=setTimeout(moveSnake, 200);
}
var food = {
coords: "",
createFood: function() {
var x = Math.floor(Math.random() * (board.DIM-1)) + 1;
var y = Math.floor(Math.random() * (board.DIM-1)) + 1;
var fruitCoords = x + '-' + y;
$('.col-' + fruitCoords).addClass('food');
food.coords = fruitCoords;
},
}
function hitItself(array) {
var valuesSoFar = Object.create(null);
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in valuesSoFar) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}
.buttonnewgame {
position: relative;
}
.newGame {
position: absolute;
top: 45%;
left: 25%;
padding: 15px;
font-size: 1em;
font-family: arial;
}
.gameContainer{
width: 100%;
}
#gameboard {
background-color:#eee;
padding:3px;
}
.playgame {
position: absolute;
top: 45%;
left: 20%;
padding: 15px;
font-size: 1em;
font-family: arial;
}
/* styling the board */
div[class^='row'] {
height: 15px;
text-align: center;
}
div[class*='col']{
display: inline-block;
border: 1px solid grey;
width: 15px;
height: 15px;
}
/*display the snake*/
.snake {
background-color: blue;
z-index: 99;
}
.food {
background: red;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game">
<div class="buttonnewgame">
<input type="button" name="new game" value="new game" class="newGame" style="display:none;" onclick="playGame()" />
<button class="playgame" onclick="play()">Play Game</button>
<div class="gameContainer">
<div id="gameboard">
<!-- snake game in here -->
</div>
</div>
</div>
You could try not to initiate a new setTimeout call at the and of the moveSnake function, but instead using.
function play() {
$('.newGame').css('visibility', 'hidden');
$('.playgame').css('visibility', 'hidden');
move = setInterval(moveSnake, 200);
getSnakeDir();
}
and remove the
move = setTimeout(moveSnake, 200)
from the moveSnake function and do
function gameover() {
clearInterval(move);
$('.newGame').css('visibility', 'visible');
}
I'm currently developing a platform little game in only js/jQuery. I have two scripts, one i currently detecting platforms and let the character go on it instead of falling. And one with a nice smooth jump. I'd like to merge them, but for some reason i just can't. When i try to do it, my character do not move anymore...
So if you have any ideas on how i could do that, it would be awesome, really.
Here are my scripts, hope you guys will find out what i can't..
//------------------ VIE -------------------------------
function CLife(iPlayerNum) {
// iPlayerNum est egal a 1 ou 2
this.propNumPlayer = iPlayerNum;
// Image pour la vie
this.ImgHeight = 30;
this.ImgWidth = 30;
this.ImgName = 'heart.png';
// Nb de vie
this.NbLife = 3;
}
CLife.prototype.Creer = function()
{
// Créer la ligne d'etoiles
var parent = document.getElementById("vie");
var child = document.createElement('div'+this.propNumPlayer);
child.setAttribute('id','div_life'+this.propNumPlayer);
if(this.propNumPlayer == 1)
{
// Joueur 1 a gauche
child.setAttribute('style','float:left; height:'+this.ImgHeight+'px; width: '+this.NbLife*this.ImgWidth+'px;');
}
else
{
// Joueur 2 a droite
child.setAttribute('style','float:right; height:'+this.ImgHeight+'px; width: '+this.NbLife*this.ImgWidth+'px;');
}
parent.appendChild(child);
// Ajouter les coeurs
parent = document.getElementById('div_life'+this.propNumPlayer);
for(var i=0; i < this.NbLife; i++)
{
child = document.createElement('img');
child.setAttribute('id','img_'+(i+1)+'_'+this.propNumPlayer);
child.setAttribute('src','img/'+this.ImgName);
child.setAttribute('width','30 px');
child.setAttribute('height','30 px');
parent.appendChild(child);
}
}
// YJoueur : ordonnée du joueur + la hauteur de l'image associee au joueur
CLife.prototype.TestFinVie = function(iYJoueur)
{
var valret = false;
console.log('Joueur : ' + iYJoueur);
console.log('Fenetre : ' + $(window).height());
//if(iYJoueur <= 10/*>= $(window).height()*/)
if(iYJoueur >= $(window).height())
{
star = document.getElementById('img_'+this.NbLife+'_'+this.propNumPlayer);
if (star != null)
{
star.style.display = 'none';
this.NbLife = this.NbLife - 1;
valret = true;
}
}
return valret;
}
//------------------ VIE -------------------------------
setInterval(bougerPersonnages, 9); //Vitesse de déplacement.
var touche = {}
var jumping = false;
var jumpingChomel = false;
var browserHeight = parseInt(document.documentElement.clientHeight);
var batmanHurt = 0;
var batmanPosX = $("#batman").offset().left;
var chomelPosX = $("#chomel").offset().left;
var tombe = false;
var life1 = new CLife(2);
var life2 = new CLife(1);
life1.Creer();
life2.Creer();
$(document).keydown(function(e) { //Fonctionne
touche[e.keyCode] = true;
});
$(document).keyup(function(e) { //Fonctionne
delete touche[e.keyCode];
});
//------INTEGRATION COLLISION DE PLATEFORME----------
//
var platforms = [];
var currentPlatform = null;
var $batman = $('#batman');
function bougerPersonnages() {
if(tombe == true)
{
// tester la fin de vie des personnages
var YPos = parseInt($("#batman").offset().top) + parseInt($("#batman").height()) + 10; // car le personnage tombe au plus bas à 10 px du bas de l'écran
if (life1.TestFinVie(YPos) == true)
{
//reinitialiser le personnage
document.getElementById('batman').setAttribute('class','dirGauche');
document.getElementById('batman').setAttribute('style','left: 1100px; bottom: 580px;');
}
YPos = parseInt($("#chomel").offset().top) + parseInt($("#chomel").height()) + 10; // car le personnage tombe au plus bas à 10 px du bas de l'écran
if (life2.TestFinVie(YPos) == true)
{
//reinitialiser le personnage
document.getElementById('chomel').setAttribute('class','dirGauche');
document.getElementById('chomel').setAttribute('style','left: 900px; bottom: 580px;');
}
tombe = false;
}
var top = $batman.offset().top;
var left = $batman.offset().left;
var newTop = top;
var newLeft = left;
for (var direction in touche) {
if (direction == 37) { //Fonctionne
batman.className = 'dirGauche';
$("#batman").css('left', '-=5px');
} else if (direction == 81) { //Fonctionne
chomel.className = 'dirGauche';
$("#chomel").css('left', '-=5px');
} else if (direction == 39) { //Fonctionne
batman.className = 'dirDroite';
$("#batman").css('left', '+=5px');
} else if (direction == 68) { //Fonctionne
chomel.className = 'dirDroite';
$("#chomel").css('left', '+=5px');
} else if (direction == 38) { //Fonctionne
if (!jumping) {
jumping = true;
$("#batman").animate({bottom: 300 + "px"}, 300);
$("#batman").animate({bottom: 10 + "px"}, 300);
setTimeout(land, 650);
}
}
else if (direction == 90) { //Fonctionne
if (!jumpingChomel) {
jumpingChomel = true;
$("#chomel").animate({bottom: 300 + "px"}, 300);
setTimeout(function() {$("#chomel").animate({bottom: 10 + "px"}, 300) }, 350);
setTimeout(landChomel, 650);
}
}
}
var batmanRect = getRectangle($("#batman"));
var chomelRect = getRectangle($("#chomel"));
$(".arrow1").each(function () {
var rect = getRectangle($(this));
if (intersectingRectangles(batmanRect, rect)) {
var batmanPosX = $("#batman").offset().left;
var chomelPosX = $("#chomel").offset().left;
console.log("batman has been shot!");
console.log("batman:" + batmanPosX);
console.log("chomel:" + chomelPosX);
console.log($(this).attr('data-arrow'));
if (batmanPosX < chomelPosX && $(this).attr('data-arrow') == "chomelShoot") {
$("#batman").animate({left: "-=50px"}, 40);
}
else if ($(this).attr('data-arrow') == "chomelShoot"){
$("#batman").animate({left: "+=50px"}, 40);
}
} else if (intersectingRectangles(chomelRect, rect)) {
var batmanPosX = $("#batman").offset().left;
var chomelPosX = $("#chomel").offset().left;
console.log("batman has been shot!");
console.log("batman:" + batmanPosX);
console.log("chomel:" + chomelPosX);
console.log($(this).attr('data-arrow'));
if (chomelPosX < batmanPosX && $(this).attr('data-arrow') == "batmanShoot") {
$("#chomel").animate({left: "-=50px"}, 40);
}
else if ($(this).attr('data-arrow') == "batmanShoot"){
$("#chomel").animate({left: "+=50px"}, 40);
}
}
});
$(".collidableRectangle").each(function () {
var rect = getRectangle($(this));
if (intersectingRectangles(batmanRect, rect)) {
console.log("BATMAN has hit a platform!");
}
});
$(".collidableRectangle").each(function () {
var rect = getRectangle($(this));
if (intersectingRectangles(chomelRect, rect)) {
console.log("CHOMEL has hit a platform!");
}
});
}
function land() {
jumping = false;
tombe = true;
}
function landChomel() {
jumpingChomel = false;
tombe = true;
}
document.addEventListener('keydown', function(e) { // Déclenche la fonction fire
switch (e.keyCode) {
case 76:
fire_batman();
break;
case 32:
fire_chomel();
break;
}
});
function fire_chomel() { //Fonctionne
var posTop = parseInt($(chomel).offset().top);
if (chomel.className == 'dirGauche') {
var posLeft = parseInt($(chomel).offset().left) - 30;
}
else {
var posLeft = parseInt($(chomel).offset().left) + 120;
}
var bullets = $('#arrow1');
var bulletElement = $('<div class="arrow1" data-arrow="chomelShoot" style="top: ' + (posTop + 14) + 'px; left: ' + posLeft + 'px"></div>');
bullets.append(bulletElement);
if (chomel.className == 'dirGauche') {
var options = {left: browserHeight * -15};
}
else {
var options = {left: browserHeight * 15};
}
ok = new Audio('sound/pistolet.mp3');
ok.play();
bulletElement.animate(options, 2000, "linear", function () {
$(this).remove();
});
}
function fire_batman() { //Fonctionne
var posTop = parseInt($(batman).offset().top) - 27;
if (batman.className == 'dirGauche') {
var posLeft = parseInt($(batman).offset().left) - 51;
}
else {
var posLeft = parseInt($(batman).offset().left) + 106;
}
var bullets = $('#arrow1');
var bulletElement = $('<div class="arrow1" data-arrow="batmanShoot" style="top: ' + (posTop + 50) + 'px; left: ' + posLeft + 'px"></div>');
bullets.append(bulletElement);
if (batman.className == 'dirGauche') {
var options = {left: browserHeight * -15};
}
else {
var options = {left: browserHeight * 15};
}
ok = new Audio('sound/pistolet.mp3');
ok.play();
bulletElement.animate(options, 2000, "linear", function () {
$(this).remove();
});
}
function intersectingRectangles(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
function getRectangle(figure) {
var rect = {};
rect.left = figure.offset().left;
rect.top = figure.offset().top;
rect.right = rect.left + figure.width();
rect.bottom = rect.top + figure.height();
return rect;
}
body {
padding: 0;
margin: 0;
background: url('http://image.noelshack.com/fichiers/2015/16/1429209179-bg.png');
background-color: #B4381F;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: 100%;
background-position: 50% 30%;
overflow: hidden;
}
#batman{
background-image:url('http://image.noelshack.com/fichiers/2015/16/1429209179-batman.png');
width:119px;
height:87px;
display:block;
background-repeat: no-repeat;
position:absolute;
}
#chomel{
background-image:url('http://image.noelshack.com/fichiers/2015/16/1429209179-chomel.png');
width:107px;
height:87px;
display:block;
background-repeat: no-repeat;
position:absolute;
}
.dirDroite{
background-position: -140px 0px;
}
.dirGauche{
background-position: 0px 0px;
}
#hautGauche{
margin-top: 25vh;
position: fixed;
width: 15vw;
margin-left: 30vh;
height: 3vh;
background-color: #663303;
z-index: 1;
}
#hautDroite{
margin-top: 25vh;
position: fixed;
width: 15vw;
margin-left: 125vh;
height: 3vh;
background-color: #663303;
z-index: 2;
}
#milieu{
margin-top: 45vh;
position: fixed;
width: 50vw;
margin-left: 45vh;
height: 3vh;
background-color: #663303;
z-index: 3;
}
#basGauche{
margin-top: 65vh;
position: fixed;
width: 25vw;
margin-left: 27.75vh;
height: 3vh;
background-color: #663303;
z-index: 4;
}
#basDroite{
margin-top: 65vh;
position: fixed;
width: 22.18vw;
margin-left: 132.8vh;
height: 3vh;
background-color: #663303;
z-index: 5;
}
#base{
margin-top: 85vh;
position: fixed;
width: 49.77vw;
margin-left: 50.7vh;
height: 3vh;
background-color: #663303;
z-index: 6;
}
#invisible {
position: fixed;
right: 0;
bottom: 0px;
left: 0;
z-index: 200;
margin: auto;
background-color: black;
width: 100%;
height: 30px;
opacity: 0;
z-index: 7;
}
.arrow1 {
position: absolute;
z-index: 3;
width: 50px;
height: 11px;
background: url('http://image.noelshack.com/fichiers/2015/16/1429209179-bullet.png') 43px 19px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LEVEL 1</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div data-platform="true" id="hautGauche" class="collidableRectangle"></div>
<div data-platform="true" id="hautDroite" class="collidableRectangle"></div>
<div data-platform="true" id="milieu" class="collidableRectangle"></div>
<div data-platform="true" id="basGauche" class="collidableRectangle"></div>
<div data-platform="true" id="basDroite" class="collidableRectangle"></div>
<div data-platform="true" id="base" class="collidableRectangle"></div>
<div data-platform="true" id="invisible"></div>
<div id="arrow1"></div>
<span style="margin-left:50px;" id="result"></span>
<div id="batman" class="dirGauche" style="left: 1100px; bottom: 580px;"></div>
<div id="chomel" class="dirGauche" style="left: 900px; bottom: 580px;"></div>
<div id="vie">
</div>
</div>
<script src="scripts/script.js" ></script>
</body>
</html>
The code above is the one with the working jump, here is the one with the working platforms :
var platforms = [];
var currentPlatform = null;
var $roger = $('#batman');
$(document).on('keydown', function (e) {
var top = $roger.offset().top;
var left = $roger.offset().left;
var newTop = top;
var newLeft = left;
switch (e.keyCode) {
case 32:
newTop = top - 400;
$roger.css("top", newTop);
setTimeout(function () {
$roger.css("top", top);
}, 100);
break;
case 37:
newLeft = left - 50;
$roger.css({left: newLeft});
break;
case 39:
newLeft = left + 50;
$roger.css({left: newLeft});
break;
}
});
setInterval(function () {
verifyPlatform();
}, 50);
$('[data-platform="true"]').each(function () {
var $element = $(this);
var x = $element.offset().left;
var y = $element.offset().top;
var xw = x + $element.width();
var yh = y + $element.height();
platforms.push({
element: $element,
x: x,
y: y,
xw: xw,
yh: yh
});
});
function getPlatformAvailable(platforms) {
var persoX = $roger.offset().left;
var persoYH = $roger.offset().top + $roger.height();
for (platform in platforms) {
var current = platforms[platform];
if (
((persoX + 50) >= current.x && persoX <= current.xw) &&
((persoYH) <= current.y)
) {
return current;
}
}
return false;
}
function verifyPlatform() {
var platformAvailable = getPlatformAvailable(platforms);
var platformAvailableString = platformAvailable.x +":"+ platformAvailable.y;
if (platformAvailable && platformAvailableString != currentPlatform) {
currentPlatform = platformAvailableString;
$roger.css('top', (platformAvailable.y - $roger.height()));
}
}
Thanks guys if you can understand and help me, i've been trying all day long.
Cheers !
I see you are binding the same event twice:
In the first code snippet:
$(document).keydown(function(e) { //Fonctionne
touche[e.keyCode] = true;
});
In the second code snippet:
$(document).on('keydown', function (e) {
var top = $roger.offset().top;
var left = $roger.offset().left;
var newTop = top;
var newLeft = left;
switch (e.keyCode) {
case 32:
newTop = top - 400;
$roger.css("top", newTop);
setTimeout(function () {
$roger.css("top", top);
}, 100);
break;
case 37:
newLeft = left - 50;
$roger.css({left: newLeft});
break;
case 39:
newLeft = left + 50;
$roger.css({left: newLeft});
break;
}
});
If you merge both codes together, that means that these 2 events will conflict and only one of the two will work.
Solution
Merge them properly together like this to solve it:
$(document).on('keydown', function (e) {
touche[e.keyCode] = true;
var top = $roger.offset().top;
var left = $roger.offset().left;
var newTop = top;
var newLeft = left;
switch (e.keyCode) {
case 32:
newTop = top - 400;
$roger.css("top", newTop);
setTimeout(function () {
$roger.css("top", top);
}, 100);
break;
case 37:
newLeft = left - 50;
$roger.css({left: newLeft});
break;
case 39:
newLeft = left + 50;
$roger.css({left: newLeft});
break;
}
});