2048 Game

Post your working scripts, libraries and tools
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

2048 Game

16 May 2018, 01:28

I had a few hours to kill so I thought I would take a stab at the game 2048.
I did this in one sitting and was getting very bored/tired by the end so I didn't bother cleaning up my code,
I might clean up the code and redo the gui later (That's code for never).
I did a fair amount of play testing and everything seems to be working fine, if you find a bug let me know and I'll do a quick fix.


Use your arrow keys to move the tiles around and try to get the highest score you can.

Image

Code: Select all

/*
	Written By: Hellbent
	Youtube: https://www.youtube.com/user/CivReborn
	Date Started: May 15th, 2018
	Date Of Last Edit: May 15th, 2018
	Last PasteBin Save: https://pastebin.com/WdQ0UWY0
	Description:
		Recreation of the game 2048.
		Use arrow keys to move tiles around. Goal: Slide tiles of the same value together to form new tiles of a higher value.
		Game ends when there is no free spaces/moves.
*/
#SingleInstance,Force
IfNotExist,%A_ScriptDir%/2048 Assets
	Create_Game_Assets()
SetWorkingDir,%A_ScriptDir%/2048 Assets
global row_col_Positions:={1:36,2:121,3:206,4:291},WB,score_x:=400,Grid_Array:=[],Tiles:={},Can_Move:=1,Value_Array:=[],Game_Active:=0,High_Scores:="" ,My_Score:=0,Scores:=[],Names:=[]
FileRead,temp_score,Scores.txt
Loop, Parse,temp_Score,*
	Scores[A_Index]:=A_LoopField
i:=1
Loop 3
	{
		tempp:=StrSplit(Scores[A_Index]," ")
		Loop,% tempp.Length()-1
			Names[i].=tempp[A_Index]
		Scores[A_Index]:=tempp[tempp.MaxIndex()],i++
	}
game:=New Game_Board()
return
GuiClose:
GuiEscape:
*^ESC::
	ExitApp
Move_Window:
	PostMessage,0xA1,2
	return
Min_Window:	
	Gui,1:Minimize
	return
Tag:
	Try	{
	 Run,https://www.youtube.com/user/CivReborn
	}
	return
New_Game:
	My_Score:=0,Game_Active:=1
	GuiControl,1:,My_Score,% My_Score
	Remove_Bot()
	game.Build_Grid()
	Loop 2
		Tiles[Tiles.Length()+1]:=New Game_Tile()
	return
Score_Scroll:
	if(score_x<0-posw)
		score_x:=396
	score_x--
	GuiControl,3:Move,ss,x%Score_X%
	return
#IfWinActive, 2048
~up::
	if(!Key_Pressed)
		{
			key_Pressed:=1
			SetTimer,Score_Scroll,Off
			Move_Tiles(3,4,2,1,1,1,-1,0,-1,0,1)
			Check_Game_State()
			SetTimer,Score_Scroll,On
			While(GetKeyState("Up"))
				sleep,10
			key_Pressed:=0
		}
	return
~Down::
	if(!Key_Pressed)
		{
			key_Pressed:=1
			SetTimer,Score_Scroll,Off
			Move_Tiles(3,4,3,1,-1,1,1,0,1,0,3)
			Check_Game_State()
			SetTimer,Score_Scroll,On
			While(GetKeyState("Down"))
				sleep,10
			key_Pressed:=0
		}
	return
~Left::
	if(!Key_Pressed)
		{
			key_Pressed:=1
			SetTimer,Score_Scroll,Off
			Move_Tiles(4,3,1,2,1,1,0,-1,0,-1,4)
			Check_Game_State()
			SetTimer,Score_Scroll,On
			While(GetKeyState("Left"))
				sleep,10
			key_Pressed:=0
		}
	return
~Right::
	if(!Key_Pressed)
		{
			key_Pressed:=1
			SetTimer,Score_Scroll,Off
			Move_Tiles(4,3,1,3,1,-1,0,1,0,1,2) 
			Check_Game_State()
			SetTimer,Score_Scroll,On
			While(GetKeyState("Right"))
				sleep,10
			key_Pressed:=0
		}
	return	
#If
Check_Game_State()
	{
		if(Game_Active=1)
			{
				i:=1
				loop 4
					{
						j:=1
						Loop 4
							{
								if(Grid_Array[i,j]=0)
									return
								j++
							}
						i++
					}
				k:=1
				Loop,% Tiles.Length()
					{
						i:=1	
						Loop, 4
							{
								j:=1
								Loop, 4
									{
										if(Tiles[k].Y=i&&Tiles[k].X=j)
											{
												Value_Array[i,j]:=Tiles[k].Value
											}
										j++	
									}
								i++	
							}
						k++	
					}
				i:=1	
				Loop 4	
					{
						j:=1
						Loop 4
							{
								if(Value_Array[i,j]=Value_Array[i-1,j]||Value_Array[i,j]=Value_Array[i+1,j]||Value_Array[i,j]=Value_Array[i,j-1]||Value_Array[i,j]=Value_Array[i,j+1])
									{
										return
									}
								j++	
							}
						i++	
					}
				Game_Over()
			}		
	}
Game_Over()
	{
		Game_Active:=0,New_Score:=0
		Remove_Bot()
		loop 3
			{
				if(My_Score>Scores[A_Index])
					{
						Gui,1:+OwnDialogs
						InputBox,name,New High Score,Enter Your Name
						New_Score:=1
						break
					}
			}
		if(New_Score=1)
			{
				if(My_Score>Scores[1])
					Scores[3]:=Scores[2],Names[3]:=Names[2],Scores[2]:=Scores[1],Names[2]:=Names[1],Scores[1]:=My_Score,Names[1]:=Name
				else if(My_Score>Scores[2])
					Scores[3]:=Scores[2],Names[3]:=Names[2],Scores[2]:=My_Score,Names[2]:=Name
				else if(My_Score>Scores[3])
					Scores[3]:=My_Score,Names[3]:=Name
				FileSetAttrib, -RH,scores.txt
				FileDelete,%A_ScriptDir%/2048 Assets/scores.txt
				FileAppend,% Names[1] " " Scores[1] "*" Names[2] " " Scores[2] "*" Names[3] " " Scores[3] "*",%A_ScriptDir%/2048 Assets/scores.txt
				FileSetAttrib, +RH,%A_ScriptDir%/2048 Assets/scores.txt         
				GuiControl,3:,ss,% "1: " Names[1] " " Scores[1] "          2: " Names[2] " " Scores[2] "          3: " Names[3] " " Scores[3] "          "
			}
		else
			{
				Gui,1:+OwnDialogs
				MsgBox,Game Over
			}
	}
Merge(new_pos,old_pos)
	{
		global
		Tiles[new_Pos].Value *= 2,My_Score+=Tiles[new_Pos].Value
		GuiControl,1:,My_Score,% My_Score
		Tiles[new_Pos].Has_Merged:=1,Grid_Array[Tiles[old_pos].Y,Tiles[old_pos].X]:=0,img:=Tiles[old_pos].img
		img.ParentNode.RemoveChild(img)
		Tiles.RemoveAt(old_pos)
		Loop,% Tiles.Length()
			Tiles[A_Index].img.src:=A_WorkingDir "\" Tiles[A_Index].Value ".png"
	}
Remove_Bot()
	{
		n:=Tiles.Length()
		Loop, % Tiles.length()+1
			{
				img:=Tiles[n].img
				img.ParentNode.RemoveChild(img)
				Tiles.RemoveAt(n)
				n--
			}	
	}
Move_Tiles(i_Loop,j_Loop,i_Start,j_Start,i_Count,j_Count,i_Array,j_Array,y_Add,x_Add,Dir)
	{
		if(Can_Move=1)
		{
			Something_Moved:=0
			Can_Move:=0
			Loop, % Tiles.Length()
				Tiles[A_Index].Has_Merged:=0
			redo:		
			i:=i_Start
			Loop % i_Loop
				{
					j:=j_Start
					Loop % j_Loop
						{
							Loop,% Tiles.Length()
								{
									if(Tiles[A_Index].Y=i&&Tiles[A_Index].X=j)
										{
											if(Grid_Array[i+i_Array,j+j_Array]=0)
												Tiles[A_Index].Is_Moving:=1,Tiles[A_Index].X+=x_Add,Tiles[A_Index].Y+=y_Add,Grid_Array[i+i_Array,j+j_Array]:=1,Grid_Array[i,j]:=0,Something_Moved:=1
											else if(Grid_Array[i+i_Array,j+j_Array]=1&&Tiles[A_Index].Is_Moving=0)
												{
													k:=A_Index
													Loop,% Tiles.Length()
														{
															if(Tiles[A_Index].Y=i+i_Array&&Tiles[A_Index].X=j+j_Array&&Tiles[A_Index].Is_Moving=0&&Tiles[A_Index].Value=Tiles[k].Value&&Tiles[A_index].Has_Merged=0&&Tiles[k].Has_Merged=0)
																{
																	Merge(A_Index,k)
																	Something_Moved:=1
																}
														}
												}
										}
								}
							j+=j_Count	
						}
					i+=i_Count	
					
				}
		m:=0
		Loop,% Tiles.Length()
			{
				if(Tiles[A_Index].Is_Moving=1)
						m++
			}
		if(m>0)
			{
				Loop 17
					{
						Loop, % Tiles.Length()
							{
								if(Dir=1)
									{
										if(Tiles[A_Index].Is_Moving=1&&Tiles[A_Index].ry>row_col_Positions[Tiles[A_Index].Y])
											Tiles[A_Index].ry-=5,Style:=Tiles[A_Index].img.Style,Style.Top:=Tiles[A_Index].ry
										else if(Tiles[A_Index].Is_Moving:=1&&Tiles[A_Index].ry<=row_col_Positions[Tiles[A_Index].Y])
											Tiles[A_Index].Is_Moving:=0,Tiles[A_Index].ry:=row_col_Positions[Tiles[A_Index].Y],Style:=Tiles[A_Index].img.Style,Style.Top:=Tiles[A_Index].ry
									}
								else if(Dir=2)
									{
										if(Tiles[A_Index].Is_Moving=1&&Tiles[A_Index].rx>row_col_Positions[Tiles[A_Index].X])
											Tiles[A_Index].rx+=5,Style:=Tiles[A_Index].img.Style,Style.Left:=Tiles[A_Index].rx
										else if(Tiles[A_Index].Is_Moving:=1&&Tiles[A_Index].rx<=row_col_Positions[Tiles[A_Index].X])
											Tiles[A_Index].Is_Moving:=0,Tiles[A_Index].rx:=row_col_Positions[Tiles[A_Index].X],Style:=Tiles[A_Index].img.Style,Style.Left:=Tiles[A_Index].rx
										else
											Tiles[A_Index].Is_Moving:=0
									}
								else if(Dir=3)
									{
										if(Tiles[A_Index].Is_Moving=1&&Tiles[A_Index].ry<row_col_Positions[Tiles[A_Index].Y])
											Tiles[A_Index].ry+=15,Style:=Tiles[A_Index].img.Style,Style.Top:=Tiles[A_Index].ry
										else if(Tiles[A_Index].Is_Moving:=1&&Tiles[A_Index].ry>=row_col_Positions[Tiles[A_Index].Y])
											Tiles[A_Index].Is_Moving:=0,Tiles[A_Index].ry:=row_col_Positions[Tiles[A_Index].Y],Style:=Tiles[A_Index].img.Style,Style.Top:=Tiles[A_Index].ry
										else
											Tiles[A_Index].Is_Moving:=0	
									}
								else if(Dir=4)
									{
										if(Tiles[A_Index].Is_Moving=1&&Tiles[A_Index].rx>row_col_Positions[Tiles[A_Index].X])
											Tiles[A_Index].rx-=5,Style:=Tiles[A_Index].img.Style,Style.Left:=Tiles[A_Index].rx
										else if(Tiles[A_Index].Is_Moving:=1&&Tiles[A_Index].rx<=row_col_Positions[Tiles[A_Index].X])
											Tiles[A_Index].Is_Moving:=0,Tiles[A_Index].rx:=row_col_Positions[Tiles[A_Index].X],Style:=Tiles[A_Index].img.Style,Style.Left:=Tiles[A_Index].rx
										else
											Tiles[A_Index].Is_Moving:=0
									}
								
							}
							
					}
				goto, redo
			}
			
			While(GetKeyState("Down"))
					Sleep,10
			Can_Move:=1		
			if(Something_Moved=1)
				Tiles[Tiles.Length()+1]:=New Game_Tile()
		}
	}
	
Class Game_Tile
	{
		__New()
			{
				i:=1,free:=0
				Loop 4
					{
						j:=1
						Loop 4
							{
								if(Grid_Array[i,j]=0)
									{
										free:=1
										break
									}
								j++
							}
						i++	
					}
				if(!free)
					{
						MsgBox, 262144, ,Game Over
						game:=New Game_Board()
					}
				else 
					{
						Loop 
							{
								Random,tx,1,4
								Random,ty,1,4
								Random,value,1,10
								if(value<7)
									This.Value:=2
								else
									This.Value:=4
								if(Grid_Array[ty,tx]=0)
									{
										This.X:=tx,This.Y:=ty,Grid_Array[ty,tx]:=1
										break
									}
							}
						This.Has_Merged:=0,This.Is_Moving:=0
						This.Draw_Tile()
					}
			}
		Draw_Tile()
			{
				
				tx:=row_col_Positions[This.X],ty:=row_col_Positions[This.Y],This.rx:=tx,This.ry:=ty
				img:=WB.CreateElement("img"),This.img:=img,img.src:=A_WorkingDir "\" This.Value ".png",Style:=img.Style
				for a,b in {Left:tx,top:ty,position:"absolute",width:75,height:75}
				Style[a]:=b
				WB.Body.AppendChild(This.img)
			}
		
	}

Class Game_Board
	{
		__New()
			{
				global
				Remove_Bot()
				score_x:=396,Can_Move:=1,Game_Active:=1
				Gui,1:Destroy
				Gui,1:+AlwaysOnTop -Caption Border
				Gui,1:Color,111111
				Gui,1:Add,Picture,x8 y8 w30 h30 gTag,Tag.png
				Gui,1:Font,c004B76 s24 Underline Q4, Segoe UI Black
				Gui,1:Add,Text,cWhite center x82 y-2 w250 BackgroundTrans,2048
				Gui,1:Add,Text, center x81 y-3 w250 BackgroundTrans gMove_Window,2048
				Gui,1:Font,
				Gui,1:Font,c004B76 s22 Q4, Segoe UI Black
				Gui,1:Add,Text,cWhite x346 y-3 w20 r1 Center BackgroundTrans,-
				Gui,1:Add,Text, x345 y-4 w20 r1 Center BackgroundTrans gMin_Window,-
				Gui,1:Add,Text,cWhite x371 y-3 w23 r1 Center BackgroundTrans,x
				Gui,1:Add,Text, x370 y-4 w23 r1 Center BackgroundTrans gGuiClose,x
				Gui,1:Font,
				Gui,1:Font,c004B76 s16 Q4, Segoe UI Black
				Gui,1:Add,Picture, x48 y50 w2 h42,border.png
				Gui,1:Add,Picture, x50 y52 w2 h38,border2.png
				Gui,1:Add,Picture, x350 y50 w2 h42,border.png
				Gui,1:Add,Picture, x348 y52 w2 h38,border2.png
				Gui,1:Add,Picture, x50 y50 w300 ,border.png
				Gui,1:Add,Picture, x52 y52 w296 ,border2.png
				Gui,1:Add,Picture, x50 y90 w300 ,border.png
				Gui,1:Add,Picture, x52 y88 w296 ,border2.png
				Gui,1:Add,Text, x-1400 y-1170  Center BackgroundTrans vgw,% "1: " Names[1] " " Scores[1] "          2: " Names[2] " " Scores[2] "          3: " Names[3] " " Scores[3] "          "
				GuiControlGet,pos,1:pos,gw
				Gui,1:Add,Text,cWhite x30 y95 w65 r1 BackgroundTrans,Score:
				Gui,1:Add,Text,x29 y94 w65 r1 BackgroundTrans,Score:
				Gui,1:Add,Text,cWhite x+10 y95 w100 r1 BackgroundTrans vMy_Score,% My_Score
				Gui,1:Add,Picture,x0 y0 w400 h2,Border.png
				Gui,1:Add,Picture,x2 y2 w400 h2,Border2.png
				Gui,1:Add,Picture,x0 y0 w2 h560,Border.png
				Gui,1:Add,Picture,x2 y2 w2 h556,Border2.png
				Gui,1:Add,Picture,x398 y0 w2 h560,Border.png
				Gui,1:Add,Picture,x396 y2 w2 h556,Border2.png
				Gui,1:Add,Picture,x0 y558 w400 h2,Border.png
				Gui,1:Add,Picture,x2 y556 w396 h2,Border2.png
				Gui,1:Add,Picture,x125 y500 w150 h40 gNew_Game,New Game.png
				Gui,3:+Parent1 -caption
				Gui,3:Color,111111
				Gui,3:Font,c004B76 s16 Q4, Segoe UI Black
				Gui,3:Add,Text,cffffff x%score_x% y0 w%posw% r1 BackgroundTrans vss,% "1: " Names[1] " " Scores[1] "          2: " Names[2] " " Scores[2] "          3: " Names[3] " " Scores[3] "          "
				Gui,2:+parent1 -Caption +LastFound +AlwaysOnTop
				Gui,2:Add,ActiveX,x0 y0 w400 h400 vWB,MSHTML:
				WB.Body.Style.Position:="Absolute"
				Style:=WB.Body.Style
				for k,v in {margin:"0px"}
					Style[k]:=v
				WB.Body.Style.BackgroundColor:="#111111"
				img:=WB.CreateElement("img")
				This.img:=img
				img.src:=A_WorkingDir "\Background.png"
				Style:=img.Style
				for a,b in {Left:25,top:25,position:"absolute",width:350,height:350}
				Style[a]:=b
				WB.Body.AppendChild(This.img)
				sleep,300
				Gui,1:Show,w400 h560,2048
				Gui,2:Show,x0 y110 w400 h400
				Gui,3:Show,x52 y55 w298
				SetTimer,Score_Scroll,30	
				This.Build_Grid()
				Loop 2
					Tiles[Tiles.Length()+1]:=New Game_Tile()
			}
		Build_Grid()
			{
				i:=1
				Loop 4
					{
						j:=1
						Loop 4
							{
								Grid_Array[i,j]:=0,j++
							}
						i++	
					}
			}
	}
Create_Game_Assets()
	{
		FileCreateDir,%A_ScriptDir%/2048 Assets
		SetWorkingDir,%A_ScriptDir%/2048 Assets
		FileSetAttrib, -RH,scores.txt
		FileDelete,%A_ScriptDir%/2048 Assets/scores.txt
		FileAppend,Hellbent 5555*CivReborn 2000*HB 1000,%A_ScriptDir%/2048 Assets/scores.txt
		FileSetAttrib, +RH,%A_ScriptDir%/2048 Assets/scores.txt
		If !pToken := Gdip_Startup()
			{
				MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
				ExitApp
			}
		Colours:= ["0xffFF6A00","0xff108Bb6","0xffB6FF00","0xff00FF21","0xff9bFFb0","0xffaaa4FF","0xff0026FF","0xff4800FF","0xffFF00DC","0xff7F0037","0xff007F7F","0xFF3388aa","0xFFaa5509"]
		Text_:=[2,4,8,16,32,64,128,256,512,1024,2048,4096,8192],Font_Size:=[48,48,48,38,38,38,28,28,28,22,22,22,22],y_Pos1:=[4,4,4,12,12,12,20,20,20,24,24,24,24],y_Pos2:=[2,2,2,10,10,10,18,18,18,22,22,22,22]
		Loop 13
			{
				pBitmap := Gdip_CreateBitmap(75,75),G := Gdip_GraphicsFromImage(pBitmap)
				Gdip_SetSmoothingMode(G, 1)
				pBrush := Gdip_BrushCreateSolid(Colours[A_Index])
				Gdip_FillRectangle(G, pBrush, 1,1 , 75, 75)
				Gdip_DeleteBrush(pBrush)
				pPen := Gdip_CreatePen(0xffffffff, 2)
				Gdip_DrawRectangle(G, pPen, 1, 1, 73, 73)
				Gdip_DeleteBrush(pPen)
				pPen := Gdip_CreatePen(0xff000000, 2)
				Gdip_DrawRectangle(G, pPen, 3, 3, 69, 69)
				Gdip_DeleteBrush(pPen)
				Font = Segoe UI Black
				If !Gdip_FontFamilyCreate(Font)
					{
					  ; MsgBox, 48, Font error!, The font you have specified does not exist on the system
					  ; ExitApp
					  Font = Arial
					}	
				Options =% "x4 y" y_Pos1[A_Index]  "cffffffff Center s" Font_Size[A_Index] 
				Gdip_TextToGraphics(G, Text_[A_Index], Options, Font, 75, 75)	
				Options =% "x1 y" y_Pos2[A_Index]  "cff000000  Center s" Font_Size[A_Index]  
				Gdip_TextToGraphics(G, Text_[A_Index], Options, Font, 75, 75)	
				Gdip_SaveBitmapToFile(pBitmap,Text_[A_Index] ".png")
				Gdip_DisposeImage(pBitmap)	
			}
		pBitmap := Gdip_CreateBitmap(350,350),G := Gdip_GraphicsFromImage(pBitmap)
		Gdip_SetSmoothingMode(G, 1)
		pBrush := Gdip_BrushCreateSolid("0xFF004B76")
		Gdip_FillRectangle(G, pBrush, 1,1 , 350, 350)
		Gdip_DeleteBrush(pBrush)
		pBrush := Gdip_BrushCreateSolid("0xFF222222")
		Gdip_FillRectangle(G, pBrush, 11,11 , 329, 329)
		Gdip_DeleteBrush(pBrush)
		pBrush := Gdip_BrushCreateSolid("0xFF004B76"),x:=86
		Loop 3
			{
				Gdip_FillRectangle(G, pBrush,x,11 ,10, 340)
				x+=85
			}
		y:=86
		Loop 3
			{
				Gdip_FillRectangle(G, pBrush,11,y ,340, 10)
				y+=85	
			}
		Gdip_DeleteBrush(pBrush)
		pPen := Gdip_CreatePen(0xffffffff, 2)
		Gdip_DrawRectangle(G, pPen, 1, 1, 348, 348)
		Gdip_DeleteBrush(pPen)
		Gdip_SaveBitmapToFile(pBitmap,"Background.png")
		Gdip_DisposeImage(pBitmap)	
		pBitmap := Gdip_CreateBitmap(30,30)
		G := Gdip_GraphicsFromImage(pBitmap)
		Gdip_SetSmoothingMode(G, 1)
		pBrush := Gdip_BrushCreateSolid("0xff004B76") 
		Gdip_FillRectangle(G, pBrush, 0,0 , 30, 30)
		Gdip_DeleteBrush(pBrush)
		pPen := Gdip_CreatePen(0xffffffff, 2)
		Gdip_DrawRectangle(G, pPen, 1, 1, 28, 28)
		Gdip_DeleteBrush(pPen)
		Font = Segoe UI Black
		If !Gdip_FontFamilyCreate(Font)
		{
		      ; MsgBox, 48, Font error!, The font you have specified does not exist on the system
		      ; ExitApp
		      Font = Arial
		}	
		Options =x1 y6  cff000000 Center s14 
		Gdip_TextToGraphics(G, "HB", Options, Font, 30, 30)	
		Options =x0 y5  cffffffff Center s14 
		Gdip_TextToGraphics(G, "HB", Options, Font, 30, 30)	
		Gdip_SaveBitmapToFile(pBitmap,"Tag.png")
		Gdip_DisposeImage(pBitmap)	
		pBitmap := Gdip_CreateBitmap(150,40)
		G := Gdip_GraphicsFromImage(pBitmap)
		Gdip_SetSmoothingMode(G, 1)
		pBrush := Gdip_BrushCreateSolid("0xFF333333")
		Gdip_FillRectangle(G, pBrush, 0,0 , 150, 40)
		Gdip_DeleteBrush(pBrush)
		pPen := Gdip_CreatePen(0xffffffff, 2)
		Gdip_DrawRectangle(G, pPen, 1, 1, 148, 38)
		Gdip_DeleteBrush(pPen)
		Font = Segoe UI Black
		If !Gdip_FontFamilyCreate(Font)
		{
		      ; MsgBox, 48, Font error!, The font you have specified does not exist on the system
		      ; ExitApp
		      Font = Arial
		}	
		Options =x0 y4  cffffffff Center s24
		Gdip_TextToGraphics(G, "New Game", Options, Font, 150, 40)	
		Options =x-1 y3  cff004B76 Center s24
		Gdip_TextToGraphics(G, "New Game", Options, Font, 150, 40)	
		Gdip_SaveBitmapToFile(pBitmap,"New Game.png")
		Gdip_DisposeImage(pBitmap)	
		pBitmap := Gdip_CreateBitmap(2,2)
		G := Gdip_GraphicsFromImage(pBitmap)
		Gdip_SetSmoothingMode(G, 1)
		pBrush := Gdip_BrushCreateSolid("0xFF004B76")
		Gdip_FillRectangle(G, pBrush, 0,0 , 2,2)
		Gdip_DeleteBrush(pBrush)
		Gdip_SaveBitmapToFile(pBitmap,"border.png")
		Gdip_DisposeImage(pBitmap)	
		pBitmap := Gdip_CreateBitmap(2,2)
		G := Gdip_GraphicsFromImage(pBitmap)
		Gdip_SetSmoothingMode(G, 1)
		pBrush := Gdip_BrushCreateSolid("0xFFFaFaFa")
		Gdip_FillRectangle(G, pBrush, 0,0 , 2,2)
		Gdip_DeleteBrush(pBrush)
		Gdip_SaveBitmapToFile(pBitmap,"border2.png")
		Gdip_DisposeImage(pBitmap)	
		Gdip_Shutdown(pToken)
	}
Gdip_Startup()
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		
		if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
			DllCall("LoadLibrary", "str", "gdiplus")
		VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
		DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
		return pToken
	}

