注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

深夜是徘徊在潮湿睫毛上的我的梦以及他的梦

是直到最后都无法放手的一种气息,是我们生命中最后的思念……

 
 
 

日志

 
 

贪吃蛇初版(自编游戏)  

2008-12-18 22:13:51|  分类: FC开发记录 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

近日,与网友常常讨论FC编程,终于决定各人写一个<贪吃蛇>,试试功力,好准备以后的合作.

下面的代码,是我编的,已经可以生成NES文件的了,也能玩.想要代码或ROM的朋友,请留下Email

贪吃蛇初版(自编游戏) - 维京人 - 深夜是徘徊在潮湿睫毛上的我的梦以及他的梦

///// v. 20081218

//header for nesasm
asm
.inesprg 1 ;//one PRG bank
.ineschr 1 ;//one CHR bank
.inesmir 0 ;//mirroring type 0
.inesmap 0 ;//memory mapper 0 (none)
.org $8000
.bank 0
endasm
///////////////////////////////////

goto start
data_1:
data "YOU LOSE",0
data_2:
data "YOU WIN",0
start:
// some init code based on Duck Hunt
// turn off the PPU
gosub vwait_start
asm
   cld
   sei
endasm

//now turn on the PPU
set $2000 %00100000
set $2001 %00011100 //sprites and bg visible, no sprite clipping
gosub clear_background
gosub vwait
gosub load_palette
gosub init_vars
gosub vwait_start
gosub draw_background
gosub vwait_end
gosub vwait_start
gosub draw_snake
gosub vwait_end

//the main program loop
mainloop:
gosub vwait_start
if moving=0 goto mainloop_2
gosub draw_snake_2
if lose=1 goto mainloop_4
if lose=2 goto mainloop_7
mainloop_2:
gosub vwait_end
gosub joy_handler
set temp01 delayer
mainloop_3:
set temp01 - temp01 1
gosub vwait
if temp01 > 0 goto mainloop_3
goto mainloop
mainloop_4:
set moving 0
set $2006 $21
set $2006 $8A
set x 0  
mainloop_5:
   set $2007 [data_1 x]
   inc x
   set a [data_1 x]
   if a <> 0 branchto mainloop_5
mainloop_6:
gosub vwait
goto mainloop_6

mainloop_7:
set moving 0
set $2006 $21
set $2006 $8A
set x 0  
mainloop_8:
   set $2007 [data_2 x]
   inc x
   set a [data_2 x]
   if a <> 0 branchto mainloop_8
goto mainloop_6

//set default sprite location
init_vars:
set snake_long 5
set snake_maxlong 49
set snake_winlong 30
set snake_headloc_h $21
set snake_headloc_l $0A
set snake_endloc_h $21
set snake_endloc_l + snake_headloc_l snake_long

set snake_facing 2 //0=左 1=右 2=上 3=下
set moving 0 //0=暂停 1=活动
set lose 0 //0=游戏中 1=失败 2=胜
set markendlater snake_long

set egg01 $9D
set egg01_M 3
set wall $81
set delayer 7

set add1_nl 0
set add1_nh 0
set add2_nl $20
set add2_nh 0
set sub1_nl 0
set sub1_nh 0
set sub2_nl $20
set sub2_nh 0

array snake 100
set snake_logend 99 //100-1
set snake_headmark 0
set snake_endmark 0

set x snake_headmark
set [snake x] snake_headloc_h
inc x
set [snake,x] snake_headloc_l
set snake_headmark 2
return

//routine to draw a sprite
draw_snake:
set $2006 snake_headloc_h
set $2006 snake_headloc_l
set $2007 $AC
//set $2007 $80
//set $2007 $80
//set $2007 $80
//set $2007 $80
//set $2007 $80
return

draw_snake_2:
set $2006 snake_headloc_h
set $2006 snake_headloc_l
set $2007 $80
if snake_facing=1 inc snake_headloc_l
if snake_facing=0 dec snake_headloc_l
if snake_facing=3 then
   set add1_nh snake_headloc_h
   set add1_nl snake_headloc_l
   set add2_nl $20
   set add2_nh 0
   gosub add16
   set snake_headloc_h add1_nh
   set snake_headloc_l add1_nl
   endif
