Sunday, February 16, 2014

HP Prime: Programming a (Very) Simple Game Part 5

Here it is - a complete simple game.  The objective is to collect dollar signs (coins) to unlock the boundary at the top of the screen to allow access to the goal.  Trees block your progress.  Avoid the purple foes at all times, one touch and it's over!  One purple foe jumps around randomly while two fly horizontal.  

Once again, you are controlling the π character.   Press the plus key to quickly exit the game.  This comes in handy if the game ever becomes "unbeatable" (although I tried to knock out all the bugs). 





The game features a status bar at the bottom of the screen that shows two things:
*  The number of coins remaining
*  A "LOCKED" indicator that indicates that the boundary is active (red) 

This is a culmination of the Simple Game series.  The program is named MOVEM7.

Note: if you are using the emulator, let d1:=1200 and d2:=200.

EXPORT MOVEM7()
BEGIN
// Version 7
// 2014-02-16
// Collect 10 coins to unlock the goal

// A status screen is added on the bottom
// Bottom row is not avialable for play
// This version puts it all together:
// Coins, trees, and enemies

// Game introduction
MSGBOX("Collect all 10 $ signs to unlock
the goal! Avoid the purple enemies!");

// Clear the screen
RECT();

// Cursor set up
LOCAL A,B,C,D;
A:=150;
B:=216;
C:=150;
D:=216;
TEXTOUT_P("π",A,B,2);

// Draw Coins
LOCAL costr,L2,L3,cx,cy,I,coins;
coins:=10; // counter
L2:=RANDINT(10,0,31)*10;  // x coin
L3:=RANDINT(10,1,17)*12;  // y coin
costr:=CHAR(36);  // $ sign
FOR I FROM 1 TO 10 DO
cx:=L2(I); cy:=L3(I);
TEXTOUT_P(costr,cx,cy,2,#FF00h);
END;

// Draw Trees
// Trees Setup
LOCAL tstr,L0,L1,S,tx,ty,J;
S:=10;
L0:=RANDINT(S,0,31)*10;   // x tree
L1:=RANDINT(S,1,17)*12;   // y tree
tstr:=CHAR(8857); // tree

// Make sure trees and coins do not
// appear in the same place.
// If there is a conflict, the coin wins.
// Middle
FOR I FROM 2 TO S-1 DO
FOR J FROM 1 TO 10 DO
IF (L0(I)==L2(J)) AND (L1(I)==L3(J)) THEN
// Use CONCAT and SUB
L0:=CONCAT(SUB(L0,1,I-1),SUB(L0,I+1,S));
L1:=CONCAT(SUB(L1,1,I-1),SUB(L1,I+1,S));
// Length of L0 and L1 decrease by 1
S:=S-1;
END;
END;
END;
// Left Side
FOR J FROM 1 TO 10 DO
IF (L0(1)==L2(J)) AND (L1(1)==L3(J)) THEN
L0:=SUB(L0,2,S); L1:=SUB(L1,2,S);
S:=S-1;
END;
END;
// Right Side
FOR J FROM 1 TO 10 DO
IF (L0(S)==L2(J)) AND (L1(S)==L3(J)) THEN
L0:=SUB(L0,1,S-1); L1:=SUB(L1,1,S-1);
S:=S-1;
END;
END;

// Draw the forest
FOR I FROM 1 TO S DO
tx:=L0(I); ty:=L1(I);
TEXTOUT_P(tstr,tx,ty,2,#8000h);
END;

// Ememy Setup
LOCAL estr,d1,d2;
LOCAL ey1A,ey2A,ey3A;
LOCAL ex1A,ex2A,ex3A;
LOCAL ey1B,ey2B,ey3B;
LOCAL ex1B,ex2B,ex3B;

// Delay
d1:=120;d2:=20;
// Enemy 1 jumps to random places
// Enemy 2 flies left to right
// Enemy 3 flies right to left

ex1A:=RANDINT(0,31)*10;
ey1A:=RANDINT(1,17)*12;

ex2A:=−10;
ey2A:=96;

ex3A:=330;
ey3A:=96;

estr:=CHAR(9991); //enemy
TEXTOUT_P(estr,ex1A,ey1A,2,#6000FFh);
TEXTOUT_P(estr,ex2A,ey2A,2,#8000FFh);
TEXTOUT_P(estr,ex3A,ey3A,2,#8000FFh);



// House setup
LOCAL hx,hy,hstr;
hx:=RANDINT(0,31)*10;
hy:=0;
hstr:=CHAR(9820); // castle
TEXTOUT_P(hstr,hx,hy,2,#964B00h);

// Lock setup
LOCAL lock:=1;

// Movement
REPEAT
// Delay Counter
d1:=d1-1; d2:=d2-1;

// Press an Arrow Key
K:=GETKEY;
IF K==7  AND A>0 THEN
C:=A-10; D:=B;
END;
IF K==8  AND A<310 THEN
C:=A+10; D:=B;
END;
IF K==12  AND B<216 THEN
C:=A; D:=B+12;
END;
IF K==2 AND B>0 THEN
C:=A; D:=B-12;
END;

// Move the Enemies
IF d1==0 THEN
d1:=120;

// Enemy 1
ex1B:=RANDINT(0,31)*10;
ey1B:=RANDINT(2,17)*12;
END;

IF d2==0 THEN
d2:=20;

// Enemy 2
ex2B:=ex2A+10;
ey2B:=ey2A;
IF ex2B>330 THEN
ex2B:=−10;
ey2B:=RANDINT(1,17)*12;
END;

// Enemy 3
ex3B:=ex3A-10;
ey3B:=ey3A;
IF ex3B<−10 THEN
ex3B:=330;
ey3B:=RANDINT(1,17)*12;
END;

END;

// Clear previous enemy spot
// Fixed objects will be drawn later
RECT_P(ex1A,ey1A,ex1A+10,ey1A+12);
RECT_P(ex2A,ey2A,ex2A+10,ey2A+12);
RECT_P(ex3A,ey3A,ex3A+10,ey3A+12);

// Draw new enemy positions
TEXTOUT_P(estr,ex1B,ey1B,2,#6000FFh);
ex1A:=ex1B;
ey1A:=ey1B;
TEXTOUT_P(estr,ex2B,ey2B,2,#8000FFh);
ex2A:=ex2B;
ey2A:=ey2B;
TEXTOUT_P(estr,ex3B,ey3B,2,#8000FFh);
ex3A:=ex3B;
ey3A:=ey3B;

// Bump in the boundary?
LOCAL collide:=0;
IF D==hy AND lock==1 THEN
collide:=1;
// No BREAK command because there is no
// FOR loop to break out of
END;

// Ran into a tree?
FOR I FROM 1 TO S DO
IF C==L0(I)  AND D==L1(I) THEN
collide:=1;
BREAK;
// BREAK needed because we have a FOR loop
END;
END;

IF collide==1 THEN
C:=A; D:=B;
END;

// Got hit by the enemy?
LOCAL death;
IF (C==ex1B) AND (D==ey1B) THEN
death:=1;
END;
IF (C==ex2B) AND (D==ey2B) THEN
death:=1;
END;
IF (C==ex3B) AND (D==ey3B) THEN
death:=1;
END;
IF death==1 THEN
MSGBOX("OUCH! :(");
BREAK;
END;

// Collect the coin?
FOR I FROM 1 TO 10 DO
IF C==L2(I)  AND D==L3(I) THEN
L2(I):=-1;
L3(I):=-1;
// Remove coin from play
coins:=coins-1;
BREAK;
END;
END;
// Are all the coins collected?
IF coins==0 THEN lock:=0 END;

// Player
RECT_P(A,B,A+10,B+12);
TEXTOUT_P("π",C,D,2);

// Draw a boundary
IF coins≠0 THEN
LINE_P(0,12,319,12,#FF0000h);
ELSE
// Unlock boundary, all coins collected
LINE_P(0,12,319,12,#FF00h);
END;

// Draw the Goal
TEXTOUT_P(hstr,hx,hy,2,#964B00h);

// Draw the Forest
FOR I FROM 1 TO S DO
tx:=L0(I); ty:=L1(I);
TEXTOUT_P(tstr,tx,ty,2,#8000h);
END;

// Draw the Coins
FOR I FROM 1 TO 10 DO
cx:=L2(I); cy:=L3(I);
// Don't draw at -1
IF L2(I)≠−1 AND L3(I)≠-1 THEN
TEXTOUT_P(costr,cx,cy,2,#FF00h);
END;

END;

// Draw Status Screen
RECT_P(0,217,319,239);
TEXTOUT_P("Coins Left: "+
STRING(IP(coins)),0,228,2);
IF lock==1 THEN
TEXTOUT_P("LOCKED",260,228,2,#FFh);
END;

// Prepare
 for the next move
A:=C; B:=D;
// Arrived home?
UNTIL K==50  OR (C==hx AND D==hy);

// Exit Conditions
// Plus Exit
IF K==50 THEN
MSGBOX("Program Terminated.");
END;
// Home Exit
IF C==hx AND D==hy THEN
MSGBOX("Home! :) "+CHAR(9829));
// CHAR(9829) produces a heart
END;

END;





Have fun, and hope you have learned something.  

Eddie

This blog is property of Edward Shore, 2014.

No comments:

Post a Comment

TI-84 Plus CE: Version 5.3 Highlights

TI-84 Plus CE:  Version 5.3 Highlights Piecewise Function The piecewise( function is added to the Math menu under the math submenu...