Gdip_Shutdown(pToken)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		
		DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
		if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
			DllCall("FreeLibrary", Ptr, hModule)
		return 0
	}
Gdip_CreateBitmap(Width, Height, Format=0x26200A)
	{
		DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", 0, "int", Format, A_PtrSize ? "UPtr" : "UInt", 0, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
		Return pBitmap
	}
Gdip_GraphicsFromImage(pBitmap)
	{
		DllCall("gdiplus\GdipGetImageGraphicsContext", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
		return pGraphics
	}
Gdip_SetSmoothingMode(pGraphics, SmoothingMode)
	{
	   return DllCall("gdiplus\GdipSetSmoothingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", SmoothingMode)
	}
Gdip_BrushCreateSolid(ARGB=0xff000000)
	{
		DllCall("gdiplus\GdipCreateSolidFill", "UInt", ARGB, A_PtrSize ? "UPtr*" : "UInt*", pBrush)
		return pBrush
	}
Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		
		return DllCall("gdiplus\GdipFillRectangle"
						, Ptr, pGraphics
						, Ptr, pBrush
						, "float", x
						, "float", y
						, "float", w
						, "float", h)
	}
Gdip_DeleteBrush(pBrush)
	{
	   return DllCall("gdiplus\GdipDeleteBrush", A_PtrSize ? "UPtr" : "UInt", pBrush)
	}