if snake_facing=2 then
   set sub1_nh snake_headloc_h
   set sub1_nl snake_headloc_l
   set sub2_nl $20
   set sub2_nh 0
   gosub sub16
   set snake_headloc_h sub1_nh
   set snake_headloc_l sub1_nl
   endif
gosub CheckBoom
if lose=1 goto draw_snake_4
set $2006 snake_headloc_h
set $2006 snake_headloc_l
set $2007 + snake_facing $AA
gosub markhead
if markendlater>0 goto draw_snake_3
gosub readendmark
set $2006 snake_endloc_h
set $2006 snake_endloc_l
set $2007 0
goto draw_snake_4
draw_snake_3:
set markendlater - markendlater 1
draw_snake_4:
return

//检测碰撞
CheckBoom:
set $2006 snake_headloc_h
set $2006 snake_headloc_l
set temp01 [$2007]
if temp01=wall set lose 1
if temp01=egg01 goto CheckBoom_1
goto CheckBoom_2
CheckBoom_1:
set markendlater + markendlater egg01_M
set snake_long + snake_long markendlater
set temp01 egg01
gosub draw_egg
set temp02 wall
gosub draw_egg
gosub draw_egg
if snake_long > snake_winlong set lose 2
CheckBoom_2:
return

//记下蛇头位置,并指向下一记录点
markhead:
set x snake_headmark
set [snake,x] snake_headloc_h
inc x
set [snake,x] snake_headloc_l

inc snake_headmark
inc snake_headmark
if snake_headmark < snake_logend goto markhead_1
set snake_headmark 0
markhead_1:
return

//读出蛇尾位置,指向下一蛇尾位置
readendmark:
set x snake_endmark
set snake_endloc_h [snake,x]
set [snake,x] 0
inc x
set snake_endloc_l [snake,x]
set [snake,x] 0
inc snake_endmark
inc snake_endmark
if snake_endmark < snake_logend goto readendmark_1
set snake_endmark 0
readendmark_1:
return


//读取手柄,并判断合法移动,接收暂停和活动指令
joy_handler:
gosub joystick1
if joy1select=1 goto joy_handler_3
if snake_facing=0 set joy1right 0
if snake_facing=1 set joy1left 0
if snake_facing=2 set joy1down 0
if snake_facing=3 set joy1up 0
if moving=1 goto joy_handler_2

set temp01 0
asm
   lda #$0
   ora joy1left
   ora joy1right
   ora joy1up
   ora joy1down
   sta temp01
endasm
if temp01<>0 set moving 1
joy_handler_2:
if joy1left=1 set snake_facing 0
if joy1right=1 set snake_facing 1
if joy1up=1 set snake_facing 2
if joy1down=1 set snake_facing 3
goto joy_handler_4
joy_handler_3:
set moving 0
joy_handler_4:
return


//设定颜色
load_palette:
//set the PPU start address (background color 0)
set $2006 $3f
set $2006 0
set $2007 $0F //sky blue
set $2007 $25 //dark green
set $2007 $21 //light green
set $2007 $28 //tan

//set the PPU start address (foreground color 0)
set $2006 $3f
set $2006 $10
set $2007 $0F //mirror sky blue
set $2007 $25 //black
set $2007 $21 //white
set $2007 $28 //grey
return

//绘画背景
draw_background:
set point_h $20
set point_l $41
set linelong 30
gosub draw_aline
set point_h $23
set point_l $81
set linelong 30
gosub draw_aline
set point_h $20
set point_l $61
set linelong 25
gosub draw_aVerticalLine
set point_h $20
set point_l $7E
set linelong 26
gosub draw_aVerticalLine

set $2006 $21
set $2006 $66
set $2007 egg01
set $2006 $20
set $2006 $B9
set $2007 egg01
set $2006 $22
set $2006 $91
set $2007 egg01
set random_seed $56
set walls 0
draw_background_1:
set temp01 wall
gosub draw_egg
if walls<9 goto draw_background_1
set temp01 egg01
gosub draw_egg
return

draw_egg:
gosub random_number
set temp02 random_seed
asm
   lda temp02
   lsr a
   lsr a
   lsr a
   lsr a
   lsr a
   lsr a
   sta temp02
endasm
set $2006 + temp02 $20
gosub random_number
set temp03 random_seed
asm
   lda temp03
   lsr a
   lsr a
   lsr a
   lsr a
   sta temp03
