summaryrefslogtreecommitdiff
path: root/examples/pong_vec/main.lua
blob: 705e68ffe37527dfe9f07d53a34c8a7c4855790e (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
131
-- Pong example using Vector2 library.

package.path = package.path..";"..RL_GetBasePath().."../resources/lib/?.lua"

Vec2 = require "vector2"

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

-- Constants.
local PLAYER_SPEED = 300
local BALL_SPEED = 330

-- Game objects.
local playerLeft = {
	pos = Vec2:new( 0, 0 ),
	size = Vec2:new( 10, 70 ),
	score = 0,
}
local playerRight = {
	pos = Vec2:new( 0, 0 ),
	size = Vec2:new( 10, 70 ),
	score = 0,
}
local ball = {
	pos = Vec2:new( 0, 0 ),
	radius = 8.0,
	vel = Vec2: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 slow.
	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 init()
	-- Set window to center of monitor.
	local mPos = Vec2:new( RL_GetMonitorPosition( monitor ) )
	local mSize = Vec2:new( RL_GetMonitorSize( monitor ) )

	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 process( delta )
	-- Left player controls.
	if RL_IsKeyDown( KEY_W ) and 0 < playerLeft.pos.y then
		playerLeft.pos.y = playerLeft.pos.y - PLAYER_SPEED * delta
	elseif RL_IsKeyDown( 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( KEY_UP ) and 0 < playerRight.pos.y then
		playerRight.pos.y = playerRight.pos.y - PLAYER_SPEED * delta
	elseif RL_IsKeyDown( 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 draw()
	RL_ClearBackground( BLACK )

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

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

	-- Draw score.
    RL_DrawText( 0, playerLeft.score, { 50, 10 }, 40, 2, WHITE )
	local rightTextSize = Vec2:new( RL_MeasureText( 0, playerRight.score, 40, 2 ) )
    RL_DrawText( 0, playerRight.score, { winSize.x - 50 - rightTextSize.x, 10 }, 40, 2, WHITE )
end