Gdip_CreatePen(ARGB, w)
	{
	   DllCall("gdiplus\GdipCreatePen1", "UInt", ARGB, "float", w, "int", 2, A_PtrSize ? "UPtr*" : "UInt*", pPen)
	   return pPen
	}
Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		
		return DllCall("gdiplus\GdipDrawRectangle", Ptr, pGraphics, Ptr, pPen, "float", x, "float", y, "float", w, "float", h)
	}
Gdip_FontFamilyCreate(Font)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		
		if (!A_IsUnicode)
		{
			nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &Font, "int", -1, "uint", 0, "int", 0)
			VarSetCapacity(wFont, nSize*2)
			DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &Font, "int", -1, Ptr, &wFont, "int", nSize)
		}
		
		DllCall("gdiplus\GdipCreateFontFamilyFromName"
						, Ptr, A_IsUnicode ? &Font : &wFont
						, "uint", 0
						, A_PtrSize ? "UPtr*" : "UInt*", hFamily)
		
		return hFamily
	}	
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0)
	{
		IWidth := Width, IHeight:= Height
		RegExMatch(Options, "i)X([\-\d\.]+)(p*)", xpos)
		RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
		RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
		RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
		RegExMatch(Options, "i)C(?!(entre|enter))([a-f\d]+)", Colour)
		RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
		RegExMatch(Options, "i)NoWrap", NoWrap)
		RegExMatch(Options, "i)R(\d)", Rendering)
		RegExMatch(Options, "i)S(\d+)(p*)", Size)
		if !Gdip_DeleteBrush(Gdip_CloneBrush(Colour2))
			PassBrush := 1, pBrush := Colour2
		if !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
			return -1
		Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
		Loop, Parse, Styles, |
			{
				if RegExMatch(Options, "\b" A_loopField)
				Style |= (A_LoopField != "StrikeOut") ? (A_Index-1) : 8
			}
		Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
		Loop, Parse, Alignments, |
			{
				if RegExMatch(Options, "\b" A_loopField)
					Align |= A_Index//2.1      ; 0|0|1|1|2|2
			}
		xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
		ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
		Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
		Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
		if !PassBrush
			Colour := "0x" (Colour2 ? Colour2 : "ff000000")
		Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
		Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12
		hFamily := Gdip_FontFamilyCreate(Font)
		hFont := Gdip_FontCreate(hFamily, Size, Style)
		FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
		hFormat := Gdip_StringFormatCreate(FormatStyle)
		pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)
		if !(hFamily && hFont && hFormat && pBrush && pGraphics)
			return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
		CreateRectF(RC, xpos, ypos, Width, Height)
		Gdip_SetStringFormatAlign(hFormat, Align)
		Gdip_SetTextRenderingHint(pGraphics, Rendering)
		ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
		if vPos
			{
				StringSplit, ReturnRC, ReturnRC, |
				
				if (vPos = "vCentre") || (vPos = "vCenter")
					ypos += (Height-ReturnRC4)//2
				else if (vPos = "Top") || (vPos = "Up")
					ypos := 0
				else if (vPos = "Bottom") || (vPos = "Down")
					ypos := Height-ReturnRC4
				
				CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
				ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
			}
		if !Measure
			E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)
		if !PassBrush
			Gdip_DeleteBrush(pBrush)
		Gdip_DeleteStringFormat(hFormat)   
		Gdip_DeleteFont(hFont)
		Gdip_DeleteFontFamily(hFamily)
		return E ? E : ReturnRC
	}	
Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		SplitPath, sOutput,,, Extension
		if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
			return -1
		Extension := "." Extension
		DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
		VarSetCapacity(ci, nSize)
		DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
		if !(nCount && nSize)
			return -2
		If (A_IsUnicode){
			StrGet_Name := "StrGet"
			Loop, %nCount%
				{
					sString := %StrGet_Name%(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
					if !InStr(sString, "*" Extension)
						continue
					pCodec := &ci+idx
					break
				}
		} else {
			Loop, %nCount%
				{
					Location := NumGet(ci, 76*(A_Index-1)+44)
					nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int",  0, "uint", 0, "uint", 0)
					VarSetCapacity(sString, nSize)
					DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "str", sString, "int", nSize, "uint", 0, "uint", 0)
					if !InStr(sString, "*" Extension)
						continue
					pCodec := &ci+76*(A_Index-1)
					break
				}
		}
		if !pCodec
			return -3
		if (Quality != 75)
			{
				Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
				if Extension in .JPG,.JPEG,.JPE,.JFIF
					{
						DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
						VarSetCapacity(EncoderParameters, nSize, 0)
						DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
						Loop, % NumGet(EncoderParameters, "UInt")      ;%
							{
								elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
								if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
								{
									p := elem+&EncoderParameters-pad-4
									NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
									break
								}
							}      
					}
			}
		if (!A_IsUnicode)
			{
				nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, 0, "int", 0)
				VarSetCapacity(wOutput, nSize*2)
				DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, &wOutput, "int", nSize)
				VarSetCapacity(wOutput, -1)
				if !VarSetCapacity(wOutput)
					return -4
				E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &wOutput, Ptr, pCodec, "uint", p ? p : 0)
			}
		else
			E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &sOutput, Ptr, pCodec, "uint", p ? p : 0)
		return E ? -5 : 0
	}	
