metanohi-misc-subsites/projects/snake/script.js

407 lines
12 KiB
JavaScript

/*
This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.
*/
window.onload=function() {
//dbg=document.createElement("div")
//document.body.appendChild(dbg)
field_width=48
field_height=30
dot_width=10
dot_height=10
create_field()
adjust_field()
point=new Array()
bpoints=new Array()
points=new Array()
lines=new Array()
speed=5
gameload()
}
function create_field() {
bfield=document.createElement("div")
bfield.id="bfield"
field=document.createElement("div")
field.id="field"
document.body.appendChild(bfield)
document.body.appendChild(field)
dotdiv=document.createElement("div")
dotdiv.id="dot"
field.appendChild(dotdiv)
score_div=document.createElement("div")
score_div.style.cssFloat="left"
score_val=document.createTextNode("Score: 0")
score_div.appendChild(score_val)
speed_div=document.createElement("div")
speed_div.style.cssFloat="right"
speed_val=document.createTextNode("Speed: 5")
speed_div.appendChild(speed_val)
bfield.appendChild(score_div)
bfield.appendChild(speed_div)
}
function adjust_field() {
bfield.style.width=field_width*dot_width-6+"px"
bfield.style.height="24px"
bfield.style.marginLeft=-(field_width*dot_width/2)-2+"px"
bfield.style.marginTop=-(field_height*dot_height/2)-18+"px"
field.style.width=field_width*dot_width+"px"
field.style.height=field_height*dot_height+"px"
field.style.marginLeft=-(field_width*dot_width/2)-2+"px"
field.style.marginTop=-(field_height*dot_height/2)+14+"px"
}
function gameload() {
score=0
score_val.data="Score: 0"
var i
var lines_len=lines.length
for (i=0;i<lines_len;i++) {
field.removeChild(lines[i])
}
point.splice(0,point.length)
bpoints.splice(0,bpoints.length)
lines.splice(0,lines_len)
point[0]=[2,3]
point[1]=[4,3]
dir=2
dotx=-1
doty=-1
mov=false
gameover=false
movement()
placedot()
}
document.onkeydown=function(e) {
var key
if (window.event) key=window.event.keyCode
else if (e) key=e.which
else key=0
if (key==19 && mov && !gameover) mov=false
else if (key==19 && !mov && !gameover) mov=true
if (key>=37 && key<=40) {
diff=[point[point.length-2][0]-point[point.length-1][0],point[point.length-2][1]-point[point.length-1][1]]
if (diff[0]<0) diff[0]=-diff[0]
if (diff[1]<0) diff[1]=-diff[1]
if (diff[0]>1 || diff[1]>1) {
var coor_a, coor_b
if (key==38 && dir!=1 && dir!=3) {
coor_a=[0,-1]
if (dir==2) coor_b=[-1,0]
else if (dir==4) coor_b=[1,0]
dir=1
}
else if (key==39 && dir!=2 && dir!=4) {
coor_a=[1,0]
if (dir==1) coor_b=[0,1]
else if (dir==3) coor_b=[0,-1]
dir=2
}
else if (key==40 && dir!=3 && dir!=1) {
coor_a=[0,1]
if (dir==2) coor_b=[-1,0]
else if (dir==4) coor_b=[1,0]
dir=3
}
else if (key==37 && dir!=4 && dir!=2) {
coor_a=[-1,0]
if (dir==3) coor_b=[0,-1]
else if (dir==1) coor_b=[0,1]
dir=4
}
if (coor_a) {
point[point.length-1]=[point[point.length-1][0]+coor_b[0],point[point.length-1][1]+coor_b[1]]
point[point.length]=[point[point.length-1][0]+coor_a[0],point[point.length-1][1]+coor_a[1]]
}
}
}
if (((key>=37 && key<=40) || key==32 || key==13) && !mov && !gameover) {
mov=true
movement()
}
if ((key==32 || key==13) && !mov && gameover) {
gameload()
}
if (key==33 && speed<9) change_speed(1)
else if (key==34 && speed>1) change_speed(-1)
}
function change_score(ud) {
score+=ud
score_val.data="Score: "+score
}
function change_speed(ud) {
speed+=ud
speed_val.data="Speed: "+speed
}
function placedot() {
var x, y, coor, t_ok
var point_len=point.length
var bpoints_len=bpoints.length
var place_ok=false
var full_len=point_len+bpoints_len
//var a=0
//dbg.innerHTML=a+":<br />"
do {
x=Math.floor(Math.random()*field_width)
y=Math.floor(Math.random()*field_height)
t_ok = true
for (i=1;i<full_len;i++) {
if (i<point_len) coor=[[point[i-1][0],point[i-1][1]],[point[i][0],point[i][1]]]
else coor=bpoints[i-point_len]
if (coor[0][1]>coor[1][1] || coor[0][0]>coor[1][0]) coor=[coor[1],coor[0]]
coor[0][1]=coor[0][1]%(field_height)
coor[1][1]=coor[1][1]%(field_height)
if (coor[0][1]<0) coor[0][1]+=field_height
if (coor[1][1]<0) coor[1][1]+=field_height
if (coor[1][1]<coor[0][1]) coor[1][1]=field_height-1
coor[0][0]=coor[0][0]%(field_width)
coor[1][0]=coor[1][0]%(field_width)
if (coor[0][0]<0) coor[0][0]+=field_width
if (coor[1][0]<0) coor[1][0]+=field_width
if (coor[1][0]<coor[0][0]) coor[1][0]=field_width-1
if (i>=point_len && coor[0][0]<coor[1][0]) coor[1][0]--
if (i>=point_len && coor[0][1]<coor[1][1]) coor[1][1]--
if (x>=coor[0][0] && x<=coor[1][0] && y>=coor[0][1] && y<=coor[1][1]) {
t_ok=false
}
//dbg.innerHTML+=x+","+y+" | "+coor[0]+"-"+coor[1]+"<br />"
}
if (t_ok)
place_ok=true
//a++
} while (!place_ok)
dotx=x
doty=y
dotdiv.style.width=dot_width+"px"
dotdiv.style.height=dot_height+"px"
dotdiv.style.left=dotx*dot_width+"px"
dotdiv.style.top=doty*dot_height+"px"
}
function movement() {
bpoints.splice(0,bpoints.length)
points.splice(0,points.length)
var point_len=point.length
var i
var coorl, iffao
if (dir==1) coorl=[0,1]
else if (dir==2) coorl=[-1,0]
else if (dir==3) coorl=[0,-1]
else if (dir==4) coorl=[1,0]
var line_height, line_width, x, y
for (i=0;i<point_len-1;i++) {
if (point[i][0]==point[i+1][0] && point[i][1]>point[i+1][1]) {
line_height=point[i][1]-point[i+1][1]+1
line_width=1
x=point[i][0]
y=point[i+1][1]
}
else if (point[i][1]==point[i+1][1] && point[i+1][0]>point[i][0]) {
line_height=1
line_width=point[i+1][0]-point[i][0]+1
x=point[i][0]
y=point[i][1]
}
else if (point[i][0]==point[i+1][0] && point[i][1]<point[i+1][1]) {
line_height=point[i+1][1]-point[i][1]+1
line_width=1
x=point[i][0]
y=point[i][1]
}
else if (point[i][1]==point[i+1][1] && point[i+1][0]<point[i][0]) {
line_height=1
line_width=point[i][0]-point[i+1][0]+1
x=point[i+1][0]
y=point[i][1]
}
if (x>field_width-1) x=x%(field_width)
else if (x<0) x=field_width+x%(field_width)
if (y>field_height-1) y=y%(field_height)
else if (y<0) y=field_height+y%(field_height)
if (x==field_width) x=0
if (y==field_height) y=0
if (x+line_width>field_width) {
bpoints[bpoints.length]=[[0,y],[(x+line_width)%(field_width),y]]
line_width=field_width-x
}
if (y+line_height>field_height) {
bpoints[bpoints.length]=[[x,0],[x,(y+line_height)%(field_height)]]
line_height=field_height-y
}
line_height*=dot_height
line_width*=dot_width
x*=dot_width
y*=dot_height
points[points.length]=[line_height,line_width,x,y]
}
var bpoints_len=bpoints.length
for (i=0;i<bpoints_len;i++) {
if (bpoints[i][0][0]==bpoints[i][1][0] && bpoints[i][0][1]>bpoints[i][1][1]) {
line_height=bpoints[i][0][1]-bpoints[i][1][1]
line_width=1
x=bpoints[i][0][0]
y=bpoints[i][1][1]
}
else if (bpoints[i][0][1]==bpoints[i][1][1] && bpoints[i][1][0]>bpoints[i][0][0]) {
line_height=1
line_width=bpoints[i][1][0]-bpoints[i][0][0]
x=bpoints[i][0][0]
y=bpoints[i][0][1]
}
else if (bpoints[i][0][0]==bpoints[i][1][0] && bpoints[i][0][1]<bpoints[i][1][1]) {
line_height=bpoints[i][1][1]-bpoints[i][0][1]
line_width=1
x=bpoints[i][0][0]
y=bpoints[i][0][1]
}
else if (bpoints[i][0][1]==bpoints[i][1][1] && bpoints[i][1][0]<bpoints[i][0][0]) {
line_height=1
line_width=bpoints[i][0][0]-bpoints[i][1][0]
x=bpoints[i][1][0]
y=bpoints[i][0][1]
}
line_height*=dot_height
line_width*=dot_width
x*=dot_width
y*=dot_height
points[points.length]=[line_height,line_width,x,y]
}
x=point[point.length-1][0]%field_width
y=point[point.length-1][1]%field_height
if (x<0) x+=field_width
if (y<0) y+=field_height
var cutend=true
if (x==dotx && y==doty) {
change_score(speed)
placedot()
cutend=false
}
var full_len=point_len+bpoints_len
var coor
for (i=1;i<full_len;i++) {
if (i<point_len) coor=[[point[i-1][0],point[i-1][1]],[point[i][0],point[i][1]]]
else coor=bpoints[i-point_len]
if (coor[0][1]>coor[1][1] || coor[0][0]>coor[1][0]) coor=[coor[1],coor[0]]
coor[0][1]=coor[0][1]%(field_height)
coor[1][1]=coor[1][1]%(field_height)
if (coor[0][1]<0) coor[0][1]+=field_height
if (coor[1][1]<0) coor[1][1]+=field_height
if (coor[1][1]<coor[0][1]) coor[1][1]=field_height-1
coor[0][0]=coor[0][0]%(field_width)
coor[1][0]=coor[1][0]%(field_width)
if (coor[0][0]<0) coor[0][0]+=field_width
if (coor[1][0]<0) coor[1][0]+=field_width
if (coor[1][0]<coor[0][0]) coor[1][0]=field_width-1
var wcoor
if (dir==2 || dir==3) wcoor=1
else wcoor=0
if (i==point_len-1 && coor[wcoor][0]==x && coor[wcoor][1]==y) coor[wcoor]=[x+coorl[0],y+coorl[1]]
else if (i==full_len-1 && coor[wcoor][0]==x+coorl[1]+1 && coor[wcoor][1]==y+coorl[0]+1) coor[wcoor]=[x+coorl[0],y+coorl[1]]
if (i>=point_len && coor[0][0]<coor[1][0]) coor[1][0]--
if (i>=point_len && coor[0][1]<coor[1][1]) coor[1][1]--
if (x>=coor[0][0] && x<=coor[1][0] && y>=coor[0][1] && y<=coor[1][1]) {
mov=false
gameover=true
}
}
if (!gameover) {
var points_len=points.length
var lines_len=lines.length
if (points_len>lines_len) {
for (i=lines_len;i<points_len;i++) {
lines[i]=document.createElement("div")
field.appendChild(lines[i])
}
}
else if (points_len<lines_len) {
for (i=0;i<lines_len-points_len;i++) {
field.removeChild(lines[i])
}
lines.splice(0,i)
}
for (i=0;i<points_len;i++) {
lines[i].style.height=points[i][0]+"px"
lines[i].style.width=points[i][1]+"px"
lines[i].style.left=points[i][2]+"px"
lines[i].style.top=points[i][3]+"px"
}
i=point_len-1
if (point[i-1][0]==point[i][0] && point[i-1][1]>point[i][1]) point[i][1]--
else if (point[i-1][1]==point[i][1] && point[i][0]>point[i-1][0]) point[i][0]++
else if (point[i-1][0]==point[i][0] && point[i-1][1]<point[i][1]) point[i][1]++
else if (point[i-1][1]==point[i][1] && point[i][0]<point[i-1][0]) point[i][0]--
if (cutend) {
if (point[0][0]==point[1][0]) {
if (point[0][1]>point[1][1]) point[0][1]--
else if (point[0][1]<point[1][1]) point[0][1]++
if (point[0][1]==point[1][1]) point.splice(0,1)
}
else if (point[0][1]==point[1][1]) {
if (point[1][0]>point[0][0]) point[0][0]++
else if (point[1][0]<point[0][0]) point[0][0]--
if (point[1][0]==point[0][0]) point.splice(0,1)
}
}
if (mov) mov_t=setTimeout(movement,450/speed)
}
}