课程设计:使用JavaScript制作一个网页上的贪吃蛇游戏

JavaScript012

课程设计:使用JavaScript制作一个网页上的贪吃蛇游戏,第1张

<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>

//package main

import java.awt.Color

import java.awt.event.ActionEvent

import java.awt.event.ActionListener

import java.awt.event.KeyEvent

import java.awt.event.KeyListener

import java.awt.event.WindowAdapter

import java.awt.event.WindowEvent

import java.io.BufferedReader

import java.io.FileInputStream

import java.io.FileOutputStream

import java.io.InputStreamReader

import javax.swing.ImageIcon

import javax.swing.JFrame

import javax.swing.JLabel

import javax.swing.JMenu

import javax.swing.JMenuBar

import javax.swing.JMenuItem

import javax.swing.JOptionPane

import javax.swing.JPanel

public class TanChiShe implements KeyListener,ActionListener{

/**

* @param args

*/

int max = 300//蛇长最大值

final int JianJu = 15 //设定蛇的运动网格间距(窗口最大32*28格)

byte fangXiang = 4 //控制蛇的运动方向,初始为右

int time = 500 //蛇的运动间隔时间

int jianTime = 2//吃一个减少的时间

int x,y//蛇的运动坐标,按网格来算

int x2,y2//暂存蛇头的坐标

int jiFenQi = 0//积分器

boolean isRuned = false//没运行才可设级别

boolean out = false//没开始运行?

boolean run = false//暂停运行

String JiBie = "中级"

JFrame f = new JFrame("贪吃蛇 V1.0")

JPanel show = new JPanel()

JLabel Message = new JLabel("级别:中级蛇长:5 时间500ms 分数:00")

// JButton play = new JButton("开始")

JLabel sheTou

JLabel shiWu

JLabel sheWei[] = new JLabel[max]

static int diJi = 4//第几个下标的蛇尾要被加上

ImageIcon shang = new ImageIcon("tuPian\\isSheTouUp.png")//产生四个上下左右的蛇头图案

ImageIcon xia = new ImageIcon("tuPian\\isSheTouDown.png")

ImageIcon zhuo = new ImageIcon("tuPian\\isSheTouLeft.png")

ImageIcon you = new ImageIcon("tuPian\\isSheTouRight.png")

JMenuBar JMB = new JMenuBar()

JMenu file = new JMenu("开始游戏")

JMenuItem play = new JMenuItem(" 开始游戏 ")

JMenuItem pause = new JMenuItem(" 暂停游戏 ")

JMenu hard = new JMenu("游戏难度")

JMenuItem gao = new JMenuItem("高级")

JMenuItem zhong = new JMenuItem("中级")

JMenuItem di = new JMenuItem("低级")

JMenu about = new JMenu(" 关于 ")

JMenuItem GF = new JMenuItem("※高分榜")

JMenuItem ZZ = new JMenuItem("关于作者")

JMenuItem YX = new JMenuItem("关于游戏")

JMenuItem QK = new JMenuItem("清空记录")

static TanChiShe tcs = new TanChiShe()

public static void main(String[] args) {

// TanChiShe tcs = new TanChiShe()

tcs.f()

}

public void f(){

f.setBounds(250,100,515,530)

f.setLayout(null)

f.setAlwaysOnTop(true)//窗口始终保持最前面

f.setBackground(new Color(0,0,0))

f.setDefaultCloseOperation(0)

f.setResizable(false)

f.setVisible(true)

// f.getContentPane().setBackground(Color.BLACK)

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0)//退出程序

}

})

f.setJMenuBar(JMB)

JMB.add(file)

file.add(play)

file.add(pause)

JMB.add(hard)

hard.add(gao)

hard.add(zhong)

hard.add(di)

JMB.add(about)

about.add(GF)

GF.setForeground(Color.blue)

about.add(ZZ)

about.add(YX)

about.add(QK)

QK.setForeground(Color.red)

f.add(show)

show.setBounds(0,f.getHeight()-92,f.getWidth(),35)

// show.setBackground(Color.green)

// f.add(play)

// play.setBounds(240,240,80,25)

play.addActionListener(this)

pause.addActionListener(this)

gao.addActionListener(this)

zhong.addActionListener(this)

di.addActionListener(this)

GF.addActionListener(this)

ZZ.addActionListener(this)

YX.addActionListener(this)

QK.addActionListener(this)

show.add(Message)