Gdip_DisposeImage(pBitmap)
	{
	   return DllCall("gdiplus\GdipDisposeImage", A_PtrSize ? "UPtr" : "UInt", pBitmap)
	}	
Gdip_CloneBrush(pBrush)
	{
		DllCall("gdiplus\GdipCloneBrush", A_PtrSize ? "UPtr" : "UInt", pBrush, A_PtrSize ? "UPtr*" : "UInt*", pBrushClone)
		return pBrushClone
	}	
Gdip_FontCreate(hFamily, Size, Style=0)
	{
	   DllCall("gdiplus\GdipCreateFont", A_PtrSize ? "UPtr" : "UInt", hFamily, "float", Size, "int", Style, "int", 0, A_PtrSize ? "UPtr*" : "UInt*", hFont)
	   return hFont
	}	
Gdip_StringFormatCreate(Format=0, Lang=0)
	{
	   DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", Lang, A_PtrSize ? "UPtr*" : "UInt*", hFormat)
	   return hFormat
	}	
CreateRectF(ByRef RectF, x, y, w, h)
	{
	   VarSetCapacity(RectF, 16)
	   NumPut(x, RectF, 0, "float"), NumPut(y, RectF, 4, "float"), NumPut(w, RectF, 8, "float"), NumPut(h, RectF, 12, "float")
	}	
