AHK版俄罗斯方块,碉堡了[已审核,请放心使用]

AHK版俄罗斯方块,碉堡了

AHK版俄罗斯方块,碉堡了[已审核,请放心使用]

下载链接https://pan.baidu.com/s/1qZGs4kk 密码:jzl9

使用方法:

键盘的上下左右键控制!剩下的自己摸索!!

;-------------------------------------------------------------------------------
;  
;  ManyTetris 0.17
;  Customizable Pocket Tetris
;  Danny Ben Shitrit (aka Icarus) 2008
;
;-------------------------------------------------------------------------------
NameString    := "ManyTetris"
VersionString := "0.17"
#SingleInstance Force

Gosub Init
Gosub Main

Return
;-------------------------------------------------------------------------------
; MAINS
;-------------------------------------------------------------------------------
Init:
  SetWorkingDir %A_ScriptDir%
  IniFile = %NameString%.ini
  
  OnMessage(0x06,  "WM_ACTIVATE")     ; Capture gui focus

  ColorString := "Options_OnColor,Options_OffColor,Options_GuiColor,Options_FontColor"
  IniHelper( "Read", IniFile, "GUI", ColorString . ",Options_Inverse" )
  IniHelper( "Read", IniFile, "Sound", "Options_EnableSound" )
  IniHelper( "Read", IniFile, "Recent", "Options_LastGame,Options_WinX,Options_WinY" )
  Score_MaxScore := Score_GetMaxScore( Options_LastGame )
  
  If( Options_Inverse ) {
    Loop Parse, ColorString, `,
      %A_LoopField% := InverseColor( %A_LoopField% )
  }
  
  Game_PushDownSpeed := 20
  Game_IsPaused := false
  
  ; Arrange games drop down list
  Loop games\*.txt 
  {
    SplitPath A_LoopFilename,,,,OutNameNoExt

    If( A_Index = 1 and Not FileExist( "games\" . Options_LastGame . ".txt" ) )
      Options_LastGame := OutnameNoExt

    If( A_Index <> 1 ) 
      Gui_GamesDdl .= "|"

    Gui_GamesDdl .= OutNameNoExt
  }
  
  Game_ReadGameConfig( Options_LastGame )
  
  Loop %Game_Piece0% {
    PieceID := A_Index
    StringSplit PiecePart, Game_Piece%A_Index%, %A_Space%
    Game_PieceStates%PieceID% := PiecePart0
    Loop %PiecePart0% {   
      StateID := A_Index
      Game_Piece%PieceID%_State%StateID% := PiecePart%A_Index%
    }
  }

  Active_DropSpeed := Game_DropSpeed
  
  Gosub Game_BuildGui
Return

Main:
  Game_PiecesDropped := 0
  Active_PlaceNewPiece()
  SetTimer Game_ProgressGame, -%Active_DropSpeed%
Return

GuiEscape:
GuiClose:
  Gosub SaveSettings
  ExitApp
Return

;-------------------------------------------------------------------------------
; GAME
;-------------------------------------------------------------------------------
Game_ReadGameConfig( file ) {
  Local FileString, ThisLine

  FileRead FileString, games\%file%.txt
  
  Game_Piece0 := 1
  
  Loop Parse, FileString, `n,`r
  {
    ThisLine = %A_LoopField%
    
    If( SubStr( ThisLine, 1, 1 ) = "#" ) {
      StringTrimLeft, ThisLine, ThisLine, 1
      StringSplit Param, ThisLine, %A_Space%
      Game_%Param1% := Param%Param0%
      Continue
    }
    
    If( ThisLine = "" or SubStr( ThisLine,1,1 ) = ";" )
      Continue
      
    If( ThisLine = "*" ) {
      StringTrimRight Game_Piece%Game_Piece0%, Game_Piece%Game_Piece0%, 1
      Game_Piece0++
    }
    Else If( ThisLine = "=" ) {
      StringTrimRight Game_Piece%Game_Piece0%, Game_Piece%Game_Piece0%, 1
      Game_Piece%Game_Piece0% .= " "
    }
    Else {
      Game_Piece%Game_Piece0% .= ThisLine . "|"
    }
  }
  
  ; Set some defaults, in case the game configuration file does not contain
  ; all the elements.
  ; Mainly for backwards compatibility with older game templates.
  If( Game_LineScore = "" )
		Game_LineScore := 10
  If( Game_PieceScore = "" )
		Game_PieceScore := 2
  If( Game_PausePenalty = "" )
		Game_PausePenalty := 5
	
}

Game_BuildGui:
  Gui Margin,2,2
  Gui Color, %Options_GuiColor%,%Options_GuiColor%
  Gui Font, c%Options_FontColor%
  
  W := Game_Cols * ( Game_BoxSize+1 ) - 83
  Gui Add, DDL, -TabStop w%W% vGui_GamesDdl, %Gui_GamesDdl%
  GuiControl ChooseString, Gui_GamesDdl, %Options_LastGame%
  
  Gui Add, Button, 0x8000 x+2 yp w80 hp+1 -wrap vGui_StartButton gGame_RestartGame, Start
  
  W := Game_Cols * ( Game_BoxSize+1 ) - 1
  
  Gui Font, s12 Bold
  Gui Add, Text, x2 y+2 w%W% h21 vGui_Score Center Border, 0
  Game_UpdateScore( 0 )
  Game_UpdateScore( "Top: " . Score_MaxScore, true )
  Gui Font, s9 Norm
  
  X := 2
  Y := 48
  W := Game_BoxSize
  Loop %Game_Rows% {
    i := A_Index
    Loop %Game_Cols% {
      j := A_Index
      Gui Add, ListView, x%X% y%Y% w%W% h%W% vGuiBox_%i%_%j% -TabStop -E0X200 0x4000 +Background%Options_OffColor%
      DataBox_%i%_%j% := 0
      X += W + 1
    }
    Y += W + 1
    X := 2
  }
  
  GuiControl Focus, Gui_StartButton
  Gui Show, x%Options_WinX% y%Options_WinY%,%NameString% %VersionString%

Return

Game_RestartGame:
  Gui Submit, NoHide
  Options_LastGame := Gui_GamesDdl
  Gosub Reload
Return

Game_ProgressGame:
  Game_ProgressGame()
Return

Game_ProgressGame() {
  Global 
  
  ; Drops a piece by one row if possible
  ; Else, remove the completed lines if any
  ; And create a new piece on top
  If( Not Active_DropPiece() ) {
		Game_SetNewDropSpeed()
      
    If( Active_PrevDropSpeed )
      Active_PrevDropSpeed := Active_DropSpeed
    Active_CheckCompletedLines()
    Active_PlaceNewPiece()    

    SetTimer Game_ProgressGame, -%Active_DropSpeed%
  }
}

Game_SetNewDropSpeed() {
	Global

	If( Game_DropSpeedPoints )
		Active_DropSpeed := Game_DropSpeed - ( Trim( Game_Score/Game_DropSpeedPoints )*Game_DropSpeedIncrease )
	Else
		Active_DropSpeed := Game_DropSpeed - ( Game_PiecesDropped*Game_DropSpeedIncrease )
	
	If( Active_DropSpeed < Game_MaxDropSpeed )
		Active_DropSpeed := Game_MaxDropSpeed
		
	;Tooltip % Active_DropSpeed		; DEBUG SPEED
}

Game_DataToGui( fromRow, toRow ) {
  ; Reads a range of rows in the data grid, and reflect it in the GUI
  ;_____________________________________________________________________________
  Local Row, Color
  
  Loop %toRow% {
    Row := fromRow + A_Index - 1
    Loop %Game_Cols% {
      Col := A_Index
      Color := DataBox_%Row%_%Col% ? Options_OnColor : Options_OffColor
      GuiControl ,+Background%Color%, GuiBox_%Row%_%Col%    
    }
  }
}

Game_GameOver() {
  ; Called when we can longer place new pieces
  ;_____________________________________________________________________________
  Local Row, Col
  
  SetTimer Game_ProgressGame, Off
  
  Critical
  SoundPlay( "Over" )
  Loop %Game_Rows% {
    Active_RemoveRow( Game_Rows )
    Game_DataToGui( 1, Game_Rows )
    Sleep 50
  } 
  Critical Off
  Game_SaveHighScore()
  Sleep 2000  
  Game_UpdateScore( 0 )

  Active_DropSpeed := Game_DropSpeed  
  Gosub Main
}

Game_UpdateScore( score, displayOnly=false ) {
  Global Game_Score

  If( score = 0 ) {
    Game_Score := 0
    GuiControl,,Gui_Score, 0
  }

  Else If( not displayOnly ) {
    Game_Score += score
    GuiControl,,Gui_Score, % Game_Score
  }
  Else {
    GuiControl,,Gui_Score, % score
  }
  
}

Game_SaveHighScore() {
  Global
  
  If( Game_Score > Score_MaxScore ) {
    Score_MaxScore := Game_Score
    Score_SetMaxScore( Options_LastGame, Score_MaxScore )
  }
}

;-------------------------------------------------------------------------------
; ACTIVE
;-------------------------------------------------------------------------------
Active_PlaceNewPiece() {
  ; Gets a random piece and places it at the top of the board
  ; Ends the game if it cannot place that piece
  ;_____________________________________________________________________________
  Local Col, Row, Failed, PieceRows
  
  Random Active_Piece, 1, %Game_Piece0%
  Game_PiecesDropped++
  Active_PieceStates := Game_PieceStates%Active_Piece%
  Active_PieceState := 1
  Active_PieceString := Game_Piece%Active_Piece%_State1
  
  StringSplit PieceRow, Game_Piece%Active_Piece%_State1, |
  Active_BaseRow := 1
  Active_PieceCols := StrLen( PieceRow1 )
  Active_BaseCol := Round( 1 + (Game_Cols/2) - (Active_PieceCols/2 ) )
  
  ; Update the data grid
  Failed := false
  Col := Active_BaseCol
  Row := Active_BaseRow
  Loop Parse, Active_PieceString
  {
    If( A_LoopField = "+" ) {
      If( DataBox_%Row%_%Col% <> 1 ) 
        DataBox_%Row%_%Col% := 2      
      Else 
        Failed := true        
    }
    Else If( A_LoopField = "|" ) {
      Col := Active_BaseCol-1
      Row++
    }
    Col++
  }
  
  Active_PieceRows := Row
  
  ; Update the GUI
  If( Failed ) {
    Game_DataToGui( 1, Active_PieceRows )
    Game_GameOver()
  }
  Else {
    SoundPlay( "Piece" )
    Game_DataToGui( 1, Active_PieceRows )
  }

  Return true
}

Active_PieceCanMove( fromRow, toRow, rowOffset, colOffset ) {
  ; Gets a range of rows to check and row+col offsets and returns true if the
  ; piece (that was found in the range of rows) can move to the specified 
  ; offsets.
  ;_____________________________________________________________________________
  Local Result, OldRow, OldCol, NewRow, NewCol

  Result := true
  Loop %Active_PieceRows% {
    OldRow := Active_BaseRow + Active_PieceRows - A_Index
    NewRow := OldRow+rowOffset
    Loop %Game_Cols% {
      OldCol := A_Index
      NewCol := OldCol+ColOffset
      If( ( DataBox_%OldRow%_%OldCol% = 2 ) and ( DataBox_%NewRow%_%NewCol% = 1 or NewRow > Game_Rows or NewCol < 1 or NewCol > Game_Cols ) ) {
        Result := false
        Break
      }
    }
  }
  
  Return Result
}

Active_LockPiece( fromRow, toRow ) {
  ; Locks a piece in place, in the data grid only (not GUI)
  ; It will replace all the 2 values in the specified row range to 1
  ;_____________________________________________________________________________
  Local Row, Col
  
  Loop %toRow% {
    Row := fromRow + A_Index - 1
    Loop %Game_Cols% {
      Col := A_Index
      If( DataBox_%Row%_%Col% = 2 )
        DataBox_%Row%_%Col% := 1
    }
  }
}

Active_DropPiece() {
  ; Drops the piece by one line
  ; If it is unable to, it will lock the piece in place (convert 2s to 1s)
  ;_____________________________________________________________________________
  Local OldRow, NewRow
  
  ; If cant drop piece anymore, change active piece to static and return false
  If( Not Active_PieceCanMove( Active_BaseRow, Active_BaseRow + Active_PieceRows, 1, 0 ) ) {
    Active_LockPiece( Active_BaseRow, Active_BaseRow+Active_PieceRows-1 )
    Return false
  }
  
  Critical
  Loop %Active_PieceRows% {
    OldRow := Active_BaseRow + Active_PieceRows - A_Index
    NewRow := OldRow+1
    Loop %Game_Cols% {
      Col := A_Index
      If( DataBox_%OldRow%_%Col% = 2 ) {
        DataBox_%OldRow%_%Col% := 0
        DataBox_%NewRow%_%Col% = 2
      }
    }
  }
  If( Active_DropSpeed > Game_PushDownSpeed )
    SoundPlay( "Step" )
  Game_DataToGui( Active_BaseRow, Active_PieceRows+1 )
  Active_BaseRow++
  
  SetTimer Game_ProgressGame, -%Active_DropSpeed%
  Critical Off
  
  Return true
}

Active_MovePiece( dir ) {
  ; Moves a piece one block to the right (1) or left (-1)
  ; Returns false on failure
  ;_____________________________________________________________________________
  Local OldCol, NewCol
  
  ; If cant move piece anymore, return false
  If( Not Active_PieceCanMove( Active_BaseRow, Active_BaseRow + Active_PieceRows, 0, dir ) ) {
    Return false
  }
  
  Critical
  Loop %Active_PieceRows% {
    Row := Active_BaseRow + A_Index - 1
    Loop %Game_Cols% {
      OldCol := dir < 0 ? A_Index : Game_Cols - A_Index + 1
      NewCol := OldCol + dir
      If( DataBox_%Row%_%OldCol% = 2 ) {
        DataBox_%Row%_%OldCol% := 0
        DataBox_%Row%_%NewCol% := 2
      }
    }
  }
  Active_BaseCol += dir
  Game_DataToGui( Active_BaseRow, Active_PieceRows+1 )
  Critical Off
  Return true
}

Active_PieceCanRotate( fromState, toState ) {
  ; Returns true if the active piece can rotate
  ;_____________________________________________________________________________
  Local Result, Row, Col

  Result := true

  ; Check GUI edges
  If( Active_BaseCol < 1 or Active_BaseCol+Active_PieceCols-1 > Game_Cols )
    Result := false
    
  ; Check collision with other pieces
  Loop %Active_PieceRows% {
    If( not Result )
      Break
    Row := Active_BaseRow+A_Index-1
    Loop %Active_PieceCols% {
      Col := Active_BaseCol+A_Index-1
      If( DataBox_%Row%_%Col% = 1 ) {
        Result := false
        Break
      }
    }
  }
  
  
  Return Result
}


Active_RotatePiece() {
  ; Rotates a piece
  ;_____________________________________________________________________________
  Local Col, Row, NewPieceState
  
  NewPieceState := Active_PieceState < Active_PieceStates ? Active_PieceState+1 : 1
  
  ; If cant move piece anymore, return false
  If( Not Active_PieceCanRotate( Active_PieceState, NewPieceState ) ) {
    Return false
  }
  Else {
    Critical
    Active_PieceState := NewPieceState
    Active_PieceString := Game_Piece%Active_Piece%_State%Active_PieceState%
    
    Row := Active_BaseRow
    Col := Active_BaseCol   
    Loop Parse, Active_PieceString
    {
      If( A_LoopField = "+" )
        DataBox_%Row%_%Col% := 2    
      Else If( A_LoopField = "-" )
        DataBox_%Row%_%Col% := 0
      Else If( A_LoopField = "|" ) {
        Col := Active_BaseCol-1
        Row++
      }
      Col++
    }
    Critical Off
  }
  
  Game_DataToGui( Active_BaseRow, Active_PieceRows+1 )
  Return true
}

Active_CheckCompletedLines() {
	; Check for completed lines and update the score (even if there are no 
	; completed lines)
  Local Row, FullRow  
  
  Critical
  ; Identify rows for removal
  Loop %Game_Rows% {
    FullRow := true
    Row := Game_Rows-A_Index+1
    Loop %Game_Cols% {
      Col := A_Index
      If( DataBox_%Row%_%Col% <> 1 ) {
        FullRow := false
        Continue
      }
    }
    If( FullRow ) {
      Active_ScoreFactor++
      Active_CycleScore += ( Active_ScoreFactor * Game_LineScore )
      Active_RemoveRow( Row )
      Active_CheckCompletedLines()
      Game_DataToGui( 1, Game_Rows )
      Return      
    }
  }
  
  If( Active_CycleScore ) {
    Gui Submit, NoHide
    SoundPlay( "Line", true )
    Game_UpdateScore( Active_CycleScore )
  }
  Else {
    Gui Submit, NoHide
    Game_UpdateScore( Game_PieceScore )
  }
  Active_ScoreFactor := 0
  Active_CycleScore := 0
  
  Critical Off
}

Active_RemoveRow( targetRow ) {
  Local Col, Row, HigherRow 
  
  Critical
  Loop % targetRow-1 {
    Row := targetRow-A_Index+1
    HigherRow := Row-1
    
    Loop %Game_Cols% {
      Col := A_Index
      DataBox_%Row%_%Col% := DataBox_%HigherRow%_%Col%
    }
  }
  
  ; Reset first row to zeros
  Loop %Game_Cols% {
    Col := A_Index
    DataBox_1_%Col% := 0
  }
  Critical Off
}

Active_DropKeyReleased:
  ; Called by timer whenever the Down key is pressed.
  ; Will restore original drop speed when key is released.
  If( not GetKeyState( "Down", "P" ) ) {
    SetTimer Active_DropKeyReleased, Off
    Active_DropSpeed := Active_PrevDropSpeed
    Active_PrevDropSpeed := 0
  }
Return

;-------------------------------------------------------------------------------
; SCORE
;-------------------------------------------------------------------------------
Score_GetMaxScore( game ) {
  Global IniFile
  
  NiceGameName := RegExReplace( game, "[\W]" )
  IniRead Result, %IniFile%, Score, %NiceGameName%, 0
  Return Result
}

Score_SetMaxScore( game, score ) {
  Global IniFile
  
  NiceGameName := RegExReplace( game, "[\W]" )
  IniWrite %score%, %IniFile%, Score, %NiceGameName%
}

;-------------------------------------------------------------------------------
; DEBUG
;-------------------------------------------------------------------------------
Debug_ShowGrid() {
  Local Row, Col, Result
  
  Result := ""
  Loop %Game_Rows% {
    Row := A_Index
    Loop %Game_Cols% {
      Col := A_Index
      Result .= DataBox_%Row%_%Col% . " " 
    }
    Result .= "`n"
  }
  Msgbox % Result
}

