用HTML做一个贪吃蛇?

html-css09

用HTML做一个贪吃蛇?,第1张

之前自己写着玩,写了一个,不完美,仅仅是实现了。代码如下

这是index.html

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8" />

<title>New Web Project</title>

<script src="js/base.js" type="text/javascript"></script>

<script src="js/application.js" type="text/javascript"></script>

</head>

<body style="width: 100%height:800pxmargin:0text-align: center">

<div id="gameZone" style="position:relativemargin-left: automargin-right: auto"></div>

</body>

</html>

以下是html中引用的两个js文件

/**

* @author bsnpbda

*/

var Class = function(parent){

var klass = function(){

this.init.apply(this,arguments)

}

//change klass's prototype'

if(parent){

var subclass = function(){}

subclass.prototype = parent.prototype

klass.prototype = new subclass

klass.prototype._super = parent.prototype

}

klass.prototype.init = function(){}

//define surname for the prototype

klass.fn = klass.prototype

//add class attribute

klass.extend = function(obj){

var extended = obj.extended

for(var i in obj){

klass[i] = obj[i]

}

if(extended) extended(klass)

}

//add instance attribute

klass.include = function(obj){

var included = obj.included

for(var i in obj){

klass.fn[i] = obj[i]

}

if(included) included(klass)

}

//add proxy method

klass.proxy = function(func){

var self = this

return (function(){

return func.apply(self,arguments)

})

}

//add instance proxy method

klass.fn.proxy = klass.proxy

return klass

} /**

* @author bsnpbda

*/

var configuration = {

unit:15,

interval:200

}

var Context = new Class

Context.extend({

context:null,

getContext:function(){

if(!this.context)

this.context = new Context

return this.context

}

})

Context.include({

init:function(){

var w = document.body.clientHeight

var h = document.body.clientWidth

this.unit = h <w?h/configuration.unit:w/configuration.unit

this.interval = configuration.interval

var gameZone = document.getElementById("gameZone")

this.gameZone = gameZone

var line = this.unit * configuration.unit

gameZone.style.width = gameZone.style.lineHeight = gameZone.style.height = line + "px"

gameZone.style.borderWidth = "1px"

gameZone.style.borderStyle = "solid"

},

setGame:function(game){

this.game = game

},

getGame:function(){

return this.game

}

})

var Dom = new Class

Dom.include({

init:function(style){

var element = document.createElement("div")

this.element = element

this.style = style

for(var s in style){

element.style[s] = this.style[s]

}

},

attach:function(){

Context.getContext().gameZone.appendChild(this.element)

},

remove:function(){

Context.getContext().gameZone.removeChild(this.element)

},

refresh:function(){

for(var s in this.style){

this.element.style[s] = this.style[s]

}

}

})

var PaintModule = {

paint:function(){

this.element = new Dom(this.style)

this.element.attach()

},

repaint:function(){

this.element.refresh()

},

wipeOff:function(){

this.element.remove()

}

}

var Sprite = new Class

Sprite.include(PaintModule)

Sprite.include({

default_cfg:{

id:0,

axisX:0,

axisY:0,

background:"black"

},

init:function(cfg){

var unit = Context.getContext().unit

this.id = cfg.id || this.default_cfg.id

this.style = {}

this.style.position = "absolute"

this.style.width = unit+'px'

this.style.height = unit+'px'

this.axisX = (cfg.axisX || this.default_cfg.axisX)

this.style.left = this.axisX*unit + 'px'

this.axisY = (cfg.axisY || this.default_cfg.axisY)

this.style.top = this.axisY*unit + 'px'

this.style.background = cfg.background || this.default_cfg.background

},

collideWith:function(sprite){

if(this.axisX == sprite.axisX &&this.axisY == sprite.axisY){

return true

}else{

return false

}

}

})

var SnakeNode = new Class(Sprite)

