|
Pongo Game - Source CodeArkanoid style block game. |
|
REBOL [
Title: "Pongo"
Author: "Kurt & Dad"
Version: 2.0.0
Date: 4-April-2003 ;Last: 4-Mar-2001
]
;-- Create the Tile Images
; This starts by making a single tile face, then creating 5 other tiles
; based on that first tile, each with a different amount of "glow".
the-tile: layout [
tile: box 50x20 edge [color: gray effect: 'bevel size: 2x2]
]
tiles: [] ; This list holds each of the new glow images.
glow-count: 5 ; The number of glow images to create.
repeat n glow-count [
tile/effect: compose [gradient 0x1 255.255.255 (100.100.100 / glow-count * n)]
append tiles to-image tile
]
tile-image: first tiles
;-- Create the Ball Image
ball-face: make face [
edge: para: font: none
size: 25x25
color: silver
effect: [gradmul 1x1 255.255.255 0.0.0 oval 0.0.0]
]
;-- Create the Paddle Image
paddle: make face [
edge: make edge [size: 4x4 color: gray effect: 'bevel]
effect: [grid 4 4]
size: 80x18
color: white
]
;-- Tile Map:
; A simple character map is used to layout the tiles on the screen.
; Different letters indicate diffent color tiles. You can change
; this map to create different levels.
level: 1
tile-maps: [
; Level 1
{
yyy yyy
y y y y
yyy yyy
bb
bb
mmmm
rrrr
rr rr
rrrr
}
; Level 2
{
rrrrrrrr
bb yy bb
r r r r
bb gg bb
r r
s s s s
r r
}
; Level 3
{
gg
gg
gllg
gllg
gllllg
gllllg
gllllg
gllllllg
gllllllg
gllllllg
llllllll
mm
mm
mm
mm
}
]
;-- Color key:
; This is what maps a letter to a specific color:
colors: reduce [
#"r" red
#"g" green
#"b" blue
#"y" yellow
#"s" silver
#"p" purple
#"m" brown
#"l" leaf
#"?" 0
]
;-- Main window:
; This inclues the title for the game, the score field,
; and the playfield where the tiles go.
main: layout [
vh2 "Kurt's Pongo Game"
scorefield: text bold gold "Press mouse button to start."
playfield: box 400x400 black
]
main/effect: [gradient 0x-1 180.180.180 80.80.80] ; window background
playfield/pane: [] ; holds the tiles, paddle, and ball.
random/seed: now ; set randomness
;-- Layout Tiles:
; Layout the actual tiles according to the map above.
tile-count: 0
layout-tiles: does [
x: 0 ; the horizontal postion of next tile
y: 2 ; the vertical position of next tile
clear playfield/pane
tile-map: pick tile-maps level
foreach char tile-map [
; For each character in the tile map...
either char = newline [
; End of line. Move to next vertical position.
x: 0
y: y + tile-image/size/y
][
; User the letter (rgbysp...) to get the color:
color-value: select colors char
if color-value [
; Add new tile face to the playfield:
tile-count: tile-count + 1
append playfield/pane make face [
color: either color-value = 0 [random 255.255.255][color-value]
offset: as-pair x y
size: tile-image/size
image: tile-image
effect: reduce ['colorize color]
edge: para: font: none
]
]
; Move to next horizontal position:
x: x + tile-image/size/x
]
]
; Reverse it so we detect collision with lower tile first:
reverse playfield/pane
; Add the Paddle and Ball to the Playfield:
insert playfield/pane paddle
insert playfield/pane ball
max-y: y + tile-image/size/y ; put the paddle after this
]
;-- Special functions:
hit-tile?: func [x y] [
; Given a position, tell us what tile we hit.
; Return NONE if we did not hit a tile.
foreach tile next next playfield/pane [
if all [
tile/offset/y + tile/size/y > y
tile/offset/x - ball/size/x < x
tile/offset/x + tile/size/x > x
][return tile]
]
none
]
set-glow: func [glow-level] [
; Set the glow level for each tile in the playfield.
; (Skip first two faces: the paddle and the ball)
foreach face next next playfield/pane [
face/image: pick tiles glow-level
]
]
bump-score: does [
; Bump up the score:
score: score + 1
scorefield/text: reform [
"Level:" level
" Score:" score
;either score > high-score [" NEW HIGH SCORE!!!"][""]
]
]
game-over: has [comments str note percent] [
; Tell user that the game is over.
str: reform ["GAME OVER! Score:" score "- "]
percent: score / tile-count * 100
comments: [
20 "You need practice."
40 "Keep working at it!"
60 "That's a good score!"
80 "Wow! That's amazing!"
]
note: "I bow to you, master pongo player."
foreach [num msg] comments [
if percent < num [note: msg break] ;>
]
alert append str note
reset-game
]
start-level: does [
layout-tiles
;-- Set the Ball and Paddle Positions:
paddle/offset: playfield/size - 200x40
ball/offset: paddle/offset - paddle/size - 6
bx: ball/offset/x ; Ball X position
by: ball/offset/y ; Ball Y position
dx: 0 ; Delta X - how much to move horizontally each time
dy: -15 ; Delta Y - how much to move vertically each time
bs: ball/size/x ; Ball size (for both x and y)
glow: 0 ; tile glow
;-- Set the Speed and Display the Window:
ball/rate: 30
started: off
won-level: false
]
;-- Make the Ball Face:
; And set it to move as time goes by.
ball: make face [
size: 25x25
color: black
image: to-image ball-face
feel: make feel [
engage: func [face act event] [
; Each time we get a "time" action:
if act = 'time [
if not started [exit]
move-ball
show ball
]
]
]
edge: para: font: none
]
;-- Ball Movement Code:
; This is the hard stuff, where we compute the next position
; for the ball as it bounces around the playfield.
do reset-game: does [
score: 0 ; total score
level: 1
past-paddle: false
start-level
]
move-ball: does [
; Move the ball to the next position:
bx: bx + dx
by: by + dy
; If it hit the right side, bounce it back:
if bx + bs >= playfield/size/x [dx: negate dx]
; If it hit the left side, bounce it back:
if bx < 0 [dx: abs dx] ;>
; If the tiles are glowing, bump them to next glow level:
if glow > 0 [
glow: glow - 1
if glow > 0 [set-glow glow]
]
; Is the ball in the tile area?
if by < max-y [ ;>
; If ball hit a tile, remove it and bump the score:
either tile: hit-tile? bx by [
remove find playfield/pane tile
bump-score
if 2 >= length? playfield/pane [won-level: true]
glow: glow-count
set-glow glow
by: tile/offset/y + tile/size/y - 5
dy: abs dy
][
if by < 0 [dy: abs dy] ;>
]
]
; Is the ball moving past the paddle (game over):
either past-paddle [
; Is the ball off the screen?
if by > playfield/size/y [
ball/rate: none
ball/offset: as-pair bx by
show ball
game-over
]
][
; Did the ball hit the paddle?
if by + ball/size/y >= paddle/offset/y [
either all [
; Check if ball is in paddle's position:
not past-paddle
bx + bs - 3 > paddle/offset/x
bx + 2 < (paddle/offset/x + paddle/size/x) ;>
][
; It hit the paddle. Bounce it off the paddle, giving it
; a little extra speed each time.
dy: min 50 dy * 20 / 19
dy: negate dy
; Make edges of the paddle deflect the ball slightly:
dx: bx - paddle/offset/x - (paddle/size/x / 2) / 10 + dx
by: paddle/offset/y - paddle/size/y - 5
if won-level [
alert "You made it to the next level!"
level: level + 1
start-level
]
][
; Past the paddle. Game over, pal.
past-paddle: true
]
]
]
ball/offset: as-pair bx by
show [playfield scorefield]
]
start-level
view/new center-face main
;-- Detect Mouse Movement and Move Paddle:
main/feel/detect: func [face event] [
if event/type = 'move [
paddle/offset/x: event/offset/x - 70
show paddle
]
if event/type = 'down [started: true]
event
]
show ball
do-events
|