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"
Vec2 = require "vector2"
-- Settings.
local winSize = Vec2: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 = 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 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 = Vec2:newT( RL.GetMonitorPosition( monitor ) )
local mSize = Vec2: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 = Vec2: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
|