SnakeNode.include({

init:function(cfg){

this._super.init.call(this,cfg)

this.direction = cfg.direction || this.default_cfg.direction

this.lastDirc = cfg.lastDirc || this.default_cfg.lastDirc

this.paint()

},

march:function(){

var unit = Context.getContext().unit

if(this.direction == 0){

this.axisY -= 1

}else if(this.direction == 6){

this.axisY += 1

}else if(this.direction == 9){

this.axisX -= 1

}else if(this.direction == 3){

this.axisX += 1

}

this.style.left = this.axisX*unit + "px"

this.style.top = this.axisY*unit + "px"

this.lastDirc = this.direction

this.repaint()

},

isOutOfBound:function(){

if(this.axisX <0 || this.axisY <0 || this.axisX >= configuration.unit || this.axisY >= configuration.unit)

return true

return false

}

})

var Snake = new Class

Snake.include({

init:function(){

this.nodes = []

this.addNode()

this.lock = false

document.onkeydown = window.onkeydown = this.proxy(function(event){

event = event?event:window.event

if(this.lock)return//prevent push button too fast

this.lock = true

var head = this.nodes[0]

var direction = head.direction

if(event.keyCode == 37){

if(direction != 3){

head.direction = 9

}

}else if(event.keyCode == 38){

if(direction != 6){

head.direction = 0

}

}else if(event.keyCode == 39){

if(direction != 9){

head.direction = 3

}

}else if(event.keyCode == 40){

if(direction != 0){

head.direction = 6

}

}

this.nodes[0].lastDirc = direction

})

},

addNode:function(){

var lastNode = this.nodes[this.nodes.length-1]

var direction = 3

var axisX = 0,axisY = 0

if(lastNode){

direction = lastNode.direction

if(lastNode.direction==0){

axisY = lastNode.axisY + 1

axisX = lastNode.axisX

}else if(lastNode.direction==6){

axisY = lastNode.axisY - 1

axisX = lastNode.axisX

}else if(lastNode.direction == 9){

axisX = lastNode.axisX + 1

axisY = lastNode.axisY

}else if(lastNode.direction == 3){

axisX = lastNode.axisX - 1

axisY = lastNode.axisY

}

}

this.nodes.push(new SnakeNode({

id:this.nodes.length+1,

direction:direction,

axisX:axisX,

axisY:axisY

}))

},

march:function(){

for(var i=0i<this.nodes.lengthi++){

var curNode = this.nodes[i]

var nextDirc = curNode.lastDirc

curNode.march()

if(i == 0){

if(curNode.isOutOfBound()){

alert("游戏结束!")

Context.getContext().game.end()

}

for(var j=1j<this.nodes.lengthj++){

if(curNode.collideWith(this.nodes[j])){

alert("游戏结束")

Context.getContext().game.end()

break

}

}

}

if(i+1 <this.nodes.length){

this.nodes[i+1].lastDirc = this.nodes[i+1].direction

this.nodes[i+1].direction = nextDirc

}

}

var game = Context.getContext().getGame()

if(this.nodes[0].collideWith(game.randomNode)){

this.addNode()

game.randomNodeFn()

}

this.lock = false

}

})

var Game = new Class

Game.include({

init:function(){

this.snake = new Snake

Context.getContext().setGame(this)

},

start:function(){

this.randomNodeFn()

var _this = this

this.interval = setInterval(function(){

_this.snake.march()

},Context.getContext().interval)

},

end:function(){

window.clearInterval(this.interval)

},

randomNodeFn:function(){

if(this.randomNode)this.randomNode.wipeOff()

while(true){

var rd_x = Math.floor(configuration.unit * Math.random())

var rd_y = Math.floor(configuration.unit * Math.random())

var isCrash = false

for(var i=0i<this.snake.nodes.lengthi++){

if(rd_x == this.snake.nodes[i].axisX &&rd_y == this.snake.nodes[i].axisY){

isCrash = true

break

}

}

if(!isCrash){

this.randomNode = new SnakeNode({

background:'red',

axisX:rd_x,

axisY:rd_y

})

break

}

}

}

})

window.onload = function(){

var game = new Game()

game.start()

}

snake.js

代码如下:::

复制代码

代码如下:

var canvas

var ctx

var timer

//measures

var x_cnt = 15

var y_cnt = 15

var unit = 48

