Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Please help me with collisions  (Read 1929 times)
0 Members and 1 Guest are viewing this topic.
Offline examorph

Senior Newbie





« Posted 2012-12-09 13:44:36 »

I am fairly new to Java and after studying most of the basics I started making a 2D state change game with the help of online tutorials, the game is a simple car racing game with a overhead view kind of like pokemon, with simple left right forward backward and diagonal movements. I have got everything I need and have written most of the code but am stuck with collisions. I understand the basic concept of setting up collisions (or at least I think I do) and the way I have seen it done in the past is you set a rectangle around the car and a rectangle around the object on the map and set an if statement saying if intersects change direction to - or something similar to that, but am having trouble putting this into my code and am hoping some of the more experienced users could help me out, the code for my game is shown below, I have not posted things like the menu class and the main class just because it would overcrowd things, but if needed please tell me.

The collision I want to set is a rectangle at coordinates:

Top left: -115, -100
Top right: -360, -100
Bottom right: -360, -280
Bottom left: -115, -280

and the rectangle of my car which is a 40x40 image.

I would just like this one collision to be explained to me or shown to me in my code and I will be able to set all the others on my own with the knowledge I gain from this one.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
package javagame;
 
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;
 
public class Play extends BasicGameState{
         
    Animation bucky, movingUp, movingDown, movingLeft, movingRight, movingBL, movingBR, movingFL, movingFR;
    Image worldMap;
    boolean quit = false;//gives user to quit the game
   int[] duration = {200, 200};//how long frame stays up for
   float buckyPositionX = 0;
    float buckyPositionY = 0;
    float shiftX = buckyPositionX + 320;//keeps user in the middle of the screem
   float shiftY = buckyPositionY + 160;//the numbers are half of the screen size
       
    public Play(int state){
    }  
    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
          worldMap = new Image("res/world.png");
          Image[] walkUp = {new Image("res/b.png"), new Image("res/b.png")}; //these are the images to be used in the "walkUp" animation
         Image[] walkDown = {new Image("res/f.png"), new Image("res/f.png")};
          Image[] walkLeft = {new Image("res/l.png"), new Image("res/l.png")};
          Image[] walkRight = {new Image("res/r.png"), new Image("res/r.png")};
          Image[] walkBL = {new Image("res/bl.png"), new Image("res/bl.png")};
          Image[] walkBR = {new Image("res/br.png"), new Image("res/br.png")};
          Image[] walkFL = {new Image("res/fl.png"), new Image("res/fl.png")};
          Image[] walkFR = {new Image("res/fr.png"), new Image("res/fr.png")};
     
