Snake Game with Controller Buttons for Mobile Use **UPDATED** - javascript

** NOTE: I've Edited the javascript below and linked to a new JSFiddle but still not getting the buttons to control the snake's movement like the arrow keys on the keyboard **
I’m trying to create a real easy snake game for project but need it to have buttons so the game will work on mobile. This is almost there except i need to have the buttons control the movement of the snake on screen:
HTML:
<div class="game-container">
<div class="container">
<div class="SplashScreen">
<h1>
Snake
</h1>
<h2>
Click To Start.
</h2>
<input class="StartButton" type="button" value="Start" />
</div>
<div class="FinishScreen" style="display:none">
<h1>
Game Over
</h1>
<p>
Your score was: <span id="score"></span>
</p>
<input class="StartButton" type="button" value="Restart" />
</div>
<canvas id="canvasArea" width="450" height="450" style="display:none;"></canvas>
</div>
<div class="button-pad">
<div class="btn-up">
<button type="submit" class="up">
<img src="http://aaronblomberg.com/sites/ez/images/btn-up.png" />
</button>
</div>
<div class="btn-right">
<button type="submit" class="right">
<img src="http://aaronblomberg.com/sites/ez/images/btn-right.png" />
</button>
</div>
<div class="btn-down">
<button type="submit" class="down">
<img src="http://aaronblomberg.com/sites/ez/images/btn-down.png" />
</button>
</div>
<div class="btn-left">
<button type="submit" class="left">
<img src="http://aaronblomberg.com/sites/ez/images/btn-left.png" />
</button>
</div>
</div>
jQuery:
( function( $ ) {
$( function() {
$(document).ready(function () {
$(".StartButton").click(function () {
$(".SplashScreen").hide();
$(".FinishScreen").hide();
$("#canvasArea").show();
init();
});
//Canvas stuff
var canvas = $("#canvasArea")[0];
var ctx = canvas.getContext("2d");
var w = $("#canvasArea").width();
var h = $("#canvasArea").height();
//Lets save the cell width in a variable for easy control
var sw = 10;
var direction;
var nd;
var food;
var score;
//Lets create the snake now
var snake_array; //an array of cells to make up the snake
function endGame() {
$("#canvasArea").hide();
$("#score").text(score);
$(".FinishScreen").show();
}
function init() {
direction = "right"; //default direction
nd = [];
create_snake();
create_food(); //Now we can see the food particle
//finally lets display the score
score = 0;
//Lets move the snake now using a timer which will trigger the paint function
//every 60ms
if (typeof game_loop != "undefined") clearInterval(game_loop);
game_loop = setInterval(paint, 60);
}
function create_snake() {
var length = 5; //Length of the snake
snake_array = []; //Empty array to start with
for (var i = length - 1; i >= 0; i--) {
//This will create a horizontal snake starting from the top left
snake_array.push({
x: i,
y: 0
});
}
}
//Lets create the food now
function create_food() {
food = {
x: Math.round(Math.random() * (w - sw) / sw),
y: Math.round(Math.random() * (h - sw) / sw),
};
//This will create a cell with x/y between 0-44
//Because there are 45(450/10) positions accross the rows and columns
}
//Lets paint the snake now
function paint() {
if (nd.length) {
direction = nd.shift();
}
//To avoid the snake trail we need to paint the BG on every frame
//Lets paint the canvas now
ctx.fillStyle = "#0056a0";
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = "#ffffff";
ctx.strokeRect(0, 0, w, h);
//The movement code for the snake to come here.
//The logic is simple
//Pop out the tail cell and place it infront of the head cell
var nx = snake_array[0].x;
var ny = snake_array[0].y;
//These were the position of the head cell.
//We will increment it to get the new head position
//Lets add proper direction based movement now
if (direction == "right") nx++;
else if (direction == "left") nx--;
else if (direction == "up") ny--;
else if (direction == "down") ny++;
//Lets add the game over clauses now
//This will restart the game if the snake hits the wall
//Lets add the code for body collision
//Now if the head of the snake bumps into its body, the game will restart
if (nx == -1 || nx == w / sw || ny == -1 || ny == h / sw || check_collision(nx, ny, snake_array)) {
//end game
return endGame();
}
//Lets write the code to make the snake eat the food
//The logic is simple
//If the new head position matches with that of the food,
//Create a new head instead of moving the tail
if (nx == food.x && ny == food.y) {
var tail = {
x: nx,
y: ny
};
score++;
//Create new food
create_food();
} else
{
var tail = snake_array.pop(); //pops out the last cell
tail.x = nx;
tail.y = ny;
}
//The snake can now eat the food.
snake_array.unshift(tail); //puts back the tail as the first cell
for (var i = 0; i < snake_array.length; i++) {
var c = snake_array[i];
//Lets paint 10px wide cells
paint_cell(c.x, c.y);
}
//Lets paint the food
paint_cell(food.x, food.y);
//Lets paint the score
var score_text = "Score: " + score;
ctx.fillStyle = "#ffffff";
ctx.fillText(score_text, 5, h - 5);
//Set the font and font size
ctx.font = '12px Arial';
//position of the fill text counter
ctx.fillText(itemCounter, 10, 10);
}
//Lets first create a generic function to paint cells
function paint_cell(x, y) {
ctx.fillStyle = "#d8d8d8";
ctx.fillRect(x * sw, y * sw, sw, sw);
}
function check_collision(x, y, array) {
//This function will check if the provided x/y coordinates exist
//in an array of cells or not
for (var i = 0; i < array.length; i++) {
if (array[i].x == x && array[i].y == y) return true;
}
return false;
}
// Lets prevent the default browser action with arrow key usage
var keys = {};
window.addEventListener("keydown",
function(e){
keys[e.keyCode] = true;
switch(e.keyCode){
case 37: case 39: case 38: case 40: // Arrow keys
case 32: e.preventDefault(); break; // Space
default: break; // do not block other keys
}
},
false);
window.addEventListener('keyup',
function(e){
keys[e.keyCode] = false;
},
false);
//Lets add the keyboard controls now
$(document).keydown(function (e) {
var key = e.which;
var td;
if (nd.length) {
var td = nd[nd.length - 1];
} else {
td = direction;
}
//We will add another clause to prevent reverse gear
if (key == "37" && td != "right") nd.push("left");
else if (key == "38" && td != "down") nd.push("up");
else if (key == "39" && td != "left") nd.push("right");
else if (key == "40" && td != "up") nd.push("down");
//The snake is now keyboard controllable
});
});
$(document).on('click', '.button-pad > button', function(e) {
if ($(this).hasClass('left-btn')) {
e = 37;
}
else if ($(this).hasClass('up-btn')) {
e = 38;
}
else if ($(this).hasClass('right-btn')) {
e = 39;
}
else if ($(this).hasClass('down-btn')) {
e = 40;
}
$.Event("keydown", {keyCode: e});
});
});
})( jQuery );
JSFiddle
http://jsfiddle.net/aaronblomberg/9w3gk3ma/3/
This is ALMOST where i need it but i need the up, down, left, and right arrow buttons to control the snake...
any help with would be greatly greatly appreciated.

