コンテンツにスキップ

迷路ゲーム

Processingで迷路ゲーム

プログラム難易度は高いので教材として解説はしないけど、遊べるので貼っておく。 ランダムで作られる迷路だけど、何度プレイしても同じ迷路ができあがるように工夫。

img01.png

class Player{
public float x;
public float y;
public PVector direction = new PVector(0, 0);
}
class GameData{
public int level = 1;
}
Player player;
GameData gameData;
MazeLogic.Block[] blocks;
PVector cameraPosition = new PVector(0, 0);
void setup(){
size(600, 400);
player = new Player();
gameData = new GameData();
createMaze();
MazeLogic.Block firstBlock = MazeLogic.getBlockFromType(blocks, 11);
player.x = firstBlock.x * 50 + 10;
player.y = firstBlock.y * 50 + 10;
}
void draw(){
background(0);
PVector prevPosition = new PVector(player.x, player.y);
player.x += player.direction.x * 5;
player.y += player.direction.y * 5;
for(int i=0; i<blocks.length; i++){
MazeLogic.Block b = blocks[i];
int x = b.x * 50;
int y = b.y * 50;
if(isHit(player.x, player.y, 30, 30, x, y, 50, 50)){
if(b.type == 0){
player.x = prevPosition.x;
player.y = prevPosition.y;
}
if(b.type == 31){
gameData.level += 1;
createMaze();
MazeLogic.Block firstBlock = MazeLogic.getBlockFromType(blocks, 11);
player.x = firstBlock.x * 50 + 10;
player.y = firstBlock.y * 50 + 10;
}
}
if(b.type == 0){
fill(255);
}
if(b.type == 1){
fill(0);
}
if(b.type == 11){
fill(0);
}
if(b.type == 21){
fill(0);
}
if(b.type == 31){
fill(0, 0, 255);
}
rect(getPosition(x, cameraPosition.x), getPosition(y, cameraPosition.y), 50, 50);
}
fill(255);
rect(getPosition(player.x, cameraPosition.x), getPosition(player.y, cameraPosition.y), 30, 30);
textAlign(RIGHT, CENTER);
fill(255, 0, 0);
textSize(60);
text(gameData.level + "F", 550, 50);
cameraPosition.x = player.x - width/2;
cameraPosition.y = player.y - height/2;
}
float getPosition(float value, float camera){
return value - camera;
}
void createMaze(){
int x = gameData.level + 5;
int y = gameData.level + 5;
if(x % 2 == 0){
x += 1;
y += 1;
}
MazeLogic.setApp(this);
MazeLogic.setSeed(gameData.level);
blocks = MazeLogic.makeMaze(x, y);
}
void keyPressed(){
if(keyCode == UP) player.direction.y = -1;
if(keyCode == DOWN) player.direction.y = 1;
if(keyCode == RIGHT) player.direction.x = 1;
if(keyCode == LEFT) player.direction.x = -1;
}
void keyReleased(){
if(keyCode == UP) player.direction.y = 0;
if(keyCode == DOWN) player.direction.y = 0;
if(keyCode == RIGHT) player.direction.x = 0;
if(keyCode == LEFT) player.direction.x = 0;
}
boolean isHit(float px, float py, float pw, float ph, float ex, float ey, float ew, float eh){
if(px < ex + ew && px + pw > ex){
if(py < ey + eh && py + ph > ey){
return true;
}
}
return false;
}
static class MazeLogic{
static PApplet app;
public static void setApp(PApplet app){
MazeLogic.app = app;
}
public static Block[] makeMaze(int W, int H){
int SIZE = W * H;
Block[] blocks = new Block[SIZE];
int index = 0;
for(int y=0; y<H; y++){
for(int x=0; x<W; x++){
Block b = new Block();
b.x = x;
b.y = y;
b.type = 0;
blocks[index] = b;
index += 1;
}
}
int startX = getRand(W);
int startY = getRand(H);
Block startBlock = searchBlock(blocks, startX, startY);
startBlock.type = 11;
IrAnahori(blocks, startBlock, 0);
Block goalBlock = null;
for(int i=0; i<blocks.length; i++){
Block b = blocks[i];
if(b.type != 21) continue;
if(goalBlock == null){
goalBlock = b;
}else{
if(b.index > goalBlock.index){
goalBlock = b;
}
}
}
goalBlock.type = 31;
return blocks;
}
public static void setSeed(int seed){
app.randomSeed(seed);
}
public static Block getBlockFromType(Block[] blocks, int type){
for(int i=0; i<blocks.length; i++){
if(blocks[i].type == type){
return blocks[i];
}
}
return null;
}
static void IrAnahori(Block[] blocks, Block parent, int index){
PVector[] directions = makeDirections();
directions = shuffleDirections(directions);
boolean isStop = true;
for(int i=0; i<directions.length; i++){
int x = (int)directions[i].x * 2 + parent.x;
int y = (int)directions[i].y * 2 + parent.y;
Block b = searchBlock(blocks, x, y);
if(b == null) continue;
if(b.type != 0) continue;
b.type = 1;
b.index = index + 1;
int _x = (int)directions[i].x + parent.x;
int _y = (int)directions[i].y + parent.y;
Block _b = searchBlock(blocks, _x, _y);
_b.type = 1;
_b.index = index + 1;
IrAnahori(blocks, b, index + 1);
isStop = false;
}
if(isStop){
parent.type = 21;
}
}
static int getRand(int max){
for(int i=0; i<10; i++){
int r = (int)app.random(0, max);
if(r % 2 == 1) return r;
}
return 1;
}
static Block searchBlock(Block[] blocks, int x, int y){
for(int i=0; i<blocks.length; i++){
Block b = blocks[i];
if(b.x == x && b.y == y){
return b;
}
}
return null;
}
static PVector[] shuffleDirections(PVector[] directions){
for(int i=0; i<10; i++){
int from = (int)app.random(0, directions.length);
int to = (int)app.random(0, directions.length);
PVector temp = directions[from];
directions[from] = directions[to];
directions[to] = temp;
}
return directions;
}
static PVector[] makeDirections(){
PVector[] directions = new PVector[4];
directions[0] = new PVector(0, 1);
directions[1] = new PVector(1, 0);
directions[2] = new PVector(0, -1);
directions[3] = new PVector(-1, 0);
return directions;
}
static class Block{
public int index;
public int x;
public int y;
public int type;
}
}