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

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

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

 
 
 

日志

 
 

贪吃蛇之2008-12-21版(自编游戏)  

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

  下载LOFTER 我的照片书  |

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

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

下面的代码,是我编的,已经可以生成NES文件的了,经过多次的修改,操作比较灵活.但仍然有BUG

下载地址:

http://www.uushare.com/user/fogota/file/1131578

 

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

goto start
data_str:
 //0
 data "YOU LOSE",0
 //9
 data "YOU WIN",0
 //17
 data "<< GREEDY SNAKE >>",0
 //36
 data "GAME LEVE ",0
 //47
 data "YOU PASS",0
 //56
 data "SNAKE      PASS",0
 //72
 data "press START.",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 load_palette
 gosub init_vars
//过关的开始
start_2:
 gosub init_vars_1
 gosub clear_background
 gosub vwait
 gosub start_3
 gosub clear_background
 gosub vwait_start
 gosub draw_background
 gosub vwait_end
 gosub vwait_start
 gosub draw_snake
 gosub vwait_end
 goto mainloop

//开始图面
start_3:
 //"<< GREEDY SNAKE >>"
 set str_stay_h $20
 set str_stay_l $E7
 set str_n 17
 gosub draw_string
 //"GAME LEVE "
 set str_stay_h $21
 set str_stay_l $4A
 set str_n 36
 gosub draw_string
 set $2007 + leve $30
//开始,待机
start_4:
 gosub draw_w_star
 return

//the main program loop
mainloop:
 gosub vwait_start
 gosub joy_handler
 if moving=0 branchto mainloop_2
 gosub draw_snake_2
mainloop_2:
 gosub vwait_end
 if lose=1 branchto mainloop_4
 if lose=2 branchto mainloop_7
 set temp02 delayer
mainloop_3:
 set temp02 - temp02 1
 gosub vwait
 if temp02 > 0 branchto mainloop_3
 goto mainloop

//失败,连关
mainloop_4:
 set moving 0
 gosub vwait_start
 //"YOU LOSE"
 set str_stay_h $21
 set str_stay_l $8A
 set str_n 0
 gosub draw_string
 gosub vwait_end 
 goto mainloop_6

//胜利
mainloop_5:
 set moving 0
 gosub vwait_start
 //"YOU WIN"
 set str_stay_h $21
 set str_stay_l $8A
 set str_n 9
 gosub draw_string

//过关待机
mainloop_6:
 gosub draw_w_star
 goto start_2

//过关,或胜利
mainloop_7:
 gosub vwait_start 
 if snake_long > snake_maxlong branchto mainloop_5
 set moving 0
 //"YOU PASS"
 set str_stay_h $21
 set str_stay_l $8A
 set str_n 46
 gosub draw_string
 gosub vwait_end
 goto mainloop_6

//set default sprite location
init_vars:
 set snake_maxlong 92
 set snake_winlong 20
 set snake_long 5

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

 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 200
 set snake_logend 199 //200-1
 set leve 1
 set lose 0 //0=游戏中 1=失败 2=胜
 set random_seed $AA
 return

init_vars_1:
 if lose=2 gosub init_vars_2
 set snake_long + leve 5
 set delayer - delayer_2 leve
 
 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_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

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

//过关,增加难度
init_vars_2:
 inc leve
 set snake_winlong + snake_winlong 12
 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 branchto 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=$80 set lose 1
 if temp01=egg01 branchto CheckBoom_1
 goto CheckBoom_2
CheckBoom_1:
 //gosub vwait
 set markendlater + markendlater egg01_M
 set snake_long + snake_long markendlater

 set egg_n wall
 gosub draw_egg
 gosub draw_egg
 set egg_n egg01
 gosub draw_egg
 gosub draw_egg
 set sum_input snake_long
 set draw_sum000_h $20
 set draw_sum000_l $29
 gosub draw_sum000
 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 branchto 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 branchto 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
 //goto draw_background_2
 set walls 0
draw_background_1:
 set egg_n wall
 gosub draw_egg
 inc walls
 if walls<9 branchto draw_background_1
 set egg_n egg01
 gosub draw_egg
draw_background_2:
 gosub vwait_start
 //"SNAKE      PASS"
 set str_stay_h $20
 set str_stay_l $23
 set str_n 56
 gosub draw_string
 set sum_input snake_winlong
 set draw_sum000_h $20
 set draw_sum000_l $33
 gosub draw_sum000
 set sum_input snake_long
 set draw_sum000_h $20
 set draw_sum000_l $29
 gosub draw_sum000
 gosub vwait_end
 return 

draw_egg:
 gosub random_number
 set temp02 random_seed
 set random_seed + random_seed snake_endloc_l
 set random_seed << random_seed 2
 gosub random_number
 set temp03 random_seed
 //temp02=mod(temp02,$1A)
 set mod1 temp02
 set mod2 $1A
 gosub mod_div
 //----------
 set temp02 + mod1 3
 //temp03=mod(temp03,$14)
 set mod1 temp03
 set mod2 $14
 gosub mod_div
 //----------
 set temp03 + mod1 4
 set temp03 << temp03 1
 //高位
 set temp01 & temp03 $F0
 set temp01 >> temp01 4
 set temp01 + temp01 $20
 //低位
 set temp04 & temp03 $F
 set temp04 << temp04 4
 set temp02 + temp02 temp04

 set $2006 temp01
 set $2006 temp02
 set $2007 egg_n
 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 branchto 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 branchto draw_aVerticalLine_1
 return
//
draw_w_star:
 //"press START."
 set str_stay_h $21
 set str_stay_l $CA
 set str_n 72
 gosub draw_string
draw_w_1:
 gosub vwait
 gosub joystick1
 if joy1start=0 branchto draw_w_1
 return

/////////////common

//显示数
draw_sum000:
 set mod1 sum_input
 set mod2 10
 gosub mod_div
 set sum3 mod1
 set mod1 div
 gosub mod_div
 set sum2 mod1
 set sum1 div
 set $2006 draw_sum000_h
 set $2006 draw_sum000_l
 set $2007 + sum1 $30
 set $2007 + sum2 $30
 set $2007 + sum3 $30
 return

//求余  mod(mod1,mod2)=mod1  mod(13,10)=3
mod_div:
 set div 0
mod_1:
 if mod1 = mod2 branchto mod_2
 if mod1 < mod2 branchto mod_3
mod_2:
 set mod1 - mod1 mod2
 inc div
 goto mod_1
mod_3:
 return

//显示一行字
draw_string:
 set $2006 str_stay_h
 set $2006 str_stay_l
 set x str_n  
 draw_string_1:
  set $2007 [data_str x]
  inc x
  set a [data_str x]
  if a <> 0 branchto draw_string_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
 gosub clear_ppu_256
 return

//clear a quarter kilobyte of ppu memory (nametable+attrib)
clear_ppu_256:
 set a 0
 set x 0
 clear_ppu_256_1:
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  set $2007 a
  inc x
  if x <> 16 branchto clear_ppu_256_1
 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

  评论这张
 
阅读(700)| 评论(3)
推荐 转载

历史上的今天

评论

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

页脚

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