Tic Tac Toe
A Tic Tac Toe game written in AutoHotkey using GDI+
See it in action on Imgur!
Releases
Source
[Game] Tic Tac Toe
Re: [Game] Tic Tac Toe
Looks very nice, thanks for sharing .
Those particles could have their own thread, seems like fun .
Cheers.
Those particles could have their own thread, seems like fun .
Cheers.
Re: [Game] Tic Tac Toe
that is very pretty
can you show just the code that makes those particles fly so noobs like me can play and learn?
can you show just the code that makes those particles fly so noobs like me can play and learn?
Re: [Game] Tic Tac Toe
TinyDancer, here is some code that demonstrates how the Particle class is used, with a bonus particle to boot!
I moved it out of the Tic Tac Toe game and made it display over the whole screen (single monitor only) like in the examples on the GDI+ library forum post.
I moved it out of the Tic Tac Toe game and made it display over the whole screen (single monitor only) like in the examples on the GDI+ library forum post.
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)
}
}
Re: [Game] Tic Tac Toe
The issue with Particles and GDI+ is that GDI+ just isn't fast enough for particles.
Recommends AHK Studio
Return to “Gaming Scripts (v1)”
Who is online
Users browsing this forum: No registered users and 109 guests