Message.setForeground(Color.blue)

f.addKeyListener(this)

// show.addKeyListener(this)

play.addKeyListener(this)

sheChuShi()

}

public void sheChuShi(){//蛇初始化

sheTou = new JLabel(you)//用向右的图来初始蛇头

f.add(sheTou)

sheTou.setBounds(JianJu*0,JianJu*0,JianJu,JianJu)

// System.out.println("ishere")

shiWu = new JLabel("■")

f.add(shiWu)

shiWu.setBounds(10*JianJu,10*JianJu,JianJu,JianJu)

for(int i=0i<=diJii++) {

sheWei[i] = new JLabel("■")

f.add(sheWei[i])

sheWei[i].setBounds(-1*JianJu,0*JianJu,JianJu,JianJu)

}

while(true){

if(out == true){

yunXing()

break

}

try{

Thread.sleep(200)

}catch(Exception ex){

ex.printStackTrace()

}

}

}

public void sheJiaChang(){//蛇的长度增加

if(diJi <max){

sheWei[++diJi] = new JLabel(new ImageIcon("tuPian\\isSheWei.jpg"))

f.add(sheWei[diJi])

sheWei[diJi].setBounds(sheWei[diJi-1].getX(),sheWei[diJi-1].getY(),JianJu,JianJu)

// System.out.println("diJi "+diJi)

}

}

public void pengZhuanJianCe(){//检测蛇的碰撞情况

if(sheTou.getX()<0 || sheTou.getY()<0 ||

sheTou.getX()>f.getWidth()-15 || sheTou.getY()>f.getHeight()-105 ){

gameOver()

// System.out.println("GameOVER")

}

if(sheTou.getX() == shiWu.getX() &&sheTou.getY() == shiWu.getY()){

out: while(true){

shiWu.setLocation((int)(Math.random()*32)*JianJu,(int)(Math.random()*28)*JianJu)

for(int i=0i<=diJii++){

if(shiWu.getX()!= sheWei[i].getX() &&shiWu.getY()!=sheWei[i].getY()

&&sheTou.getX()!=shiWu.getX() &&sheTou.getY()!= shiWu.getY()){//如果食物不在蛇身上则退出循环,产生食物成功

break out

}

}

}

sheJiaChang()

// System.out.println("吃了一个")

if(time>100 ){

time -= jianTime

}

else{}

Message.setText("级别:"+JiBie+" 蛇长:"+(diJi+2)+"时间:"+time+"ms 分数:"+(jiFenQi+=10)+"")

}

for(int i=0i<=diJii++){

if(sheTou.getX() == sheWei[i].getX() &&sheTou.getY() == sheWei[i].getY()){

gameOver()

// System.out.println("吃到尾巴了")

}

}

}

public void yunXing(){

while(true){

while(run){

if(fangXiang == 1){//上

y-=1

}

if(fangXiang == 2){//下

y+=1

}

if(fangXiang == 3){//左

x-=1

}

if(fangXiang == 4){//右

x+=1

}

x2 = sheTou.getX()

y2 = sheTou.getY()

sheTou.setLocation(x*JianJu,y*JianJu)//设置蛇头的坐标 网格数*间隔

for(int i=diJii>=0i--){

if(i==0){

sheWei[i].setLocation(x2,y2)

// System.out.println(i+" "+sheTou.getX()+" "+sheTou.getY())

}

else{

sheWei[i].setLocation(sheWei[i-1].getX(),sheWei[i-1].getY())

//System.out.println(i+" "+sheWei[i].getX()+" "+sheWei[i].getY())

}

}

pengZhuanJianCe()

try{

Thread.sleep(time)

}catch(Exception e){

e.printStackTrace()

}

}

Message.setText("级别:"+JiBie+" 蛇长:"+(diJi+2)+"时间:"+time+"ms 分数:"+(jiFenQi+=10)+"")

try{

Thread.sleep(200)

}catch(Exception e){

e.printStackTrace()

}

}

}