Gdip_SetStringFormatAlign(hFormat, Align)
	{
	   return DllCall("gdiplus\GdipSetStringFormatAlign", A_PtrSize ? "UPtr" : "UInt", hFormat, "int", Align)
	}	
Gdip_SetTextRenderingHint(pGraphics, RenderingHint)
	{
		return DllCall("gdiplus\GdipSetTextRenderingHint", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", RenderingHint)
	}	
Gdip_MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		VarSetCapacity(RC, 16)
		if !A_IsUnicode
			{
				nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, "uint", 0, "int", 0)
				VarSetCapacity(wString, nSize*2)   
				DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, &wString, "int", nSize)
			}
		DllCall("gdiplus\GdipMeasureString"
						, Ptr, pGraphics
						, Ptr, A_IsUnicode ? &sString : &wString
						, "int", -1
						, Ptr, hFont
						, Ptr, &RectF
						, Ptr, hFormat
						, Ptr, &RC
						, "uint*", Chars
						, "uint*", Lines)
		return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
	}	
Gdip_DrawString(pGraphics, sString, hFont, hFormat, pBrush, ByRef RectF)
	{
		Ptr := A_PtrSize ? "UPtr" : "UInt"
		if (!A_IsUnicode)
			{
				nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, 0, "int", 0)
				VarSetCapacity(wString, nSize*2)
				DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, &wString, "int", nSize)
			}
		return DllCall("gdiplus\GdipDrawString"
						, Ptr, pGraphics
						, Ptr, A_IsUnicode ? &sString : &wString
						, "int", -1
						, Ptr, hFont
						, Ptr, &RectF
						, Ptr, hFormat
						, Ptr, pBrush)
	}	
