was bored.. made a maze game.. use arrows to move, or change them to something more suitable for you. change the ROWS to a higher value to make more difficult. if you make the maze real big, change the gridlineSize to 1.. anything over 160 or so it pretty much unplayable.
edit:
changed alot of things.. mazes much larger than screen size possible.. use middle mouse button to pan map.. H for help.
screenshot
Code
Spoiler
;maze game.. maze created using recursive backtrace
;use arrows to move, middle mouse button to pan
;change rows/columns values to make hard/easier
;ton80
;to do
; 'throw' while panning
; minimap view
; timer
; solver (gulp)
; mouse controls movement
; show map creation
; update rate
; gui for settings
SetBatchLines -1
#NoEnv
#SingleInstance force
gosub, init_constants
rows := 108 ;# of rows in grid (54)
columns := round(rows * 1.78) ;# of columns in grid.. (default keeps 16:9 aspect)
cellWidth := 20
cellHeight := cellWidth
gridColor := 0xd3d08c ;color of grid lines
gridLineSize:= 6 ;size of the gridlines
backColor := 0x3f3f3f ;background color
p1Color := 0x0000FF ;color for player
p1North := "Up" ;key used to move player North
p1South := "Down" ;key used to move player South
p1East := "Right" ;key used to move player East
p1West := "Left" ;key used to move player West
goHome := "F1" ;key used to view your starting cell
goEnd := "F2" ;key used to view the ending cell
goMe := "F3" ;key used to view your current cell
startColor := 0x0FF00F ;color for the STARTING cell
endColor := 0xF00FF0 ; color for the END cell
panIt := "MButton" ;button used to PAN the map
helpMe := "H" ;key used to view help
mazeInfo := "I" ;key used to display info about the maze
togglePath := "P" ;key used to toggle the path on/off
pathColor := 0x0000FF ;color of traveled path, white will always show as solid style
pathStyle := 4 ;style of path lines (0 solid, 1 dash, 2 dot, 3 dashdot, 4 dashdotdot)
pathWidth := 1 ;anything larger than one will revert style back to solid
panSpeed := 1 ;speed (in pixels) to pan
moveDelay := 75 ;delay between moves (to low makes it hard to control)
showPath := 0
startTime := A_TickCount
allControls := "p1North,p1South,p1East,p1West,goHome,goEnd,goMe,panIt,mazeInfo,helpMe,togglePath"
maze := new cMaze(rows,columns,cellHeight,cellWidth,gridColor,backColor,p1Color,startColor,endColor,gridLineSize,showPath,pathColor,pathStyle,pathWidth)
gosub, main_loop
return
main_loop:
RenderTime := (A_TickCount - startTime) / 1000
Loop
loop, parse, allControls, csv
If (GetKeyState(%A_Loopfield%, "P") && (winActive() = maze.hwndWin))
gosub, %a_loopfield%
return
init_constants:
Global SRCCOPY := 0xCC0020
global isVisited := 1
global isBorderN := 2
global isBorderE := 4
global isBorderS := 8
global isBorderW := 16
global isWallN := 32
global isWallE := 64
global isWallS := 128
global isWallW := 256
global dNorth := 1
global dEast := 2
global dSouth := 3
global dWest := 4
global Rect
return
p1North:
maze.move(1)
sleep, moveDelay
return
p1East:
maze.move(2)
sleep, moveDelay
return
p1South:
maze.move(3)
sleep, moveDelay
return
p1West:
maze.move(4)
sleep, moveDelay
return
goHome:
maze.offsetX := 0
maze.offsetY := 0
maze.update()
return
goEnd:
maze.offsetX := maze.OffsetX := maze.width - A_ScreenWidth
maze.offsetY := maze.OffsetY := maze.Height - A_ScreenHeight
maze.update()
return
goMe:
maze.offsetX := maze.cell[maze.currentCell].xpos
maze.offsetY := maze.cell[maze.currentCell].ypos
maze.update()
return
panIt:
initialX := maze.OffsetX ; initial position of board before panning began
initialY := maze.OffsetY
MouseGetPos, mx, my ; initial position of mouse when panning started
while (getkeystate(panIt, "P"))
{
MouseGetPos, ox,oy
maze.offsetX := initialX + ((mx-ox) * panSpeed)
maze.offsetY := initialY + ((my-oy) * panSpeed)
if (maze.OffsetY < 0)
maze.OffsetY := 0
if (maze.OffsetX + A_ScreenWidth > maze.width)
maze.OffsetX := maze.width - A_ScreenWidth
if (maze.OffsetY + A_ScreenHeight > maze.Height)
maze.OffsetY := maze.Height - A_ScreenHeight
if (maze.OffsetX < 0)
maze.OffsetX := 0
maze.update()
}
return
mazeInfo:
info := "This maze consists of " maze.cell.maxindex() " cells.`nIt took " renderTime " seconds to create the maze."
info .= "`nYou have made " maze.moveCount " moves so far."
clipboard := info
MsgBox % info
return
helpMe:
help := p1North " moves north.`n"
help .= p1East " moves east.`n"
help .= p1South " moves south.`n"
help .= p1West " moves west.`n"
help .= panIt " pans the map.`n"
help .= goHome " changes the view to the starting cell`n"
help .= goEnd " changes the view to the ending cell.`n"
help .= goMe " changes the view to your current position.`n"
help .= helpMe " brings up this box.`n"
help .= mazeInfo " shows map info.`n"
help .= togglePath " toggles the travled path.`n"
MsgBox % help
return
togglePath:
maze.showPath := maze.showPath ? 0 : 1
maze.update()
sleep, moveDelay
return
esc::
maze.Destroy()
exitapp
class cMaze{
__new(rows,columns,cellHeight,cellWidth,gridColor = 0xFFFFFF, backColor=0x000000,p1Color=0x0000FF,startColor=0x0FF00F,endColor=0xF00FF0,gridLineSize=1,showPath=0,pathColor=0xFFFFFF,pathStyle=0,pathWidth=1){
this.offsetX := 0
this.offSetY := 0
this.rows := rows
this.columns := columns
this.height := cellHeight * rows
this.width := cellwidth * columns
this.gridColor := gridColor
this.backColor := backColor
this.p1Color := p1Color
this.startColor := startColor
this.endColor := endColor
this.currentCell := 1
this.startCell := 1
this.showPath := showpath
this.pathColor := pathColor
this.pathStyle := pathStyle
this.pathWidth := pathWidth
this.endCell := this.rows * this.columns
this.cellWidth := floor(this.width / this.columns)
this.cellHeight := floor(this.height / this.rows)
this.gridLineSize := gridLineSize
;this.path := {}
width := this.width
height := this.height
VarSetCapacity(Rect,16,0)
NumPut(0,rect,0)
NumPut(0,rect,4)
NumPut(width,rect,8)
NumPut(height,rect,12)
this.createCellArray()
this.moveCount := 0
}
createCellArray(){
xpos := 0, ypos := 0
this.cell := {}
loop % this.rows{
cRow := a_index
Loop % this.columns{
flags := 480
cCol := a_index
if (cRow = 1)
flags |= isBorderN
if (cCol = this.columns)
flags |= isBorderE
if (cRow = this.rows)
flags |= isBorderS
if (cCol = 1)
flags |= isBorderW
this.cell.insert(new cCell(xpos,ypos,flags))
xpos += this.cellWidth
}
xpos := 0
ypos += this.cellHeight
}
this.show()
this.generateMaze()
}
generateMaze(){
global PBar
cells_unvisited := this.rows * this.columns
gui,5: add, text,, Creating Maze
gui,5: add, progress, w200 h20 vPBar range0-%cells_unvisited%
gui,5: -caption
gui,5: show
visitedCell := {}
Random,rndCell,1,this.rows * this.columns
this.rndCell := rndCell
while (cells_unvisited > 0){
this.getPossibleMoves()
if (this.possMoves.maxindex() > 1)
visitedCell.insert(this.rndCell)
Random,newCell, 1,this.possMoves.maxindex()
if (this.possMoves[newCell] = "North"){
this.cell[this.rndCell].flags &= ~isWallN
this.rndCell -= this.columns
this.cell[this.rndCell].flags &= ~isWallS
}
else if (this.possMoves[newCell] = "East"){
this.cell[this.rndCell].flags &= ~isWallE
this.rndCell += 1
this.cell[this.rndCell].flags &= ~isWallW
}
else if (this.possMoves[newCell] = "South"){
this.cell[this.rndCell].flags &= ~isWallS
this.rndCell += this.columns
this.cell[this.rndCell].flags &= ~isWallN
}
else if (this.possMoves[newCell] = "West"){
this.cell[this.rndCell].flags &= ~isWallW
this.rndCell -= 1
this.cell[this.rndCell].flags &= ~isWallE
}
else{
visitedCell.remove(visitedCellIndex)
this.rndCell := visitedCell[visitedCellIndex -=1]
continue
}
cells_unvisited --
visitedCellIndex := visitedCell.maxindex()
this.cell[this.rndCell].flags |= isVisited
guicontrol,5:, PBar, +1
}
gui,5:destroy
this.createGameDCS()
this.drawCells()
this.update()
}
show(){
gui, -caption
gui, color, % this.backColor
gui, show, % "h"this.height " w"this.width " x"0 " y"0
this.hwndWin := WinExist("A")
this.hdcWin := DllCall("GetDC", "ptr", this.hwndWin)
this.hdcGrid := DllCall("CreateCompatibleDC", "ptr", this.hdcWin)
hbm := DllCall("CreateCompatibleBitmap", "ptr", this.hdcWin, "uint", this.width, "uint", this.height)
DllCall("SelectObject", "ptr", this.hdcGrid, "uint", hbm)
DllCall("DeleteObject", "ptr", hbm)
}
drawCells(){
this.createBrush(this.hdcGrid,this.backColor)
this.createPen(this.hdcGrid,0,this.gridLineSize,this.gridColor)
DllCall("FillRect", "ptr", this.hdcGrid, "ptr", &Rect, "ptr", this.brush)
for index, val in this.cell{
if (this.cell[index].flags & isWallN) || (this.cell[index].flags & isBorderN){
this.moveTo(this.hdcGrid, this.cell[index].xpos, this.cell[index].ypos)
this.lineTo(this.hdcGrid, this.cell[index].xpos + this.cellWidth, this.cell[index].ypos)
}
if (this.cell[index].flags & isWallE) || (this.cell[index].flags & isBorderE){
this.moveTo(this.hdcGrid,this.cell[index].xpos + this.cellWidth, this.cell[index].ypos)
this.lineTo(this.hdcGrid, this.cell[index].xpos + this.cellWidth, this.cell[index].ypos + this.cellHeight)
}
if (this.cell[index].flags & isBorderS){
this.moveTo(this.hdcGrid, this.cell[index].xpos + this.cellWidth, this.cell[index].ypos + this.cellHeight)
this.lineTo(this.hdcGrid, this.cell[index].xpos, this.cell[index].ypos + this.cellHeight)
}
if (this.cell[index].flags & isBorderW){
this.moveTo(this.hdcGrid, this.cell[index].xpos, this.cell[index].ypos + this.cellHeight)
this.lineTo(this.hdcGrid, this.cell[index].xpos, this.cell[index].ypos)
}
}
this.deletePen()
this.deleteBrush()
this.drawSpecial()
DllCall("BitBlt", "ptr", this.hdcPath, "uint", 0, "uint", 0, "uint", this.width, "uint", this.height, "ptr", this.hdcGrid, "uint",0, "uint", 0, "uint", SRCCOPY)
}
drawSpecial(){ ;draw the starting and ending cells
h := this.cellHeight
w := this.cellWidth
s := this.gridLineSize / 2
ss := this.startCell
es := this.endCell
this.createBrush(this.hdcGrid,this.startColor)
this.createPen(this.hdcGrid,0,1,this.startColor)
DllCall("Rectangle", "ptr", this.hdcGrid, "uint", this.cell[ss].xpos + s, "uint", this.cell[ss].ypos + s, "uint", this.cell[ss].xpos + w - s, "uint", this.cell[ss].ypos + h - s)
this.deleteBrush()
this.deletePen()
this.createBrush(this.hdcGrid,this.endColor)
this.createPen(this.hdcGrid,0,1,this.endColor)
DllCall("Rectangle", "ptr", this.hdcGrid, "uint", this.cell[es].xpos + s, "uint", this.cell[es].ypos + s, "uint", this.cell[es].xpos + w - s, "uint", this.cell[es].ypos + h - s)
this.deleteBrush()
this.deletePen()
}
creategameDCs(){
this.hdcOutput := DllCall("CreateCompatibleDC", "ptr", this.hdcWin)
hbm := DllCall("CreateCompatibleBitmap", "ptr", this.hdcWin, "uint", this.width, "uint", this.height)
DllCall("SelectObject", "ptr", this.hdcOutput, "uint", hbm)
DllCall("DeleteObject", "ptr", hbm)
this.hdcPath := DllCall("CreateCompatibleDC", "ptr", this.hdcWin)
hbm := DllCall("CreateCompatibleBitmap", "ptr", this.hdcWin, "uint", this.width, "uint", this.height)
DllCall("SelectObject", "ptr", this.hdcPath, "uint", hbm)
DllCall("DeleteObject", "ptr", hbm)
}
getPossibleMoves(){
cc := this.rndCell
this.possMoves := {}
if !(this.cell[cc].flags & isBorderN) && !(this.cell[cc - this.columns].flags & isVisited)
this.possMoves.Insert("North")
if !(this.cell[cc].flags & isBorderE) && !(this.cell[cc + 1].flags & isVisited)
this.possMoves.Insert("East")
if !(this.cell[cc].flags & isBorderS) && !(this.cell[cc + this.columns].flags & isVisited)
this.possMoves.Insert("South")
if !(this.cell[cc].flags & isBorderW) && !(this.cell[cc - 1].flags & isVisited)
this.possMoves.Insert("West")
}
createPen(hdc,pstyle=0,size=1,pcolor=0xFFFFFF){
this.pen := DllCall("CreatePen", "uint", pstyle, "uint", size, "uint", pcolor)
DllCall("SelectObject", "ptr", hdc, "ptr", this.pen)
}
deletePen(){
DllCall("DeleteObject", "ptr", this.pen)
}
createBrush(hdc,color=0x000000){
this.brush := DllCall("CreateSolidBrush", "uint", color)
DllCall("SelectObject", "ptr", hdc, "ptr", this.brush)
}
deleteBrush(){
DllCall("DeleteObject", "ptr", this.brush)
}
moveTo(hdc,x,y){
DllCall("MoveToEx", "ptr", hdc, "uint", x, "uint", y, "uint", 0)
}
lineTo(hdc,x,y){
DllCall("LineTo", "ptr", hdc, "uint", x, "uint", y)
}
Destroy(){
DllCall("ReleaseDC", "ptr", this.hwndWin, "ptr", this.hdcWin)
DllCall("DeleteDC", "ptr", this.hdcGrid)
DllCall("DeleteDC", "ptr", this.hdcOutput)
DllCall("DeleteDC", "ptr", this.hdcPath)
this.cells := {}
}
move(dir){
cc := this.currentCell
if (dir=1) && !(this.cell[cc].flags & isWallN) && !(this.cell[cc].flags & isBorderN)
this.currentCell -= this.columns
else if (dir=2) && !(this.cell[cc].flags & isWallE) && !(this.cell[cc].flags & isBorderE)
this.currentCell += 1
else if (dir=3) && !(this.cell[cc].flags & isWallS) && !(this.cell[cc].flags & isBorderS)
this.currentCell += this.columns
else if (dir=4) && !(this.cell[cc].flags & isWallW) && !(this.cell[cc].flags & isBorderW)
this.currentCell --
;draw path lines
this.createPen(this.hdcPath,this.pathStyle,this.pathWidth,this.pathColor)
this.moveTo(this.hdcPath,this.cell[cc].xpos + this.cellWidth /2,this.cell[cc].ypos + this.cellHeight /2)
this.lineTo(this.hdcPath,this.cell[this.currentCell].xpos + this.cellWidth /2, this.cell[this.currentCell].ypos + this.cellwidth /2)
this.deletePen()
this.upDate()
this.moveCount++
}
update(){
cc := this.currentCell
h := this.cellHeight
w := this.cellWidth
s := this.gridLineSize
hdc := this.showPath ? this.hdcPath : this.hdcGrid
DllCall("BitBlt", "ptr", this.hdcOutput, "uint", 0, "uint", 0, "uint", this.width, "uint", this.height, "ptr", hdc, "uint",0, "uint", 0, "uint", SRCCOPY)
this.createBrush(this.hdcOutput, this.p1Color)
DllCall("Ellipse", "ptr", this.hdcOutput, "uint", this.cell[cc].xpos + Round(s / 2), "uint", this.cell[cc].ypos + Round(s / 2), "uint", this.cell[cc].xpos + w - s / 2, "uint", this.cell[cc].ypos + h - s / 2)
this.deleteBrush()
DllCall("BitBlt", "ptr", this.hdcWin, "uint", 0, "uint",0, "uint", this.width, "uint", this.height, "ptr", this.hdcOutput, "uint", this.OffsetX, "uint", this.OffsetY, "uint", SRCCOPY)
if (this.currentCell = this.endCell)
this.winner()
}
winner(){
MsgBox,,Woot!, % "You win!`nIt took " this.movecount " moves."
this.Destroy()
Reload
}
}
class cCell{
__new(xpos,ypos,flags){
this.xpos := xpos
this.ypos := ypos
this.flags := flags
}
}