在这个Snake游戏中,我需要按钮来控制蛇,就像箭头键一样。这将允许游戏在移动设备上播放。你可以看到我在那里有按钮的代码,但它们没有正常工作而且没有控制蛇的运动。
任何使按钮工作的建议都将不胜感激!谢谢!
HTML
<section class="game" id="share">
<div class="container">
<div class="columns twelve borders center">
<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" height="300" width="300" style="display:none;"></canvas>
</div>
<div class="button-pad">
<div class="btn-up">
<input type="image" src="http://aaronblomberg.com/sites/ez/images/btn-up.png" alt="Up" class="button up-btn" />
</div>
<div class="btn-right">
<input type="image" src="http://aaronblomberg.com/sites/ez/images/btn-right.png" alt="Right" class="button right-btn" />
</div>
<div class="btn-down">
<input type="image" src="http://aaronblomberg.com/sites/ez/images/btn-down.png" alt="Down" class="button down-btn" />
</div>
<div class="btn-left">
<input type="image" src="http://aaronblomberg.com/sites/ez/images/btn-left.png" alt="Left" class="button left-btn" />
</div>
</div>
</div>
</div>
</div>
</section>
JAVASCRIPT
( 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 );
答案 0 :(得分:0)
AND TIME
所以基本上你有一些错误。你的第一个是你的造型。你真的需要让你的风格更灵活,但这将解决我遇到的正确按钮问题。
.button-pad > div {
z-index: 9999;
width: 50px;
}
http://jsfiddle.net/34oeacnm/8/
$(document).on('click', '.button-pad .button', function(e) {
var e = jQuery.Event("keydown");
if ($(this).hasClass('left-btn')) {
e.which = 37;
}
else if ($(this).hasClass('up-btn')) {
e.which = 38;
}
else if ($(this).hasClass('right-btn')) {
e.which = 39;
}
else if ($(this).hasClass('down-btn')) {
e.which = 40;
}
$(document).trigger(e);
});
你关闭了一些选择器。我偷了一些关于如何从Definitive way to trigger keypress events with jQuery触发的信息。
答案 1 :(得分:0)
这是在蛇游戏中添加Moile控制的代码; (如果您想要蛇游戏的全部代码,请评论);
// The dogList parameter
ParameterExpression dogParam = Expression.Parameter(typeof(List<Dog>), "dog");
// Begin of inner Select expression
// d parameter
ParameterExpression dParam = Expression.Parameter(typeof(Dog), "d");
// d.Breed *property* access (if it is a *field*, use Expression.Field)
MemberExpression dogProperty = Expression.Property(dParam, nameof(Dog.Breed));
// d.Breed.Trim() method call
MethodCallExpression trimCall = Expression.Call(dogProperty, nameof(string.Trim), Type.EmptyTypes);
// d.Breed.Trim().Length property access
MemberExpression lengthProperty = Expression.Property(trimCall, nameof(string.Length));
// d => d.Breed.Trim().Length
Expression<Func<Dog, int>> selectExpression = Expression.Lambda<Func<Dog, int>>(lengthProperty, dParam);
// End of inner Select expression
// Find the "right" overload of Enumerable.Select... A pain.
MethodInfo selectTSourceTResult = (from x in typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where x.Name == nameof(Enumerable.Select)
let args = x.GetGenericArguments()
where args.Length == 2
let pars = x.GetParameters()
where pars.Length == 2 &&
pars[0].ParameterType == typeof(IEnumerable<>).MakeGenericType(args[0]) &&
pars[1].ParameterType == typeof(Func<,>).MakeGenericType(args[0], args[1])
select x).Single();
// Make the generic overload of Enumerable.Select "specific" for using with Func<Dog, int>
MethodInfo selectDogInt32 = selectTSourceTResult.MakeGenericMethod(typeof(Dog), typeof(int));
// Note that Enumerable.Select is a static method, the first parameter is the IEnumerable, the second is the Func<,>
// Enumerable.Select(dogList, d => d.Breed.Trim().Length)
MethodCallExpression selectCall = Expression.Call(selectDogInt32, dogParam, selectExpression);
// Begin of inner OrderByDescending expression
// d1 parameter
ParameterExpression d1Param = Expression.Parameter(typeof(int), "d1");
// d1 => d1
Expression<Func<int, int>> orderByExpression = Expression.Lambda<Func<int, int>>(d1Param, d1Param);
// End of inner OrderByDescending expression
// Find the "right" overload of Enumerable.OrderByDescending... Another pain.
MethodInfo orderByDescendingTSourceTKey = (from x in typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where x.Name == nameof(Enumerable.OrderByDescending)
let args = x.GetGenericArguments()
where args.Length == 2
let pars = x.GetParameters()
where pars.Length == 2 &&
pars[0].ParameterType == typeof(IEnumerable<>).MakeGenericType(args[0]) &&
pars[1].ParameterType == typeof(Func<,>).MakeGenericType(args[0], args[1])
select x).Single();
// Make the generic overload of Enumerable.OrderByDescending "specific" for using with Func<int, int>
MethodInfo orderByDescendingInt32Int32 = orderByDescendingTSourceTKey.MakeGenericMethod(typeof(int), typeof(int));
// Note that Enumerable.OrderByDescending is a static method, the first parameter is the IEnumerable, the second is the Func<,>
// Enumerable.OrderByDescending(Enumerable.Select(...), d1 => d1)
MethodCallExpression orderByDescendingCall = Expression.Call(orderByDescendingInt32Int32, selectCall, orderByExpression);
// Find the "right" overload of Enumerable.First... Third big pain.
MethodInfo firstTSource = (from x in typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where x.Name == nameof(Enumerable.First)
let args = x.GetGenericArguments()
where args.Length == 1
let pars = x.GetParameters()
where pars.Length == 1 &&
pars[0].ParameterType == typeof(IEnumerable<>).MakeGenericType(args[0])
select x).Single();
// Make the generic overload of Enumerable.OrderByDescending "specific" for using with int
MethodInfo firstInt32 = firstTSource.MakeGenericMethod(typeof(int));
// Note that Enumerable.First is a static method, the first parameter is the IEnumerable
// Enumerable.First(Enumerable.OrderByDescending(...))
MethodCallExpression firstCall = Expression.Call(firstInt32, orderByDescendingCall);
这里是HTML;
//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;
}
}
说明:我只是在html页面中添加了四个按钮,在js中创建了四个函数,它们将移动蛇,因为它应该沿不同的方向移动并将它们分别添加到不同按钮的'onclick'属性中。>