endasm
set $2006 + temp03 $60
set $2007 temp01
return


//画横线 point_h,point_l起点地址 linelong线长
draw_aline:
set $2006 point_h
set $2006 point_l
set x 0
draw_aline_1:
set $2007 wall
inc x
if x < linelong goto draw_aline_1
return

//画竖线 point_h,point_l起点地址 linelong线长
draw_aVerticalLine:
set x 0
draw_aVerticalLine_1:
set $2006 point_h
set $2006 point_l
set $2007 wall
set add1_nh point_h
set add1_nl point_l
set add2_nl $20
set add2_nh 0
gosub add16
set point_h add1_nh
set point_l add1_nl
inc x
if x < linelong goto draw_aVerticalLine_1
return

///////////////////////////////

//update joystick button status
joystick1:
set $4016 1 //first strobe byte
set $4016 0 //second strobe byte
set joy1a & [$4016] 1
set joy1b & [$4016] 1
set joy1select & [$4016] 1
set joy1start & [$4016] 1
set joy1up & [$4016] 1
set joy1down & [$4016] 1
set joy1left & [$4016] 1
set joy1right & [$4016] 1
return

//wait for the start of the vertical blanking interval
vwait_start:
asm
   bit $2002
   bpl vwait_start
endasm
return

//wait for the end of the vertical blanking interval
vwait_end:
asm
   bit $2002
   bmi vwait_end
endasm
set a 0
set $2005 a
set $2005 a
set $2006 a
set $2006 a
return

//wait until screen refresh
vwait:
gosub vwait_start
gosub vwait_end
return

//clear the first background buffer (0)
clear_background:
gosub vwait
gosub clear_background_one
gosub vwait
gosub clear_background_two
return

clear_background_one:
set clear_background_temp $20
gosub clear_background_helper
set clear_background_temp $21
gosub clear_background_helper
set clear_background_temp $22
gosub clear_background_helper
set clear_background_temp $23
gosub clear_background_helper
gosub vwait
return

clear_background_two:
set clear_background_temp $24
gosub clear_background_helper
set clear_background_temp $25
gosub clear_background_helper
set clear_background_temp $26
gosub clear_background_helper
set clear_background_temp $27
gosub clear_background_helper
gosub vwait
return

clear_background_helper:
gosub vwait
set $2006 clear_background_temp
set $2006 0
return

clear_palette:
//wait for start of vblank
asm
   lda $2002
   bpl clear_palette
endasm
set $2006 $3f
set $2006 0
set x 0
clear_palette_1:
   set $2007 $0e
   inc x
   if x <> 32 branchto clear_palette_1
//wait for end of vblank
clear_palette_2:
   asm
    lda $2002
    bmi clear_palette_2
    lda #0
    sta $2005
    sta $2005
    sta $2006
    sta $2006
   endasm
return

add16:
asm
   lda add1_nl ;//mov a,add1_number_l
   clc
   adc add2_nl ;//add a,add2_number_l
   sta add1_nl ;//mov add1_number_l,a
   lda add1_nh ;//mov a,add1_number_h
   adc add2_nh ;//addc a,add2_number_h
   sta add1_nh ;//mov add1_number_h,a
endasm
return

sub16:
asm
   lda sub1_nl
   sec
   sbc sub2_nl
   sta sub1_nl
   lda sub1_nh
   sbc sub2_nh
   sta sub1_nh
endasm
return

// You must set random_seed to a non-zero value to initialize
array random_seed 1

// The function returns the random number in the A register
random_number:
asm
lda random_seed
and #$b8
ldx #$05
ldx #$00
random_number_floop:
   asl a
   bcc random_number_bitclr
   iny
random_number_bitclr:
   dex
   bne random_number_floop
random_number_noclr:
   tya
   lsr a
   lda random_seed
   rol a
   sta random_seed
   rts
endasm
/////////////////////////


//file footer
asm
;//jump table points to NMI, Reset, and IRQ start points
.bank 1
.org $fffa
.dw start, start, start
;//include CHR ROM
.bank 2
.org $0000
.incbin "ascii_2.chr"
.incbin "ascii_2.chr"
endasm

  评论这张
 
阅读(551)| 评论(4)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017