    movingUp = new Animation(walkUp, duration, false);
    movingDown = new Animation(walkDown, duration, false);  
    movingLeft = new Animation(walkLeft, duration, false);  
    movingRight = new Animation(walkRight, duration, false);
    movingBL = new Animation(walkBL, duration, false);
    movingBR = new Animation(walkBR, duration, false);
    movingFL = new Animation(walkFL, duration, false);
    movingFR = new Animation(walkFR, duration, false);
    bucky = movingDown;//facing screen initially on startup
   }
     
     
    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
    worldMap.draw(buckyPositionX, buckyPositionY);//position 0,0
   bucky.draw(shiftX, shiftY);//makes him appear at center of map
   g.drawString("Suraj's X: "+buckyPositionX+"\nSuraj's Y: "+buckyPositionY,400,20);//tells us the position
   
    if(quit==true){
        g.drawString("Resume(R)", 250, 100);
        g.drawString("Main(M)", 250, 150);
        g.drawString("Quit Game(Q)", 250, 200);
        if(quit==false){
            g.clear();//wipe off everything from screen
       }
    }
    }
     
    public void update(GameContainer gc, StateBasedGame sbg, int delta)throws SlickException{
    Input input = gc.getInput();
    //up
   if(input.isKeyDown(Input.KEY_UP)){
        bucky = movingUp;//changes the image to his back
       buckyPositionY += 10;;//increase the Y coordinates of bucky (move him up)
       if(buckyPositionY>162){//if I reach the top
           buckyPositionY -= 10;//stops any further movement in that direction
       }
    }
     
    //down
   if(input.isKeyDown(Input.KEY_DOWN)){
        bucky = movingDown;
        buckyPositionY -= 10;
        if(buckyPositionY<-600){
            buckyPositionY += 10;//basically change the direction if + make -
   }}
    //left
   if(input.isKeyDown(Input.KEY_LEFT)){
        bucky = movingLeft;
        buckyPositionX += 10;
        if(buckyPositionX>324){
            buckyPositionX -= 10;//delta * .1f
   }}
    //right
   if(input.isKeyDown(Input.KEY_RIGHT)){
        bucky = movingRight;
        buckyPositionX -= 10;
        if(buckyPositionX<-840){
            buckyPositionX += 10;
    }}
     
     
     
     
    //2 key combos start here
   if(input.isKeyDown(Input.KEY_RIGHT) && input.isKeyDown(Input.KEY_UP)){
        bucky = movingBR;
        buckyPositionX -= delta * .1f;
        if(buckyPositionX<-840){
            buckyPositionX += delta * .1f;
            if(buckyPositionY>162){
                buckyPositionY -= delta * .1f;
            }}}
    if(input.isKeyDown(Input.KEY_LEFT) && input.isKeyDown(Input.KEY_UP)){
        bucky = movingBL;
        buckyPositionX -= delta * .1f;
        if(buckyPositionX>324){
            buckyPositionX -= delta * .1f;
            if(buckyPositionY>162){
                buckyPositionY -= delta * .1f;
            }}}
    if(input.isKeyDown(Input.KEY_RIGHT) && input.isKeyDown(Input.KEY_DOWN)){
        bucky = movingFR;
        buckyPositionX -= delta * .1f;
        if(buckyPositionY<-600){
            buckyPositionY += delta * .1f;
            if(buckyPositionX<-840){
                buckyPositionX += delta * .1f;
            }}}
    if(input.isKeyDown(Input.KEY_LEFT) && input.isKeyDown(Input.KEY_DOWN)){
        bucky = movingFL;
        buckyPositionX -= delta * .1f;
        if(buckyPositionY<-600){
            buckyPositionY += delta * .1f;
            if(buckyPositionX>324){
                buckyPositionX -= delta * .1f;
            }}}
     
     //escape
   if(input.isKeyDown(Input.KEY_ESCAPE)){
        quit=true;
    }
    //when the menu is up
   if(quit==true){//is the menu on the screen
       if(input.isKeyDown(Input.KEY_R)){
            quit = false;//resumes the game, makes menu dissapear
       }
        if(input.isKeyDown(Input.KEY_M)){
            sbg.enterState(0);//takes you to the main menu
       }
        if(input.isKeyDown(Input.KEY_Q)){
            System.exit(0);//quits the game
       }
    }
     
}
     
    public int getID(){
        return 1;
    }
}


Thank you for your help in advance.
Offline P0jahn

Senior Member


Projects: 3



« Reply #1 - Posted 2012-12-09 15:02:05 »

There is a super fast rectangle-vs-rectangle collision algorithm here:
http://www.gamedev.net/page/resources/_/technical/game-programming/collision-detection-r735
Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 128
Projects: 4
Exp: 3 years



« Reply #2 - Posted 2012-12-09 16:50:13 »

Pokemon is not a true top down game, just saying. Viewpoint is angled 45 degrees back.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline examorph

Senior Newbie





« Reply #3 - Posted 2012-12-10 20:39:08 »

Thank you for the replies.

P0jahn then link you had posted seems very interesting and helpful but as I am a noob with Java I am having a hard time understanding exactly what I have to do, I would like to use the first code on the website (which seems to be the simplest):

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
// Object-to-object bounding-box collision detector:
short int Sprite_Collide(sprite_ptr object1, sprite_ptr object2) {
   
    int left1, left2;
    int right1, right2;
    int top1, top2;
    int bottom1, bottom2;
 
    left1 = object1->x;
    left2 = object2->x;
    right1 = object1->x + object1->width;
    right2 = object2->x + object2->width;
    top1 = object1->y;
    top2 = object2->y;
    bottom1 = object1->y + object1->height;
    bottom2 = object2->y + object2->height;
 
    if (bottom1 < top2) return(0);
    if (top1 > bottom2) return(0);
 
    if (right1 < left2) return(0);
    if (left1 > right2) return(0);
 
    return(1);
 
};


Am I correct in thinking object one and object two are the two rectangles that I need to make around my player and the house on the map? If so, how exactly do I make these rectangles and where do I place the code above and the rectangle code in my code(under the render method, update method or something else)?

Also, would this code work if I wanted to set up more than one collision, for example my map contains many houses, would this code work for that or would a Recatngle getBound() type method with a if (intersects) way work better? (I dont really know either of them two very well but types of code have seen a bit of both done before)

I am sorry for asking all these questions which may seem very easy to you, I am new with Java and might take a while to understand simple things. Thank you.
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #4 - Posted 2012-12-10 21:13:42 »

I guess.. simply, this is the exact same method written in java, which I use, and it's working:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public static boolean rectVsRect(Rect r1, Rect r2) {
   // Sperating axis theorem simplified for AABBes.
  if ((r1.x >= (r2.x + r2.w)) || ((r1.x + r1.w) <= r2.x)) {
      return false;
   }
   if ((r1.y >= (r2.y + r2.h)) || ((r1.y + r1.h) <= r2.y)) {
      return false;
   }
   return true;
}