var box_x = 0

var box_y = 0

var box_width = 15 * unit

var

box_height = 15 * unit

var bound_left = box_x

var bound_right = box_x

+ box_width

var bound_up = box_y

var bound_down = box_y + box_height

//images

var image_sprite

//objects

var snake

var food

var food_x

var food_y

//functions

function Role(sx, sy, sw,

sh, direction, status, speed, image, flag)

{

this.x = sx

this.y =

sy

this.w = sw

this.h = sh

this.direction = direction

this.status = status

this.speed = speed

this.image = image

this.flag = flag

}

function transfer(keyCode)

{

switch

(keyCode)

{

case 37:

return 1

case 38:

return 3

case

39:

return 2

case 40:

return 0

}

}

function addFood()

{

//food_x=box_x+Math.floor(Math.random()*(box_width-unit))

//food_y=box_y+Math.floor(Math.random()*(box_height-unit))

food_x =

unit * Math.floor(Math.random() * x_cnt)

food_y = unit *

Math.floor(Math.random() * y_cnt)

food = new Role(food_x, food_y, unit,

unit, 0, 0, 0, image_sprite, true)

}

function play(event)

{

var

keyCode

if (event == null)

{

keyCode = window.event.keyCode

window.event.preventDefault()

}

else

{

keyCode =

event.keyCode

event.preventDefault()

}

var cur_direction =

transfer(keyCode)

snake[0].direction = cur_direction

}

function

update()

{

//add a new part to the snake before move the snake

if

(snake[0].x == food.x &&snake[0].y == food.y)

{

var length =

snake.length

var tail_x = snake[length - 1].x

var tail_y =

snake[length - 1].y

var tail = new Role(tail_x, tail_y, unit, unit,

snake[length - 1].direction, 0, 0, image_sprite, true)

snake.push(tail)

addFood()

}

//modify attributes

//move the head

switch

(snake[0].direction)

{

case 0: //down

snake[0].y += unit

if

(snake[0].y >bound_down - unit)

snake[0].y = bound_down - unit

break

case 1: //left

snake[0].x -= unit

if (snake[0].x <

bound_left)

snake[0].x = bound_left

break

case 2: //right

snake[0].x += unit

if (snake[0].x >bound_right - unit)

snake[0].x = bound_right - unit

break

case 3: //up

snake[0].y

-= unit

if (snake[0].y <bound_up)

snake[0].y = bound_up

break

}

//move other part of the snake

for (var i = snake.length - 1i

>= 0i--)

{

if (i >0)

//snake[i].direction=snake[i-1].direction

{

snake[i].x = snake[i -

1].x

snake[i].y = snake[i - 1].y

}

}

}

function

drawScene()

{

ctx.clearRect(box_x, box_y, box_width, box_height)

ctx.strokeStyle = "rgb(0,0,0"

ctx.strokeRect(box_x, box_y, box_width,

box_height)

//detection collisions

//draw images

for (var i = 0i

<snake.lengthi++)

{

ctx.drawImage(image_sprite, snake[i].x,

snake[i].y)

}

ctx.drawImage(image_sprite, food.x, food.y)

}

function init()

{

canvas = document.getElementById("scene")

ctx

= canvas.getContext('2d')

//images

image_sprite = new Image()

image_sprite.src = "images/sprite.png"

image_sprite.onLoad = function

()

{}

//ojects

snake = new Array()

var head = new Role(0 *

unit, 0 * unit, unit, unit, 5, 0, 1, image_sprite, true)

snake.push(head)

window.addEventListener('keydown', play, false)

addFood()

setInterval(update, 300)//note

setInterval(drawScene, 30)

}

望采纳!!!!

<html>

<head>

<title>贪吃蛇 Snake v2.4</title>

<style>

body{

font-size:9pt

}

table{

border-collapse: collapse

border:solid #333 1px

}

td{

height: 10px

width: 10px

font-size: 0px

}

.filled{

background-color:blue

}

</style>

</head>

<script>

function $(id){return document.getElementById(id)}