You cold make something like this:
var isMobile;
checkMobile = function() {
if ($(window).width() <= 766) {
isMobile = true;
}
else {
isMobile = false;
}
}
$(window).resize(checkMobile());
$(document).ready(checkMobile());
if (isMobile) {
$('.button-pad').show();
}
else {
$('.button-pad').hide();
}
.button-pad:
$(document).on('click', '.button-pad > button', function(e) {
if ($(this).hasClass('left')) {
e = 37;
}
else if ($(this).hasClass('up')) {
e = 38;
}
else if ($(this).hasClass('right')) {
e = 39;
}
else if ($(this).hasClass('down')) {
e = 40;
}
$.Event("keydown", {keyCode: e});
}

Here is the code to add moile control to the snake game;
(If you want the whole code for the snake game please comment);
//Here is javascript;
// left key
function l() {
if(snake.dx === 0) {
snake.dx = -grid;
snake.dy = 0;
}
}
// up key
function u() {
if(snake.dy === 0) {
snake.dy = -grid;
snake.dx = 0;
}
}
// right key
function r() {
if(snake.dx === 0) {
snake.dx = grid;
snake.dy = 0;
}
}
// down key
function d() {
if(snake.dy === 0) {
snake.dy = grid;
snake.dx = 0;
}
}
Here is HTML;
<div>
<button onclick="u()" type="button" id="U">U</button>
<button onclick="l()" type="button" id="L">L</button>
<button onclick="r()" type="button" id="R">R</button>
<button onclick="d()" type="button" id="D">D</button>
</div>
Description: I simply added four buttons in the html page, created four functions in the js which will move snake as it should move in different directions and simply added them to the 'onclick' attribute of the different buttons respectively.

Related

Function to test if snake has collided with itself won't work

Hey everyone I'm making a snake game in JS. Right Now I'm working on the function that will stop the game if the snake head has hit somewhere on the snake body. since the snakes an array, I loop through every snake unit and compare it with the head unit. The problem is now the game stops before you can even start. Since the snake head is in the array that's being looped through the very first loop compares the head position with itself and since there both at the same position the game stops. Any ideas?
//declare global variables
const canvas = document.querySelector('#canvas');
//set canvas context
const ctx = canvas.getContext('2d');
//put canvas dimensions into variables
const cvsW = canvas.width;
const cvsH = canvas.height;
//create snake unit
const unit = 16;
//create snake and set starting position
let snake = [{
x : cvsW/2,
y : cvsH/2
}]
//create food object and set its position somewhere on board
let food = {
//Math.floor(Math.random()*cvsW + 1)---number from 1 to 784
//Math.floor(Math.random()*cvsW/unit + 1)---number from 1 to 79
//Math.floor(Math.random()*cvsW/unit + 1)*unit---number from 1 to 784(but it's a multiple of unit)
//Math.floor(Math.random()*(cvsW/unit - 1)+1)*unit---same as above but -1 keeps food inside canvas
x : Math.floor(Math.random()*(cvsW/unit - 1)+1)*unit-unit/2,
y : Math.floor(Math.random()*(cvsH/unit - 1)+1)*unit-unit/2
}
//create a variable to store the direction of the snake
let direction;
//add event to read users input then change direction
document.addEventListener('keydown', (e) => {
if(e.keyCode == 37 && direction != 'right') direction = 'left';
else if (e.keyCode == 38 && direction != 'down') direction = 'up';
else if (e.keyCode == 39 && direction != 'left') direction = 'right';
else if (e.keyCode == 40 && direction != 'up') direction = 'down';
})
function draw() {
//clear canvas and redraw snake
ctx.clearRect(0, 0, cvsW, cvsH);
for(let i = 0; i < snake.length; i++) {
ctx.fillStyle = 'limegreen';
ctx.fillRect(snake[i].x-unit/2, snake[i].y-unit/2, unit, unit);
}
//draw food
ctx.fillStyle = 'red';
ctx.fillRect(food.x-unit/2, food.y-unit/2, unit, unit);
//grab heads position
let headX = snake[0].x;
let headY = snake[0].y;
//move snake in chosen direction
if(direction == 'left') headX -= unit;
else if(direction == 'right') headX += unit;
else if(direction == 'up') headY -= unit;
else if(direction == 'down') headY += unit;
//create new snake unit
let newHead = {x : headX, y :headY}
//check to see if snakes eaten food
if(headX === food.x && headY === food.y) {
food = {
x : Math.floor(Math.random()*(cvsW/unit - 1)+1)*unit-unit/2,
y : Math.floor(Math.random()*(cvsH/unit - 1)+1)*unit-unit/2
}
//create 4 new units
for(let i = 4; i > 0; i--) {
//add those units -without this code snake will not grow
snake.unshift(newHead);
}
} else {
//remove tail -without this code snake will keep growing
snake.pop();
}
//add new head position -without this code snake will not move
snake.unshift(newHead);
//check to see if snake has hit a wall or itself
if(headX < 0 || headX > cvsW || headY < 0 || headY > cvsH || collision(headX, headY)) {
clearInterval(runGame);
}
}
let runGame = setInterval(draw, 70);
function collision(x, y) {
for(let i = 0; i < snake.length; i++) {
if(x == snake[i].x && y == snake[i].y) return true;
}
return false;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Snake Game</title>
<style>
body {
background-color: #333;
}
canvas {
background-color: #4d4d4d;
margin: auto;
display: block;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 750px;
height: 500px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="script.js"></script>
</body>
</html>
Add collision script to ignore the first two links of the snake when checking collisions with itself.
function selfcollision(x, y) {
for(let i = 2; i < snake.length; i++) {
if(x == snake[i].x && y == snake[i].y) return true;
}
return false;
}

My javascript doesn't give any output and when i reload the page it crashes

This is my code and when run instead of a black box containing my game in the centre of the screen there is just a gap and no website can seem to tell me where I went wrong:
console.log("start")
//Global functions
var canvas = document.getElementById("canva");
var canvasCon;
var snakeX = 400;
var snakeY = 300;
var direction;
var snakeSpeed = 1;
var apple = false;
var appleX;
var appleY
var snakeSize = 30;
var scoreboard = document.getElementById("score");
var Score = 0;
var trailX = new Array();
var trailY = new Array();
console.log("set global variables!")
window.onload = function(){
console.log("ran on window load function")
canvasCon = canvas.getContext('2d');
//Calls "drawing" and "move" fps times per second
var fps = 30
setInterval(function(){
move()
drawing()
},1000/fps);
}
document.addEventListener('keydown', getKey);
function getKey(event){
//gets the keycode
direction = event.keyCode;
return direction;
}
//moves the objsects
function move(){
//creates a easier to read way to check the value of getKey
var left = 37;
var up = 38;
var right = 39;
var down = 40;
//changing the position of the snake
switch(direction){
case right:
snakeX = snakeX + snakeSpeed;
break;
case left:
snakeX = snakeX - snakeSpeed;
break;
case up:
snakeY = snakeY - snakeSpeed;
break;
case down:
snakeY = snakeY + snakeSpeed;
break;
}
trail()
//checks if snake has gone off the board and then moves the snake to the other end of the board if that returns True
if(snakeX > canvas.width){
snakeX = 0
}else if(snakeX < 0){
snakeX = canvas.width
}
if(snakeY > canvas.height){
snakeY = 0
}else if(snakeY < 0){
snakeY = canvas.height
}
}
//draws everything /w updated coordinates
function drawing(){
//Backround of the Game
canvasCon.fillStyle = 'black';
canvasCon.fillRect(0,0,canvas.width,canvas.height);
//The snake
canvasCon.fillStyle = 'green';
canvasCon.fillRect(snakeX,snakeY,snakeSize,snakeSize);
//apple creation
apples()
canvasCon.fillStyle = 'red';
canvasCon.fillRect(appleX,appleY,25,25);
}
//makes the apples work
function apples(){
if(collision()){
Score += 1
console.log(Score)
scoreboard.innerHTML = "<b>Score: "+Score+"<b>"
apple = false
}
if(apple == false){
apple = true
appleX = Math.floor(Math.random() * (canvas.width - 50));
appleY = Math.floor(Math.random() * (canvas.height - 50));
}
}
function collision(){
var distX = Math.abs(appleX - snakeX-snakeSize/2);
var distY = Math.abs(appleY - snakeY-snakeSize/2);
if (distX <= (snakeSize/2) && distY <= (snakeSize/2)) { return true; }
}
function trail(){
//adds X and Y coordinates to their respective lists
trailX.push(snakeX)
trailY.push(snakeY)
//makes sure the lists are the right length
while(trailX.length > Score){
var index = trailX.indexOf(0);
trailX.splice(index, 1);
}
while(trailY.length > Score){
var index = trailY.indexOf(0);
trailY.splice(index, 1);
}
if(trailY.length != trailX.length){
console.log("trailY != trailX")
}
for(i= trailX.length-1; i<=0; i--){
canvasCon.fillStyle = 'yellow';
canvasCon.fillRect(trailX[i],trailY[i],25,25);
}
}
<title>SNAKE!!</title>
<body>
<p style="text-align:center; text-color:red"><b>Hope you Enjoy Ma GREAT GAME!!</b></p>
<br/><br/><br/>
<div style="width:800px; margin:0 auto;">
<canvas id=canva width="800" height="600"></canvas>
<br/>
<p id="score">Score: </p>
</div>
</body>
whenever the page gets reloaded even on jsfiddle.net it crashes.
plz help I have no idea what i did wrong!
First rule of JS - if it is stuck, you probably have an endless loop.
And indeed You have an endless loop with your final for:
for(i= trailX.length-1; i<=0; i--){
canvasCon.fillStyle = 'yellow';
canvasCon.fillRect(trailX[i],trailY[i],25,25);
}
i<=0
If i start with 0 and goes down by 1 each iteration, it will always be less or equal to 0 so the end condition will never be met.

HTML5 Javascript game

I'm trying to make a HTML5 game in javascript. Similar to pong, but once the bubble hits the paddle or bottom screen it "bursts" or disappears. I cant seem to get the Bubble to disappear or burst in my code. Could anyone help me?
var canvasColor;
var x,y,radius,color;
var x=50, y=30
var bubbles=[];
var counter;
var lastBubble=0;
var steps=0, burst=0, escaped=0;
var batonMovement = 200;
var moveBatonRight = false;
var moveBatonLeft = false;
function startGame()
{
var r,g,b;
var canvas,color;
//Initialize
canvasColor = '#EAEDDC';
x = 10;
y = 10;
radius = 10;
clearScreen();
counter=0;
while (counter <100)
{
//make bubble appear randomly
x=Math.floor(Math.random()*450)
//Set up a random color
r = Math.floor(Math.random()*256);
g = Math.floor(Math.random()*256);
b = Math.floor(Math.random()*256);
color='rgb('+r+','+g+','+b+')';
bubbles[counter] = new Bubble(x,y,radius,color);
counter+=1;
}
setInterval('drawForever()',50);
}
function Bubble (x,y,radius,color)
{
this.x=x;
this.y=y;
this.radius=radius;
this.color=color;
this.active=false;
}
function drawForever()
{
var canvas, pen;
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
steps +=1
clearScreen();
if (steps%20==0 && lastBubble < 100){
bubbles[lastBubble].active=true;
lastBubble +=1;
}
drawBaton();
counter=0;
while (counter <100)
{
if (bubbles[counter].active==true){
pen.fillStyle = bubbles[counter].color;
pen.beginPath();
pen.arc(bubbles[counter].x,
bubbles[counter].y,
bubbles[counter].radius,
0,
2*Math.PI);
pen.fill();
bubbles[counter].y+=2;
}
if (y>=240 && y<=270 && x>=batonMovement-10 && x<=batonMovement+60)
{
bubbles[lastBubble]=false;
}
else if (y>=450)
{
bubbles[lastBubble]=false;
}
counter +=1;
}
}
function clearScreen()
{
var canvas, pen;
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
pen.fillStyle = canvasColor;
pen.fillRect(0,0,450,300);
}
function drawBaton()
{
var canvas, pen;
if (moveBatonLeft == true && batonMovement > 0)
{
batonMovement -= 20;
}
else if (moveBatonRight == true && batonMovement < 400)
{
batonMovement += 20;
}
//draw Baton (rectangle)
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
pen.fillStyle = '#0000FF';
pen.fillRect(batonMovement,250,50,10);
}
function moveLeft()
{
moveBatonLeft=true;
}
function moveRight()
{
moveBatonRight=true;
}
function stopMove()
{
moveBatonLeft=false;
moveBatonRight=false;
}
Below is the HTML code...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bubble Burster</title>
<script type="text/javascript" src="project.js"></script>
</head>
<body onload="startGame();">
<div style="text-align:center;">
<h2>Bubble Burster</h2>
<canvas id="myCanvas" width="450" height="300" style="border:5px solid #000000; background-color: #f1f1f1;">
Your browser does not support the canvas element.
</canvas><br>
<button onmousedown="moveLeft();" onmouseup="stopMove();">LEFT</button>
<button onmousedown="moveRight();" onmouseup="stopMove();">RIGHT</button><br><br>
<form>
<input type="radio" name="difficulty" value="easy" onclick="check(this.value);" checked> Easy
<input type="radio" name="difficulty" value="moderate" onclick="check(this.value)"> Moderate
<input type="radio" name="difficulty" value="hard" onclick="check(this.value)"> Hard <br><br>
</form>
<span id="burst">Burst:</span>
<span id="escaped">Escaped: </span>
<span id="steps">Steps elapsed:</span>
<h3 id="output"></h3>
</div>
</body>
</html>
You are referring to x, y which are not defined in the drawForever function. The global values of x and y may not refer to the right bubble. In fact y is set to 10 in the startGame function and never altered subsequently. You also probably want to refer to bubbles[counter] rather than bubbles[lastBubble]. The game seems to work if you make the changes below, referring to bubbles[counter].x and bubbles[counter].y instead of x and y.
function drawForever() {
var canvas, pen;
canvas = document.getElementById('myCanvas');
pen = canvas.getContext('2d');
steps += 1
clearScreen();
if (steps % 20 == 0 && lastBubble < 100) {
bubbles[lastBubble].active = true;
lastBubble += 1;
}
drawBaton();
counter = 0;
while (counter < 100) {
if (bubbles[counter].active == true) {
pen.fillStyle = bubbles[counter].color;
pen.beginPath();
pen.arc(bubbles[counter].x,
bubbles[counter].y,
bubbles[counter].radius,
0,
2 * Math.PI);
pen.fill();
bubbles[counter].y += 2;
}
y = bubbles[counter].y; // ADDED (y was not defined in original code)
x = bubbles[counter].x; // ADDED (x was not defined in original code)
if (y >= 240 && y <= 270 && x >= batonMovement - 10 && x <= batonMovement + 60) {
bubbles[counter] = false; // ALTERED (burst the current bubble, not whatever lastBubble refers to
} else if (y >= 450) {
bubbles[counter] = false; // ALTERED (burst the current bubble, not whatever lastBubble refers to
}
counter += 1;
}
}
https://jsfiddle.net/acLot87q/4/
You should also make x and y local variables within each function; they are not currently serving the purpose that you seem to think.

Sprite vs Group Collider not working in phaser with enableBody set as true

I'm a bit new to JavaScript and have been playing around with Phaser lately. So I'm building an infinite side scroller and everything works fine except that my player won't collide with the walls. Both sprites have physics enabled and I have tried multiple solutions, none of which work. Can you please help me out?
function bloxo()
{
var game = new Phaser.Game(1200, 600, Phaser.CANVAS, 'gameStage', { preload: preload, create: create, update: update });
var prevHole = 3;
function preload() {
game.load.image('bloxoDown','../bloxo/assets/images/bloxoDown.png');
game.load.image('bloxoUp','../bloxo/assets/images/bloxoUp.png');
game.load.image('wall','../bloxo/assets/images/platform.png',400,200);
var space;
var esc;
var player;
var walls;
var score;
}
function create() {
//Canvas With a White Bacground and Physics is Created
game.stage.backgroundColor = "#ffffff";
game.physics.startSystem(Phaser.Physics.ARCADE);
//Sets the initial Score.
score = 0;
//Sets how fast the tiles move
tileSpeed = -300;
tileWidth = game.cache.getImage('wall').width;
tileHeight = game.cache.getImage('wall').height;;
//Keys for User Input are created
space = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
esc = game.input.keyboard.addKey(Phaser.Keyboard.ESC);
//Adds Bloxo to the game as a sprite.
player = game.add.sprite(200,200,'bloxoDown');
player.scale.setTo(0.6, 0.6);
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true;
player.body.immovable = true;
//Walls Group is created
walls = game.add.physicsGroup();
walls.createMultiple(50, 'wall');
walls.enableBody = true;
game.physics.arcade.overlap(player, walls,null,this)
game.physics.arcade.collide(player,walls,gameOver);
// Stop the following keys from propagating up to the browser
game.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR, Phaser.Keyboard.ESC,]);
//Unpausing Function
window.onkeydown = function(event)
{
if (esc.onDown && (esc.timeDown > 2000))
{
if(game.paused)
{
game.paused = !game.paused;
pauseLbl.destroy();
}
}
}
//Add an initial platform
addWall();
//Add a platform every 3 seconds
var timerWorld = game.time.events.loop(500, addWall);
}
function update() {
if (space.isDown)
{
player.body.y -=5;
bloxoUp();
}
else
{
player.body.y +=5;
bloxoDown();
}
if(esc.isDown)
{
pauseGame();
}
}
function bloxoUp()
{
player.loadTexture('bloxoUp');
}
function bloxoDown()
{
player.loadTexture('bloxoDown');
}
function pauseGame()
{
game.paused = true;
pauseLbl = game.add.text(500, 300, 'Game Paused', { font: '30px Roboto', fill: '#aaaaaa' });
}
function addTile(x,y)
{
//Get a tile that is not currently on screen
var tile = walls.getFirstDead();
//Reset it to the specified coordinates
tile.reset(x,y);
tile.body.velocity.x = tileSpeed;
tile.body.immovable = true;
//When the tile leaves the screen, kill it
tile.checkWorldBounds = true;
tile.outOfBoundsKill = true;
}
function addWall()
{
//Speed up the game to make it harder
tileSpeed -= 1;
score += 1;
//Work out how many tiles we need to fit across the whole screen
var tilesNeeded = Math.ceil(game.world.height / tileHeight);
//Add a hole randomly somewhere
do
{
var hole = Math.floor(Math.random() * (tilesNeeded - 2)) + 1;
}while((hole > (prevHole + 2)) && (hole < (prevHole - 2)) );
prevHole = hole;
//Keep creating tiles next to each other until we have an entire row
//Don't add tiles where the random hole is
for (var i = 0; i < tilesNeeded; i++){
if (i != hole && (i != hole+1 && i != hole-1) && (i != hole+2 && i != hole-2)){
addTile(game.world.width, i * tileHeight);
}
}
}
function gameOver()
{
console.log("player hit");
player.kill();
game.state.start(game.state.current);
}
}
You have just to move collide call into your update method:
game.physics.arcade.collide(player, walls, gameOver);
Take a look to the runnable snippet below(I have resized the canvas for the preview, sorry) or Fiddle:
var game = new Phaser.Game(450, 150, Phaser.CANVAS, 'gameStage', {
preload: preload,
create: create,
update: update
});
var prevHole = 3;
function preload() {
game.load.image('bloxoDown', '../bloxo/assets/images/bloxoDown.png');
game.load.image('bloxoUp', '../bloxo/assets/images/bloxoUp.png');
game.load.image('wall', '../bloxo/assets/images/platform.png', 400, 100);
var space;
var esc;
var player;
var walls;
var score;
}
function create() {
//Canvas With a White Bacground and Physics is Created
game.stage.backgroundColor = "#ffffff";
game.physics.startSystem(Phaser.Physics.ARCADE);
//Sets the initial Score.
score = 0;
//Sets how fast the tiles move
tileSpeed = -300;
tileWidth = game.cache.getImage('wall').width;
tileHeight = game.cache.getImage('wall').height;;
//Keys for User Input are created
space = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
esc = game.input.keyboard.addKey(Phaser.Keyboard.ESC);
//Adds Bloxo to the game as a sprite.
player = game.add.sprite(200, 200, 'bloxoDown');
player.scale.setTo(0.6, 0.6);
game.physics.enable(player, Phaser.Physics.ARCADE);
player.body.collideWorldBounds = true;
player.body.immovable = true;
//Walls Group is created
walls = game.add.physicsGroup();
walls.createMultiple(50, 'wall');
walls.enableBody = true;
game.physics.arcade.overlap(player, walls, null, this)
// remove your call to collide
// Stop the following keys from propagating up to the browser
game.input.keyboard.addKeyCapture([Phaser.Keyboard.SPACEBAR, Phaser.Keyboard.ESC, ]);
//Unpausing Function
window.onkeydown = function(event) {
if (esc.onDown && (esc.timeDown > 2000)) {
if (game.paused) {
game.paused = !game.paused;
pauseLbl.destroy();
}
}
}
//Add an initial platform
addWall();
//Add a platform every 3 seconds
var timerWorld = game.time.events.loop(500, addWall);
}
function update() {
if (space.isDown) {
player.body.y -= 5;
bloxoUp();
} else {
player.body.y += 5;
bloxoDown();
}
// move your collide call here
game.physics.arcade.collide(player, walls, gameOver);
if (esc.isDown) {
pauseGame();
}
}
function bloxoUp() {
player.loadTexture('bloxoUp');
}
function bloxoDown() {
player.loadTexture('bloxoDown');
}
function pauseGame() {
game.paused = true;
pauseLbl = game.add.text(500, 300, 'Game Paused', {
font: '30px Roboto',
fill: '#aaaaaa'
});
}
function addTile(x, y) {
//Get a tile that is not currently on screen
var tile = walls.getFirstDead();
//Reset it to the specified coordinates
if (tile) {
tile.reset(x, y);
tile.body.velocity.x = tileSpeed;
tile.body.immovable = true;
//When the tile leaves the screen, kill it
tile.checkWorldBounds = true;
tile.outOfBoundsKill = true;
}
}
function addWall() {
//Speed up the game to make it harder
tileSpeed -= 1;
score += 1;
//Work out how many tiles we need to fit across the whole screen
var tilesNeeded = Math.ceil(game.world.height / tileHeight);
var prevHole;
//Add a hole randomly somewhere
do {
var hole = Math.floor(Math.random() * (tilesNeeded - 2)) + 1;
} while ((hole > (prevHole + 2)) && (hole < (prevHole - 2)));
prevHole = hole;
//Keep creating tiles next to each other until we have an entire row
//Don't add tiles where the random hole is
for (var i = 0; i < tilesNeeded; i++) {
if (i != hole && (i != hole + 1 && i != hole - 1) && (i != hole + 2 && i != hole - 2)) {
addTile(game.world.width, i * tileHeight);
}
}
}
function gameOver() {
console.log("player hit");
player.kill();
game.state.start(game.state.current);
}
canvas{
border: 5px solid #333;
margin-left:25px;
margin-top:25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser/2.6.2/phaser.min.js"></script>

How to make a character move smoothly in Javascript

I'm making a game, and I'd like to know how to make a character move more smoothly. The character can already move, but it moves really choppy; when you click the arrow key, it instantly appears 10 pixels ahead. I'd like it to move smoothly so it doesn't just "appear" 10 pixels ahead of itself.
Here is the Code:
document.onkeydown = checkKey;
var canvas;
var ctx;
var up;
var down;
var left;
var right;
var bobX = 200;
var bobY = 200;
var bobWidth = 30;
var bobHeight = 30;
window.onload = function() {
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
var fps = 200; // frames per second
setInterval(function() {
updateAll();
drawAll();
}, 1000/fps)
};
var drawAll = function() {
// draw background
ctx.fillStyle = "white";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// draw bob
ctx.fillStyle = "red";
ctx.fillRect(bobX, bobY, bobWidth, bobHeight);
};
var updateAll = function() {
if (up == true) {
up = false;
}
if (down == true) {
bobY += 1;
down = false;
}
if (left == true) {
bobX -= 1;
left = false;
}
if (right == true) {
bobX += 1;
right = false;
}
};
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
up = true;
}
else if (e.keyCode == '40') {
down = true;
}
else if (e.keyCode == '37') {
left = true;
}
else if (e.keyCode == '39') {
right = true;
}
}
I tried doing moving it by one pixel every keypress, but it moves very slowly when I do that.
Your screen has maximum refreshrate, usually 60 fps. Some screens can get up to 120fps, but that's a rather rare case.
So what is happening here:
var fps = 200; // frames per second
setInterval(function() {
updateAll();
drawAll();
}, 1000/fps)
};
The canvas gets redrawn and the position gets updated at a rate which your screen can't catch up with. You simply can't see that your character only moves 1 pixel instead of 10 pixel.
Solution would be to use requestAnimationFrame instead. Which invokes when the screen refreshes:
function animate() {
requestAnimationFrame(animate);
updateAll();
drawAll();
};
animate();

Categories