This is the fastest AABB vs AABB collision detection algorithm known to me, so... yeah Smiley It's just the same as the C++ version above, but implemented in java without this redunant int allocations Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #5 - Posted 2012-12-10 21:18:03 »

I guess.. simply, this is the exact same method written in java, which I use, and it's working:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public static boolean rectVsRect(Rect r1, Rect r2) {
   // Sperating axis theorem simplified for AABBes.
  if ((r1.x >= (r2.x + r2.w)) || ((r1.x + r1.w) <= r2.x)) {
      return false;
   }
   if ((r1.y >= (r2.y + r2.h)) || ((r1.y + r1.h) <= r2.y)) {
      return false;
   }
   return true;
}


This is the fastest AABB vs AABB collision detection algorithm known to me, so... yeah Smiley It's just the same as the C++ version above, but implemented in java without this redunant int allocations Smiley

If you have a tile map you can do it even quicker. (when colliding with the tile map)
Just cast the coords of each corner to ints, and check those points to see if they equal the tile coords.

This got me thinking if it was possible to do the same, but to scale/translate the coords of one rectangle and then do the same method as above.

Anyone done this before?

Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #6 - Posted 2012-12-10 21:24:10 »

I guess.. simply, this is the exact same method written in java, which I use, and it's working:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public static boolean rectVsRect(Rect r1, Rect r2) {
   // Sperating axis theorem simplified for AABBes.
  if ((r1.x >= (r2.x + r2.w)) || ((r1.x + r1.w) <= r2.x)) {
      return false;
   }
   if ((r1.y >= (r2.y + r2.h)) || ((r1.y + r1.h) <= r2.y)) {
      return false;
   }
   return true;
}


This is the fastest AABB vs AABB collision detection algorithm known to me, so... yeah Smiley It's just the same as the C++ version above, but implemented in java without this redunant int allocations Smiley

If you have a tile map you can do it even quicker. (when colliding with the tile map)
Just cast the coords of each corner to ints, and check those points to see if they equal the tile coords.

This got me thinking if it was possible to do the same, but to scale/translate the coords of one rectangle and then do the same method as above.

Anyone done this before?

Yes I do do what you suggested at first Wink
this would be done like that:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
public static int clamp(int val, int min, int max) {
    return Math.max(Math.min(val, max), min);
}

public static boolean collidesWithMap(Map map, Rect rect) {
    int beginx = ((int) rect.x) / map.getTileWidth();
    int beginy = ((int) rect.y) / map.getTileHeight();
    int endx = ((int) rect.x + rect.w) / map.getTileWidth() + 1;
    int endy = ((int) rect.y + rect.h) / map.getTileHeight() + 1;
    // Clamp the values to the map's dimensions:
   beginx = clamp(beginx, 0, map.getWidth());
    beginy = clamp(beginy, 0, map.getHeight());
    endx = clamp(endx, 0, map.getWidth());
    endy = clamp(endy, 0, map.getHeight());
    // Iterate over the found "possible" tile positions:
   for (int y = beginy; y < endy; y++) {
        for (int x = beginx; x < endx; x++) {
            if (map.getTile(x, y) != null) { // or something like: map.isTileAt(x, y), which should return a boolean then
               return true;
            }
        }
    }
}

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline examorph

Senior Newbie





« Reply #7 - Posted 2012-12-10 21:51:43 »

Thank you for the help, Matheus23, the code you ave shown in your post:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public static boolean rectVsRect(Rect r1, Rect r2) {
   // Sperating axis theorem simplified for AABBes.
  if ((r1.x >= (r2.x + r2.w)) || ((r1.x + r1.w) <= r2.x)) {
      return false;
   }
   if ((r1.y >= (r2.y + r2.h)) || ((r1.y + r1.h) <= r2.y)) {
      return false;
   }
   return true;
}


How do I put this code into my code and how do I set up my r1 and r2 to be my player(the car) and the collision (the house)?
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #8 - Posted 2012-12-10 21:55:02 »

Basically, I have this 'Rect' class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
public class Rect {

   public float x;
   public float y;
   public float w;
   public float h;

   public Rect() {
      set(0, 0, 1, 1);
   }

   public Rect(float w, float h) {
      set(0, 0, w, h);
   }

   public Rect(float x, float y, float w, float h) {
      set(x, y, w, h);
   }

   public Rect set(float x, float y, float w, float h) {
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;

      return this;
   }

   public float right() {
      return x + w;
   }

   public float bottom() {
      return y + h;
   }

}