/**************************************************************

* javascript贪吃蛇 v2.4 <br />

* author: sunxing007 05/14/2009<br />

* 转载请注明来自http://blog.csdn.net/sunxing007 谢谢!<br />

* v2.4修正了蛇身颜色可以随着蛇前进而移动

**************************************************************/

//贪吃蛇类

var Snake = {

tbl: null,

/**

* body: 蛇身,数组放蛇的每一节,

* 数据结构{x:x0, y:y0, color:color0},

* x,y表示坐标,color表示颜色

**/

body: [],

//当前移动的方向,取值0,1,2,3, 分别表示向上,右,下,左, 按键盘方向键可以改变它

direction: 0,

//定时器

timer: null,

//速度

speed: 250,

//是否已经暂停

paused: true,

//行数

rowCount: 30,

//列数

colCount: 30,

//初始化

init: function(){

var colors = ['red','orange','yellow','green','blue','purple','#ccc']

this.tbl = $("main")

var x = 0

var y = 0

var colorIndex = 0

//产生初始移动方向

this.direction = Math.floor(Math.random()*4)

//构造table

for(var row=0row<this.rowCountrow++){

var tr=this.tbl.insertRow(-1)

for(var col=0col<this.colCountcol++) {

var td=tr.insertCell(-1)

}

}

//产生20个松散节点

for(var i=0i<10i++){

x = Math.floor(Math.random()*this.colCount)

y = Math.floor(Math.random()*this.rowCount)

colorIndex = Math.floor(Math.random()*7)

if(!this.isCellFilled(x,y)){

this.tbl.rows[y].cells[x].style.backgroundColor = colors[colorIndex]

}

}

//产生蛇头

while(true){

x = Math.floor(Math.random()*this.colCount)

y = Math.floor(Math.random()*this.rowCount)

if(!this.isCellFilled(x,y)){

this.tbl.rows[y].cells[x].style.backgroundColor = "black"

this.body.push({x:x,y:y,color:'black'})

break

}

}

this.paused = true

//添加键盘事件

document.onkeydown= function(e){

if (!e)e=window.event

switch(e.keyCode | e.which | e.charCode){

case 13: {

if(Snake.paused){

Snake.move()

Snake.paused = false

}

else{

//如果没有暂停,则停止移动

Snake.pause()

Snake.paused = true

}

break

}

case 37:{//left

//阻止蛇倒退走

if(Snake.direction==1){

break

}

Snake.direction = 3

break

}

case 38:{//up

//快捷键在这里起作用

if(event.ctrlKey){

Snake.speedUp(-20)

break

}

if(Snake.direction==2){//阻止蛇倒退走

break

}

Snake.direction = 0

break

}

case 39:{//right

if(Snake.direction==3){//阻止蛇倒退走

break

}

Snake.direction = 1

break

}

case 40:{//down

if(event.ctrlKey){

Snake.speedUp(20)

break

}

if(Snake.direction==0){//阻止蛇倒退走

break

}

Snake.direction = 2

break

}

}

}

},

//移动

move: function(){

this.timer = setInterval(function(){

Snake.erase()

Snake.moveOneStep()

Snake.paint()

}, this.speed)

},

//移动一节身体

moveOneStep: function(){

if(this.checkNextStep()==-1){

clearInterval(this.timer)

alert("Game over!\nPress Restart to continue.")

return

}

if(this.checkNextStep()==1){

var _point = this.getNextPos()

var _x = _point.x

var _y = _point.y

var _color = this.getColor(_x,_y)

this.body.unshift({x:_x,y:_y,color:_color})

//因为吃了一个食物,所以再产生一个食物

this.generateDood()

return

}

//window.status = this.toString()

var point = this.getNextPos()

//保留第一节的颜色

var color = this.body[0].color

//颜色向前移动

for(var i=0i<this.body.length-1i++){

this.body[i].color = this.body[i+1].color

}

//蛇尾减一节, 蛇尾加一节,呈现蛇前进的效果

this.body.pop()

this.body.unshift({x:point.x,y:point.y,color:color})

//window.status = this.toString()

},

//探寻下一步将走到什么地方

pause: function(){

clearInterval(Snake.timer)

this.paint()

},

getNextPos: function(){

var x = this.body[0].x

var y = this.body[0].y

var color = this.body[0].color

//向上

if(this.direction==0){

y--

}

//向右

else if(this.direction==1){

x++

}

//向下

else if(this.direction==2){

y++

}

//向左

else{

x--

}

//返回一个坐标

return {x:x,y:y}

},

//检查将要移动到的下一步是什么

checkNextStep: function(){

var point = this.getNextPos()

var x = point.x

var y = point.y

if(x<0||x>=this.colCount||y<0||y>=this.rowCount){

return -1//触边界,游戏结束

}

for(var i=0i<this.body.lengthi++){

if(this.body[i].x==x&&this.body[i].y==y){

return -1//碰到自己的身体,游戏结束

}

}

if(this.isCellFilled(x,y)){

return 1//有东西

}

return 0//空地

},

//擦除蛇身

erase: function(){

for(var i=0i<this.body.lengthi++){

this.eraseDot(this.body[i].x, this.body[i].y)

}

},

//绘制蛇身

paint: function(){

for(var i=0i<this.body.lengthi++){

this.paintDot(this.body[i].x, this.body[i].y,this.body[i].color)

}

},

//擦除一节

eraseDot: function(x,y){

this.tbl.rows[y].cells[x].style.backgroundColor = ""

},

paintDot: function(x,y,color){

this.tbl.rows[y].cells[x].style.backgroundColor = color

},

//得到一个坐标上的颜色

getColor: function(x,y){

return this.tbl.rows[y].cells[x].style.backgroundColor

},

//用于调试

toString: function(){

var str = ""

for(var i=0i<this.body.lengthi++){

str += "x:" + this.body[i].x + " y:" + this.body[i].y + " color:" + this.body[i].color + " - "

}

return str

},

//检查一个坐标点有没有被填充

isCellFilled: function(x,y){

if(this.tbl.rows[y].cells[x].style.backgroundColor == ""){

return false

}

return true

},

//重新开始

restart: function(){

if(this.timer){

clearInterval(this.timer)

}

for(var i=0i<this.rowCounti++){

this.tbl.deleteRow(0)

}

this.body = []

this.init()

this.speed = 250

},

//加速

speedUp: function(time){

if(!this.paused){

if(this.speed+time<10||this.speed+time>2000){

return

}

this.speed +=time

this.pause()

this.move()

}

},

//产生食物。

generateDood: function(){

var colors = ['red','orange','yellow','green','blue','purple','#ccc']

var x = Math.floor(Math.random()*this.colCount)

var y = Math.floor(Math.random()*this.rowCount)

var colorIndex = Math.floor(Math.random()*7)

if(!this.isCellFilled(x,y)){

this.tbl.rows[y].cells[x].style.backgroundColor = colors[colorIndex]

}

}

}

</script>

<body onload="Snake.init()">

/*************************************************************<br />

* javascript贪吃蛇 v2.4<br />

* author: sunxing007 05/14/2009<br />

* 转载请注明来自 <a href="http://blog.csdn.net/sunxing007">http://blog.csdn.net/sunxing007</a>谢谢!<br />

**************************************************************/<br />

<table id="main" border="1" cellspacing="0" cellpadding="0"></table>

<input type="button" id="btn" value="开始/暂停" />点左边按钮或按Enter开始/暂停游戏<br />

<input type="button" id="reset" value="重新开始" /><br />

<input type="button" id="upSpeed" value="加速" />点左边按钮或按Ctrl + ↑加速<br />

<input type="button" id="downSpeed" value="减速" />点左边按钮或按Ctrl + ↓减速

<script>

$('btn').onclick = function(){

if(Snake.paused){

Snake.move()

Snake.paused = false

}

else{

Snake.pause()

Snake.paused = true

}

}

$("reset").onclick = function(){

Snake.restart()

this.blur()

}

$("upSpeed").onclick = function(){

Snake.speedUp(-20)

}

$("downSpeed").onclick = function(){

Snake.speedUp(20)

}

</script>

</body>

</html>