Code Example:
"Pong", by Pieter-Bas IJdens |
This example was submitted by Pieter-Bas IJdens, and is a
Yabasic PS/2 adaptation of the classic "Pong" game made famous by
Atari a long, long time ago, when even I myself was still in my pre-teens ...
;-) Thanks to Pieter-Bas for submitting this example, which is truly examplary
in it's neatness. A tip for the beginner - 0 and 1 are frequently used instead
of 'true' and 'false', but obviously 0 and 1 take up less space and save a lot
of typing - knowing that should help you understand the code below a bit better
still.
rem Author: Pieter-Bas IJdens
rem spam@monad.freeserve.co.uk
rem 10 Feb 2001
rem
rem Legal stuff:
rem This code is specifically copyright free and may be used by anyone
rem for any purpose.
rem PADS: The number of pads. Usually a player would use
rem up, down. In one-pad mode TRI, X control the
rem right bat
PADS = 2
BAT_HEIGHT = 40
BAT_WIDTH = 8
BAT_SPEED = 10
BAT_OFFSET = 20
BALL_RADIUS = 6
BALL_SPEED = 11
XSIZE = 640
YSIZE = 512
main()
sub main()
init()
cont = 1
wait_controller("Press any button to start.")
while(cont = 1)
draw_new_field()
update_bat(left_bat(), "PORT1", 16, 64)
if (PADS = 2) then
update_bat(right_bat(), "PORT2", 16, 64)
else
update_bat(right_bat(), "PORT1", 4096, 16384)
endif
update_ball()
pause 0.02
wend
end sub
sub update_bat(bat(), addr$, up, down)
local maxstep
if (and(peek(addr$), down) > 0) then
maxstep = YSIZE - (bat(2) + (bat(4) / 2))
bat(2) = bat(2) + min(maxstep, BAT_SPEED)
elsif (and(peek(addr$), up) > 0) then
maxstep = bat(2) - (bat(4) / 2)
bat(2) = bat(2) - min(maxstep, BAT_SPEED)
endif
end sub
sub update_ball()
b_newx = ball(1) + ball(5) * cos(ball(4))
b_newy = ball(2) + ball(5) * sin(ball(4))
b_newr = ball(3)
b_newa = ball(4)
b_news = ball(5)
check_topbot_collission()
check_bat_collission(left_bat())
check_bat_collission(right_bat())
check_leftright_collission()
ball(1) = b_newx
ball(2) = b_newy
ball(3) = b_newr
ball(4) = b_newa
ball(5) = b_news
end sub
sub check_topbot_collission()
local r, y_toomuch
r = ball(3)
if (b_newy < r) then
b_newy = r + (r - b_newy)
b_newa = (2 * pi) - b_newa
beep
endif
if (b_newy > (YSIZE - r)) then
y_toomuch = r + (b_newy - YSIZE)
b_newy = YSIZE - (y_toomuch + r)
b_newa = (2 * pi) - b_newa
beep
endif
end sub
sub check_leftright_collission()
local r, reinit
r = b_newr
reinit = 0
if (b_newx < r) then
score(2) = score(2) + 2
reinit = 1
beep
elsif (b_newx > (XSIZE - r)) then
score(1) = score(1) + 1
reinit = 1
beep
endif
if (reinit = 1) then
b_newx = XSIZE / 2
b_newy = YSIZE / 2
b_newa = random_angle()
wait_controller("Press any button to start.")
endif
end sub
sub check_bat_collission(bat())
local a, b, x, y, rev, bx_n, bx_o
local ignore, y_top, y_bot, too_much
if (bat(1) > (XSIZE / 2)) then
x = bat(1) - (bat(3) / 2)
rev = -1
bx_o = ball(1) + ball(3)
bx_n = b_newx + b_newr
if (bx_o >= bx_n) then
ignore = 1
elsif ((bx_o > x) or (bx_n < x)) then
ignore = 1
endif
else
x = bat(1) + (bat(3) / 2)
rev = 1
bx_o = ball(1) - ball(3)
bx_n = b_newx - b_newr
if (bx_o <= bx_n) then
ignore = 1
elsif ((bx_o < x) or (bx_n > x)) then
ignore = 1
endif
endif
if (ignore = 0) then
rem Let's give the players a bit of slack (b_newr / 2)
y_top = bat(2) - (bat(4) / 2) - (b_newr / 2)
y_bot = bat(2) + (bat(4) / 2) + (b_newr / 2)
a = (ball(2) - b_newy) / (ball(1) - b_newx)
b = b_newy - (a * b_newx)
y = a * x + b
if (y >= y_top and y <= y_bot) then
if (b_news > 2 * b_newr) then
draw_the_ball(x + (rev * b_newr), y, b_newr)
endif
too_much = b_newx - (x + (rev * b_newr))
b_newx = (x + (rev * b_newr)) - too_much
b_newa = pi - b_newa
endif
endif
end sub
sub draw_new_field()
buffer = 1 - buffer
setdrawbuf buffer
setrgb 0, 64, 127, 64
clear window
draw_bat(left_bat())
draw_bat(right_bat())
draw_ball()
draw_score()
setdispbuf buffer
end sub
sub draw_ball()
draw_the_ball(ball(1), ball(2), ball(3))
end sub
sub draw_the_ball(x, y, r)
setrgb 1, 127, 127, 127
fill circle x, y, r
end sub
sub draw_bat(bat())
local ltx, lty, rbx, rby
ltx = bat(1) - (bat(3) / 2)
lty = bat(2) - (bat(4) / 2)
rbx = bat(1) + (bat(3) / 2)
rby = bat(2) + (bat(4) / 2)
setrgb 1, 127, 127, 127
fill rectangle ltx, lty, rbx, rby
end sub
sub draw_score()
setrgb 1, 0, 0, 0
text 50, 20, str$(score(1)), "cc"
text XSIZE - 50, 20, str$(score(1)), "cc"
end sub
sub init()
init_structures()
init_screen()
end sub
sub init_structures()
rem ball: x, y, radius, angle, speed
dim ball(5)
init_ball()
rem left_bat: x, y (center), width, height
dim left_bat(4)
left_bat(1) = BAT_OFFSET
left_bat(2) = YSIZE / 2
left_bat(3) = BAT_WIDTH
left_bat(4) = BAT_HEIGHT
rem right_bat: x, y (center), width, height
dim right_bat(4)
right_bat(1) = XSIZE - BAT_OFFSET
right_bat(2) = YSIZE / 2
right_bat(3) = BAT_WIDTH
right_bat(4) = BAT_HEIGHT
rem score: left, right
dim score(2)
score(1) = 0
score(2) = 0
end sub
sub init_ball()
ball(1) = XSIZE / 2
ball(2) = YSIZE / 2
ball(3) = BALL_RADIUS
ball(4) = random_angle()
ball(5) = BALL_SPEED
end sub
sub random_angle()
local r
r = ran() * 2 * pi
rem These angles keep the game interesting
while (((r > 0.4 * pi) and (r < 0.6 * pi)) or ((r > 1.4 * pi) and (r < 1.6 * pi)))
r = ran() * 2 * pi
wend
return r
end sub
sub init_screen(text$)
open window XSIZE, YSIZE
buffer = 0
setdrawbuf buffer
setrgb 0, 64, 127, 64
clear window
end sub
sub wait_controller(text$)
setrgb 1, 0, 0, 0
text XSIZE / 2, YSIZE / 2, text$, "cc"
while (or(peek("PORT1"), peek("PORT2")) = 0)
pause 0.02
wend
end sub
|
(c) 2001 Arwin van Arum
"Sony" and "Playstation 2" are registered trademarks owned by Sony Inc.
"Tekken" and "Bust-A-Groove"
are registered trademarks and are owned by Namco.
|