Gdip_DeleteStringFormat(hFormat)
	{
	   return DllCall("gdiplus\GdipDeleteStringFormat", A_PtrSize ? "UPtr" : "UInt", hFormat)
	}	
Gdip_DeleteFont(hFont)
	{
	   return DllCall("gdiplus\GdipDeleteFont", A_PtrSize ? "UPtr" : "UInt", hFont)
	}	
Gdip_DeleteFontFamily(hFamily)
	{
	   return DllCall("gdiplus\GdipDeleteFontFamily", A_PtrSize ? "UPtr" : "UInt", hFamily)
	}

EDIT: If your computer doesn't have the Segoe UI Black Font type, the script will switch to Arial.
This will cause the spacing of the text to get messed up a bit, but it is still "Good enough".
Last edited by Hellbent on 16 May 2018, 19:11, edited 2 times in total.
User avatar
nnnik
Posts: 3453
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: 2048 Game

16 May 2018, 03:18

Looks good.
Recommends AHK Studio
User avatar
kczx3
Posts: 660
Joined: 06 Oct 2015, 21:39

Re: 2048 Game

16 May 2018, 09:04

This is quite impressive! I would have expected some of your functions to actually be methods of the Game_Board class. Such as Move_Tiles, Merge, and Remove_Bot.
User avatar
SpeedMaster
Posts: 235
Joined: 12 Nov 2016, 16:09