;-------------------------------------------------------------------------------
; MISC
;-------------------------------------------------------------------------------
IniHelper( op, file, section, keys ) {
  ; Reads or writes specific keys from an INI section, and sets the values as
  ; global variables
  ;_____________________________________________________________________________
  Global
  
  StringSplit iniKey, keys, `,
  
  Loop %iniKey0% {
    If( op = "Read" ) {
      IniKey := % iniKey%A_Index%
      IniRead %IniKey%, %file%, %section%, %IniKey%
    }
    Else If( op = "Write" ) {
      IniValue := % iniKey%A_Index%
      IniValue := %IniValue%
      IniKey   := iniKey%A_Index%
      IniWrite %IniValue%, %file%, %section%, %IniKey%
    }
  }
}

InverseColor( color ) {
  SetFormat Integer, H
  Result := ""
  Loop Parse, Color
  {
    Result .= 0xF - A_LoopField
    StringReplace Result, Result, 0x
  }
    
  SetFormat Integer, D
  Return Result
}

SoundPlay( sound, wait=false ) {
  Global Options_EnableSound
  If( Not Options_EnableSound )
    Return
  Wait := wait ? "WAIT" : ""
  SoundPlay sounds\%sound%.wav, %WAIT%
}

Trim( num ) {
	StringSplit NumElement, num, .
	Return %NumElement1%
}

SaveSettings:
  Gui +LastFound
  WinGetPos Options_WinX, Options_WinY
  IniHelper( "Write", IniFile, "Recent", "Options_LastGame,Options_WinX,Options_WinY" )
  Game_SaveHighScore()
Return

Reload:
  Gosub SaveSettings
  Reload
Return

WM_ACTIVATE() {
  Global NameString, Game_IsPaused
  
  IfWinActive %NameString% ahk_Class AutoHotkeyGUI
  {
    If( Game_IsPaused )
      Gosub p
  }
  Else If( !Game_IsPaused )
    Gosub p
}


;-------------------------------------------------------------------------------
; HOTKEYS
;-------------------------------------------------------------------------------
#IfWinActive ManyTetris ahk_Class AutoHotkeyGUI
Right::
  If( Game_IsPaused )
    Gosub p
  Active_MovePiece( 1 )
Return

Left::
  If( Game_IsPaused )
    Gosub p
  Active_MovePiece( -1 )
Return

Up::
  If( Game_IsPaused )
    Gosub p
  Active_RotatePiece()
Return  

Down::
  If( Game_IsPaused )
    Gosub p
    
  ; If key is already pushed, do nothing (the Active_DropKeyReleased is working)
  If( Active_PrevDropSpeed )    
    Return
    
  SetTimer Game_ProgressGame, Off
  
  Active_PrevDropSpeed := Active_DropSpeed
  Active_DropSpeed := Game_PushDownSpeed  
  SetTimer Active_DropKeyReleased, 20
  Gosub Game_ProgressGame
Return  

p::
  Game_IsPaused := !Game_IsPaused
  If( Game_IsPaused )
    SetTimer Game_ProgressGame, Off
  Else {
    If( Game_Score > 0 )
      Game_Score -= Game_PausePenalty
    SetTimer Game_ProgressGame, -%Active_DropSpeed%
  }
Return
  

 

给TA捐赠
共{{data.count}}人
人已捐赠
其他应用

autohotkey Dota辅助

2018-1-19 21:00:38

其他应用

autohotkey设计的碰碰球游戏

2018-1-28 18:25:35

10 条回复 A文章作者 M管理员
  1. 奥运特别号

    为啥现在不能运行了?ahk这么不稳定,每次新版本就会导致原来能用的脚本不能再用么?

  2. MrLiu

    有点意思,66666

  3. 湛影丶

    66666

  4. AHKiller

    ?

  5. […] AHK版俄罗斯方块:非常经典的小游戏,值得大家收藏! […]

  6. NoSpicyPls

    不过画质不大好

    • 河许人

      哈哈 ,只是一个简单实例,如果有需要可以自己完善一下!

  7. lugg

    有意思!!! ❓ 💡 💡

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索