Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
JBARLOW
Contributor
1,996
As a couple of people have asked, this blog will try to explain the scripting thought process used to create the Pac Man Analytic Application.

It's worth calling this out from the outset:
The idea and scripting more or less evolved as each step presented a new challenge.
I'll be the first to admit the coding is inelegant, inefficient and without doubt could be dramatically improved.

I won't cover all of the coding - mainly as
A. I didn't document it at the time
B. I don't have time now   🙂

Part 1 is here: Part 1

.........................................................................................................................................................

The Application consists of 3 main panels as shown below:

Title and Score are just just used to group text widgets etc, so purely for ease of layout.
pnl_main contains the most of what's happening in the Application



High Level Explanation

The logic is fairly simple, we have a container panel of known Height & Width, the Pac Man images are stored within a panel and there is a panel for each dot.

When a user clicks the R,L,U,D buttons logic is run to check the position of the pacman panel
e.g. For the R button, check the Right position of the pacman panel - if it's <0 then move the panel right in increments of 10px

A sub loop is also run that shows/hides the Pac Man images of open/closed to give the animated effect.

Global variables are updated in each run of the move loop to store the Right / Left / Top / Bottom position of the Pac Man panel.

As part of this movement loop, we also loop through the array of panels containing the dots and check the Top & Right position of each dot panel.
If any of the values match the Top & Right value of the pacman panel -  set that dot panel to invisible & add one to the score count (a global variable storing a numeric value)


Because we're using a grid of known size, we also know where the Pac Man panel shouldn't be allowed to move up/down/left/right.

The movement is all hardcoded with conditions to stop the Pac Man panel from moving off the course of dots.

Move Down example
For down movement there are only 3 X position values where it makes sense for Pac Man to move down

If any of the conditions below are met - then run the Script Function "MOVE.PGO_DOWN"
which moves Pac Man down in increments of 10px
if( LEFT===50 && RIGHT===300 &&TOP <100)
{MOVE.PGO_DOWN();}

if( LEFT===200 && RIGHT===150 &&TOP >99)
{MOVE.PGO_DOWN();}

if( RIGHT===0 )
{MOVE.PGO_DOWN();}


MOVE.PGO_DOWN Function

if(BOTTOM >0) // check the BOTTOM variable value
{ pnl_pac.getLayout().setTop(TOP+10);
TOP=TOP+10;
pnl_pac.getLayout().setBottom(BOTTOM-10);
BOTTOM =BOTTOM-10;

for (var i=0;i<SHAPES.length;i++)
{var SHAPE_RIGHT = SHAPES[i].getLayout().getRight().value;
var SHAPE_TOP = SHAPES[i].getLayout().getTop().value;

if(RIGHT===SHAPE_RIGHT && TOP===SHAPE_TOP)
{SHAPES[i].setVisible(false);
SCORE1.SCORE2();} } //Run the score function

if(RFLAG>0) {RFLAG=0;}

if(LFLAG>0) {RFLAG=0;}

if(UFLAG>0) {UFLAG=0;}}

if(RIGHT===GRIGHT && TOP===GTOP)
{img_gameover.setVisible(true);}


The Score function

var COUNT = 0;
for (var i=0;i<SHAPES.length;i++)
{if(!SHAPES[i].isVisible())
{COUNT = COUNT+1;}}
var SCORE = ConvertUtils.numberToString(COUNT);

//Write the Score value to the score text box
txt_Score.applyText("SCORE:"+ " "+SCORE);

// If all dots are invisible show the Win image
if(COUNT===26)
{txt_win.setVisible(true);
txt_win.setCssClass('FONT_YELLOW_TEXT');

// Start the win timer
Timer_Win.start(3);}


Automated movement of the Ghost Panel

This would win an award for the most inefficient coding

When the GO button is clicked to start the game, a Script Function is called that contains the code below.

The Ghost panel follows a pre-set path following the dots - this movement loops until either Pac Man eats all the dots and wins the game , or the Ghost panel position matches that of the Pac Man panel and it's game over.