Re: 2048 Game

16 May 2018, 12:08

Good game. Thank you for sharing :bravo:

Works good on windows 10 :thumbup:
but... Not working on my win 7 64 bit Home Edition :? (Font error!, The font you have specified does not exist on the system)
the game works well after replacing the missing font with arial ;)

cheers,
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

16 May 2018, 14:06

I would have expected some of your functions to actually be methods of the Game_Board class. Such as Move_Tiles, Merge, and Remove_Bot.
I had started out with everything being in the classes, but because my time was limited and because classes are something that I have only been trying to force myself to learn (really wish there were video tutorials on them, the documentation is so full of terminology and so little simple ground up working examples that it is pretty much useless to me), I decided to go with hotkeys to first work out the logic and then to cut down on the code I worked out a quick function that could deal with all four hotkeys. Even the function is incomplete and I just said "to hell with it" and tried to just push to the end of this project to put it to bed.

In the end, my goal was to create a game that worked and everything else was superfluous. In each new project I do try to pick up new things and to push my knowledge forward and this one had a number of things that did that without worrying about getting bogged down in the class aspect. Perhaps now that I have a working program I will pick it apart and work out a new approach, but first I needed a working program to do that on. I have a saying, "If I wanted patience I would have became a doctor.". So for me, making progress is the key to keep any interest, I can bang my head against a wall tomorrow.
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

16 May 2018, 14:12

Not working on my win 7 64 bit Home Edition :? (Font error!, The font you have specified does not exist on the system)
the game works well after replacing the missing font with arial ;)
cheers,
lol it's so funny that you mentioned the font. When I was writing this out I was thinking about having it switch to another font rather than exiting the script, but I figured "well this font came with my computer so surely everyone must have it."

Did the arial fit without any adjustments being needed to the spacing etc?
If so, I can just edit the code to have it switch if the segoe Ui black font is not found.
OCP
Posts: 83
Joined: 28 Mar 2018, 19:28

Re: 2048 Game

16 May 2018, 17:10

impressive you can do shit like this

it wont work for me because of my weird dpi settings the gui does not form the way it should on my end

i also got the font thing you can get the font here btw https://www.dafontfree.net/freefonts-se ... f63033.htm
Last edited by OCP on 26 Jul 2018, 22:33, edited 1 time in total.
User avatar
SpeedMaster
Posts: 235
Joined: 12 Nov 2016, 16:09

Re: 2048 Game

