A Tic Tac Toe game written in AutoHotkey using GDI+
See it in action on Imgur!

Releases
Source
Code: Select all
#NoEnv
SetBatchLines, -1
; Set the mouse coordinate mode to be relative to the screen.
CoordMode, Mouse, Screen
; Start gdi+
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
; Set the width and height we want as our drawing area, to draw everything in.
; This will be the dimensions of our bitmap
Width := A_ScreenWidth
Height := A_ScreenHeight
; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!)
; that is always on top (+AlwaysOnTop), has no taskbar entry or caption
Gui, -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop +hWndhWnd1
; Show the window
Gui, Show, NA
; Create a gdi bitmap with width and height of what we are going to draw into it.
; This is the entire drawing area for everything
hbm := CreateDIBSection(Width, Height)
; Get a device context compatible with the screen
hdc := CreateCompatibleDC()
; Select the bitmap into the device context
obm := SelectObject(hdc, hbm)
; Get a pointer to the graphics of the bitmap, for use with drawing functions
G := Gdip_GraphicsFromHDC(hdc)
; Set the smoothing mode to antialias = 4 to make shapes appear smoother
; (only used for vector drawing and filling)
Gdip_SetSmoothingMode(G, 4)
; Create an array to store all of our particles
Particles := []
; Set a timer to handle the creation of new particles
SetTimer, SpawnParticle, 250
; Set a timer to handle the physics updates
SetTimer, Update, 20
return
Escape::ExitApp
Update:
; Clear the bitmap
Gdip_GraphicsClear(G)
; Create a new array for particles that should not be deleted
ParticlesToKeep := []
; Update each particle
for Index, Particle in Particles
{
; Call the particle's update routine
Particle.Step()
; If it's still above the bottom of the bitmap
if (Particle.y < Height)
{
; Put it on the list of particles to keep
ParticlesToKeep.Push(Particle)
; Draw it to the bitmap
Particle.Draw(G)
}
}
; Overwrite the list of particles with the list of particles we want to keep.
; Particles that were on the old list will be automatically deleted.
Particles := ParticlesToKeep
; Update the specified window we have created (hwnd1) with a handle to our
; bitmap (hdc), specifying the x,y,w,h we want it positioned on our screen
; So this will position our gui at (0,0) with the Width and Height specified earlier
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
return
SpawnParticle:
; We want the particle to be at the mouse's x and y position
MouseGetPos, x, y
; Generate some random speed values
Random, HorizontalSpeed, -10, 10
Random, VerticalSpeed, -10, -20
; Generate a random starting rotation and rotation speed
Random, Rotation, -6.28, 6.28
Random, RotationSpeed, -0.3, 0.3
; Generate a random hexadecimal color code
Random, Color, 0x000000, 0xFFFFFF
; Choose a random particle type
Random, ParticleType, 1, 3
; Create the particle
if (ParticleType == 1)
Particle := new Star(x, y, Rotation, HorizontalSpeed, VerticalSpeed, RotationSpeed, Color)
else if (ParticleType == 2)
Particle := new Rect(x, y, Rotation, HorizontalSpeed, VerticalSpeed, RotationSpeed, Color)
else if (ParticleType == 3)
Particle := new Duck(x, y, Rotation, HorizontalSpeed, VerticalSpeed, RotationSpeed, Color)
; Add it to our list of particles
Particles.Push(Particle)
return
; Define a new type of particle called "Duck" with a list of Cartesian coordinates
; that form a rectangle on the Cartesian plane, centered around the origin (0, 0)
class Duck extends Particle
{
Points :=
( LTrim Join
[
[-16.981300, -14.790800],
[-15.110600, -14.969360],
[-12.321600, -16.261850],
[-10.825000, -19.254960],
[ -7.831900, -21.363750],
[ -4.906800, -22.180050],
[ -1.641600, -21.771900],
[ 1.351500, -19.867190],
[ 3.460300, -16.465920],
[ 3.596300, -12.792550],
[ 1.691600, -8.370900],
[ 8.290100, -9.663390],
[ 10.330900, -11.295990],
[ 11.963500, -12.928600],
[ 12.983800, -13.268730],
[ 14.548400, -12.384400],
[ 16.181000, -9.799440],
[ 17.473500, -5.990020],
[ 18.085700, -2.044550],
[ 17.745600, 2.036970],
[ 16.521200, 5.642320],
[ 14.616400, 8.635430],
[ 11.079100, 11.152370],
[ 5.909200, 12.716950],
[ -1.913700, 13.329180],
[ -7.219700, 12.648930],
[-11.641300, 10.472120],
[-14.226300, 7.683080],
[-16.063000, 3.533530],
[-16.335100, 0.064240],
[-14.634500, -3.745180],
[-12.525700, -5.990020],
[-10.961100, -7.622630],
[-11.029100, -8.302880],
[-11.437300, -8.915110],
[-13.546000, -9.391290],
[-15.246700, -10.479690],
[-16.743200, -12.044270]
]
)
}
; Define a new type of particle called "Star" with a list of Cartesian coordinates
; that form a star on the Cartesian plane, centered around the origin (0, 0)
class Star extends Particle
{
Points :=
( LTrim Join
[
[40/2 * cos(0.628 * 0), 40/2 * sin(0.628 * 0)],
[40/4 * cos(0.628 * 1), 40/4 * sin(0.628 * 1)],
[40/2 * cos(0.628 * 2), 40/2 * sin(0.628 * 2)],
[40/4 * cos(0.628 * 3), 40/4 * sin(0.628 * 3)],
[40/2 * cos(0.628 * 4), 40/2 * sin(0.628 * 4)],
[40/4 * cos(0.628 * 5), 40/4 * sin(0.628 * 5)],
[40/2 * cos(0.628 * 6), 40/2 * sin(0.628 * 6)],
[40/4 * cos(0.628 * 7), 40/4 * sin(0.628 * 7)],
[40/2 * cos(0.628 * 8), 40/2 * sin(0.628 * 8)],
[40/4 * cos(0.628 * 9), 40/4 * sin(0.628 * 9)]
]
)
}
; Define a new type of particle called "Rect" with a list of Cartesian coordinates
; that form a rectangle on the Cartesian plane, centered around the origin (0, 0)
class Rect extends Particle
{
Points :=
( LTrim Join
[
[-20/2, -10/2],
[-20/2, 10/2],
[ 20/2, 10/2],
[ 20/2, -10/2]
]
)
}
; Define the base particle, with methods for rotating, moving, and drawing to the screen
class Particle
{
Points := []
Origin := [0, 0]
; Save all the parameters given when the particle is created
__New(x, y, r, sx, sy, sr, c)
{
this.x := x
this.y := y
this.r := r
this.sx := sx
this.sy := sy
this.sr := sr
this.c := c
}
; This is a helper function to generate a list with all the original
; Cartesian coordinate pairs rotated around the origin point (0, 0)
GetRotated()
{
Rotated := []
; https://stackoverflow.com/a/22491252
for i, Point in this.Points
{
x1 := Point[1] - this.Origin[1]
y1 := Point[2] - this.Origin[2]
x2 := x1 * Cos(this.r) - y1 * Sin(this.r)
y2 := x1 * Sin(this.r) + y1 * Cos(this.r)
Rotated.Push([x2 + this.Origin[1], y2 + this.Origin[2]])
}
return Rotated
}
; Move the particle according to the defined speeds
Step()
{
this.x += this.sx
this.y += this.sy
this.r += this.sr
this.sy += 1
}
; Draw the particle to the bitmap
Draw(pGraphics)
{
; Get a list of rotated and translated points
; compatible with Gdip_FillPolygon
for i, Point in this.GetRotated()
TextPoints .= "|" Point[1] + this.x "," Point[2] + this.y
; Draw the polygon
pBrush := Gdip_BrushCreateSolid(0xFF000000 | this.c)
Gdip_FillPolygon(pGraphics, pBrush, SubStr(TextPoints, 2))
Gdip_DeleteBrush(pBrush)
}
}
Users browsing this forum: No registered users and 10 guests