There are a load of Timers with flag variables to tell them whether to run or not
(based on the Ghost Panel's position)

The Timer start delay is determined by the value set when a user clicks one of the 3 game mode buttons (Easy, Medium, Hard)
This start delay affects how fast the Ghost Panel moves.
if(RIGHT===GRIGHT && TOP===GTOP)
{img_gameover.setVisible(true);
move_mask.setVisible(true);}
/* The code above checks the PacMan & Ghost panel position values
if they match show the gameover image
*/

else{
if(AUTOMOVE_FLAG<100)
//cap the number of loops round the maze made by the ghost
{
if(TIMER_RIGHT_FLAG<35)
{Timer_right.start(GAME_MODE);}

else{ if(TIMER_UP_FLAG<27)
{Timer_up.start(GAME_MODE);}

else{ if(TIMER_LEFT_FLAG<35)
{Timer_left.start(GAME_MODE); }

else {if(TIMER_LEFT_FLAG===35 && TIMER_RIGHT_FLAG2<5)
{Timer_right2.start(GAME_MODE);}

else {if(TIMER_DOWN_FLAG<10 && TIMER_RIGHT_FLAG2===5)
{Timer_down.start(GAME_MODE);}

else {if(TIMER_DOWN_FLAG===10 && TIMER_RIGHT_FLAG2===5 &&TIMER_UP_FLAG===27)
{ if(TIMER_RIGHT_FLAG3<16)
{Timer_right3.start(GAME_MODE);}

else {if(TIMER_RIGHT_FLAG3===16)
{ if(TIMER_DOWN_FLAG2<20)
{Timer_down2.start(GAME_MODE);}

else {if(TIMER_RIGHT_FLAG3===16 && GBOTTOM===0)
{ if(TIMER_LEFT_FLAG2<19)
{Timer_left2.start(GAME_MODE);}}}

}
}}
}}}}}}}


Other bits and pieces


When the new game button is clicked or the game is won  / lost the following actions happen.

1. Global variable values are reset to their default value
2. All Timers are stopped
3. All the dot panels are set back to visible
4. The Ghost and Pac Man panels are set back to their original position
5. The score variable value is reset to 0

 

Things to consider

1. Layout
It was important the Pac Man, Dots & Ghost panels were all the same size
and that the movement steps were in blocks of 10 px

This was to ensure that at some point the Top and Right position would match allowing us
to flag when to hide a dot, update the score and trigger the game win/lose code

2. Hardcoded logic
There's no real intelligence in the movement logic - Pac Man can only move if hardcoded
conditions are met  & the Ghost simply follows a pre-set path on a loop.

3. Lack of Parallel Script running
The game doesn't truly work - in as much as we can't run Parallel scripts in SAC
So when you click the Pac Man movement buttons, it temporarily stops the Ghost movement
scripts from running.


Bonus content... of sorts - SAC Wordle





 

 

 
3 Comments
Bob0001
Advisor
Advisor
0 Kudos
Nice work jbarlowjb, might be a nice exercise for the community to improve the scripting and implementation for performance and best practices. Some suggestions from my side:

  • Performance: When it comes to performance on such fast repeating loops one advice from the Developer Handbook is to keep already calculated variables in a variable like the result of getLayout instead of getting it again.

  • Performance: Also using standard JavaScript functions like <number>.toString() is faster than ConvertUtils.

  • Style: More a minor thing. All-upper-case variable names in software development usually indicate a constant value which you don't wanna/can't change anymore. It might be confusing for software developers to read your code. But would be interesting to hear from you whether you did this for a reason e.g. because you find it easier to read.


Regarding your comment on parallel scripting, there isn't really such thing in plain JavaScript itself. When it comes to game development you would usually solve this by the game-loop pattern (somewhat explained here but for other programming environments). In your case it would make sense to have a repeating game loop by using timer which calculates new state and renders. The script handlers for the move buttons would not trigger rendering but just store the actions or already update the state of the pac-man sprite. This should give you a more smooth animation.
0 Kudos
Some great insights there, jbarlowjb
JBARLOW
Contributor
0 Kudos
Thanks Bob,

As always great points!

Using ConvertUtils is a bad habit I think I've got into,
as for the upper case names - yep did it deliberately so it was easier to read.

Must admit, I probably won't invest time in updating the app - mainly as it was originally intended as a throwaway learning exercise for myself  🙂

 

 
Labels in this area