Advertisement
StormWingDelta

ThreeJavaClassesIssue

Feb 23rd, 2012
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 21.12 KB | None | 0 0
  1. //The first class
  2. //Nothing wrong with this class it is just here to make it so people can test it.
  3. /**
  4.  * Write a description of class BaseGameEntity here.
  5.  *
  6.  * @author (your name)
  7.  * @version (a version number or a date)
  8.  */
  9. public class BaseGameEntity extends Object
  10. {
  11.     //variables
  12.     protected boolean alive;
  13.     protected double x, y;
  14.     protected double velX, velY;
  15.     protected double moveAngle, faceAngle;
  16.    
  17.     //accessor methods
  18.     public boolean isAlive() {return alive;}
  19.     public double getX() {return x;}
  20.     public double getY() {return y;}
  21.     public double getVelX() {return velX;}
  22.     public double getVelY() {return velY;}
  23.     public double getMoveAngle() {return moveAngle;}
  24.     public double getFaceAngle() {return faceAngle;}
  25.    
  26.     //mutator methods
  27.     public void setAlive(boolean alive) {this.alive = alive;}
  28.     public void setX(double x) {this.x = x;}
  29.     public void incX(double i) {this.x += i;}
  30.     public void setY(double y) {this.y = y;}
  31.     public void incY(double i) {this.y += i;}
  32.     public void setVelX(double velX) {this.velX = velX;}
  33.     public void incVelX(double i) {this.velX += i;}
  34.     public void setVelY(double velY) {this.velY = velY;}
  35.     public void incVelY(double i) {this.velY += i;}
  36.     public void setFaceAngle(double angle) {this.faceAngle = angle;}
  37.     public void incFaceAngle(double i) {this.faceAngle += i;}
  38.     public void setMoveAngle(double angle) {this.moveAngle = angle;}
  39.     public void incMoveAngle(double i) {this.moveAngle += i;}
  40.    
  41.     //default constructor
  42.     BaseGameEntity()
  43.     {
  44.         setAlive(false);
  45.         setX(0.0);
  46.         setY(0.0);
  47.         setVelX(0.0);
  48.         setVelY(0.0);
  49.         setMoveAngle(0.0);
  50.         setFaceAngle(0.0);
  51.     }
  52.  
  53. }
  54.  
  55. //The second class
  56.  
  57. //base game class for bitmapped entities
  58. import java.awt.*;
  59. import java.awt.geom.*;
  60. import javax.swing.*;
  61. import java.net.*;
  62. import java.applet.*;
  63. /**
  64.  * Write a description of class ImageEntity here.
  65.  *
  66.  * @author (your name)
  67.  * @version (a version number or a date)
  68.  */
  69. public class ImageEntity extends BaseGameEntity
  70. {
  71.     //variables
  72.     protected Image image;
  73.     protected JFrame frame;
  74.     protected Applet appFrame;
  75.     protected AffineTransform at;
  76.     protected Graphics2D g2d;
  77.    
  78.     //default constructor
  79.    
  80.     ImageEntity(JFrame a)
  81.     {
  82.         frame = a;
  83.         setImage(null);
  84.         setAlive(true);
  85.     }
  86.    
  87.     ImageEntity(Applet a)
  88.     {
  89.         appFrame = a;
  90.         setImage(null);
  91.         setAlive(true);
  92.     }
  93.    
  94.     public Image getImage() {return image;}
  95.    
  96.     public void setImage(Image image)
  97.     {
  98.         this.image = image;
  99.         double x = frame.getSize().width / 2 - width() / 2;
  100.         double y = frame.getSize().height / 2 - height() / 2;
  101.         at = AffineTransform.getTranslateInstance(x,y);
  102.     }
  103.    
  104.     public int width()
  105.     {
  106.         if(image != null)
  107.         {
  108.             return image.getWidth(frame);
  109.         }
  110.         else
  111.         {
  112.             return 0;
  113.         }
  114.     }
  115.    
  116.     public int height()
  117.     {
  118.         if(image != null)
  119.         {
  120.             return image.getHeight(frame);
  121.         }
  122.         else
  123.         {
  124.             return 0;
  125.         }
  126.     }
  127.    
  128.     public double getCenterX()
  129.     {
  130.         return getX() + width() / 2;
  131.     }
  132.     public double getCenterY()
  133.     {
  134.         return getY() + height() / 2;
  135.     }
  136.    
  137.     public void setGraphics(Graphics2D g)
  138.     {
  139.         g2d = g;
  140.     }
  141.    
  142.     private URL getURL(String filename)
  143.     {
  144.         URL url = null;
  145.         try
  146.         {
  147.             url = this.getClass().getResource(filename);
  148.            
  149.         }
  150.         catch (Exception e)
  151.         {
  152.        
  153.         }
  154.         return url;
  155.     }
  156.    
  157.     public void load(String filename)
  158.     {
  159.         Toolkit tk = Toolkit.getDefaultToolkit();
  160.         image = tk.getImage(getURL(filename));
  161.         while(getImage().getWidth(frame) <= 0);
  162.         double x = frame.getSize().width / 2 - width() / 2;
  163.         double y = frame.getSize().height / 2 - height() / 2;
  164.         at = AffineTransform.getTranslateInstance(x,y);
  165.     }
  166.    
  167.     public void transform()
  168.     {
  169.         at.setToIdentity();
  170.         at.translate((int)getX() + width() / 2, (int)getY() + height() / 2);
  171.         at.rotate(Math.toRadians(getFaceAngle()));
  172.         at.translate(-width() / 2, -height() / 2);
  173.     }
  174.    
  175.     public void draw()
  176.     {
  177.         g2d.drawImage(getImage(),at,frame);
  178.     }
  179.     public void drawApp()
  180.     {
  181.         g2d.drawImage(getImage(),at,appFrame);
  182.     }
  183.     //bounding rectangle
  184.     public Rectangle getBounds()
  185.     {
  186.         Rectangle r;
  187.         r = new Rectangle((int)getX(), (int)getY(), width(),height());
  188.         return r;
  189.     }
  190.    
  191. }
  192.  
  193. //The third class
  194.  
  195. import java.applet.*;
  196. import java.awt.*;
  197. import java.awt.event.*;
  198. import java.awt.geom.*;
  199. import java.awt.image.*;
  200. import java.util.*;
  201. import javax.swing.*;
  202. /**
  203.  * Write a description of class AsteroidsMain here.
  204.  *
  205.  * @author (your name)
  206.  * @version (a version number or a date)
  207.  */
  208. //Primary game class
  209. public class GalacticWarCJR extends Applet implements Runnable, KeyListener
  210. {
  211.     //the main tread becomes the game loop
  212.     Thread gameloop;
  213.    
  214.     //use double buffer
  215.     BufferedImage backbuffer;
  216.    
  217.     //the main drawing object for the back buffer
  218.     Graphics2D g2d;
  219.    
  220.     //toggle for drawing bounding boxes
  221.     boolean showBounds = false;
  222.    
  223.     //create random number generator
  224.     Random rand = new Random();
  225.    
  226.     //create the asteroid array
  227.     int ASTEROIDS = (rand.nextInt(10) + 10);
  228.     AsteriodClass[] ast = new AsteriodClass[ASTEROIDS];
  229.    
  230.     //create the bullet array
  231.     int BULLETS = 1000;
  232.     BulletClass[] bullet = new BulletClass[BULLETS];
  233.     int currentBullet = 0;
  234.     int boomShot = 0;
  235.     //the player's ship
  236.     ImageEntity ship2 = new ImageEntity(this);
  237.    
  238.     //create id transform(0,0)
  239.     AffineTransform identity = new AffineTransform();
  240.    
  241.     //load sounds
  242.     SoundClip shoot;
  243.     SoundClip explode;
  244.    
  245.    
  246.     //Key Event Control booleans
  247.     boolean Up1 = false;
  248.     boolean Left1 = false;
  249.     boolean Right1 = false;
  250.     boolean Shoot1 = false;
  251.     boolean Bomb1 = false;
  252.     //applet init event
  253.     public void init()
  254.     {
  255.         //create the back buffer for smooth graphics
  256.         backbuffer = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB);
  257.         g2d = backbuffer.createGraphics();
  258.         /*
  259.         //set up the ship
  260.         ship2.setX(320);
  261.         ship2.setY(240);
  262.         ship2.load("PlayerShip.png");
  263.         ship2.setGraphics(g2d);
  264.         */
  265.         //set up the bullets
  266.         for(int n = 0; n < BULLETS; n++)
  267.         {
  268.             bullet[n] = new BulletClass();
  269.            
  270.         }
  271.        
  272.        
  273.         //create asteroids
  274.         for(int n2 = 0; n2 < ASTEROIDS; n2++)
  275.         {
  276.             ast[n2] = new AsteriodClass();
  277.             ast[n2].setRotationVelocity(rand.nextInt(30) + 1);
  278.             ast[n2].setX((double)rand.nextInt(600) + 20);
  279.             ast[n2].setY((double)rand.nextInt(440) + 20);
  280.             ast[n2].setMoveAngle(rand.nextInt(360));
  281.             double ang = ast[n2].getMoveAngle() - 90;
  282.             ast[n2].setVelX(calcAngleMoveX(ang));
  283.             ast[n2].setVelY(calcAngleMoveY(ang));
  284.         }
  285.        
  286.         shoot = new SoundClip("SmallBlaster.wav");
  287.         explode = new SoundClip("Biglaser1.wav");
  288.         //start the user input listener
  289.         addKeyListener(this);
  290.     }
  291.    
  292.     //applet update event to redraw the screen
  293.     public void update(Graphics g)
  294.     {
  295.         //start off transfors at identity
  296.         g2d.setTransform(identity);
  297.        
  298.         //erase the background
  299.         g2d.setPaint(Color.BLACK);
  300.         g2d.fillRect(0,0, getSize().width, getSize().height);
  301.        
  302.         //print some status information
  303.         g2d.setColor(Color.YELLOW);
  304.         //g2d.drawString( "Ship: " + Math.round(ship2.getX()) + "," + Math.round(ship2.getY()), 5 , 10 );
  305.         //g2d.drawString( "Move angle: " + Math.round(ship2.getMoveAngle() + 90), 5, 25 );
  306.         //g2d.drawString( "Face angle: " + Math.round(ship2.getFaceAngle()), 5, 40 );
  307.        
  308.         //draw the game graphics
  309.         //drawShip();
  310.         drawBullets();
  311.         drawAsteroids();
  312.        
  313.         //reprint the applet window
  314.         paint(g);
  315.     }
  316.     /*
  317.     //draw Ship called by applet update event
  318.     public void drawShip()
  319.     {
  320.         ship2.transform();
  321.         ship2.drawApp();
  322.         //ship.rotate(Math.toRadians(ship.getFaceAngle()));
  323.        
  324.         if(showBounds)
  325.         {
  326.             g2d.setTransform(identity);
  327.             //g2d.translate(ship.getX(), ship.getY());
  328.             g2d.setColor(Color.GREEN);
  329.             g2d.fill(ship2.getBounds());
  330.         }
  331.     }
  332.     */
  333.     //draw bullets called by applet update event
  334.     public void drawBullets()
  335.     {
  336.         //iterate through the array of bullets
  337.         for(int n = 0; n < BULLETS; n++)
  338.         {
  339.             //is this bullet currently in use?
  340.             if(bullet[n].isAlive())
  341.             {
  342.                 //draw the bullet
  343.                 g2d.setTransform(identity);
  344.                 g2d.translate(bullet[n].getX(), bullet[n].getY());
  345.                 g2d.setColor(Color.RED);
  346.                 g2d.draw(bullet[n].getShape());
  347.                
  348.             }
  349.         }
  350.     }
  351.    
  352.     //draw asteroids called by applet
  353.     public void drawAsteroids()
  354.     {
  355.         for(int n2 = 0; n2 < ASTEROIDS; n2++)
  356.         {
  357.             //is this asteroid being used?
  358.             if(ast[n2].isAlive())
  359.             {
  360.                 //draw the asteroid
  361.                 g2d.setTransform(identity);
  362.                 g2d.translate(ast[n2].getX(), ast[n2].getY());
  363.                 g2d.rotate(Math.toRadians(ast[n2].getMoveAngle()));
  364.                 g2d.setColor(Color.BLUE);
  365.                 g2d.fill(ast[n2].getShape());
  366.                
  367.             }
  368.         }
  369.     }
  370.    
  371.     //applet window repaint event - - draw the back buffer
  372.     public void paint(Graphics g)
  373.     {
  374.         //draw the back buffer onto the applet window
  375.         g.drawImage(backbuffer, 0, 0, this);
  376.     }
  377.    
  378.     //tread start event - start the game loop running
  379.     public void start()
  380.     {
  381.         //create the gameloop tread for real - time updates
  382.         gameloop = new Thread(this);
  383.         gameloop.start();
  384.     }
  385.    
  386.     //thread run event (game loop)
  387.     public void run()
  388.     {
  389.         //acquire the current thread
  390.         Thread t = Thread.currentThread();
  391.        
  392.         //keep going as long as the thread is alive
  393.         while(t == gameloop)
  394.         {
  395.             try
  396.             {
  397.                 //update the game loop
  398.                 gameUpdate();
  399.                
  400.                 //target framerate is 50 fps
  401.                 Thread.sleep(20);
  402.             }
  403.             catch(InterruptedException e)
  404.             {
  405.                 e.printStackTrace();
  406.             }
  407.             repaint();
  408.         }
  409.        
  410.     }
  411.    
  412.     //thread stop event
  413.     public void stop()
  414.     {
  415.         //kill gameloop thread
  416.         gameloop = null;
  417.     }
  418.    
  419.     //move and animate the objects in the game
  420.     private void gameUpdate()
  421.     {
  422.         //updateShip();
  423.         updateBullets();
  424.         updateAsteroids();
  425.         checkCollisions();
  426.         //keyPressed();
  427.         //keyReleased();
  428.         //HandleInPuts();
  429.     }
  430.     /*
  431.     //Update the ship position based on velocity
  432.     public void updateShip()
  433.     {
  434.         //update ship's X position
  435.         ship2.incX(ship2.getVelX());
  436.        
  437.         //wrap around left/right
  438.         if(ship2.getX() < -10)
  439.         {
  440.             ship2.setX(getSize().width + 10);
  441.         }
  442.         else if(ship2.getX() > getSize().width + 10)
  443.         {
  444.             ship2.setX(-10);
  445.         }
  446.        
  447.         //update ship's Y position
  448.         ship2.incY(ship2.getVelY());
  449.        
  450.         //wrap around up/down
  451.         if(ship2.getY() < -10)
  452.         {
  453.             ship2.setY(getSize().height + 10);
  454.         }
  455.         else if(ship2.getY() > getSize().height + 10)
  456.         {
  457.             ship2.setY(-10);
  458.         }
  459.        
  460.     }
  461.     */
  462.     //update the bullets based on velocity
  463.     public void updateBullets()
  464.     {
  465.         //move each bullet
  466.         for(int n = 0; n < BULLETS; n++)
  467.         {
  468.            
  469.             //is this bullet being used?
  470.             if(bullet[n].isAlive())
  471.             {
  472.                 //update bullet's position
  473.                 bullet[n].incX(bullet[n].getVelX());
  474.                
  475.                 //bullet disappears at left/right edge
  476.                 if(bullet[n].getX() < 0 || bullet[n].getX() > getSize().width)
  477.                 {
  478.                     bullet[n].setAlive(false);
  479.                 }
  480.                
  481.                 //update bullet's Y position
  482.                 bullet[n].incY(bullet[n].getVelY());
  483.                
  484.                 //bullet disappears at top/bottom edge
  485.                 if(bullet[n].getY() < 0 || bullet[n].getY() > getSize().height)
  486.                 {
  487.                     bullet[n].setAlive(false);
  488.                 }
  489.                
  490.             }
  491.         }
  492.     }
  493.    
  494.     //update the asteroids based on velocity
  495.     public void updateAsteroids()
  496.     {
  497.         //move and rotate Asteroids
  498.         for(int n2 = 0; n2 < ASTEROIDS; n2++)
  499.         {
  500.             //is this asteroid being used
  501.             if(ast[n2].isAlive())
  502.             {
  503.                 //update the asteroid's X value
  504.                 ast[n2].incX(ast[n2].getVelX());
  505.                
  506.                 //wrap the asteroid at left/right
  507.                 if(ast[n2].getX() < -20)
  508.                 {
  509.                     ast[n2].setX(getSize().width + 20);
  510.                 }
  511.                 else if(ast[n2].getX() > getSize().width + 20)
  512.                 {
  513.                     ast[n2].setX(-20);
  514.                 }
  515.                
  516.                 //update the asteroid's Y value
  517.                 ast[n2].incY(ast[n2].getVelY());
  518.                
  519.                 //wrap the asteroid at left/right
  520.                 if(ast[n2].getY() < -20)
  521.                 {
  522.                     ast[n2].setY(getSize().height + 20);
  523.                 }
  524.                 else if(ast[n2].getY() > getSize().height + 20)
  525.                 {
  526.                     ast[n2].setY(-20);
  527.                 }
  528.                
  529.                 //update the asteroid's rotation
  530.                 ast[n2].incMoveAngle(ast[n2].getRotationVelocity());
  531.                
  532.                 //keep the asgle within 0-359 degrees
  533.                 if(ast[n2].getMoveAngle() < 0)
  534.                 {
  535.                     ast[n2].setMoveAngle(360 - ast[n2].getRotationVelocity());
  536.                 }
  537.                 else if(ast[n2].getMoveAngle() > 360)
  538.                 {
  539.                     ast[n2].setMoveAngle(ast[n2].getRotationVelocity());
  540.                 }
  541.                
  542.             }
  543.         }
  544.     }
  545.    
  546.     //collision engine for asteroids
  547.     public void checkCollisions()
  548.     {
  549.         //iterate through the asteroids array
  550.         for(int m = 0; m < ASTEROIDS; m++)
  551.         {
  552.             //is this asteroid being used?
  553.             if(ast[m].isAlive())
  554.             {
  555.                 //check for collision with bullet
  556.                 for(int n = 0; n < BULLETS; n++)
  557.                 {
  558.                     //is this bullet being used?
  559.                     if(bullet[n].isAlive())
  560.                     {
  561.                         //perform the collision test
  562.                         if(ast[m].getBounds().contains(bullet[n].getX(), bullet[n].getY()))
  563.                         {
  564.                             bullet[n].setAlive(false);
  565.                             ast[m].setAlive(false);
  566.                             continue;
  567.                         }
  568.                     }
  569.                    
  570.                 }
  571.                 /*
  572.                 //check for collision with ship
  573.                 if(ast[m].getBounds().intersects(ship2.getBounds()))
  574.                 {
  575.                     ast[m].setAlive(false);
  576.                     ship2.setX(320);
  577.                     ship2.setY(240);
  578.                     ship2.setFaceAngle(0);
  579.                     ship2.setVelX(0);
  580.                     ship2.setVelY(0);
  581.                     continue;
  582.                 }
  583.                 */
  584.             }
  585.         }
  586.     }
  587.    
  588.     //key listener events
  589.     public void keyReleased(KeyEvent k)
  590.     {
  591.         int keyCode = k.getKeyCode();
  592.        
  593.         if(KeyEvent.VK_LEFT == keyCode)
  594.         {
  595.             Left1 = false;
  596.         }
  597.        
  598.         if(KeyEvent.VK_RIGHT == keyCode)
  599.         {
  600.              Right1 = false;
  601.         }
  602.        
  603.         if(KeyEvent.VK_UP == keyCode)
  604.         {
  605.              Up1 = false;
  606.         }
  607.        
  608.         if(KeyEvent.VK_SPACE == keyCode)
  609.         {
  610.              Shoot1 = false;
  611.         }
  612.        
  613.         if(KeyEvent.VK_ENTER == keyCode)
  614.         {
  615.              Bomb1 = false;
  616.         }
  617.     }
  618.     public void keyTyped(KeyEvent k)
  619.     {
  620.         int keyCode = k.getKeyCode();
  621.        
  622.     }
  623.    
  624.     public void keyPressed(KeyEvent k)
  625.     {
  626.    
  627.         int keyCode = k.getKeyCode();
  628.        
  629.         if(KeyEvent.VK_LEFT == keyCode)
  630.         {
  631.             Left1 = true;
  632.         }
  633.        
  634.         if(KeyEvent.VK_RIGHT == keyCode)
  635.         {
  636.              Right1 = true;
  637.         }
  638.        
  639.         if(KeyEvent.VK_UP == keyCode)
  640.         {
  641.              Up1 = true;
  642.         }
  643.        
  644.         if(KeyEvent.VK_SPACE == keyCode)
  645.         {
  646.              Shoot1 = true;
  647.         }
  648.        
  649.         if(KeyEvent.VK_ENTER == keyCode)
  650.         {
  651.              Bomb1 = true;
  652.         }
  653.     }
  654.     /*
  655.     public void HandleInPuts()
  656.     {
  657.         if(Left1 == true)
  658.         {
  659.             //left arrow rotates ship left 5 degrees
  660.             ship2.incFaceAngle(-5);
  661.             if(ship2.getFaceAngle() < 0)
  662.             {
  663.                 ship2.setFaceAngle(360 - 5);
  664.             }
  665.         }
  666.        
  667.         if(Right1 == true)
  668.         {
  669.             //right arrow rotates ship right 5 degrees
  670.             ship2.incFaceAngle(5);
  671.             if(ship2.getFaceAngle() > 360)
  672.             {
  673.                  ship2.setFaceAngle(5);
  674.             }
  675.         }
  676.        
  677.         if(Up1 == true)
  678.         {
  679.             //up arrow adds thrust to ship (1/10 normal speed)
  680.             ship2.setMoveAngle(ship2.getFaceAngle() - 90);
  681.             ship2.incVelX(calcAngleMoveX(ship2.getMoveAngle()) * 0.1);
  682.             ship2.incVelY(calcAngleMoveY(ship2.getMoveAngle()) * 0.1);
  683.         }
  684.        
  685.         if(Shoot1 == true)
  686.         {
  687.             //fire a bullet
  688.             currentBullet++;
  689.             if(currentBullet > BULLETS - 1)
  690.             {
  691.                 currentBullet = 0;
  692.             }
  693.             bullet[currentBullet].setAlive(true);
  694.                    
  695.             //point bullet in same direction ship is facing
  696.             bullet[currentBullet].setX(ship2.getX());
  697.             bullet[currentBullet].setY(ship2.getY());
  698.             bullet[currentBullet].setMoveAngle(ship2.getFaceAngle() - 90);
  699.                    
  700.             //fire bullet at angle of the shipbullet[currentBullet]
  701.             double angle = ship2.getFaceAngle() - 90;
  702.             double svx = ship2.getVelX();
  703.             double svy = ship2.getVelY();
  704.             bullet[currentBullet].setVelX(svx + calcAngleMoveX(angle) * 15);
  705.             bullet[currentBullet].setVelY(svy + calcAngleMoveY(angle) * 15);
  706.         }
  707.        
  708.         if(Bomb1 == true)
  709.         {
  710.             //fire a bullet
  711.             for(int C = 0; C < 360; C++)
  712.             {
  713.                 currentBullet++;
  714.                 boomShot++;
  715.                 if(boomShot >= 360)
  716.                 {
  717.                     boomShot = 0;
  718.                 }
  719.                 if(currentBullet > BULLETS - 1)
  720.                 {
  721.                     currentBullet = 0;
  722.                 }
  723.                 if(currentBullet > 360)
  724.                 {
  725.                     bullet[currentBullet].setAlive(true);
  726.                    
  727.                     //point bullet in same direction ship is facing
  728.                     bullet[currentBullet].setX(ship2.getX());
  729.                     bullet[currentBullet].setY(ship2.getY());
  730.                     bullet[currentBullet].setMoveAngle(ship2.getFaceAngle() - 90);
  731.                    
  732.                     //fire bullet at angle of the shipbullet[currentBullet]
  733.                     double angle = ship2.getFaceAngle() - boomShot;
  734.                     double svx = ship2.getVelX();
  735.                     double svy = ship2.getVelY();
  736.                     bullet[currentBullet].setVelX(svx + calcAngleMoveX(angle) * 15);
  737.                     bullet[currentBullet].setVelY(svy + calcAngleMoveY(angle) * 15);
  738.                 }
  739.             }
  740.         }
  741.     }
  742.     */
  743.     //calculate X movement value based on direction
  744.     public double calcAngleMoveX(double angle)
  745.     {
  746.         return (double)(Math.cos(angle * Math.PI / 180));
  747.     }
  748.    
  749.     //calculate Y movement value based on direction
  750.     public double calcAngleMoveY(double angle)
  751.     {
  752.         return (double)(Math.sin(angle * Math.PI / 180));
  753.     }
  754.    
  755. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement