HP Prime for All

English  Русский 
Breakout games-app screenshot}}
Name Breakout
Description Bounce the ball off the bricks to break them all.
Author Egan Ford (datajerk)

Source code (download):

Source code formatted by website engine

ICON resource lines were stripped.

// breakout hp prime v 1.0 // // Egan Ford < egan@sense.net > // // Inspired by Tugdual's Pong alpha and Atari 2600 Breakout // // TO DO (maybe): // fix hard coded speed // change SCORE to 1UP // add two player mode // track high scores // change Apple II font to arcade font // d pad support // brick boarders? brickout(); drawbricks(); drawballs(); drawscore(); drawtext(); local j, t, m; local paddle_x, paddle_y, paddle_w, paddle_h, paddle_m; // paddle local score_y, brick_h, brick_n; // bricks local brick_colors, brixel_x, brixel_y, brick_w; local x, y, vx, vy, ball_m, ball_w, ball_n, rel_x; // ball local vx_set, vy_set, x0, last_vy; local frame_l, frame_r, frame_b; local inplay, speed_base, speed, score, level, score_l, last_score; local pixel, hit, demomode, demoran, new, level_max, score_base; local start_text, ready_text, ready_text_p; local start_text_w, ready_text_w; local start_text_p, pulse_color, pulse, pulse_inc; local start_text_x, start_text_y, ready_text_x, ready_text_y; local game_over, game_over_x, game_over_y, game_over_w; local base_ticks, ball_base, reset; local numbers, numbers_w; local score_text, score_text_w, level_text, level_text_w; export breakout() begin pixel := 4; // must divide 320x240 // geo in large pixels 80x60 frame_l := 0; frame_r := 79; frame_b := 59; paddle_w := 10; paddle_y := 52; paddle_h := 1; score_base := 7; score_y := 7; brick_h := 2; brick_n := 16; // must divide 80 brick_w := (frame_r - frame_l + 1) / brick_n; paddle_m := paddle_w / 2; ball_w := 1; ball_m := ball_w/2; demomode := 1; demoran := 0; last_score := 0; score := 0; level := 0; level_max := 5; new := 1; pulse := 0; pulse_inc := 1; pulse_color := 7; inplay := 0; speed_base := 1; speed := speed_base; ball_base := 5; ball_n := ball_base; base_ticks := 25; reset := 1; //red, orange, yellow, green, blue, purple brick_colors := {#FF0000h, #FFA500h, #FFFF00h, #00FF00h, #0000FFh, #FF00FFh}; // probably should have stuck with this idea :-) //bricks := makemat(1, size(brick_colors), brick_n); rect_p(G0, 0, 0, 319, 239, 0); // black out screen (add please wait?) textout_p("BOOTING...DON'T PANIC...", G0, 0, 0, 2, #FFFFFFh, 200, #0h); dimgrob_p(G1, 320, 240); // background rect_p(G1, 0, 0, 319, 239, 0); // black background dimgrob_p(G2, 320, 240); // playground // create "tap to start" text dimgrob_p(G3, 320, 240); // start text pre-rendered start_text_p := 80; start_text_w := 2; start_text_x := (320/start_text_w - 12*6-1) / 2; start_text_y := 70; start_text := { {#11111100010001111000000001111100b, #111100000000011100111110001000b, #1111100111110b}, {#10010000101001000100000000010001b, #100010000000100010001000010100b, #1100010001000b}, {#10010001000101000100000000010001b, #100010000000100000001000100010b, #1100010001000b}, {#10010001000101111000000000010001b, #100010000000011100001000100010b, #1111100001000b}, {#10010001111101000000000000010001b, #100010000000000010001000111110b, #1101000001000b}, {#10010001000101000000000000010001b, #100010000000100010001000100010b, #1100100001000b}, {#10010001000101000000000000010000b, #111100000000011100001000100010b, #1100010001000b} }; rect_p(G3, 0, 0, 319, 239, 0); // black background for j from 2 to 15 do drawtext(G3, start_text, 12*6-1, (j-2) * 7, start_text_w, j * #111111h); end; // create "ready play one" text dimgrob_p(G4, 320, 240); // ready text pre-rendered ready_text_p := 4000 / 16; // 3 seconds to get ready ready_text_w := 2; ready_text_x := (320/ready_text_w - 16*6-1) / 2; ready_text_y := 70; ready_text := { {#1111100111110001000111100100010b, #1000000111100100000001000100010b, #1111110111100000000011100100010b… {#1100010100000010100100010100010b, #1000000100010100000010100100010b, #1100000100010000000100010100010b, #1100000b}, {#1100010100000100010100010010100b, #1000000100010100000100010010100b, #1100000100010000000100010110010b, #1100000b}, {#1111100111100100010100010001000b, #1000000111100100000100010001000b, #1111100111100000000100010101010b, #1111100b}, {#1101000100000111110100010001000b, #1000000100000100000111110001000b, #1100000101000000000100010100110b, #1100000b}, {#1100100100000100010100010001000b, #1000000100000100000100010001000b, #1100000100100000000100010100010b, #1100000b}, {#1100010111110100010111100001000b, #1000000100000111110100010001000b, #1111110100010000000011100100010b, #1111110b} }; rect_p(G4, 0, 0, 319, 239, 0); // black background for j from 0 to 15 do drawtext(G4, ready_text, 16*6-1, j*7, ready_text_w, j * #111111h); end; game_over_w := 2; game_over_x := 320/game_over_w - (320/game_over_w - 9*6-1) / 2; game_over_y := 70; game_over := { {#1011110001000100010111110000000b, #1011100100010111110111100b}, {#1100000010100110110100000000000b, #1100010100010100000100010b}, {#1100000100010101010100000000000b, #1100010100010100000100010b}, {#1100000100010101010111100000000b, #1100010100010111100111100b}, {#1100110111110100010100000000000b, #1100010100010100000101000b}, {#1100010100010100010100000000000b, #1100010010100100000100100b}, {#1011110100010100010111110000000b, #1011100001000111110100010b} }; // create score number text dimgrob_p(G5, 320, 240); // numbers pre-rendered numbers_w := 1; numbers := { {#1011100001000011100111110000100b, #1111110001110111110011100011100b}, {#1100010011000100010000010001100b, #1100000010000000010100010100010b}, {#1100110001000000010000100010100b, #1111100100000000100100010100010b}, {#1101010001000001100001100100100b, #1000010111100001000011100011110b}, {#1110010001000010000000010111110b, #1000010100010010000100010000010b}, {#1100010001000100000100010000100b, #1100010100010010000100010000100b}, {#1011100011100111110011100000100b, #1011100011100010000011100111000b} }; rect_p(G5, 0, 0, 319, 239, 0); // black background drawtext(G5, numbers, 10*6-1, 0, numbers_w, #FFFFFFh); score_text_w := 1; score_text := { {#1011100011100011100111100111110b, #1000000b}, {#1100010100010100010100010100000b, #1001100b}, {#1100000100000100010100010100000b, #1001100b}, {#1011100100000100010111100111100b, #1000000b}, {#1000010100000100010101000100000b, #1001100b}, {#1100010100010100010100100100000b, #1001100b}, {#1011100011100011100100010111110b, #1000000b} }; drawtext(G5, score_text, 6*6-1, 20, score_text_w, #FFFFFFh); level_text_w := 1; level_text := { {#1100000111110100010111110100000b, #1000000b}, {#1100000100000100010100000100000b, #1001100b}, {#1100000100000100010100000100000b, #1001100b}, {#1100000111100100010111100100000b, #1000000b}, {#1100000100000100010100000100000b, #1001100b}, {#1100000100000010100100000100000b, #1001100b}, {#1111110111110001000111110111110b, #1000000b} }; drawtext(G5, level_text, 6*6-1, 30, level_text_w, #FFFFFFh); // flush mouse buffer repeat m := mouse; until size(m(1)) = 0; // main loop repeat t := ticks+base_ticks/speed; if reset = 1 then reset := 0; demomode := 1; new := 1; ball_n := ball_base; level := 0; score := 0; last_score := 0; pulse := 0; pulse_inc := 1; pulse_color := 7; end; if new = 1 then new := 0; inplay := 0; paddle_x := (frame_r-frame_l+1) / 2 - paddle_m; // center paddle vx := 0.5; vy := 1; last_vy := 0; demoran := 0; x := paddle_x+paddle_m; y := paddle_y-ball_w; score_l := 0; speed := speed_base; score_y := score_base + (level mod level_max) * brick_h; level := level + 1; drawbricks(); drawballs(); drawscore(); // display level at bottom of screen end; // read finger or not if demomode = 1 then // pulse tap to start if ticks > pulse then pulse := ticks + start_text_p; if pulse_color = 15 then pulse_inc := -pulse_inc; end; if pulse_color = 3 then pulse_inc := -pulse_inc; end; pulse_color := pulse_color + pulse_inc; blit_p(G1, (start_text_x+1) * start_text_w, start_text_y*start_text_w, G3, 0, (pulse_color-2) * 7*start_text_w, 12*6*sta… end; if vy > 0 and last_vy < 0 then // if on the down after an up generate a random paddle hit demoran := randint(-paddle_m, paddle_m); end; paddle_x := x - paddle_m + demoran * (y / (paddle_y-1)); // track the ball center if paddle_x < frame_l then paddle_x := frame_l; end; if paddle_x > frame_r - paddle_w then paddle_x := frame_r - paddle_w + 1; end; last_vy := vy; inplay := 1; // tap, exit demo mode m := mouse; if size(m(1)) > 0 then demomode := 0; inplay := 0; new := 1; level := 0; score := 0; last_score := 0; pulse := 0; pulse_color := 16; end; else if inplay = 0 then // start ready player one fade to black if ticks > pulse then pulse := ticks + ready_text_p; pulse_color := pulse_color - 1; blit_p(G1, (ready_text_x+1) * ready_text_w, ready_text_y*ready_text_w, G4, 0, (pulse_color) * 7*ready_text_w, 16*6*ready… if pulse_color = 15 then ball_n := ball_n - 1; drawballs(); end; if pulse_color = 0 then pulse := 0; pulse_color := 16; inplay := 1; end; end; end; m := mouse; if size(m(1)) > 0 then paddle_x := floor(m(1, 1) / pixel) - paddle_m; if paddle_x < frame_l then paddle_x := frame_l; end; if paddle_x > frame_r - paddle_w then paddle_x := frame_r - paddle_w + 1; end; end; end; // background blit_p(G2, G1); // player rect_p(G2, paddle_x*pixel, paddle_y*pixel, (paddle_x+paddle_w) * pixel-1, (paddle_y+paddle_h) * pixel-1, #FFFFFFh); // ball if inplay = 0 then //x := paddle_x+3*ball_w; // make random x := paddle_x+paddle_m; // make random y := paddle_y-ball_w; vx := 0.5; vy := 1; end; if inplay = 1 then case if y < paddle_y - ball_w then // field case if x < = frame_l then // left edge vx := -vx; x := frame_l; end; if x > = frame_r then // right edge vx := -vx; x := frame_r; end; end; case if y < = 0 then // top of screen vy := -vy; y := 0; end; if y = score_y + size(brick_colors) * brick_h + 1 and vy > 0 then // update score on ball down drawscore(); end; //if y > = score_y - 1 and y < = score_y + size(brick_colors) * brick_h + 1 then if y > = score_y and y < = score_y + size(brick_colors) * brick_h then // check bricks if vx > 0 then x0 := floor(x) else x0 := ceiling(x); end; // did new position hit a brick? // check all 4 sides vy_set := 0; vx_set := 0; if (vy > 0) then // going down if getpix_p(G1, x0*pixel, (y+ball_w) * pixel) > 0 then brixel_x := floor(x0 / 5) * 5; brixel_y := y + ball_w; brickout(); vy := -vy; vy_set := 1; end; else // going up if getpix_p(G1, x0*pixel, y*pixel-1) > 0 then brixel_x := floor(x0 / 5) * 5; brixel_y := y - brick_h; brickout(); vy := -vy; vy_set := 1; end; end; if (vx > 0) then // going right if getpix_p(G1, (x0+ball_w) * pixel, y*pixel) > 0 then brixel_x := floor((x0 + 1) / 5) * 5; brixel_y := y - ((y - score_y) mod brick_h); brickout(); vx := -vx; vx_set := 1; end; else // going left if getpix_p(G1, x0*pixel-1, y*pixel) > 0 then brixel_x := floor((x0 - 1) / 5) * 5; brixel_y := y - ((y - score_y) mod brick_h); brickout(); vx := -vx; vx_set := 1; end; end; // check all 4 corners only if x is on exact brick boundary if x0 / 5.0 = floor(x0/5) and vx < 0 then // left brick boundary if vy > 0 and (y - score_y) mod brick_h = brick_h - 1 then // going down and left if getpix_p(G1, x0*pixel-1, (y+ball_w) * pixel) > 0 then brixel_x := floor((x0-1) / 5) * 5; brixel_y := y + ball_w; brickout(); if vy_set = 0 then vy := -vy; end; if vx_set = 0 then vx := -vx; end; end; end; if vy < 0 and (y - score_y) mod brick_h = 0 then // going up and left if getpix_p(G1, x0*pixel-1, y*pixel-1) > 0 then brixel_x := floor((x0-1) / 5) * 5; brixel_y := y - brick_h; brickout(); if vy_set = 0 then vy := -vy; end; if vx_set = 0 then vx := -vx; end; end; end; end; if (x0+1) / 5.0 = floor((x0+1) / 5) and vx > 0 then // right brick boundary if vy > 0 and (y - score_y) mod brick_h = brick_h - 1 then // going down and right if getpix_p(G1, (x0+1) * pixel, (y+ball_w) * pixel) > 0 then brixel_x := floor((x0+1) / 5) * 5; brixel_y := y + ball_w; brickout(); if vy_set = 0 then vy := -vy; end; if vx_set = 0 then vx := -vx; end; end; end; if vy < 0 and (y - score_y) mod brick_h = 0 then // going up and right if getpix_p(G1, (x0+1) * pixel, y*pixel-1) > 0 then brixel_x := floor((x0+1) / 5) * 5; brixel_y := y - brick_h; brickout(); if vy_set = 0 then vy := -vy; end; if vx_set = 0 then vx := -vx; end; end; end; end; end; end; end; if y < paddle_y then // is ball on or in paddle plane //do x to check for hit or miss first if x > = paddle_x - ball_w and x < = paddle_x + paddle_w then vy := -vy; // change angle based on position on paddle // hard coded for paddle size of 10 for now rel_x := paddle_x + paddle_m - x; if rel_x > 1 or rel_x < -2 then vx := -(rel_x / 4); else if speed = 2 then speed := 1.5; end; // ok, i'll give you a chanceand just reflect if near center end; //case // if rel_x < -4 then vx := -2; end; // if rel_x < -2 then vx := -1; end; // if rel_x < 2 then vx := vx; end; // reflect // if rel_x < 4 then vx := -1; end; // default vx := 2; //end; // corner cases if x < = frame_l then // left edge vx := -vx; end; if x > = frame_r - ball_w then // right edge vx := -vx; end; end; end; if y > frame_b - ball_w then // miss inplay := 0; if ball_n = 0 then // game over drawtext(G0, game_over, game_over_x, game_over_y, game_over_w, #FFFFFFh); repeat m := mouse; until size(m(1)) = 0; repeat m := mouse; until size(m(1)) > 0; repeat m := mouse; until size(m(1)) = 0; reset := 1; end; // if in demo mode just keep going (demo mode should not miss! :-) end; end; x := x + vx; y := y + vy; end; rect_p(G2, x*pixel, y*pixel, (x+ball_w) * pixel-1, (y+ball_w) * pixel-1, #FFFFFFh); while ticks < t do t := t; end; blit_p(G0, G2); // display it until iskeydown(4); wait(0); end; brickout() begin if ((brixel_y - score_y) mod brick_h) > 0 then brixel_y := brixel_y - ((brixel_y - score_y) mod brick_h); end; // hack, already got it, dunno why i'm here, return if getpix_p(G1, brixel_x*pixel, brixel_y*pixel) = 0 and getpix_p(G1, (brixel_x+brick_w) * pixel-1, (brixel_y+brick_h) * … // log screen shot and other data for debug return end; rect_p(G1, brixel_x*pixel, brixel_y*pixel, (brixel_x+brick_w) * pixel-1, (brixel_y+brick_h) * pixel-1, #0h); if brixel_y < score_y + 2 * brick_h then speed := 2; end; score_l := score_l + level * (size(brick_colors) - (brixel_y-score_y) / brick_h); score := last_score + score_l; if score_l = level * brick_n * (size(brick_colors) * (size(brick_colors) + 1)) / 2 then // other game cleanup, next level, etc... last_score := score; new := 1; end; // debug //textout_p(score+" "+score_l+" "+level+" "+ball_n, G1, 5, 5, 1, #FFFFFFh, 200, #0h); end; drawbricks() begin local j, len, tmp, x, n, y; y := 239 - (239 - (paddle_y+paddle_h) * pixel) / 2 - 7*level_text_w/2; // draw bricks // probably should improve look of bricks rect_p(G1, 0, 0, 319, 239, 0); // black background for j from 0 to size(brick_colors) - 1 do rect_p(G1, 0, score_y*pixel+brick_h*pixel*j, 319, score_y*pixel+brick_h*pixel * (j+1) - 1, brick_colors(j+1)); end; blit_p(G1, ball_w*pixel, y, G5, 0, 30, 7*6*level_text_w, 30+7*level_text_w); len := floor(log(level) + 1); x := (len+7) * 6 * numbers_w; tmp := level; for j from 1 to len do n := tmp mod 10; blit_p(G1, x, y, G5, n*6*numbers_w, 0, (n+1) * 6*numbers_w, 7*numbers_w); x := x - 6*numbers_w; tmp := floor(tmp / 10); end; end; // print right to left drawtext(target, text, text_x, text_y, text_w, text_c) begin local j, k, l, x; for j from 1 to size(text) do x := text_x; for l from size(text(j)) downto 1 do k := text(j, l); while k > 1 do if bitand(k, #1b) = #1b then rect_p(target, text_w*x, text_w * (text_y+j-1), text_w * (x+1) - 1, text_w * (text_y+j) - 1, text_c); end; k := bitsr(k); x := x - 1; end; end; end; end; drawballs() begin local y; y := 239 - (239 - (paddle_y+paddle_h) * pixel) / 2; rect_p(G1, 319-2*ball_base*pixel, y, 319, y+pixel*ball_w-1, #000000h); for j from 1 to ball_n do rect_p(G1, 320-2*j*ball_w*pixel, y, 319 - ((2*j) - 1) * ball_w*pixel, y+pixel*ball_w-1, #FFFFFFh); end; end; drawscore() begin local j, len, tmp, x, n, y; y := 5; blit_p(G1, ball_w*pixel, y, G5, 0, 20, 7*6*level_text_w, 20+7*level_text_w); if score = 0 then return; end; len := floor(log(score) + 1); //center //x := 160 - ((len+6) * 6 * numbers_w) / 2 + ((len+5) * 6 * numbers_w); //blit_p(G1, x - (len+6) * numbers_w*6, y, G5, 0, 20, 7*6*numbers_w, 20+7*numbers_w); x := (len+7) * 6 * numbers_w; tmp := score; for j from 1 to len do n := tmp mod 10; blit_p(G1, x, y, G5, n*6*numbers_w, 0, (n+1) * 6*numbers_w, 7*numbers_w); x := x - 6*numbers_w; tmp := floor(tmp / 10); end; end;

Comments