16 May 2018, 17:49

Did the arial fit without any adjustments being needed to the spacing etc?
If so, I can just edit the code to have it switch if the segoe Ui black font is not found.
Here's what i get with Arial without any adjustments: :roll:
Even if it's not perfect, switch security is a good idea :thumbup:
2048_arial.png
2048_arial.png (28.02 KiB) Viewed 888 times
burque505
Posts: 626
Joined: 22 Jan 2017, 19:37

Re: 2048 Game

16 May 2018, 17:53

Hi, wish I had Win10 to try it out, looks really nice. I tried it on Win7-64, both with Arial and the Segoe UI Black I downloaded, no luck (also tried on XP in a VM, but that was a shot in the dark).
I'm wondering if it might be my GDIP lib, since the tiles are not being drawn.
2048.PNG
2048.PNG (15.24 KiB) Viewed 885 times
Regards,
burque505
User avatar
kczx3
Posts: 660
Joined: 06 Oct 2015, 21:39

Re: 2048 Game

16 May 2018, 18:41

All the necessary gdip functions are in the OP
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

16 May 2018, 18:43


it wont work for me because of my weird dpi settings the gui does not form the way it should on my end
I only have one computer as my sample size so when things go off tilt on other peoples computers I don't have the means to even begin to understand what the underlying issues are.

That said, I do know that there is a gui option called +/-DPIScale.
I don't really know what it does but it could be a fix for you. The only thing I can remember about DPI is from back in the 1980's and early 1990's you could adjust the dpi of your printer. What your computer screen has to do with the number of "dots" per inch is beyond me.

Try running this

Code: Select all

Tooltip,%  A_ScreenDPI
I get 96, if you get some other value, using the +/-DPIScale option might work?
Anyone familiar with this DPI stuff care to weigh in?

At any rate you can try adding -DPIScale to the options of the 3 Guis, I tried on my end but I see no change either way.

Out of curiosity, would you mind sharing a shot of what it looks like on your screen as it is now?
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

16 May 2018, 19:01

Hi, wish I had Win10 to try it out, looks really nice. I tried it on Win7-64, both with Arial and the Segoe UI Black I downloaded, no luck (also tried on XP in a VM, but that was a shot in the dark).
I'm wondering if it might be my GDIP lib, since the tiles are not being drawn.
burque505
As was mentioned by kczx3, all the GDIP functions that are required to run this are included at the bottom of the script.

Can you check to see if a subfolder called "2048 Assets" is being created?
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

16 May 2018, 19:15

Did the arial fit without any adjustments being needed to the spacing etc?
If so, I can just edit the code to have it switch if the segoe Ui black font is not found.
Here's what i get with Arial without any adjustments: :roll:
Even if it's not perfect, switch security is a good idea :thumbup:
Thanks. I edited the OP with the switch added.
OCP
Posts: 83
Joined: 28 Mar 2018, 19:28

Re: 2048 Game

17 May 2018, 00:23

Try running this

Code: Select all

Tooltip,%  A_ScreenDPI
i get 120

adding -DPIScale fixed it tho
i added these 3 lines and that fixed it

Code: Select all

Gui,1:-DPIScale
Gui,2:-DPIScale
Gui,3:-DPIScale
Out of curiosity, would you mind sharing a shot of what it looks like on your screen as it is now?
my before looked as the image posted by burque505

cheers
OCP
Posts: 83
Joined: 28 Mar 2018, 19:28

Re: 2048 Game

17 May 2018, 00:38

i just realize the same thing will also fix that quick launcher you posted a while ago on tube to work for me :)
Last edited by OCP on 26 Jul 2018, 22:33, edited 1 time in total.
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

17 May 2018, 00:45

i just realize the same thing will also fix that quick launcher you posted a while ago on tube to work for me :)
I was thinking the same thing, but in that case there is a fair bit more than just 3 guis lol. Not tons but def more than 3.
In my opinion it is well worth the 10-20 mins of editing.

Edit: Just did a quick look, and I count 11 windows.
OCP
Posts: 83
Joined: 28 Mar 2018, 19:28

Re: 2048 Game

17 May 2018, 01:06

Just did a quick look, and I count 11 windows.
5 min work :) find and replace

edit: nice game tho i am impressed you can make things like this pretty cool cheers :bravo:
Last edited by OCP on 26 Jul 2018, 22:33, edited 1 time in total.
Hellbent
Posts: 143
Joined: 23 Sep 2017, 13:34

Re: 2048 Game

17 May 2018, 02:06

Just did a quick look, and I count 11 windows.
5 min work :) find and replace

edit: nice game tho i am impressed you can make things like this pretty cool cheers :bravo:
I don't work on a computer so I don't have much use for the normal stuff that AHK can do.So in order for me to have a reason to keep learning this stuff I have to invent things to use it for, and in large part that is playing around with making little games etc.

In my opinion, this is the second most boring and lame game that I have made so far, but it was a quick game to work through. Most of the games I make, I only end up getting the core mechanics done before I get too bored and move on to the next project.

I think my favorite game so far would be my Space Invaders game. I never ended up finishing it, but the core is done. It has a beginning, middle and end. It's just missing some polish.



A close second would be my bots. While they are not a game per se, they are a training ground for creating the logic that could be used to create 100's of different games.

OCP
Posts: 83
Joined: 28 Mar 2018, 19:28

Re: 2048 Game

17 May 2018, 03:02

nice stuff i am not even close to understanding haha been watching some of your vids on this stuff

you sparked something i want to figure out now, a way to have my gui's auto adjust to the dpi of the system it runs on that way i could share my gui's and not have to worry about the need for people to adjust coordinates in the script

Return to “Scripts and Functions”

Who is online

Users browsing this forum: wsimon98, xcracked and 54 guests