public void gameOver(){//游戏结束时处理

int in = JOptionPane.showConfirmDialog(f,"游戏已经结束!\n是否要保存分数","提示",JOptionPane.YES_NO_OPTION)

if(in == JOptionPane.YES_OPTION){

// System.out.println("YES")

String s = JOptionPane.showInputDialog(f,"输入你的名字:")

try{

FileInputStream fis = new FileInputStream("GaoFen.ini")//先把以前的数据读出来加到写的数据前

InputStreamReader isr = new InputStreamReader(fis)

BufferedReader br = new BufferedReader(isr)

String s2,setOut = ""

while((s2=br.readLine())!= null){

setOut =setOut+s2+"\n"

}

FileOutputStream fos = new FileOutputStream("GaoFen.ini")//输出到文件流

s = setOut+s+":"+jiFenQi+"\n"

fos.write(s.getBytes())

}catch(Exception e){}

}

System.exit(0)

}

public void keyTyped(KeyEvent arg0) {

// TODO 自动生成方法存根

}

public void keyPressed(KeyEvent arg0) {

// System.out.println(arg0.getSource())

if(arg0.getKeyCode() == KeyEvent.VK_UP){//按上下时方向的值相应改变

if(fangXiang != 2){

fangXiang = 1

// sheTou.setIcon(shang)//设置蛇的方向

}

//System.out.println("UP")

}

if(arg0.getKeyCode() == KeyEvent.VK_DOWN){

if(fangXiang != 1){

fangXiang = 2

// sheTou.setIcon(xia)

}

//System.out.println("DOWN")

}

if(arg0.getKeyCode() == KeyEvent.VK_LEFT){//按左右时方向的值相应改变

if(fangXiang != 4){

fangXiang = 3

//sheTou.setIcon(zhuo)

}

// System.out.println("LEFT")

}

if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){

if(fangXiang != 3){

fangXiang = 4

//sheTou.setIcon(you)

}

// System.out.println("RIGHT")

}

}

public void keyReleased(KeyEvent arg0) {

// TODO 自动生成方法存根

}

public void actionPerformed(ActionEvent arg0) {

// TODO 自动生成方法存根

JMenuItem JI = (JMenuItem)arg0.getSource()

if(JI == play){

out = true

run = true

isRuned = true

gao.setEnabled(false)

zhong.setEnabled(false)

di.setEnabled(false)

}

if(JI == pause){

run = false

}

if(isRuned == false){//如果游戏还没运行,才可以设置级别

if(JI == gao){

time = 200

jianTime = 1

JiBie = "高级"

Message.setText("级别:"+JiBie+" 蛇长:"+(diJi+2)+"时间:"+time+"ms 分数:"+jiFenQi)

}

if(JI == zhong){

time = 400

jianTime = 2

JiBie = "中级"

Message.setText("级别:"+JiBie+" 蛇长:"+(diJi+2)+"时间:"+time+"ms 分数:"+jiFenQi)

}

if(JI == di){

time = 500

jianTime = 3

JiBie = "低级"

Message.setText("级别:"+JiBie+" 蛇长:"+(diJi+2)+"时间:"+time+"ms 分数:"+jiFenQi)

}

}

if(JI == GF){

try{

FileInputStream fis = new FileInputStream("GaoFen.ini")

InputStreamReader isr = new InputStreamReader(fis)

BufferedReader br = new BufferedReader(isr)

String s,setOut = ""

while((s=br.readLine())!= null){

setOut =setOut+s+"\n"

}

if(setOut.equals("")){

JOptionPane.showMessageDialog(f,"暂无保存记录!","高分榜",JOptionPane.INFORMATION_MESSAGE)

}

else{

JOptionPane.showMessageDialog(f,setOut)

}

}catch(Exception e){

e.printStackTrace()

}

}

if(JI == ZZ){//关于作者

JOptionPane.showMessageDialog(f,"软件作者:申志飞\n地址:四川省绵阳市\nQQ:898513806\nE-mail:[email protected]","关于作者",JOptionPane.INFORMATION_MESSAGE)

}

if(JI == YX){//关于游戏

JOptionPane.showMessageDialog(f,"贪吃蛇游戏\n游戏版本 V1.0","关于游戏",JOptionPane.INFORMATION_MESSAGE)

}

if(JI == QK){

try{

int select = JOptionPane.showConfirmDialog(f,"确实要清空记录吗?","清空记录",JOptionPane.YES_OPTION)

if(select == JOptionPane.YES_OPTION){

String setOut = ""

FileOutputStream fos = new FileOutputStream("GaoFen.ini")//输出到文件流

fos.write(setOut.getBytes())

}

}catch(Exception ex){}

}

}

}

//是我自己写的,本来里面有图片的,但无法上传,所以把图片去掉了,里面的ImageIcon等语句可以去掉。能正常运行。