Then you'd need to create a Rect for your car and a Rect for your house. You have to position the rects to match the positions and sizes of the car / house, and then you'd check collisions with the method I gave you Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline examorph

Senior Newbie





« Reply #9 - Posted 2012-12-10 22:39:37 »

Thank you for helping me Matheus23, I am sorry for asking noob questions but could you please tell me how I would continue after making the Rect class please, I think I have a basic Idea of what I need to do but keep messing up, so to start off, is this how I would make the rectangles:
1  
2  
3  
public Rectangle getBounds() {
     return new r1(x, y, width, height);//I would set this as r1 for the car and r2 for the house?
}


So I would make 2 of the above code, 1 for the house and one for the car, but would I have to make a object of the Rect class to be able to do this? Also, under what section of code would I place this, would it be under my Render method or my Update method or something else?

The I would have to place your if statement into my code, but again,where would this be placed(in the render, update, other)?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #10 - Posted 2012-12-11 02:21:09 »

1  
2  
3  
4  
5  
    // Clamp the values to the map's dimensions:
   clamp(beginx, 0, map.getWidth());
    clamp(beginy, 0, map.getHeight());
    clamp(endx, 0, map.getWidth());
    clamp(endy, 0, map.getHeight());

This code does nothing... better fix it! persecutioncomplex

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #11 - Posted 2012-12-11 05:27:38 »

I guess.. simply, this is the exact same method written in java, which I use, and it's working:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public static boolean rectVsRect(Rect r1, Rect r2) {
   // Sperating axis theorem simplified for AABBes.
  if ((r1.x >= (r2.x + r2.w)) || ((r1.x + r1.w) <= r2.x)) {
      return false;
   }
   if ((r1.y >= (r2.y + r2.h)) || ((r1.y + r1.h) <= r2.y)) {
      return false;
   }
   return true;
}


This is the fastest AABB vs AABB collision detection algorithm known to me, so... yeah Smiley It's just the same as the C++ version above, but implemented in java without this redunant int allocations Smiley

Haha! I made a quicker collision detection method than you. Cool Grin (not referring to my previous post)

My entities have their coords in the centre, and their size value is half the real size.
1  
2  
3  
4  
//Like this
leftSide = pos.x - size.x;
rightSide = pos.x + size.x;
//And so on for y coords


So collision detection is similar to circles (but with 2 checks (for each axis))

1  
2  
3  
4  
if(Math.abs(pos.x-other.pos.x) < size.x + other.size.x)
{
//Do same for Y axis
}


Only 2 checks.

Beat that!

Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #12 - Posted 2012-12-11 07:24:13 »

You don't need pastebin for short code.  Pointing

Offline examorph

Senior Newbie





« Reply #13 - Posted 2012-12-11 11:50:01 »

Can anyone please tell me how to make a rectangle around my player and my house, am I supposed to use the code bellow?

1  
2  
3  
public Rectangle getBounds() {
     return new r1(x, y, width, height);//not too sure if this is supposed to be r1
}


If so, where do I place this code in my code?
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #14 - Posted 2012-12-11 14:05:46 »

nah, since "Rect" is a class, it's supposed to be
new Rect(...)
...

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline examorph

Senior Newbie





« Reply #15 - Posted 2012-12-11 14:50:11 »

Then how does java know the difference between 2 different rectangles, I mean if I say that code twice (1 for the house 1 for the car) how will java know what r1 is and what r2 is?
Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #16 - Posted 2012-12-11 15:01:31 »

Then how does java know the difference between 2 different rectangles, I mean if I say that code twice (1 for the house 1 for the car) how will java know what r1 is and what r2 is?

I gave you this method:
public static boolean rectVsRect(Rect r1, Rect r2) { ... }
. You can invoke this method using
boolean houseAndCarColliding = rectVsRect(houseRect, carRect);
.

Then how do you get houseRect and carRect? Simply create them as a class member:
1  
2  
public Rect houseRect = new Rect([insert house-x-position], [insert house-y-position], [insert house-width], [insert house-height]);
public Rect carRect = new Rect([insert car-x-position], [insert car-y-position], [insert car-width], [insert car-height]);


But the questions you've asked seem to be a bit more about java itself... probably you should read some more tutorials or source code in java.

1  
2  
3  
4  
5  
    // Clamp the values to the map's dimensions:
   clamp(beginx, 0, map.getWidth());
    clamp(beginy, 0, map.getHeight());
    clamp(endx, 0, map.getWidth());
    clamp(endy, 0, map.getHeight());

This code does nothing... better fix it! persecutioncomplex
:& Fixing... (*forgets things when he doesn't test code...*  persecutioncomplex )

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (24 views)
2014-08-22 19:31:30

atombrot (34 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (28 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (27 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (33 views)
2014-08-08 02:01:56

Norakomi (42 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!