
・弾も回転とスクロールに対応シてみました。
------------以下、操作方法は前回と同じ---------
・操作は下記の通り
左右ボタンで方向変更
Fireボタンで弾を発射
※キーボード使用時は、MACHIKAP.INIファイルのEMULATEBUTTONの#を除いて、キーボードでボタンが使えるようにしてください。
FireボタンはキーボードではFキーになります。
SCROLL_SPEED#が縦スクロールの速さになります。その他、パラメーターをいろいろ変えて楽しんでみてください。
USEGRAPHIC
USEVAR SW,SH,SHIPX#,SHIPY#,SHIPR,MAXBULLETS,MAXASTEROIDS,BULLETSPEED#,SCORE,LIVES,GAMEOVER,ASTEROIDMINSIZE,ASTEROIDMAXSIZE,ASTEROIDMINSPEED#,ASTEROIDMAXSPEED#,DX#,DY#,DIST#,COLORWHITE,COLORBLACK,BULLETSX#,BULLETSY#,BULLETVX#,BULLETVY#,BULLETACTIVE,ASTEROIDSX#,ASTEROIDSY#,ASTEROIDVX#,ASTEROIDVY#,ASTEROIDSIZE#,ASTEROIDACTIVE,SIDE,ROTATE_DEG#,COSROT#,SINROT#,NEWX#,NEWY#,STARSX#,STARSY#,NUMSTARS,SCROLL_SPEED#
DIM BULLETSX#(20)
DIM BULLETSY#(20)
DIM BULLETVX#(20)
DIM BULLETVY#(20)
DIM BULLETACTIVE(20)
DIM ASTEROIDSX#(8)
DIM ASTEROIDSY#(8)
DIM ASTEROIDVX#(8)
DIM ASTEROIDVY#(8)
DIM ASTEROIDSIZE#(8)
DIM ASTEROIDACTIVE(8)
DIM STARSX#(100)
DIM STARSY#(100)
REM Initialize constants
SW=336
SH=216
SHIPX#=FLOAT#(SW)/2
SHIPY#=FLOAT#(SH)/5*4
SHIPR=8
MAXBULLETS=20
MAXASTEROIDS=8
BULLETSPEED#=3
ASTEROIDMINSIZE=6
ASTEROIDMAXSIZE=16
ASTEROIDMINSPEED#=1.5
ASTEROIDMAXSPEED#=2.0
ROTATE_DEG#=1
NUMSTARS=100
SCROLL_SPEED#=0.8
COLORWHITE=255
COLORBLACK=0
REM Initialize game variables
SCORE=0
LIVES=3
GAMEOVER=0
REM Clear arrays
FOR I=0 TO MAXBULLETS-1
BULLETACTIVE(I)=0
NEXT
FOR I=0 TO MAXASTEROIDS-1
ASTEROIDACTIVE(I)=0
NEXT
REM Initialize stars (random positions)
FOR I=0 TO NUMSTARS-1
STARSX#(I)=FLOAT#(RND() % SW)
STARSY#(I)=FLOAT#(RND() % SH)
NEXT
REM Generate initial asteroids
FOR I=0 TO 3
GOSUB GENERATEASTEROID
NEXT
REM Main game loop
WHILE GAMEOVER=0
GCLS
REM Handle rotation input (隕石、星、弾を回転)
IF KEYS(4) THEN
COSROT#=COS#(ROTATE_DEG#*PI#/180)
SINROT#=SIN#(ROTATE_DEG#*PI#/180)
REM Rotate asteroids
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=1 THEN
NEWX#=ASTEROIDSX#(I)-SHIPX#
NEWY#=ASTEROIDSY#(I)-SHIPY#
ASTEROIDSX#(I)=NEWX#*COSROT#-NEWY#*SINROT#+SHIPX#
ASTEROIDSY#(I)=NEWX#*SINROT#+NEWY#*COSROT#+SHIPY#
ENDIF
NEXT
REM Rotate stars
FOR I=0 TO NUMSTARS-1
NEWX#=STARSX#(I)-SHIPX#
NEWY#=STARSY#(I)-SHIPY#
STARSX#(I)=NEWX#*COSROT#-NEWY#*SINROT#+SHIPX#
STARSY#(I)=NEWX#*SINROT#+NEWY#*COSROT#+SHIPY#
NEXT
REM Rotate bullets
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=1 THEN
NEWX#=BULLETSX#(I)-SHIPX#
NEWY#=BULLETSY#(I)-SHIPY#
BULLETSX#(I)=NEWX#*COSROT#-NEWY#*SINROT#+SHIPX#
BULLETSY#(I)=NEWX#*SINROT#+NEWY#*COSROT#+SHIPY#
ENDIF
NEXT
ENDIF
IF KEYS(8) THEN
COSROT#=COS#(-ROTATE_DEG#*PI#/180)
SINROT#=SIN#(-ROTATE_DEG#*PI#/180)
REM Rotate asteroids
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=1 THEN
NEWX#=ASTEROIDSX#(I)-SHIPX#
NEWY#=ASTEROIDSY#(I)-SHIPY#
ASTEROIDSX#(I)=NEWX#*COSROT#-NEWY#*SINROT#+SHIPX#
ASTEROIDSY#(I)=NEWX#*SINROT#+NEWY#*COSROT#+SHIPY#
ENDIF
NEXT
REM Rotate stars
FOR I=0 TO NUMSTARS-1
NEWX#=STARSX#(I)-SHIPX#
NEWY#=STARSY#(I)-SHIPY#
STARSX#(I)=NEWX#*COSROT#-NEWY#*SINROT#+SHIPX#
STARSY#(I)=NEWX#*SINROT#+NEWY#*COSROT#+SHIPY#
NEXT
REM Rotate bullets
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=1 THEN
NEWX#=BULLETSX#(I)-SHIPX#
NEWY#=BULLETSY#(I)-SHIPY#
BULLETSX#(I)=NEWX#*COSROT#-NEWY#*SINROT#+SHIPX#
BULLETSY#(I)=NEWX#*SINROT#+NEWY#*COSROT#+SHIPY#
ENDIF
NEXT
ENDIF
REM Scroll asteroids, stars, and bullets downward
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=1 THEN
ASTEROIDSY#(I)=ASTEROIDSY#(I)+SCROLL_SPEED#
ENDIF
NEXT
FOR I=0 TO NUMSTARS-1
STARSY#(I)=STARSY#(I)+SCROLL_SPEED#
IF STARSY#(I)>FLOAT#(SH) THEN STARSY#(I)=STARSY#(I)-FLOAT#(SH)
NEXT
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=1 THEN
BULLETSY#(I)=BULLETSY#(I)+SCROLL_SPEED#
ENDIF
NEXT
REM Draw stars (background)
GCOLOR COLORWHITE
FOR I=0 TO NUMSTARS-1
PSET INT(STARSX#(I)),INT(STARSY#(I)),COLORWHITE
NEXT
REM Draw cannon (fixed, always pointing up)
GCOLOR COLORWHITE
CIRCLE INT(SHIPX#),INT(SHIPY#),SHIPR,COLORWHITE
LINE INT(SHIPX#),INT(SHIPY#),INT(SHIPX#),INT(SHIPY#-20),COLORWHITE
REM Handle fire
IF KEYS(32) THEN GOSUB FIREBULLET
REM Update bullets (upward movement relative to scroll)
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=1 THEN
BULLETSY#(I)=BULLETSY#(I)-BULLETSPEED#
IF BULLETSY#(I)<0 THEN BULLETACTIVE(I)=0
ENDIF
NEXT
REM Update asteroids (additional movement beyond scroll)
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=1 THEN
ASTEROIDSX#(I)=ASTEROIDSX#(I)+ASTEROIDVX#(I)
ASTEROIDSY#(I)=ASTEROIDSY#(I)+ASTEROIDVY#(I)
IF ASTEROIDSY#(I)>FLOAT#(SH)+20 OR ASTEROIDSX#(I)<FLOAT#(-20) OR ASTEROIDSX#(I)>FLOAT#(SW)+20 THEN
ASTEROIDACTIVE(I)=0
GOSUB GENERATEASTEROID
ENDIF
ENDIF
NEXT
REM Check bullet-asteroid collision
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=1 THEN
FOR J=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(J)=1 THEN
DX#=BULLETSX#(I)-ASTEROIDSX#(J)
DY#=BULLETSY#(I)-ASTEROIDSY#(J)
DIST#=SQRT#(DX#*DX#+DY#*DY#)
IF DIST#<ASTEROIDSIZE#(J)+FLOAT#(3) THEN
BULLETACTIVE(I)=0
ASTEROIDACTIVE(J)=0
SCORE=SCORE+10
GOSUB GENERATEASTEROID
ENDIF
ENDIF
NEXT
ENDIF
NEXT
REM Check ship-asteroid collision
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=1 THEN
DX#=SHIPX#-ASTEROIDSX#(I)
DY#=SHIPY#-ASTEROIDSY#(I)
DIST#=SQRT#(DX#*DX#+DY#*DY#)
IF DIST#<FLOAT#(SHIPR)+ASTEROIDSIZE#(I) THEN
LIVES=LIVES-1
ASTEROIDACTIVE(I)=0
GOSUB GENERATEASTEROID
IF LIVES<=0 THEN GAMEOVER=1
ENDIF
ENDIF
NEXT
REM Draw bullets
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=1 THEN
CIRCLEFILL INT(BULLETSX#(I)),INT(BULLETSY#(I)),3,COLORWHITE
ENDIF
NEXT
REM Draw asteroids
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=1 THEN
CIRCLE INT(ASTEROIDSX#(I)),INT(ASTEROIDSY#(I)),INT(ASTEROIDSIZE#(I)),COLORWHITE
ENDIF
NEXT
REM Draw HUD
GPRINT 0,0,COLORWHITE,COLORBLACK,"SCORE:"+DEC$(SCORE)
GPRINT 0,10,COLORWHITE,COLORBLACK,"LIVES:"+DEC$(LIVES)
WAIT 1
WEND
GCLS
GPRINT SW/2-50,SH/2,COLORWHITE,COLORBLACK,"GAME OVER"
GPRINT SW/2-50,SH/2+10,COLORWHITE,COLORBLACK,"SCORE:"+DEC$(SCORE)
WAIT 300
END
LABEL FIREBULLET
FOR I=0 TO MAXBULLETS-1
IF BULLETACTIVE(I)=0 THEN
BULLETACTIVE(I)=1
BULLETSX#(I)=SHIPX#
BULLETSY#(I)=SHIPY#-20
BULLETVX#(I)=0
BULLETVY#(I)=-BULLETSPEED#
RETURN
ENDIF
NEXT
RETURN
LABEL GENERATEASTEROID
FOR I=0 TO MAXASTEROIDS-1
IF ASTEROIDACTIVE(I)=0 THEN
ASTEROIDACTIVE(I)=1
SIDE=RND() % 3
IF SIDE=0 THEN
ASTEROIDSX#(I)=FLOAT#(-20)
ASTEROIDSY#(I)=FLOAT#(RND() % SH)
ASTEROIDVX#(I)=ASTEROIDMINSPEED#+(FLOAT#(RND())/32768)*(ASTEROIDMAXSPEED#-ASTEROIDMINSPEED#)
ASTEROIDVY#(I)=(FLOAT#(RND())/32768)*2-1
ELSEIF SIDE=1 THEN
ASTEROIDSX#(I)=FLOAT#(SW)+20
ASTEROIDSY#(I)=FLOAT#(RND() % SH)
ASTEROIDVX#(I)=-(ASTEROIDMINSPEED#+(FLOAT#(RND())/32768)*(ASTEROIDMAXSPEED#-ASTEROIDMINSPEED#))
ASTEROIDVY#(I)=(FLOAT#(RND())/32768)*2-1
ELSE
ASTEROIDSX#(I)=FLOAT#(RND() % SW)
ASTEROIDSY#(I)=FLOAT#(-20)
ASTEROIDVX#(I)=(FLOAT#(RND())/32768)*4-2
ASTEROIDVY#(I)=ASTEROIDMINSPEED#+(FLOAT#(RND())/32768)*(ASTEROIDMAXSPEED#-ASTEROIDMINSPEED#)
ENDIF
ASTEROIDSIZE#(I)=FLOAT#(ASTEROIDMINSIZE)+FLOAT#(INT((FLOAT#(RND())/32768)*(FLOAT#(ASTEROIDMAXSIZE)-FLOAT#(ASTEROIDMINSIZE))))
RETURN
ENDIF
NEXT
RETURN