[Game] Tic Tac Toe

Post gaming related scripts
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

[Game] Tic Tac Toe

20 Dec 2017, 13:36

Tic Tac Toe

A Tic Tac Toe game written in AutoHotkey using GDI+

See it in action on Imgur!

Image

Releases

Source
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Game] Tic Tac Toe

20 Dec 2017, 13:56

Looks very nice, thanks for sharing :thumbup: .
Those particles could have their own thread, seems like fun :geek:.

Cheers.
TinyDancer

Re: [Game] Tic Tac Toe

20 Dec 2017, 14:00

that is very pretty

can you show just the code that makes those particles fly so noobs like me can play and learn?
geek
Posts: 1052
Joined: 02 Oct 2013, 22:13
Location: GeekDude
Contact:

Re: [Game] Tic Tac Toe

20 Dec 2017, 17:35

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.

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)
	}
}
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: [Game] Tic Tac Toe

21 Dec 2017, 04:57

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 46 guests