We are about to switch to a new forum software. Until then we have removed the registration on this forum.
so, i want to make a game about push box. which when the ellipse touch the box, the box will move. i don't know how to make the ellipse and box interact each other. can anyone please help me? thank you very much
float oX = 250; float oY = 250; PFont font; String time = "030"; int t; int interval = 30;
float speed = 2;
boolean upPressed = false; boolean downPressed = false; boolean leftPressed = false; boolean rightPressed = false; void setup(){ size (400,450); font = createFont("Arial", 10); background(255); fill(0); }
void draw(){
if (upPressed) { oY -= speed; } if (downPressed) { oY += speed; } if (leftPressed) { oX -= speed; } if (rightPressed) { oX += speed; } background(255);
ellipse(oX, oY, 40,40); rect(95,200,50,50); rect(35,255,50,50); rect(200,255,50,50); rect(145,310,50,50);
t = interval-int(millis()/1000);
time = nf(t , 2);
if(t == 0){
textSize(32);
text("GAME OVER",10,30);
}
text(time, 100, 100);
strokeWeight(3); line(90,150,150,150); line(150,150,150,250); line(150,250,300,250); line(300,250,300,310); line(300,310,200,310); line(200,310,200,410); line(200,410,140,410); line(140,410,140,310); line(140,310,1,310); line(1,310,1,250); line(1,250,90,250); line(90,250,90,150);
} void keyPressed(KeyEvent e) { if (key == CODED) { if (keyCode == UP) { upPressed = true; } else if (keyCode == DOWN) { downPressed = true; } else if (keyCode == LEFT) { leftPressed = true; } else if (keyCode == RIGHT) { rightPressed = true; } } }
void keyReleased(KeyEvent e) { if (key == CODED) { if (keyCode == UP) { upPressed = false; } else if (keyCode == DOWN) { downPressed = false; } else if (keyCode == LEFT) { leftPressed = false; } else if (keyCode == RIGHT) { rightPressed = false; } } }
Answers
you use variables for the position of the ellipse
you have to do the same with the rects so that you can recalculate the position of the rects when the ball is pushing them
To achieve this, I use the data type
PVector
for the 4 rects (see reference)the collision is in the part collision which gets all 4 rects as a parameter
later you want to have them in an array
game over
also I introduced the var
gameOver
and some related code lines to reset the thing with space bargrid
if you had a grid underneath we could let the boxes move like on tracks and stop at the black lines
we'll come to that later
Best, Chrisir ;-)
Hello Chrisir,
thank you so much for your kind reply! I really appreciate it as i now understand the use of new codes you showed me! i've made the grid on size 500,500 to be put underneath so we could let the box stay on track and stopping at the black lines. because when i applied grid with my code, there's error about void keyReleased(KeyEvent e). would you like to help? Once again, thank you so much for your help!
int horizontal = 10; int vertical = 10;
void setup() { size (500,500); }
void draw() { background (255); stroke(0);
float jhorizontal = (float)height/horizontal; float jvertical = (float)width/vertical;
for(int i = 0; i < horizontal; i++) { line(0, ijhorizontal, width, ijvertical);
}
for(int i = 0; i < vertical; i++) { line (ijhorizontal,0,ijvertical, height); } }
Explanation line 165 to 175
1st we check if on y axis the ellipse is next to the rect with
>
and<
2nd on x axis if it's next to the box
if so we move the box
We have to say
/2
sometimes to convert the diameter to radiushere's the right code for the grid, i mistakenly type int horizontal = 10; int vertical = 10;
thank you for your explanation !
You need to look at arrays
when you store the data (where is wall, where is a corridor for the box) you can check those data I guess
Especially when you plan to have multiple levels, we could make a grid that knows the position of the boxes and the position of the walls etc. for every level
what is the goal of the game please?
I thought of a way to win.
there is a small weapon shooting (or lamp emitting light)
when the light / laser beams / bullets reach the target on the left, you win.
Now you need to move the boxes out of the way between laser and target
;-)
hello chris, sorry for late reply and thanks for your helped :> :> . so the goal is to move the boxes in the proper place, there's a red ellipse in each corner (right place). then you will go to the next level. my question is how to make a border, so the ball and the box can't cross the line. i already made the line like maze. and how to stop the timer when you already achieved the quest.
first, you can use ctrl-t in processing to auto-format your code.
This is especially useful for indents.
second, I asked quark about your "box need to stay inside the lines"-issue and here is what he wrote:
third, you wrote:
I recommend a new var
questAchieved
similar togameOver
don't increase the timer when
questAchieved == true
since I haven't understood quarks idea, I made a full new version, based on a grid
Now, what do I mean with a grid?
I don't mean single lines that look like a grid.
I mean a grid of data. The grid is like a chess board.
Each field / cell / Tile of it has a position and a size (size is the same for all).
This grid gives us our level.
So instead of drawing the lines and the blocks and the targets, we draw the grid. Each cell in the grid shows itself as a target or a wall or so. It's a huge different.
The grid knows for each of it's field whether it holds a
corridor
a wall
a target
a block (moveable)
an ellipse (we move it with cursor keys)
Now, when we move the ellipse, we in fact just copy it to the next field in the grid (up, down, left or right) and delete the ellipse from the field it was before (meaning we set the field back to be a corridor). We change the grid holding the data (wall, ellipse...).
Now, in a program, the grid (chess board) is a 2D array (there is a tutorial on that). Each cell / Tile is an object from the class Tile (object oriented programming is another concept. There is a tutorial for that too. It means, we can make a package of data, like a package of data for a tile).
A Tile in turn has a lot of properties, position, size and type (which is target, wall etc. )
Now, I invented a list of strings to define our level :
we read that string and copy each letter into our tiles as its type.
You can recognize your level when you see, w is wall, t is target, b is block, e is ellipse... c corridor
it is a simple trick to store data about the level as a map.
I hope this helps you a bit.
Best, Chrisir ;-)
P.S.
stuff to work on: you can't currently make a level where the ellipse is initially on a target field. Bad.
you can crash the sketch when you push a block over the edge. We could just surround the field with walls to avoid this.
small improvements
key UP is now better than the others
new version with a new level and some improvements in the code
i try to understand your code, but i can't get it espescially in the void build thegrid :((. is it possible to make a multilevel? if it's possible can you teach me ? like when the boxes already in the proper place, then we will go to the next level.
this is level 1 float oX = 170; float oY = 275;
and this is level 2
im so sorry if i asked you too much questions :((
do you interact with the lines? the walls I mean?
i have to , but i will think another way, like if the ball cross the line then the timer will reduce for 7 seconds. because if i built the grid like you teach me, it just too deep for me and i can't understand :( i think if i reduce the timer it will make the code more simple.
quark told you... but his way is hard.....
see, you need a counter that tells you in which level you are. depending on this, draw the lines. And do the text() about the level number.
but you draw the lines but they are not in data, so they are hard to interact with.
the grid is better solution
I can explain the grid later
A new idea would be that you
send out test beams from the block to detect lines.
Let me explain. When you push the block left it sends out 2 beams from the 2 left corners to the left. With get() the beams grab the color. If it's black, stop (or set a var tell it to stop).
The beam is of course invisible it's just a for-loop with i and the get is like
Color colGet = get(r1.x-i, r1.y);
etc.
The grid....
now imagine a chess board
In build grid we define each field of it.
That's the line with new.
Here we also give the new tile a Position and size and type.
The Double for loop in build grid is there to cover the entire chessboard, basically rows and columns.
with grid[][] we can access a single field by passing column number and row number to it
i already get what you tried to explain in this code
i wanna ask about the function of tempside in here. and what the meaning o fchar previous type ?
float x, y; float side;
char type='u'; char previousType='u';
Tile (float tempX, float tempY, float tempSide, char tempType) { x = tempX; y = tempY; side = tempSide; type=tempType;
look! now i can build my own maze. thanks to you ! ;) // the grid (a 2D-Array) Tile[] [] grid; // grid int unit = 50; // size of one tile int wideCount = 150 ; // how many int highCount=150 ; // how many
// the coding:
// w =wall // t =target // e =ellipse (we steer it with cursor) // b =block, moveable // c =corridor, empty // u =unknown type (don't use this here)
String[] map = { "iiwtwii", "iiwcwww", "wwwbcbt", "wtcbeww", "wwwwbwi", "iiiwtwi",
};
// counter for the targets int targetCounter = 0; // current
int targetCounterMax = 4; // number of all targets in the level
// font PFont font;
// timer String time = ""; int t=0; int interval = 30; int startTime;
// game over? boolean gameOver = false;
// --------------------------------------------------------
void setup() { size (900, 550); background(255);
font = createFont("Arial", 10); fill(0);
buildTheGrid(); }
void draw() {
background(255);
if (targetCounter==targetCounterMax) { // Win !!!
} else { // normal game
}// else }//func
// ----------------------------------------------------------
void buildTheGrid() {
wideCount = map[1].length(); // the length of one String/line in the array map highCount = map.length; // how many lines in the array map
grid = new Tile[wideCount][highCount];
boolean ellipseFound=false; boolean targetFound=false;
// double for-loop for a 2D-Array for (int x=0; x< wideCount; x++) { for (int y=0; y< highCount; y++) {
}//for
}
void generalScreenDesign() {
// show grid for (int x=0; x< wideCount; x++) { for (int y=0; y< highCount; y++) { grid[x][y].display(); } }
// frame around grid noFill(); stroke(0); rect (grid[0][0].x, grid[0][0].y, 350,300); }
void keyPressed() { if (!gameOver&& targetCounter<targetCounterMax) { if (key == CODED) { if (keyCode == UP) { // push Ellipse up (y = -1) pushEllipse(0, -1); } else if (keyCode == DOWN) { // push Ellipse down (y = 1) pushEllipse(0, 1); } else if (keyCode == LEFT) { // push Ellipse left (x = -1) pushEllipse(-1, 0); } else if (keyCode == RIGHT) { // push Ellipse right (x = 1) pushEllipse(1, 0); } } } else { if (key==' ') { // reset gameOver=false; startTime=millis(); } } }
void pushEllipse( int xAdd, int yAdd ) {
// push Ellipse in a direction given by xAdd and yAdd
// get the position of the ellipse PVector pvE=ellipsePosition();
int x=int(pvE.x); int y=int(pvE.y); // test: must be an ellipse
// -----------------------------------------------------------
// if (x+xAdd<0||y+yAdd<0|| x+xAdd>wideCount-1||y+yAdd>highCount-1) return;
// test: target tile must be c, b or t if (!grid[x+xAdd][y+yAdd].allowedTileForEllipse()) return;
if (grid[x+xAdd][y+yAdd].type=='b') {
} else { // normal move if (grid[x][y].previousType!='u'&&grid[x][y].previousType!='b') grid[x][y].type=grid[x][y].previousType; else grid[x][y].type='c'; // corridor
grid[x+xAdd][y+yAdd].previousType = grid[x+xAdd][y+yAdd].type;
grid[x+xAdd][y+yAdd].type='e'; return; } }// func
PVector ellipsePosition() { for (int x=0; x< wideCount; x++) { for (int y=0; y< highCount; y++) { if ( grid[x][y].type=='e' ) { return new PVector(x, y); }// if } }
// error return null; }
// ==========================================================
class Tile {
float x, y; float side;
char type='u'; char previousType='u';
Tile (float tempX, float tempY, float tempSide, char tempType) { x = tempX; y = tempY; side = tempSide; type=tempType; }
void display() {
}// func
void corridor() { // draw corridor // (also as background for block and target etc.) fill(255); // white stroke(255); rect (x, y, side, side); }//func
boolean allowedTileForEllipse() {
}// func }//class //
i still have one questin. how to make a next level when i already put the boxes i the rght place?
You are making great progress!
This is were you win
Now here you need to wait for key press: space bar
Then say
levelNumber ++;
and reset all :
target counter , target max, timer
,define new grid with new map (wwcwwt......)
Look at states also, when you want to see a concept how to treat the different states within a program
state being game / gameover / newlevel / win etc. - all with different messages / screens
Btw you need a way go say give up, when you Can't solve it anymore you can restart level
Try search state here in the forum
Is this homework?
When do you have to hand it in?
do you mean i have to write final int stategame = 0; case stategame: like this? is it ok if i wrote final int stategame, because i have read that if we use 'final' then it will be our final. yes, i have to hand it every thursday to explain my progress with this game :)
int state = 0;
and then 1 and 2 ...
but then use
switch(state) {
indraw()
you can give the states names and then use the names instead of 0,1,2....:
etc.
then you can use those constants in
also use an
indexLevel
or so to monitor the level numberthis is a typical (empty) sketch with states
actually you don't need states - just concentrate on the different levels
I did it! Finished!
so i don't need states? function of states just for pause, start and other things right? so where i have to put my new grid (level 2) in the code?
You can go on without states
You have map={......
here you could say map1 ......
And map2........
And map3.....
Now in buildTheGrid depending on your levelNumber choose one switch(levelNumber){ ....
i already made like you said, but it wont work. in void built the grid
In line 125 you need that switch(levelNumber
like this? switch (level1){ char type = map[y].charAt(x); }
Read the reference for switch
case 0:
char......
break;
case 1:
char.....
break;
level1 is not a good name; it is levelNumber which you will increase after each level
is it right? but in widecount = map[1].length() wont resolve, under builtthegrid(){
The switch looks correct
Where do you increase levelnumber ?
There are 2 kinds of length - the one you got there is without ()
Sorry, the () is correct there, since we are using length on a String I think
but where you define the map iiiwtwi", }
the last comma is wrong (before the } )
how to increase levelnumber?
still cant resolve the
wideCount = map[1].length(); // the length of one String/line in the array map
. it says "map cannot resolved to a variable" when i add switch (levelnumber){ case 0:It's map1 or map2, not map
to increase just say levelNumber ++;
but where in the code?