summaryrefslogtreecommitdiff
path: root/examples/pong/main.lua
blob: 8de5de9b48d2871c1b3e516b381c2a7eea182bad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua"

Vector2 = require "vector2"

-- Settings.
local winSize = Vector2:new( 800, 600 )
local monitor = 0

-- Constants.
local PLAYER_SPEED = 300 -- Pixels per second.
local BALL_SPEED = 330 -- Pixels per second.

-- Game objects.
local playerLeft = {
	pos = Vector2:new( 0, 0 ),
	size = Vector2:new( 10, 70 ),
	score = 0,
}
local playerRight = {
	pos = Vector2:new( 0, 0 ),
	size = Vector2:new( 10, 70 ),
	score = 0,
}
local ball = {
	pos = Vector2:new( 0, 0 ),
	radius = 8.0,
	vel = Vector2:new( 0, 0 ),
}

local function reset()
	-- Initialize player positions.
	playerLeft.pos.x = playerLeft.size.x
	playerLeft.pos.y = winSize.y / 2 - playerLeft.size.y / 2
	
	playerRight.pos.x = winSize.x - playerRight.size.x * 2
	playerRight.pos.y = winSize.y / 2 - playerRight.size.y / 2

	-- Set ball to center.
	ball.pos:set( winSize.x / 2, winSize.y / 2 )
	-- Short for if math random result 1, set BALL_SPEED otherwise set -BALL_SPEED.
	-- Could be replaced by normal if statement for easier readability.
	ball.vel.x = math.random( 0, 1 ) == 1 and BALL_SPEED or -BALL_SPEED
	-- Start easy.
	ball.vel.y = 0
end

local function ballHit( padPos, padSize )
	ball.vel.x = -ball.vel.x

	local padCenter = padPos.y + padSize.y / 2
	local relHitPos = ball.pos.y - padCenter
	ball.vel.y = BALL_SPEED * relHitPos / padSize.y * 2
end

function RL.init()
	-- Set window to center of monitor.
	local mPos = Vector2:newT( RL.GetMonitorPosition( monitor ) )
	local mSize = Vector2:newT( RL.GetMonitorSize( monitor ) )

	RL.SetConfigFlags( RL.FLAG_VSYNC_HINT )
	RL.SetWindowSize( winSize )
	RL.SetWindowPosition( { mPos.x + mSize.x / 2 - winSize.x / 2, mPos.y + mSize.y / 2 - winSize.y / 2 } )
	RL.SetWindowTitle( "Pong" )

	-- Initialize ball pos.
	math.randomseed( os.time() )
	reset()
end

function RL.update( delta )
	-- Left player controls.
	if RL.IsKeyDown( RL.KEY_W ) and 0 < playerLeft.pos.y then
		playerLeft.pos.y = playerLeft.pos.y - PLAYER_SPEED * delta
	elseif RL.IsKeyDown( RL.KEY_S ) and playerLeft.pos.y + playerLeft.size.y < winSize.y then
		playerLeft.pos.y = playerLeft.pos.y + PLAYER_SPEED * delta
	end

	-- Right player controls.
	if RL.IsKeyDown( RL.KEY_UP ) and 0 < playerRight.pos.y then
		playerRight.pos.y = playerRight.pos.y - PLAYER_SPEED * delta
	elseif RL.IsKeyDown( RL.KEY_DOWN ) and playerRight.pos.y + playerRight.size.y < winSize.y then
		playerRight.pos.y = playerRight.pos.y + PLAYER_SPEED * delta
	end

	-- Move ball.
	ball.pos = ball.pos + ball.vel:scale( delta )

	-- Bounce from window edge.
	if ( ball.pos.y < ball.radius and ball.vel.y < 0 )
	or ( winSize.y < ball.pos.y + ball.radius and 0 < ball.vel.y ) then
		ball.vel.y = -ball.vel.y
	end

	-- Bounce from players.
	local playerLeftRect = { playerLeft.pos.x, playerLeft.pos.y,
							 playerLeft.size.x, playerLeft.size.y }
	local playerRightRect = { playerRight.pos.x, playerRight.pos.y,
							  playerRight.size.x, playerRight.size.y }

	if RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerLeftRect ) and ball.vel.x < 0 then
		ballHit( playerLeft.pos, playerLeft.size )
	elseif RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerRightRect ) and 0 < ball.vel.x then
		ballHit( playerRight.pos, playerRight.size )
	end

	-- Score.
	if ball.pos.x < 0 then
		playerRight.score = playerRight.score + 1
		reset()
	elseif winSize.x < ball.pos.x then
		playerLeft.score = playerLeft.score + 1
		reset()
	end
end

function RL.draw()
	RL.ClearBackground( RL.BLACK )

	-- Draw players.
	RL.DrawRectangle( { playerLeft.pos.x, playerLeft.pos.y, playerLeft.size.x, playerLeft.size.y }, RL.WHITE )
	RL.DrawRectangle( { playerRight.pos.x, playerRight.pos.y, playerRight.size.x, playerRight.size.y }, RL.WHITE )

	-- Draw ball. Ball position will be the center in drawCircle.
	RL.DrawCircle( ball.pos, ball.radius, RL.WHITE )

	-- Draw score.
    RL.DrawText( tostring( playerLeft.score ), { 50, 10 }, 40, RL.WHITE )
	local rightTextSize = Vector2:newT( RL.MeasureTextEx( RL.GetFontDefault(), tostring( playerRight.score ), 40, 2 ) )
    RL.DrawText( tostring( playerRight.score ), { winSize.x - 50 - rightTextSize.x, 10 }, 40, RL.WHITE )
end