Skip to content

Commit

Permalink
new ghost
Browse files Browse the repository at this point in the history
  • Loading branch information
valentin-stamate committed Aug 9, 2019
1 parent ddcafe5 commit 3133549
Show file tree
Hide file tree
Showing 12 changed files with 336 additions and 214 deletions.
File renamed without changes.
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
# <p align="center">PacMan</p>

<p align="center">
<img width="400" src="https://i.postimg.cc/bvYx7yWB/Capture.png">
<img width="400" src="https://i.postimg.cc/xT4kvKnd/Capture-Ds.png">
</p>

### About

The game was made using [Processing](https://processing.org).
For ghosts I used A* algorithm.

The rules are pretty straight forward : eat the food , don't be the food.
The rules are pretty straight forward : eat the food , don't be the food.

I think I finished this game. I kinda make this game harder to play than I thought... but it works. I tried to make it look very similar with the original game : the map, the ghosts behavior and I added the path each one is following.
For more information about the original game check the credits below.

### What's New?
* A nice looking path
* Ghost interaction with Pacman
* Weak Mode for ghosts
* Auto return to home when a ghost is eaten by Pacman
* Few bugs fixed
* New ghost
* Ghosts behavior improved

### Credits
* [CodeBullet](https://www.youtube.com/channel/UC0e3QhIYukixgh5VVpKHH9Q)
* [GeeksForGeeks](https://www.geeksforgeeks.org)
* [Wikipedia](https://en.wikipedia.org/wiki/Pac-Man)
* [DEV](https://dev.to/code2bits/pac-man-patterns--ghost-movement-strategy-pattern-1k1a)
* [TodayIFoundOut](http://www.todayifoundout.com/index.php/2015/10/ghosts-pac-man-work/)
39 changes: 39 additions & 0 deletions Sketch/Blinky.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// blinky alway chase pacman
// TODO Cruise Elroy (speed increasing)
class Blinky extends Ghost {
Blinky(int i, int j){
super(i, j);
super.currentCell = array.get(i).get(j);
}

public void search() {

if(super.x % sc == 0 && super.y % sc == 0){
super.i = (int)super.y / sc;
super.j = (int)super.x / sc;

super.currentCell = array.get(super.i).get(super.j);

// when is weak and can be eaten by pacman it choses a random cell
if( (super.isWeak || super.isRecovering ) && super.isAffectedBy ){

if(super.searchingList.size() <= 2 ){
if(super.isWeak){
super.cellToFollow = super.getRandomCell();
} else if(super.isRecovering){
super.cellToFollow = super.getRandomCellFromHouse();
}
}
}
else {
// here is the specific behaviour
super.cellToFollow = pacman.currentCell;
}

AStar( super.currentCell, super.cellToFollow );
super.searchingList = path;

}
super.update();
}
}
4 changes: 3 additions & 1 deletion Sketch/Cell.pde
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
class Cell{
public int i, j;
public boolean isWall = false;
public float f = Float.MAX_VALUE, h, g;
public Cell parent;

public boolean isWall = false;
public boolean tempViz = false;

Cell(int i, int j){
this.i = i;
this.j = j;
Expand Down
44 changes: 44 additions & 0 deletions Sketch/Clyde.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Clyde search for the tile 8 away from pacman
class Clyde extends Ghost {
private int newSearch = 10;
Clyde(int i, int j){
super(i, j);
super.currentCell = array.get(i).get(j);
}

public void search() {

if(super.x % sc == 0 && super.y % sc == 0){
super.i = (int)super.y / sc;
super.j = (int)super.x / sc;

this.newSearch--;

super.currentCell = array.get(super.i).get(super.j);

// when is weak and can be eaten by pacman it choses a random cell
if( (super.isWeak || super.isRecovering ) && super.isAffectedBy ){
this.newSearch = 1;
if(super.searchingList.size() <= 2 ){
if(super.isWeak){
super.cellToFollow = super.getRandomCell();
} else if(super.isRecovering){
super.cellToFollow = super.getRandomCellFromHouse();
}
}
}
else {
// here is the specific behaviour
if(this.newSearch == 0){
super.cellToFollow = super.getCellInFrontOf(12);
this.newSearch = 10;
}
}

AStar( super.currentCell, super.cellToFollow );
super.searchingList = path;

}
super.update();
}
}
36 changes: 0 additions & 36 deletions Sketch/Destroyer.pde

This file was deleted.

99 changes: 70 additions & 29 deletions Sketch/Ghost.pde
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,35 @@ import java.util.List;

class Ghost {
public float x, y;
private List<Cell> searchingList;
private int dirX = 1, dirY = 0;
public int i, j;
private float speed = 2.5;
private int i, j;
private int dirX = 1, dirY = 0;
private int r, g, b;
private Cell cellToFollow;
private List<Cell> homeCells;
private Cell currentCell;
private Cell currentCell, cellToFollow;
private List<Cell> searchingList, ghostHouseCells;

public boolean isWeak = false;
public boolean isRecovering = false;

public boolean isAffectedBy = false;

// the weak time is controled by pacman.isInvincible
private int recoveringCountDowm = 720;// 12 sec

Ghost(int x, int y){
this.x = x;
this.y = y;

Ghost(int i, int j){
this.x = j * sc;
this.y = i * sc;
this.searchingList = new ArrayList<Cell>();
this.cellToFollow = this.getRandomCell();
this.homeCells = new ArrayList<Cell>();
this.ghostHouseCells = new ArrayList<Cell>();

for(int i = 13; i <= 15; i++){
for(int j = 11; j <= 16; j ++){
this.homeCells.add( array.get(i).get(j) );
for(int k = 13; k <= 15; k++){
for(int l = 11; l <= 16; l ++){
this.ghostHouseCells.add( array.get(k).get(l) );
}
}
}

private void update(){
if(this.x % sc == 0 && this.y % sc == 0){
//search is called first so it's irrelevant
// i = (int)this.y / sc;
// j = (int)this.x / sc;

Cell up = null, left = null, down = null, right = null;
try{
Expand Down Expand Up @@ -79,9 +72,8 @@ class Ghost {

}

// for a bug, if not i think there is a 50% chance
if(this.x % 2.5 == 0 && this.y % 2.5 == 0){
if( (this.isWeak || this.isRecovering) && this.isAffectedBy){// TODO
if( (this.isWeak || this.isRecovering) && this.isAffectedBy){
this.speed = 1.25;
} else{
this.speed = 2.5;
Expand All @@ -90,7 +82,7 @@ class Ghost {

if(this.isRecovering){
if(this.recoveringCountDowm == 0){
println("stops recovering");
//println("Stop Recovering");
this.recoveringCountDowm = 720;
this.isRecovering = false;
this.isAffectedBy = false;
Expand Down Expand Up @@ -122,26 +114,26 @@ class Ghost {

public void makeWeak(){
if(!this.isWeak && this.isAffectedBy){
println("ghost weak");
//println("Ghost Weak");
this.cellToFollow = this.getRandomCell();
this.isWeak = true;
}
}

public void makeNormal(){
if(this.isWeak){
println("ghost normal");
//println("Ghost Normal");
this.isWeak = false;
this.isAffectedBy = false;
}
}

public void retreat(){
if(!this.isRecovering && this.isAffectedBy){
println("ghost retreat");
//println("Ghost Retreat");
this.isRecovering = true;
this.isWeak = false;
this.cellToFollow = this.getRandomCellFromHome();
this.cellToFollow = this.getRandomCellFromHouse();
}
}

Expand All @@ -166,6 +158,7 @@ class Ghost {
}
line(current.x , current.y , next.x , next.y );
}

}

private Cell getRandomCell(){
Expand All @@ -180,9 +173,57 @@ class Ghost {
return c;
}

private Cell getRandomCellFromHome(){
int n = (int)random(0, this.homeCells.size());
return this.homeCells.get(n);
private Cell getRandomCellFromHouse(){
int n = (int)random(0, this.ghostHouseCells.size());
return this.ghostHouseCells.get(n);
}

private Cell getCellInFrontOf(int n){
List<Cell> positions = new ArrayList<Cell>();
int i = pacman.i + pacman.dirY;
int j = pacman.j + pacman.dirX;

Cell initial = array.get(pacman.i).get(pacman.j);
Cell root = array.get(i).get(j);
Cell c = null;

for(int l = 1; l <= n; l ++){
positions.clear();
try{
c = array.get(root.i - 1).get(root.j);
if(!c.isWall)
positions.add( c );
} catch (Exception e){}
try{
c = array.get(root.i).get(root.j - 1);
if(!c.isWall)
positions.add( c );
} catch (Exception e){}
try{
c = array.get(root.i + 1).get(root.j);
if(!c.isWall)
positions.add( c );
} catch (Exception e){}
try{
c = array.get(root.i).get(root.j + 1);
if(!c.isWall)
positions.add( c );
} catch (Exception e){}

positions.remove(initial);
initial = root;

int x = (int)random(0, positions.size());
try{
root = positions.get(x);
} catch(Exception e){
root = this.getRandomCell();
break;
}
}
// fill(255, 0, 0);
// rect(root.j * sc, root.i * sc, sc, sc);
return root;
}

}
46 changes: 46 additions & 0 deletions Sketch/Inky.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Inky is dummy
class Inky extends Ghost{
Inky(int x, int y){
super(x, y);
}

public void search() {

if(super.x % sc == 0 && super.y % sc == 0){
super.i = (int)super.y / sc;
super.j = (int)super.x / sc;

super.currentCell = array.get(super.i).get(super.j);

// when is weak and can be eaten by pacman it choses a random cell
if( (super.isWeak || super.isRecovering ) && super.isAffectedBy ){

if(super.searchingList.size() <= 2 ){
if(super.isWeak){
super.cellToFollow = super.getRandomCell();
} else if(super.isRecovering){
super.cellToFollow = super.getRandomCellFromHouse();
}
}
}
else {
// here is the specific behaviour
int possibleI = 2 * pacman.i - blinky.i;
int possibleJ = 2 * pacman.j - blinky.j;
// for the explanation of what he follows search it on Google
try{
if( !array.get(possibleI).get(possibleJ).isWall )
super.cellToFollow = array.get(possibleI).get(possibleJ);
} catch(Exception e){
if(super.searchingList.size() <= 2)
super.cellToFollow = super.getRandomCell();
}
}

AStar( super.currentCell, super.cellToFollow );
super.searchingList = path;

}
super.update();
}
}
Loading

0 comments on commit 3133549

Please sign in to comment.