Popular Post Andreik Posted April 26, 2023 Popular Post Share Posted April 26, 2023 (edited) This is a replication of an old game called Bulldozer created by John 'FlyMan' Hattan (The Code Zone). There is another implementation in AutoHotkey made by Weston Campbell so I made one in AutoIt. In Weston's github repository you can check the game objective and all valid movements and objects. The controls are: UP - Move bulldozer up DOWN - Move bulldozer down RIGHT - Move bulldozer right LEFT - Move bulldozer left R - Restart current level U - Undo last move J - Jump to a specific level PAUSE - Pause the game Currently I added just first 30 40 60 levels but the original game have 180 levels (eventually I will add all of them). Since Weston's code is on github I suppose it's under some kind of creative license so I didn't bother to create other sprites but if someone have time and inspiration to create new sprites, I am open to add new sprites. To do: Maybe some music Hall of fame / Score table Add all original game levels Add more custom levels Provide access to settings (fonts, colors, sprites, hotkeys, etc) In the attachment is a compiled executable and also the source code. expandcollapse popup#NoTrayIcon #include-once #include <GDIPlus.au3> #include <WinAPI.au3> #include <SQLite.au3> If Not FileExists(@ScriptDir & '\Bulldozer.sqlite') Then MsgBox(0x10, 'Error', 'Database could not be located!', 10) Exit EndIf _SQLite_Startup(@ScriptDir & '\sqlite3.dll') Global $hDB = _SQLite_Open(@ScriptDir & '\Bulldozer.sqlite') Global Const $TileSize = Number(ReadProperty('TileSize', 32)) Global Const $XTiles = Number(ReadProperty('XTiles', 35)) Global Const $YTiles = Number(ReadProperty('YTiles', 25)) If @DesktopWidth < $XTiles * $TileSize Or @DesktopHeight < $YTiles * $TileSize Then MsgBox(0x30, 'Warning', 'For a better experience you need a display with a resolution ' & String($XTiles * $TileSize) & 'x' & String($YTiles * $TileSize) & '.', 10) EndIf Global $X, $Y, $Direction Global $mResources[] Global $mTiles[] Global $aTiles = GetTiles() If IsArray($aTiles) Then For $Index = 1 To UBound($aTiles) - 1 If $aTiles[$Index][1] Then $mTiles[$aTiles[$Index][0]] = $aTiles[$Index][1] Next Else _SQLite_Close() _SQLite_Shutdown() MsgBox(0x10, 'Error', 'Cannot retrieve game tiles from database!', 10) Exit EndIf Global $CurrentLevel = 1 Global $MaxLevel = Number(ReadProperty('MaxLevel', 1)) Global $AutoRestart = Number(ReadProperty('AutoRestart', 0)) Global $Font = ReadProperty('Font', 'Segoe UI') Global $FontSize = Number(ReadProperty('FontSize', 40)) Global $SecFontSize = Number(ReadProperty('SMFontSize', 20)) Global $MessageColor = ReadProperty('MessageColor', 0xFFFFFFFF) Global $SecMessageColor = ReadProperty('SMColor', 0xFF00A000) Global $Start, $PlayTime = 0, $Pause = False, $MsgShow = False Global $LastMove = Null, $PrevLevel = Null, $NumOfMoves = 0 Global $hMain, $aLevel[$YTiles][$XTiles] Global $ClearColor = ReadProperty('ClearColor', '0xFF000000') Global $KeyboardEnabled = False _GDIPlus_Startup() $mResources['Bitmap'] = _GDIPlus_BitmapCreateFromScan0($XTiles * $TileSize, $YTiles * $TileSize) $mResources['Graphics'] = _GDIPlus_ImageGetGraphicsContext($mResources['Bitmap']) _GDIPlus_GraphicsSetCompositingMode($mResources['Graphics'], 0) _GDIPlus_GraphicsSetCompositingQuality($mResources['Graphics'], 2) _GDIPlus_GraphicsSetInterpolationMode($mResources['Graphics'], 2) _GDIPlus_GraphicsSetSmoothingMode($mResources['Graphics'], 2) _GDIPlus_GraphicsSetTextRenderingHint($mResources['Graphics'], 3) For $Index = 1 To UBound($aTiles) - 1 If $aTiles[$Index][2] Then $mResources[$aTiles[$Index][0]] = _GDIPlus_BitmapCreateFromMemory(Unpack($aTiles[$Index][2])) Next $hMain = GUICreate('Bulldozer', $XTiles * $TileSize, $YTiles * $TileSize) $hPic = GUICtrlCreatePic('', 0, 0, $XTiles * $TileSize, $YTiles * $TileSize) GUISetState(@SW_SHOW, $hMain) LoadLevel() DrawLevel() DrawBulldozer($mResources['Bulldozer' & $Direction]) PushToScreen() While True If GUIGetMsg() = -3 Then Quit() If LevelDone() Then NextLevel() If WinActive($hMain) Then If $KeyboardEnabled = False Then KeyboardInput(True) Else If $KeyboardEnabled Then KeyboardInput(False) EndIf Sleep(10) WEnd Func Quit() Local $aKeys = MapKeys($mResources) For $Index = 0 To UBound($aKeys) - 1 $aKeys[$Index] = 'Graphics' ? _GDIPlus_GraphicsDispose($mResources[$aKeys[$Index]]) : _GDIPlus_BitmapDispose($mResources[$aKeys[$Index]]) Next _GDIPlus_Shutdown() _SQLite_Close() _SQLite_Shutdown() Exit EndFunc Func KeyboardInput($Set = True) Local $aKeys = GetKeyboard() If IsArray($aKeys) Then For $Index = 1 To UBound($aKeys) - 1 HotKeySet($aKeys[$Index][0], $Set ? $aKeys[$Index][1] : Null) Next EndIf $KeyboardEnabled = $Set EndFunc Func MoveRight() If $Pause Or $MsgShow Then Return $PrevLevel = $aLevel IsMovable($X + 1, $Y) If $X + 1 < $XTiles And IsMovable($X + 1, $Y) Then If IsRock($X + 1, $Y) And (IsEmpty($X + 2, $Y) Or IsEmptySocket($X + 2, $Y)) Then $aLevel[$Y][$X + 1] = IsSocket($X + 1, $Y) ? $mTiles['Socket'] : $mTiles['None'] $aLevel[$Y][$X + 2] = IsEmpty($X + 2, $Y) ? $mTiles['Rock'] : $mTiles['RockSocket'] $X += 1 ElseIf IsRock($X + 1, $Y) And (Not IsMovable($X + 2, $Y) Or IsRock($X + 2, $Y)) Then $X = $X Else $X += 1 EndIf $NumOfMoves += 1 EndIf $LastMove = 'R' DrawLevel() DrawBulldozer($mResources['BulldozerR']) PushToScreen() EndFunc Func MoveLeft() If $Pause Or $MsgShow Then Return $PrevLevel = $aLevel If $X - 1 > 0 And IsMovable($X - 1, $Y) Then If IsRock($X - 1, $Y) And (IsEmpty($X - 2, $Y) Or IsEmptySocket($X - 2, $Y)) Then $aLevel[$Y][$X - 1] = IsSocket($X - 1, $Y) ? $mTiles['Socket'] : $mTiles['None'] $aLevel[$Y][$X - 2] = IsEmpty($X - 2, $Y) ? $mTiles['Rock'] : $mTiles['RockSocket'] $X -= 1 ElseIf IsRock($X - 1, $Y) And (Not IsMovable($X - 2, $Y) Or IsRock($X - 2, $Y)) Then $X = $X Else $X -= 1 EndIf $NumOfMoves += 1 EndIf $LastMove = 'L' DrawLevel() DrawBulldozer($mResources['BulldozerL']) PushToScreen() EndFunc Func MoveUp() If $Pause Or $MsgShow Then Return $PrevLevel = $aLevel If $Y - 1 > 0 And IsMovable($X, $Y - 1) Then If IsRock($X, $Y - 1) And (IsEmpty($X, $Y - 2) Or IsEmptySocket($X, $Y - 2)) Then $aLevel[$Y - 1][$X] = IsSocket($X, $Y - 1) ? $mTiles['Socket'] : $mTiles['None'] $aLevel[$Y - 2][$X] = IsEmpty($X, $Y - 2) ? $mTiles['Rock'] : $mTiles['RockSocket'] $Y -= 1 ElseIf IsRock($X, $Y - 1) And (Not IsMovable($X, $Y - 2) Or IsRock($X, $Y - 2)) Then $Y = $Y Else $Y -= 1 EndIf $NumOfMoves += 1 EndIf $LastMove = 'U' DrawLevel() DrawBulldozer($mResources['BulldozerU']) PushToScreen() EndFunc Func MoveDown() If $Pause Or $MsgShow Then Return $PrevLevel = $aLevel If $Y + 1 < $YTiles And IsMovable($X, $Y + 1) Then If IsRock($X, $Y + 1) And (IsEmpty($X, $Y + 2) Or IsEmptySocket($X, $Y + 2)) Then $aLevel[$Y + 1][$X] = IsSocket($X, $Y + 1) ? $mTiles['Socket'] : $mTiles['None'] $aLevel[$Y + 2][$X] = IsEmpty($X, $Y + 2) ? $mTiles['Rock'] : $mTiles['RockSocket'] $Y += 1 ElseIf IsRock($X, $Y + 1) And (Not IsMovable($X, $Y + 2) Or IsRock($X, $Y + 2)) Then $Y = $Y Else $Y += 1 EndIf $NumOfMoves += 1 EndIf $LastMove = 'D' DrawLevel() DrawBulldozer($mResources['BulldozerD']) PushToScreen() EndFunc Func IsMovable($CX, $CY) If $CX < 0 Or $CX >= $XTiles Then Return False If $CY < 0 Or $CY >= $YTiles Then Return False Switch $aLevel[$CY][$CX] Case $mTiles['None'], $mTiles['Rock'], $mTiles['RockSocket'], $mTiles['Socket'] Return True Case Else Return False EndSwitch EndFunc Func IsRock($CX, $CY) If $CX < 0 Or $CX >= $XTiles Then Return False If $CY < 0 Or $CY >= $YTiles Then Return False Switch $aLevel[$CY][$CX] Case $mTiles['Rock'], $mTiles['RockSocket'] Return True Case Else Return False EndSwitch EndFunc Func IsEmpty($CX, $CY) If $CX < 0 Or $CX >= $XTiles Then Return False If $CY < 0 Or $CY >= $YTiles Then Return False Switch $aLevel[$CY][$CX] Case $mTiles['None'] Return True Case Else Return False EndSwitch EndFunc Func IsEmptySocket($CX, $CY) If $CX < 0 Or $CX >= $XTiles Then Return False If $CY < 0 Or $CY >= $YTiles Then Return False Switch $aLevel[$CY][$CX] Case $mTiles['Socket'] Return True Case Else Return False EndSwitch EndFunc Func IsSocket($CX, $CY) If $CX < 0 Or $CX >= $XTiles Then Return False If $CY < 0 Or $CY >= $YTiles Then Return False Switch $aLevel[$CY][$CX] Case $mTiles['RockSocket'], $mTiles['Socket'] Return True Case Else Return False EndSwitch EndFunc Func JumpToLevel() Local $iLevel = InputBox('Jump to level', 'Please type the level that you want to play') If $iLevel And Int($iLevel) > 0 And Int($iLevel) <= $MaxLevel Then $CurrentLevel = $iLevel LoadLevel() DrawLevel() DrawBulldozer($mResources['Bulldozer' & $Direction]) PushToScreen() EndIf EndFunc Func LevelDone() For $j = 0 To $YTiles - 1 For $i = 0 To $XTiles - 1 If $aLevel[$j][$i] = $mTiles['Socket'] Then Return False Next Next Return True EndFunc Func NextLevel() $PlayTime += Int(TimerDiff($Start) / 1000) ShowMessage('Level ' & $CurrentLevel & ' completed.' & @CRLF & ' ', 'Solved in ' & $NumOfMoves & ' moves.' & @CRLF & 'Time: ' & FormatTime($PlayTime), 4000) If $CurrentLevel + 1 > $MaxLevel Then GameEnd() Else $CurrentLevel += 1 LoadLevel() DrawLevel() DrawBulldozer($mResources['Bulldozer' & $Direction]) PushToScreen() EndIf EndFunc Func LoadLevel() Local $Data = SQLite_Query($hDB, 'SELECT Data FROM levels WHERE Level = ' & $CurrentLevel) If @extended Then $Data = BinaryToString(Unpack($Data[1][0])) $Data = StringSplit($Data, @CRLF, 1) For $Line = 1 To $YTiles Local $Row = StringSplit($Data[$Line], '') For $Index = 1 To $Row[0] $aLevel[$Line - 1][$Index - 1] = $Row[$Index] Next Next $X = $Data[26] $Y = $Data[27] $Direction = $Data[28] ShowMessage('Level ' & $CurrentLevel) $NumOfMoves = 0 $PlayTime = 0 $Start = TimerInit() EndIf EndFunc Func RestartLevel() If $Pause Then Return LoadLevel() DrawLevel() DrawBulldozer($mResources['Bulldozer' & $Direction]) PushToScreen() EndFunc Func GameEnd() ShowMessage('Congratulations!' & @CRLF & @CRLF & 'You have finished the game.', Null, 4000) If $AutoRestart Then $CurrentLevel = 1 RestartLevel() Else Quit() EndIf EndFunc Func FormatTime($Sec) If $Sec < 60 Then Return $Sec & ' seconds' Local $Min = Int($Sec / 60) $Sec -= $Min * 60 If $Min > 60 Then Local $Hours = Int($Sec / 60) $Min -= $Hours * 60 Return $Hours & ' hour' & ($Hours > 1 ? 's' : '') & ($Min <> 0 ? ', ' & $Min & ' minute' & ($Min > 1 ? 's' : '') : '') & ($Sec <> 0 ? ', ' & $Sec & ' second' & ($Sec > 1 ? 's' : '') : '') Else Return $Min & ' minute' & ($Min > 1 ? 's' : '') & ($Sec <> 0 ? ', ' & $Sec & ' second' & ($Sec > 1 ? 's' : '') : '') EndIf EndFunc Func ShowMessage($Message, $SecMessage = Null, $iDelay = 1500) $MsgShow = True Local $hFamily = _GDIPlus_FontFamilyCreate($Font) Local $hFont = _GDIPlus_FontCreate($hFamily, $FontSize, 1) Local $tLayout = _GDIPlus_RectFCreate(0, 0, $XTiles * $TileSize, ($SecMessage ? ($YTiles * $TileSize / 2) : ($YTiles * $TileSize))) Local $hBrush = _GDIPlus_BrushCreateSolid($MessageColor) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, ($SecMessage ? 2 : 1)) _GDIPlus_GraphicsClear($mResources['Graphics'], $ClearColor) _GDIPlus_GraphicsDrawStringEx($mResources['Graphics'], $Message, $hFont, $tLayout, $hFormat, $hBrush) If $SecMessage Then _GDIPlus_StringFormatSetLineAlign($hFormat, 0) Local $hSecFont = _GDIPlus_FontCreate($hFamily, $SecFontSize, 1) Local $tSecLayout = _GDIPlus_RectFCreate(0, ($YTiles * $TileSize / 2) , $XTiles * $TileSize, $YTiles * $TileSize / 2) Local $hSecBrush = _GDIPlus_BrushCreateSolid($SecMessageColor) _GDIPlus_GraphicsDrawStringEx($mResources['Graphics'], $SecMessage, $hSecFont, $tSecLayout, $hFormat, $hSecBrush) EndIf PushToScreen() _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_FontDispose($hFont) If $SecMessage Then _GDIPlus_BrushDispose($hSecBrush) _GDIPlus_FontDispose($hSecFont) EndIf _GDIPlus_FontFamilyDispose($hFamily) Local $DelayTimer = TimerInit() Do If GUIGetMsg() = -3 Then Quit() Sleep(10) Until TimerDiff($DelayTimer) >= $iDelay $MsgShow = False EndFunc Func UndoLastMove() If $PrevLevel = Null Then Return If $LastMove = Null Then Return If $Pause Then Return $aLevel = $PrevLevel DrawLevel() Switch $LastMove Case 'R' $X -= 1 DrawBulldozer($mResources['BulldozerR']) Case 'L' $X += 1 DrawBulldozer($mResources['BulldozerL']) Case 'U' $Y += 1 DrawBulldozer($mResources['BulldozerU']) Case 'D' $Y -= 1 DrawBulldozer($mResources['BulldozerD']) EndSwitch PushToScreen() $PrevLevel = Null $NumOfMoves -= 1 EndFunc Func Pause() $Pause = Not $Pause If $Pause Then $PlayTime += Int(TimerDiff($Start) / 1000) ShowMessage('Game is paused.', 'Press {Pause} button to resume your game.', 10) Else DrawLevel() DrawBulldozer($mResources['Bulldozer' & $Direction]) PushToScreen() $Start = TimerInit() EndIf Do Sleep(10) Until $Pause = False EndFunc Func DrawLevel() _GDIPlus_GraphicsClear($mResources['Graphics'], $ClearColor) For $j = 0 To $YTiles - 1 For $i = 0 To $XTiles - 1 Switch $aLevel[$j][$i] Case $mTiles['Wall1'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall1'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall2'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall2'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall3'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall3'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall4'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall4'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall5'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall5'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall6'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall6'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall7'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall7'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Wall8'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Wall8'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Rock'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Rock'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['RockSocket'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['RockSocket'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) Case $mTiles['Socket'] _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $mResources['Socket'], $i * $TileSize, $j * $TileSize, $TileSize, $TileSize) EndSwitch Next Next EndFunc Func DrawBulldozer($hImage) _GDIPlus_GraphicsDrawImageRect($mResources['Graphics'], $hImage, $X * $TileSize, $Y * $TileSize, $TileSize, $TileSize) EndFunc Func PushToScreen() Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($mResources['Bitmap']) _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, 0x0172, 0, $hHBITMAP)) _WinAPI_DeleteObject($hHBITMAP) EndFunc Func ReadProperty($sProperty, $vFallback = Null) Local $aQuery = SQLite_Query($hDB, "SELECT Value FROM settings WHERE Property = " & _SQLite_FastEscape($sProperty)) If @extended Then Return $aQuery[1][0] Else Return $vFallback EndIf EndFunc Func GetTiles($vFallback = Null) Local $aQuery = SQLite_Query($hDB, 'SELECT Tile, Symbol, Data FROM tiles') If @extended Then Return $aQuery Else Return $vFallback EndIf EndFunc Func GetKeyboard($vFallback = Null) Local $aQuery = SQLite_Query($hDB, 'SELECT Key, Function FROM keyboard') If @extended Then Return $aQuery Else Return $vFallback EndIf EndFunc Func SQLite_Query($hDB, $sQuery) Local $aResult, $iRows, $iColumns _SQLite_GetTable2d($hDB, $sQuery, $aResult, $iRows, $iColumns) If @error Then Return SetError(1, 0, False) Else Return SetError(0, UBound($aResult, 1) - 1, $aResult) EndIf EndFunc Func Unpack($bData) Local $tData = DllStructCreate('byte Data[' & BinaryLen($bData) & ']') Local $bCode = Binary('0x8B7424048B4C2408AC347F8846FF4975F7C20800') Local $iSize = BinaryLen($bCode) Local $tCode = DllStructCreate('byte Code[' & $iSize & ']') DllStructSetData($tCode, 'Code', $bCode) DllStructSetData($tData, 'Data', $bData) DllCallAddress('int', DllStructGetPtr($tCode), 'ptr', DllStructGetPtr($tData), 'int', DllStructGetSize($tData)) Return DllStructGetData($tData, 'Data') EndFunc Have fun! Bulldozer.zip Edited May 18, 2023 by Andreik Updated code. ioa747, Zedna, mLipok and 3 others 6 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
AutoBert Posted April 28, 2023 Share Posted April 28, 2023 After adding #AutoIt3Wrapper_UseX64=n it works. Link to comment Share on other sites More sharing options...
Andreik Posted April 28, 2023 Author Share Posted April 28, 2023 Most probably because your default setting is to use x64 version of AutoIt and Sqlite3.dll is x86 version. Anyway, glad you figured it out. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
AutoBert Posted April 28, 2023 Share Posted April 28, 2023 (edited) 21 minutes ago, Andreik said: Anyway, glad you figured it out. Easier, as finding a solution for level 8. Edited April 28, 2023 by AutoBert Andreik 1 Link to comment Share on other sites More sharing options...
Andreik Posted April 28, 2023 Author Share Posted April 28, 2023 Probably there is even a better way to solve it with less moves. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Andreik Posted May 13, 2023 Author Share Posted May 13, 2023 Added 10 more levels. Some of them might be challenging. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
AndyG Posted May 14, 2023 Share Posted May 14, 2023 On 4/28/2023 at 8:49 PM, Andreik said: Probably there is even a better way to solve it with less moves. 63 Moves....but 50 Seconds needed....😁 And btw....xor al, 0x7f, SO CUTE!!😍 Andreik 1 Link to comment Share on other sites More sharing options...
Andreik Posted May 14, 2023 Author Share Posted May 14, 2023 13 hours ago, AndyG said: And btw....xor al, 0x7f, SO CUTE!!😍 You got me, next time I will go for AES-NI. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
argumentum Posted May 15, 2023 Share Posted May 15, 2023 Would you show the Pack() for the Unpack() ? Thanks Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted May 15, 2023 Author Share Posted May 15, 2023 (edited) 9 hours ago, argumentum said: Would you show the Pack() for the Unpack() ? Thanks There is no Pack() because I am lazy. Unpack() can also Pack() because as AndyG said it's just a simple XOR with a constant. Here is the code: 8B 74 24 04 mov esi, [esp + 4] 8B 4C 24 08 mov ecx, [esp + 8] AC next: lodsb 34 7F xor al, 127 88 46 FF mov [esi - 1], al 49 dec ecx 75 F7 jnz next C2 08 00 ret 8 Edited May 15, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Skeletor Posted May 15, 2023 Share Posted May 15, 2023 Okay let me ask a noob question. How did you achieve to draw the sprites? Kind RegardsSkeletor "Coffee: my defense against going postal." Microsoft Office Splash Screen | Basic Notepad Program (Beginner) | Transparent Splash Screen | Full Screen UI Link to comment Share on other sites More sharing options...
Andreik Posted May 15, 2023 Author Share Posted May 15, 2023 In bulldozer.sqlite there is a table named tiles that saves sprites as a blob. It's just a matter of querying the database for the desired sprite and then basic GDI+ to convert from binary to bitmap. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Skeletor Posted May 15, 2023 Share Posted May 15, 2023 I actually did not think it was in the DB. Thats some really clever code. Kind RegardsSkeletor "Coffee: my defense against going postal." Microsoft Office Splash Screen | Basic Notepad Program (Beginner) | Transparent Splash Screen | Full Screen UI Link to comment Share on other sites More sharing options...
Andreik Posted May 15, 2023 Author Share Posted May 15, 2023 Usually it's not a good practice to store assets in database but since I have only fifteen assets and each around 2 - 3 Kb in size, it works in my case. argumentum 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
AndyG Posted May 16, 2023 Share Posted May 16, 2023 On 5/14/2023 at 11:57 PM, Andreik said: You got me, next time I will go for AES-NI. Oh no! Please use those >50 years old techniques more! I am always so impressed and surprised when examining/investigate such a piece of "gold" code😇 I played the "original" Sokoban in the 80s, it was fun at all! So thank you so much transferring the idea into AutoIt code! argumentum 1 Link to comment Share on other sites More sharing options...
Andreik Posted May 17, 2023 Author Share Posted May 17, 2023 Well, games in those days were not all about shooting and killing things. I still have in mind some old games that I would like to recreate in AutoIt and maybe to extend their game play. Xandy, Skeletor and argumentum 3 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Skeletor Posted May 18, 2023 Share Posted May 18, 2023 I vote for Tetris Kind RegardsSkeletor "Coffee: my defense against going postal." Microsoft Office Splash Screen | Basic Notepad Program (Beginner) | Transparent Splash Screen | Full Screen UI Link to comment Share on other sites More sharing options...
Andreik Posted May 18, 2023 Author Share Posted May 18, 2023 (edited) Added 20 more levels, so there are 60 levels now. Since some of you already played some levels I added also the option to start to a specific level so you don't have to play again from the beginning. To use this functionality just press J and enter the level that you want to play. Edited May 18, 2023 by Andreik Skeletor and AutoBert 2 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
DanielMedina Posted August 25, 2023 Share Posted August 25, 2023 it's great to have more levels because I've played all the levels Link to comment Share on other sites More sharing options...
Andreik Posted August 25, 2023 Author Share Posted August 25, 2023 I'll add more these days. Skeletor 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now